📄 net.c
字号:
/* * The olsr.org Optimized Link-State Routing daemon(olsrd) * Copyright (c) 2004, Andreas T鴑nesen(andreto@olsr.org) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of olsr.org, olsrd nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Visit http://www.olsr.org for more information. * * If you find this software useful feel free to make a donation * to the project. For more information see the website or contact * the copyright holders. * * $Id: net.c,v 1.34 2007/04/25 22:08:18 bernd67 Exp $ *//* * Linux spesific code */#include "net.h"#include "../defs.h"#include "../net_os.h"#include "../parser.h"/* *Wireless definitions for ioctl calls *(from linux/wireless.h) */#define SIOCGIWNAME 0x8B01 /* get name == wireless protocol */#define SIOCGIWRATE 0x8B21 /* get default bit rate (bps) *//* The original state of the IP forwarding proc entry */static char orig_fwd_state;static char orig_global_redirect_state;/** *Bind a socket to a device * *@param sock the socket to bind *@param dev_name name of the device * *@return negative if error */intbind_socket_to_device(int sock, char *dev_name){ /* *Bind to device using the SO_BINDTODEVICE flag */ OLSR_PRINTF(3, "Binding socket %d to device %s\n", sock, dev_name); return setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, dev_name, strlen(dev_name)+1);}/** *Enable IP forwarding. *Just writing "1" to the /proc/sys/net/ipv4/ip_forward *if using IPv4 or /proc/sys/net/ipv6/conf/all/forwarding *if using IPv6. *Could probably drop the check for *"0" here and write "1" anyways. * *@param version IP version. * *@return 1 on sucess 0 on failiure */ intenable_ip_forwarding(int version){ FILE *proc_fwd; const char * const procfile = version == AF_INET ? "/proc/sys/net/ipv4/ip_forward" : "/proc/sys/net/ipv6/conf/all/forwarding"; if ((proc_fwd=fopen(procfile, "r"))==NULL) { /* IPv4 */ if(version == AF_INET) fprintf(stderr, "WARNING! Could not open the %s file to check/enable IP forwarding!\nAre you using the procfile filesystem?\nDoes your system support IPv4?\nI will continue(in 3 sec) - but you should mannually ensure that IP forwarding is enabeled!\n\n", procfile); /* IPv6 */ else fprintf(stderr, "WARNING! Could not open the %s file to check/enable IP forwarding!\nAre you using the procfile filesystem?\nDoes your system support IPv6?\nI will continue(in 3 sec) - but you should mannually ensure that IP forwarding is enabeled!\n\n", procfile); sleep(3); return 0; } orig_fwd_state = fgetc(proc_fwd); fclose(proc_fwd); if(orig_fwd_state == '1') { OLSR_PRINTF(3, "\nIP forwarding is enabled on this system\n"); } else { if ((proc_fwd=fopen(procfile, "w"))==NULL) { fprintf(stderr, "Could not open %s for writing!\n", procfile); fprintf(stderr, "I will continue(in 3 sec) - but you should mannually ensure that IP forwarding is enabeled!\n\n"); sleep(3); return 0; } else { syslog(LOG_INFO, "Writing \"1\" to %s\n", procfile); fputs("1", proc_fwd); } fclose(proc_fwd); } return 1; }intdisable_redirects_global(int version){ FILE *proc_redirect; const char * const procfile = "/proc/sys/net/ipv4/conf/all/send_redirects"; if(version == AF_INET6) return -1; if((proc_redirect = fopen(procfile, "r")) == NULL) { fprintf(stderr, "WARNING! Could not open the %s file to check/disable ICMP redirects!\nAre you using the procfile filesystem?\nDoes your system support IPv4?\nI will continue(in 3 sec) - but you should mannually ensure that ICMP redirects are disabled!\n\n", procfile); sleep(3); return -1; } orig_global_redirect_state = fgetc(proc_redirect); fclose(proc_redirect); if(orig_global_redirect_state == '0') return 0; if ((proc_redirect = fopen(procfile, "w"))==NULL) { fprintf(stderr, "Could not open %s for writing!\n", procfile); fprintf(stderr, "I will continue(in 3 sec) - but you should mannually ensure that ICMP redirect is disabeled!\n\n"); sleep(3); return 0; } syslog(LOG_INFO, "Writing \"0\" to %s", procfile); fputs("0", proc_redirect); fclose(proc_redirect); return 1;}/** * *@return 1 on sucess 0 on failiure */ intdisable_redirects(const char *if_name, struct interface *iface, int version){ FILE *proc_redirect; char procfile[FILENAME_MAX]; if(version == AF_INET6) return -1; /* Generate the procfile name */ snprintf(procfile, sizeof(procfile), REDIRECT_PROC, if_name); if((proc_redirect = fopen(procfile, "r")) == NULL) { fprintf(stderr, "WARNING! Could not open the %s file to check/disable ICMP redirects!\nAre you using the procfile filesystem?\nDoes your system support IPv4?\nI will continue(in 3 sec) - but you should mannually ensure that ICMP redirects are disabled!\n\n", procfile); sleep(3); return 0; } iface->nic_state.redirect = fgetc(proc_redirect); fclose(proc_redirect); if ((proc_redirect = fopen(procfile, "w"))==NULL) { fprintf(stderr, "Could not open %s for writing!\n", procfile); fprintf(stderr, "I will continue(in 3 sec) - but you should mannually ensure that ICMP redirect is disabeled!\n\n"); sleep(3); return 0; } syslog(LOG_INFO, "Writing \"0\" to %s", procfile); fputs("0", proc_redirect); fclose(proc_redirect); return 1;}/** * *@return 1 on sucess 0 on failiure */ intdeactivate_spoof(const char *if_name, struct interface *iface, int version){ FILE *proc_spoof; char procfile[FILENAME_MAX]; if(version == AF_INET6) return -1; /* Generate the procfile name */ sprintf(procfile, SPOOF_PROC, if_name); if((proc_spoof = fopen(procfile, "r")) == NULL) { fprintf(stderr, "WARNING! Could not open the %s file to check/disable the IP spoof filter!\nAre you using the procfile filesystem?\nDoes your system support IPv4?\nI will continue(in 3 sec) - but you should mannually ensure that IP spoof filtering is disabled!\n\n", procfile); sleep(3); return 0; } iface->nic_state.spoof = fgetc(proc_spoof); fclose(proc_spoof); if ((proc_spoof = fopen(procfile, "w")) == NULL) { fprintf(stderr, "Could not open %s for writing!\n", procfile); fprintf(stderr, "I will continue(in 3 sec) - but you should mannually ensure that IP spoof filtering is disabeled!\n\n"); sleep(3); return 0; } syslog(LOG_INFO, "Writing \"0\" to %s", procfile); fputs("0", proc_spoof); fclose(proc_spoof); return 1;}/** *Resets the spoof filter and ICMP redirect settings */intrestore_settings(int version){ struct interface *ifs; OLSR_PRINTF(1, "Restoring network state\n"); /* Restore IP forwarding to "off" */ if(orig_fwd_state == '0') { const char * const procfile = version == AF_INET ? "/proc/sys/net/ipv4/ip_forward" : "/proc/sys/net/ipv6/conf/all/forwarding"; FILE *proc_fd; if ((proc_fd = fopen(procfile, "w")) == NULL) { fprintf(stderr, "Could not open %s for writing!\nSettings not restored!\n", procfile); } else { syslog(LOG_INFO, "Resetting %s to %c\n", procfile, orig_fwd_state); fputc(orig_fwd_state, proc_fd); fclose(proc_fd); } } /* Restore global ICMP redirect setting */ if(orig_global_redirect_state != '0') { if(version == AF_INET) { const char * const procfile = "/proc/sys/net/ipv4/conf/all/send_redirects"; FILE *proc_fd; if ((proc_fd = fopen(procfile, "w")) == NULL) { fprintf(stderr, "Could not open %s for writing!\nSettings not restored!\n", procfile); } else { syslog(LOG_INFO, "Resetting %s to %c\n", procfile, orig_global_redirect_state); fputc(orig_global_redirect_state, proc_fd); fclose(proc_fd); } } } if(version == AF_INET6) return 0; for(ifs = ifnet; ifs != NULL; ifs = ifs->int_next) { char procfile[FILENAME_MAX]; FILE *proc_fd; /* Discard host-emulation interfaces */ if(ifs->is_hcif) continue; /* ICMP redirects */ /* Generate the procfile name */ snprintf(procfile, sizeof(procfile), REDIRECT_PROC, ifs->int_name); if ((proc_fd = fopen(procfile, "w")) == NULL) fprintf(stderr, "Could not open %s for writing!\nSettings not restored!\n", procfile); else { syslog(LOG_INFO, "Resetting %s to %c\n", procfile, ifs->nic_state.redirect); fputc(ifs->nic_state.redirect, proc_fd); fclose(proc_fd); } /* Spoof filter */ /* Generate the procfile name */ sprintf(procfile, SPOOF_PROC, ifs->int_name); if ((proc_fd = fopen(procfile, "w")) == NULL) fprintf(stderr, "Could not open %s for writing!\nSettings not restored!\n", procfile); else { syslog(LOG_INFO, "Resetting %s to %c\n", procfile, ifs->nic_state.spoof); fputc(ifs->nic_state.spoof, proc_fd); fclose(proc_fd); } } return 1;}/** *Creates a nonblocking broadcast socket. *@param sa sockaddr struct. Used for bind(2). *@return the FD of the socket or -1 on error. */intgethemusocket(struct sockaddr_in *pin){ int sock, on = 1; OLSR_PRINTF(1, " Connecting to switch daemon port 10150..."); if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("hcsocket"); syslog(LOG_ERR, "hcsocket: %m"); return -1; } if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { perror("SO_REUSEADDR failed"); close(sock); return -1; } /* connect to PORT on HOST */ if (connect(sock,(struct sockaddr *) pin, sizeof(*pin)) < 0) { printf("FAILED\n"); fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno)); printf("connection refused\n"); close(sock); return -1; } printf("OK\n"); /* Keep TCP socket blocking */ return sock;}/** *Creates a nonblocking broadcast socket. *@param sa sockaddr struct. Used for bind(2). *@return the FD of the socket or -1 on error. */intgetsocket(struct sockaddr *sa, int bufspace, char *int_name){ struct sockaddr_in *sin=(struct sockaddr_in *)sa; int sock, on = 1; if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); syslog(LOG_ERR, "socket: %m"); return -1; }#ifdef SO_BROADCAST if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { perror("setsockopt"); syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m"); close(sock); return -1; }#endif if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { perror("SO_REUSEADDR failed"); close(sock); return -1; }#ifdef SO_RCVBUF for (on = bufspace; ; on -= 1024) { if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &on, sizeof (on)) == 0) break; if (on <= 8*1024) { perror("setsockopt"); syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m"); break; } }#endif /* * WHEN USING KERNEL 2.6 THIS MUST HAPPEN PRIOR TO THE PORT BINDING!!!! */ /* Bind to device */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -