📄 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.38 2007/10/04 22:27:31 bernd67 Exp $ */#include "defs.h"#include "net_os.h"#include "parser.h" /* dnc: needed for call to packet_parser() */#include "net.h"#include <net/if.h>#ifdef __NetBSD__#include <sys/param.h>#include <net/if_ether.h>#endif#ifdef __OpenBSD__#include <netinet/if_ether.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <netinet/ip_icmp.h>#include <netinet/icmp_var.h>#include <netinet/icmp6.h>#include <netinet6/in6_var.h> /* For struct in6_ifreq */#include <ifaddrs.h>#include <sys/uio.h>#endif#ifdef __FreeBSD__#include <ifaddrs.h>#include <net/if_var.h>#include <net/ethernet.h>#include <netinet/in_var.h>#ifndef FBSD_NO_80211#include <net80211/ieee80211.h>#include <net80211/ieee80211_ioctl.h>#endif#endif#ifdef __MacOSX__#include <ifaddrs.h>#include <net/if_var.h>#include <net/ethernet.h>#include <netinet/in_var.h>#endif#include <net/if_dl.h>#ifdef SPOOF#include <libnet.h>#endif /* SPOOF *///#define SIOCGIFGENERIC _IOWR('i', 58, struct ifreq) /* generic IF get op *///#define SIOCGWAVELAN SIOCGIFGENERIC#include <sys/sysctl.h>static int ignore_redir;static int send_redir;static int gateway;static int set_sysctl_int(char *name, int new){ int old;#if __MacOSX__ || __OpenBSD__ size_t len = sizeof (old);#else unsigned int len = sizeof (old);#endif#ifdef __OpenBSD__ int mib[4]; /* Set net.inet.ip.forwarding by default. */ mib[0] = CTL_NET; mib[1] = PF_INET; mib[2] = IPPROTO_IP; mib[3] = IPCTL_FORWARDING; if (!strcmp(name, "net.inet6.ip6.forwarding")) { mib[1] = PF_INET6; mib[2] = IPPROTO_IPV6; } else if (!strcmp(name, "net.inet.icmp.rediraccept")) { mib[2] = IPPROTO_ICMP; mib[3] = ICMPCTL_REDIRACCEPT; } else if (!strcmp(name, "net.inet6.icmp6.rediraccept")) { mib[2] = IPPROTO_ICMPV6; mib[3] = ICMPV6CTL_REDIRACCEPT; } else if (!strcmp(name, "net.inet.ip.redirect")) { mib[3] = IPCTL_SENDREDIRECTS; } else if (!strcmp(name, "net.inet6.ip6.redirect")) { mib[1] = PF_INET6; mib[2] = IPPROTO_IPV6; mib[3] = IPCTL_SENDREDIRECTS; } if (sysctl(mib, 4, &old, &len, &new, sizeof (new)) < 0) return -1;#else if (sysctlbyname(name, &old, &len, &new, sizeof (new)) < 0) return -1;#endif return old;}int enable_ip_forwarding(int version){ char *name; if (olsr_cnf->ip_version == AF_INET) name = "net.inet.ip.forwarding"; else name = "net.inet6.ip6.forwarding"; gateway = set_sysctl_int(name, 1); if (gateway < 0) { fprintf(stderr, "Cannot enable IP forwarding. Please enable IP forwarding manually. Continuing in 3 seconds...\n"); sleep(3); } return 1;}intdisable_redirects_global(int version){ char *name; // do not accept ICMP redirects#ifdef __OpenBSD__ if (olsr_cnf->ip_version == AF_INET) name = "net.inet.icmp.rediraccept"; else name = "net.inet6.icmp6.rediraccept"; ignore_redir = set_sysctl_int(name, 0);#elif defined __FreeBSD__ || defined __MacOSX__ if (olsr_cnf->ip_version == AF_INET) { name = "net.inet.icmp.drop_redirect"; ignore_redir = set_sysctl_int(name, 1); } else { name = "net.inet6.icmp6.rediraccept"; ignore_redir = set_sysctl_int(name, 0); }#else if (olsr_cnf->ip_version == AF_INET) name = "net.inet.icmp.drop_redirect"; else name = "net.inet6.icmp6.drop_redirect"; ignore_redir = set_sysctl_int(name, 1);#endif if (ignore_redir < 0) { fprintf(stderr, "Cannot disable incoming ICMP redirect messages. Please disable them manually. Continuing in 3 seconds...\n"); sleep(3); } // do not send ICMP redirects if (olsr_cnf->ip_version == AF_INET) name = "net.inet.ip.redirect"; else name = "net.inet6.ip6.redirect"; send_redir = set_sysctl_int(name, 0); if (send_redir < 0) { fprintf(stderr, "Cannot disable outgoing ICMP redirect messages. Please disable them manually. Continuing in 3 seconds...\n"); sleep(3); } return 1;}int disable_redirects(const char *if_name, struct interface *iface, int version){ // this function gets called for each interface olsrd uses; however, // FreeBSD can only globally control ICMP redirects, and not on a // per-interface basis; hence, only disable ICMP redirects in the "global" // function return 1;}int deactivate_spoof(const char *if_name, struct interface *iface, int version){ return 1;}int restore_settings(int version){ char *name; // reset IP forwarding if (olsr_cnf->ip_version == AF_INET) name = "net.inet.ip.forwarding"; else name = "net.inet6.ip6.forwarding"; set_sysctl_int(name, gateway); // reset incoming ICMP redirects#ifdef __OpenBSD__ if (olsr_cnf->ip_version == AF_INET) name = "net.inet.icmp.rediraccept"; else name = "net.inet6.icmp6.rediraccept";#elif defined __FreeBSD__ || defined __MacOSX__ if (olsr_cnf->ip_version == AF_INET) name = "net.inet.icmp.drop_redirect"; else name = "net.inet6.icmp6.rediraccept";#else if (olsr_cnf->ip_version == AF_INET) name = "net.inet.icmp.drop_redirect"; else name = "net.inet6.icmp6.drop_redirect";#endif set_sysctl_int(name, ignore_redir); // reset outgoing ICMP redirects if (olsr_cnf->ip_version == AF_INET) name = "net.inet.ip.redirect"; else name = "net.inet6.ip6.redirect"; set_sysctl_int(name, send_redir); 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);}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); } if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { perror("setsockopt"); syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m"); close(sock); return (-1); } if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { perror("SO_REUSEADDR failed"); close(sock); return (-1); } if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0) { perror("SO_REUSEPORT failed"); close(sock); return (-1); } if (setsockopt(sock, IPPROTO_IP, IP_RECVIF, &on, sizeof(on)) < 0) { perror("IP_RECVIF failed"); close(sock); return (-1); } 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; } } if (bind(sock, (struct sockaddr *)sin, sizeof (*sin)) < 0) { perror("bind"); syslog(LOG_ERR, "bind: %m"); close(sock); return (-1); } if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1) syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n"); return (sock);}int getsocket6(struct sockaddr_in6 *sin, int bufspace, char *int_name){ int sock, on = 1; if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { perror("socket"); syslog(LOG_ERR, "socket: %m"); return (-1); } 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; } } if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -