📄 ifnet.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: ifnet.c,v 1.51 2007/08/23 21:20:02 bernd67 Exp $ */#if defined __FreeBSD__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__#define ifr_netmask ifr_addr#endif#include "interfaces.h"#include "ifnet.h"#include "defs.h"#include "olsr.h"#include "net_os.h"#include "net_olsr.h"#include "socket_parser.h"#include "parser.h"#include "scheduler.h"#include "generate_msg.h"#include "mantissa.h"#include "lq_packet.h"#include "log.h"#include "link_set.h"#include <signal.h>#include <sys/types.h>#include <net/if.h>#include <net/if_arp.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <arpa/inet.h>#include <netdb.h>#include <unistd.h>int bufspace = 127*1024; /* max. input buffer size to request */intset_flag(char *ifname, short flag __attribute__((unused))){ struct ifreq ifr; strncpy(ifr.ifr_name, ifname, IFNAMSIZ); /* Get flags */ if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) { fprintf(stderr,"ioctl (get interface flags)"); return -1; } strncpy(ifr.ifr_name, ifname, IFNAMSIZ); //printf("Setting flags for if \"%s\"\n", ifr.ifr_name); if(!(ifr.ifr_flags & (IFF_UP | IFF_RUNNING))) { /* Add UP */ ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); /* Set flags + UP */ if(ioctl(olsr_cnf->ioctl_s, SIOCSIFFLAGS, &ifr) < 0) { fprintf(stderr, "ERROR(%s): %s\n", ifr.ifr_name, strerror(errno)); return -1; } } return 1;}voidcheck_interface_updates(void *foo __attribute__((unused))){ struct olsr_if *tmp_if;#ifdef DEBUG OLSR_PRINTF(3, "Checking for updates in the interface set\n");#endif for(tmp_if = olsr_cnf->interfaces; tmp_if != NULL; tmp_if = tmp_if->next) { if(tmp_if->host_emul) continue; if(olsr_cnf->host_emul) /* XXX: TEMPORARY! */ continue; if(!tmp_if->cnf->autodetect_chg) {#ifdef DEBUG /* Don't check this interface */ OLSR_PRINTF(3, "Not checking interface %s\n", tmp_if->name)#endif continue; } if(tmp_if->configured) { chk_if_changed(tmp_if); } else { chk_if_up(tmp_if, 3); } } return;}/** * Checks if an initialized interface is changed * that is if it has been set down or the address * has been changed. * *@param iface the olsr_if struct describing the interface */intchk_if_changed(struct olsr_if *iface){ struct interface *ifp, *tmp_ifp; struct ifreq ifr; struct sockaddr_in6 tmp_saddr6; int if_changes; if_changes = 0;#ifdef DEBUG OLSR_PRINTF(3, "Checking if %s is set down or changed\n", iface->name);#endif if(iface->host_emul) return -1; ifp = iface->interf; if(ifp == NULL) { /* Should not happen */ iface->configured = 0; return 0; } memset(&ifr, 0, sizeof(struct ifreq)); strncpy(ifr.ifr_name, iface->name, IFNAMSIZ); /* Get flags (and check if interface exists) */ if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) { OLSR_PRINTF(3, "No such interface: %s\n", iface->name); goto remove_interface; } ifp->int_flags = ifr.ifr_flags; /* * First check if the interface is set DOWN */ if ((ifp->int_flags & IFF_UP) == 0) { OLSR_PRINTF(1, "\tInterface %s not up - removing it...\n", iface->name); goto remove_interface; } /* * We do all the interface type checks over. * This is because the interface might be a PCMCIA card. Therefore * It might not be the same physical interface as we configured earlier. */ /* Check broadcast */ if ((olsr_cnf->ip_version == AF_INET) && !iface->cnf->ipv4_broadcast.v4 && /* Skip if fixed bcast */ (!(ifp->int_flags & IFF_BROADCAST))) { OLSR_PRINTF(3, "\tNo broadcast - removing\n"); goto remove_interface; } if (ifp->int_flags & IFF_LOOPBACK) { OLSR_PRINTF(3, "\tThis is a loopback interface - removing it...\n"); goto remove_interface; } ifp->is_hcif = OLSR_FALSE; /* trying to detect if interface is wireless. */ ifp->is_wireless = check_wireless_interface(ifr.ifr_name); /* Set interface metric */ if(iface->cnf->weight.fixed) ifp->int_metric = iface->cnf->weight.value; else ifp->int_metric = calculate_if_metric(ifr.ifr_name); /* Get MTU */ if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMTU, &ifr) < 0) ifp->int_mtu = 0; else { ifr.ifr_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE; if(ifp->int_mtu != ifr.ifr_mtu) { ifp->int_mtu = ifr.ifr_mtu; /* Create new outputbuffer */ net_remove_buffer(ifp); /* Remove old */ net_add_buffer(ifp); } } /* Get interface index */ ifp->if_index = if_nametoindex(ifr.ifr_name); /* * Now check if the IP has changed */ /* IP version 6 */ if(olsr_cnf->ip_version == AF_INET6) { /* Get interface address */ if(get_ipv6_address(ifr.ifr_name, &tmp_saddr6, iface->cnf->ipv6_addrtype) <= 0) { if(iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL) OLSR_PRINTF(3, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name); else OLSR_PRINTF(3, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name); goto remove_interface; } #ifdef DEBUG OLSR_PRINTF(3, "\tAddress: %s\n", ip6_to_string(&tmp_saddr6.sin6_addr));#endif if(memcmp(&tmp_saddr6.sin6_addr, &ifp->int6_addr.sin6_addr, olsr_cnf->ipsize) != 0) { OLSR_PRINTF(1, "New IP address for %s:\n", ifr.ifr_name); OLSR_PRINTF(1, "\tOld: %s\n", ip6_to_string(&ifp->int6_addr.sin6_addr)); OLSR_PRINTF(1, "\tNew: %s\n", ip6_to_string(&tmp_saddr6.sin6_addr)); /* Check main addr */ if(memcmp(&olsr_cnf->main_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize) == 0) { /* Update main addr */ memcpy(&olsr_cnf->main_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize); } /* Update address */ memcpy(&ifp->int6_addr.sin6_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize); memcpy(&ifp->ip_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize); run_ifchg_cbs(ifp, IFCHG_IF_UPDATE); return 1; } return 0; } else /* IP version 4 */ { /* Check interface address (IPv4)*/ if(ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0) { OLSR_PRINTF(1, "\tCould not get address of interface - removing it\n"); goto remove_interface; }#ifdef DEBUG OLSR_PRINTF(3, "\tAddress:%s\n", sockaddr_to_string(&ifr.ifr_addr));#endif if(memcmp(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr, &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr, olsr_cnf->ipsize) != 0) { /* New address */ OLSR_PRINTF(1, "IPv4 address changed for %s\n", ifr.ifr_name); OLSR_PRINTF(1, "\tOld:%s\n", sockaddr_to_string(&ifp->int_addr)); OLSR_PRINTF(1, "\tNew:%s\n", sockaddr_to_string(&ifr.ifr_addr)); ifp->int_addr = ifr.ifr_addr; if(memcmp(&olsr_cnf->main_addr, &ifp->ip_addr, olsr_cnf->ipsize) == 0) { OLSR_PRINTF(1, "New main address: %s\n", sockaddr_to_string(&ifr.ifr_addr)); olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", sockaddr_to_string(&ifr.ifr_addr)); memcpy(&olsr_cnf->main_addr, &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr, olsr_cnf->ipsize); } memcpy(&ifp->ip_addr, &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr, olsr_cnf->ipsize); if_changes = 1; } /* Check netmask */ if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0) { olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name); goto remove_interface; }#ifdef DEBUG OLSR_PRINTF(3, "\tNetmask:%s\n", sockaddr_to_string(&ifr.ifr_netmask));#endif if(memcmp(&((struct sockaddr_in *)&ifp->int_netmask)->sin_addr.s_addr, &((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr, olsr_cnf->ipsize) != 0) { /* New address */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -