📄 networkinterfaces.c
字号:
/* For each item in the interface configuration list... */ ifr = ifc.ifc_req; for (n = ifc.ifc_len / sizeof(struct ifreq); --n >= 0; ifr++) { struct interface* olsrIntf; union olsr_ip_addr ipAddr; /* Skip the BMF network interface itself */ if (strncmp(ifr->ifr_name, EtherTunTapIfName, IFNAMSIZ) == 0) { continue; /* for (n = ...) */ } /* ...find the OLSR interface structure, if any */ COPY_IP(&ipAddr, &((struct sockaddr_in*)&ifr->ifr_addr)->sin_addr.s_addr); olsrIntf = if_ifwithaddr(&ipAddr); if (skipThisIntf != NULL && olsrIntf == skipThisIntf) { continue; /* for (n = ...) */ } if (olsrIntf == NULL && ! IsNonOlsrBmfIf(ifr->ifr_name)) { /* Interface is neither OLSR interface, nor specified as non-OLSR BMF * interface in the BMF plugin parameter list */ continue; /* for (n = ...) */ } nOpenedSockets += CreateInterface(ifr->ifr_name, olsrIntf); } /* for (n = ...) */ free(ifc.ifc_buf); /* Create the BMF network interface */ EtherTunTapFd = CreateLocalEtherTunTap(); if (EtherTunTapFd >= 0) { nOpenedSockets++; } if (BmfInterfaces == NULL) { olsr_printf(1, "%s: could not initialize any network interface\n", PLUGIN_NAME); } else { olsr_printf(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpenedSockets); } return 0;} /* CreateBmfNetworkInterfaces *//* ------------------------------------------------------------------------- * Function : AddInterface * Description: Add an OLSR-enabled network interface to the list of BMF-enabled * network interfaces * Input : newIntf - network interface to add * Output : none * Return : none * Data Used : none * ------------------------------------------------------------------------- */void AddInterface(struct interface* newIntf){ int nOpened; assert(newIntf != NULL); nOpened = CreateInterface(newIntf->int_name, newIntf); olsr_printf(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpened);} /* AddInterface *//* ------------------------------------------------------------------------- * Function : CloseBmfNetworkInterfaces * Description: Closes every socket on each network interface used by BMF * Input : none * Output : none * Return : none * Data Used : none * Notes : Closes * - the local EtherTunTap interface (e.g. "tun0" or "tap0") * - for each BMF-enabled interface, the socket used for * capturing multicast packets * - for each OLSR-enabled interface, the socket used for * encapsulating packets * Also restores the network state to the situation before BMF * was started. * ------------------------------------------------------------------------- */void CloseBmfNetworkInterfaces(void){ int nClosed = 0; u_int32_t totalOlsrBmfPacketsRx = 0; u_int32_t totalOlsrBmfPacketsRxDup = 0; u_int32_t totalOlsrBmfPacketsTx = 0; u_int32_t totalNonOlsrBmfPacketsRx = 0; u_int32_t totalNonOlsrBmfPacketsRxDup = 0; u_int32_t totalNonOlsrBmfPacketsTx = 0; /* Close all opened sockets */ struct TBmfInterface* nextBmfIf = BmfInterfaces; while (nextBmfIf != NULL) { struct TBmfInterface* bmfIf = nextBmfIf; nextBmfIf = bmfIf->next; if (bmfIf->capturingSkfd >= 0) { close(bmfIf->capturingSkfd); nClosed++; } if (bmfIf->encapsulatingSkfd >= 0) { close(bmfIf->encapsulatingSkfd); nClosed++; } OLSR_PRINTF( 7, "%s: %s interface \"%s\": RX pkts %d (%d dups); TX pkts %d\n", PLUGIN_NAME_SHORT, bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR", bmfIf->ifName, bmfIf->nBmfPacketsRx, bmfIf->nBmfPacketsRxDup, bmfIf->nBmfPacketsTx); olsr_printf( 1, "%s: closed %s interface \"%s\"\n", PLUGIN_NAME_SHORT, bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR", bmfIf->ifName); /* Add totals */ if (bmfIf->olsrIntf != NULL) { totalOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx; totalOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup; totalOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx; } else { totalNonOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx; totalNonOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup; totalNonOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx; } free(bmfIf); } /* while */ if (EtherTunTapFd >= 0) { close(EtherTunTapFd); nClosed++; OLSR_PRINTF(7, "%s: closed \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName); } BmfInterfaces = NULL; olsr_printf(1, "%s: closed %d sockets\n", PLUGIN_NAME_SHORT, nClosed); OLSR_PRINTF( 7, "%s: Total all OLSR interfaces : RX pkts %d (%d dups); TX pkts %d\n", PLUGIN_NAME_SHORT, totalOlsrBmfPacketsRx, totalOlsrBmfPacketsRxDup, totalOlsrBmfPacketsTx); OLSR_PRINTF( 7, "%s: Total all non-OLSR interfaces: RX pkts %d (%d dups); TX pkts %d\n", PLUGIN_NAME_SHORT, totalNonOlsrBmfPacketsRx, totalNonOlsrBmfPacketsRxDup, totalNonOlsrBmfPacketsTx);} /* CloseBmfNetworkInterfaces */#define MAX_NON_OLSR_IFS 32static char NonOlsrIfNames[MAX_NON_OLSR_IFS][IFNAMSIZ];static int nNonOlsrIfs = 0;/* ------------------------------------------------------------------------- * Function : AddNonOlsrBmfIf * Description: Add an non-OLSR enabled network interface to the list of BMF-enabled * network interfaces * Input : ifName - network interface (e.g. "eth0") * data - not used * addon - not used * Output : none * Return : success (0) or fail (1) * Data Used : NonOlsrIfNames * ------------------------------------------------------------------------- */int AddNonOlsrBmfIf(const char* ifName, void* data __attribute__((unused)), set_plugin_parameter_addon addon __attribute__((unused))){ assert(ifName != NULL); if (nNonOlsrIfs >= MAX_NON_OLSR_IFS) { olsr_printf( 1, "%s: too many non-OLSR interfaces specified, maximum is %d\n", PLUGIN_NAME, MAX_NON_OLSR_IFS); return 1; } strncpy(NonOlsrIfNames[nNonOlsrIfs], ifName, IFNAMSIZ - 1); NonOlsrIfNames[nNonOlsrIfs][IFNAMSIZ - 1] = '\0'; /* Ensures null termination */ nNonOlsrIfs++; return 0;} /* AddNonOlsrBmfIf *//* ------------------------------------------------------------------------- * Function : IsNonOlsrBmfIf * Description: Checks if a network interface is OLSR-enabled * Input : ifName - network interface (e.g. "eth0") * Output : none * Return : true (1) or false (0) * Data Used : NonOlsrIfNames * ------------------------------------------------------------------------- */int IsNonOlsrBmfIf(const char* ifName){ int i; assert(ifName != NULL); for (i = 0; i < nNonOlsrIfs; i++) { if (strncmp(NonOlsrIfNames[i], ifName, IFNAMSIZ) == 0) return 1; } return 0;} /* IsNonOlsrBmfIf *//* ------------------------------------------------------------------------- * Function : CheckAndUpdateLocalBroadcast * Description: For an IP packet, check if the destination address is not a * multicast address. If it is not, the packet is assumed to be * a local broadcast packet. In that case, set the destination * address of the IP packet to the passed broadcast address. * Input : ipPacket - the IP packet * broadAddr - the broadcast address to fill in * Output : none * Return : none * Data Used : none * Notes : See also RFC1141 * ------------------------------------------------------------------------- */void CheckAndUpdateLocalBroadcast(unsigned char* ipPacket, union olsr_ip_addr* broadAddr){ struct iphdr* iph; union olsr_ip_addr destIp; assert(ipPacket != NULL && broadAddr != NULL); iph = (struct iphdr*) ipPacket; COPY_IP(&destIp, &iph->daddr); if (! IsMulticast(&destIp)) { u_int32_t origDaddr, newDaddr; u_int32_t check; origDaddr = ntohl(iph->daddr); COPY_IP(&iph->daddr, broadAddr); newDaddr = ntohl(iph->daddr); /* Re-calculate IP header checksum for new destination */ check = ntohs(iph->check); check = ~ (~ check - ((origDaddr >> 16) & 0xFFFF) + ((newDaddr >> 16) & 0xFFFF)); check = ~ (~ check - (origDaddr & 0xFFFF) + (newDaddr & 0xFFFF)); /* Add carry */ check = check + (check >> 16); iph->check = htons(check); if (iph->protocol == SOL_UDP) { /* Re-calculate UDP/IP checksum for new destination */ int ipHeaderLen = GetIpHeaderLength(ipPacket); struct udphdr* udph = (struct udphdr*) (ipPacket + ipHeaderLen); /* RFC 1624, Eq. 3: HC' = ~(~HC - m + m') */ check = ntohs(udph->check); check = ~ (~ check - ((origDaddr >> 16) & 0xFFFF) + ((newDaddr >> 16) & 0xFFFF)); check = ~ (~ check - (origDaddr & 0xFFFF) + (newDaddr & 0xFFFF)); /* Add carry */ check = check + (check >> 16); udph->check = htons(check); } /* if */ } /* if */} /* CheckAndUpdateLocalBroadcast *//* ------------------------------------------------------------------------- * Function : AddMulticastRoute * Description: Insert a route to all multicast addresses in the kernel * routing table. The route will be via the BMF network interface. * Input : none * Output : none * Return : none * Data Used : none * ------------------------------------------------------------------------- */void AddMulticastRoute(void){ struct rtentry kernel_route; int ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0); if (ioctlSkfd < 0) { BmfPError("socket(PF_INET) error"); return; } memset(&kernel_route, 0, sizeof(struct rtentry)); ((struct sockaddr_in*)&kernel_route.rt_dst)->sin_family = AF_INET; ((struct sockaddr_in*)&kernel_route.rt_gateway)->sin_family = AF_INET; ((struct sockaddr_in*)&kernel_route.rt_genmask)->sin_family = AF_INET; /* 224.0.0.0/4 */ ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr.s_addr = htonl(0xE0000000); ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr.s_addr = htonl(0xF0000000); kernel_route.rt_metric = 0; kernel_route.rt_flags = RTF_UP; kernel_route.rt_dev = EtherTunTapIfName; if (ioctl(ioctlSkfd, SIOCADDRT, &kernel_route) < 0) { BmfPError("error setting multicast route via EtherTunTap interface \"%s\"", EtherTunTapIfName); /* Continue anyway */ } close(ioctlSkfd);} /* AddMulticastRoute *//* ------------------------------------------------------------------------- * Function : DeleteMulticastRoute * Description: Delete the route to all multicast addresses from the kernel * routing table * Input : none * Output : none * Return : none * Data Used : none * ------------------------------------------------------------------------- */void DeleteMulticastRoute(void){ if (EtherTunTapIp != ETHERTUNTAPDEFAULTIP) { struct rtentry kernel_route; int ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0); if (ioctlSkfd < 0) { BmfPError("socket(PF_INET) error"); return; } memset(&kernel_route, 0, sizeof(struct rtentry)); ((struct sockaddr_in*)&kernel_route.rt_dst)->sin_family = AF_INET; ((struct sockaddr_in*)&kernel_route.rt_gateway)->sin_family = AF_INET; ((struct sockaddr_in*)&kernel_route.rt_genmask)->sin_family = AF_INET; /* 224.0.0.0/4 */ ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr.s_addr = htonl(0xE0000000); ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr.s_addr = htonl(0xF0000000); kernel_route.rt_metric = 0; kernel_route.rt_flags = RTF_UP; kernel_route.rt_dev = EtherTunTapIfName; if (ioctl(ioctlSkfd, SIOCDELRT, &kernel_route) < 0) { BmfPError("error deleting multicast route via EtherTunTap interface \"%s\"", EtherTunTapIfName); /* Continue anyway */ } close(ioctlSkfd); } /* if */} /* DeleteMulticastRoute */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -