📄 networkinterfaces.c
字号:
{ static char* deviceName = "/dev/net/tun"; struct ifreq ifreq; int etfd; int ioctlSkfd; int ioctlres; etfd = open(deviceName, O_RDWR | O_NONBLOCK); if (etfd < 0) { BmfPError("error opening %s", deviceName); return -1; } memset(&ifreq, 0, sizeof(ifreq)); strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1); ifreq.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */ /* Specify the IFF_TUN flag for IP packets. * Specify IFF_NO_PI for not receiving extra meta packet information. */ ifreq.ifr_flags = IFF_TUN; ifreq.ifr_flags |= IFF_NO_PI; if (ioctl(etfd, TUNSETIFF, (void *)&ifreq) < 0) { BmfPError("ioctl(TUNSETIFF) error on %s", deviceName); close(etfd); return -1; } memset(&ifreq, 0, sizeof(ifreq)); strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1); ifreq.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */ ifreq.ifr_addr.sa_family = AF_INET; ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0); if (ioctlSkfd < 0) { BmfPError("socket(PF_INET) error on %s", deviceName); close(etfd); return -1; } /* Give the EtherTunTap interface an IP address. * The default IP address is the address of the first OLSR interface; * the default netmask is 255.255.255.255 . Having an all-ones netmask prevents * automatic entry of the BMF network interface in the routing table. */ if (EtherTunTapIp == ETHERTUNTAPIPNOTSET) { struct TBmfInterface* nextBmfIf = BmfInterfaces; while (nextBmfIf != NULL) { struct TBmfInterface* bmfIf = nextBmfIf; nextBmfIf = bmfIf->next; if (bmfIf->olsrIntf != NULL) { EtherTunTapIp = ntohl(bmfIf->intAddr.v4); EtherTunTapIpBroadcast = EtherTunTapIp; } } } if (EtherTunTapIp == ETHERTUNTAPIPNOTSET) { /* No IP address configured for BMF network interface, and no OLSR interface found to * copy IP address from. Fall back to default: 10.255.255.253 . */ EtherTunTapIp = ETHERTUNTAPDEFAULTIP; } ((struct sockaddr_in*)&ifreq.ifr_addr)->sin_addr.s_addr = htonl(EtherTunTapIp); ioctlres = ioctl(ioctlSkfd, SIOCSIFADDR, &ifreq); if (ioctlres >= 0) { /* Set net mask */ ((struct sockaddr_in*)&ifreq.ifr_netmask)->sin_addr.s_addr = htonl(EtherTunTapIpMask); ioctlres = ioctl(ioctlSkfd, SIOCSIFNETMASK, &ifreq); if (ioctlres >= 0) { /* Set broadcast IP */ ((struct sockaddr_in*)&ifreq.ifr_broadaddr)->sin_addr.s_addr = htonl(EtherTunTapIpBroadcast); ioctlres = ioctl(ioctlSkfd, SIOCSIFBRDADDR, &ifreq); if (ioctlres >= 0) { /* Bring EtherTunTap interface up (if not already) */ ioctlres = ioctl(ioctlSkfd, SIOCGIFFLAGS, &ifreq); if (ioctlres >= 0) { ifreq.ifr_flags |= (IFF_UP | IFF_RUNNING | IFF_BROADCAST); ioctlres = ioctl(ioctlSkfd, SIOCSIFFLAGS, &ifreq); } } } } if (ioctlres < 0) { /* Any of the above ioctl() calls failed */ BmfPError("error bringing up EtherTunTap interface \"%s\"", EtherTunTapIfName); close(etfd); close(ioctlSkfd); return -1; } /* if (ioctlres < 0) */ /* Set the multicast flag on the interface */ memset(&ifreq, 0, sizeof(ifreq)); strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1); ifreq.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */ ioctlres = ioctl(ioctlSkfd, SIOCGIFFLAGS, &ifreq); if (ioctlres >= 0) { ifreq.ifr_flags |= IFF_MULTICAST; ioctlres = ioctl(ioctlSkfd, SIOCSIFFLAGS, &ifreq); } if (ioctlres < 0) { /* Any of the two above ioctl() calls failed */ BmfPError("error setting multicast flag on EtherTunTap interface \"%s\"", EtherTunTapIfName); /* Continue anyway */ } /* Use ioctl to make the tuntap persistent. Otherwise it will disappear * when this program exits. That is not desirable, since a multicast * daemon (e.g. mrouted) may be using the tuntap interface. */ if (ioctl(etfd, TUNSETPERSIST, (void *)&ifreq) < 0) { BmfPError("error making EtherTunTap interface \"%s\" persistent", EtherTunTapIfName); /* Continue anyway */ } OLSR_PRINTF(8, "%s: opened 1 socket on \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName); AddDescriptorToInputSet(etfd); /* If the user configured a specific IP address for the BMF network interface, * help the user and advertise the IP address of the BMF network interface * on the OLSR network via HNA */ if (TunTapIpOverruled != 0) { union olsr_ip_addr temp_net; union olsr_ip_addr temp_netmask; temp_net.v4 = htonl(EtherTunTapIp); temp_netmask.v4 = htonl(0xFFFFFFFF); add_local_hna4_entry(&temp_net, &temp_netmask); } close(ioctlSkfd); return etfd;} /* CreateLocalEtherTunTap *//* ------------------------------------------------------------------------- * Function : CreateInterface * Description: Create a new TBmfInterface object and adds it to the global * BmfInterfaces list * Input : ifName - name of the network interface (e.g. "eth0") * : olsrIntf - OLSR interface object of the network interface, or * NULL if the network interface is not OLSR-enabled * Output : none * Return : the number of opened sockets * Data Used : BmfInterfaces, LastBmfInterface * ------------------------------------------------------------------------- */static int CreateInterface( const char* ifName, struct interface* olsrIntf){ int capturingSkfd = -1; int encapsulatingSkfd = -1; int listeningSkfd = -1; int ioctlSkfd; struct ifreq ifr; int nOpened = 0; struct TBmfInterface* newIf = malloc(sizeof(struct TBmfInterface)); assert(ifName != NULL); if (newIf == NULL) { return 0; } if (olsrIntf != NULL) { /* On OLSR-enabled interfaces, create socket for encapsulating and forwarding * multicast packets */ encapsulatingSkfd = CreateEncapsulateSocket(ifName); if (encapsulatingSkfd < 0) { free(newIf); return 0; } nOpened++; } /* Create socket for capturing and sending of multicast packets on * non-OLSR interfaces, and on OLSR-interfaces if configured. */ if ((olsrIntf == NULL) || (CapturePacketsOnOlsrInterfaces != 0)) { capturingSkfd = CreateCaptureSocket(ifName); if (capturingSkfd < 0) { close(encapsulatingSkfd); free(newIf); return 0; } nOpened++; } /* Create promiscuous mode listening interface if BMF uses IP unicast * as underlying forwarding mechanism */ if (BmfMechanism == BM_UNICAST_PROMISCUOUS) { listeningSkfd = CreateListeningSocket(ifName); if (listeningSkfd < 0) { close(listeningSkfd); close(encapsulatingSkfd); /* no problem if 'encapsulatingSkfd' is -1 */ free(newIf); return 0; } nOpened++; } /* For ioctl operations on the network interface, use either capturingSkfd * or encapsulatingSkfd, whichever is available */ ioctlSkfd = (capturingSkfd >= 0) ? capturingSkfd : encapsulatingSkfd; /* Retrieve the MAC address of the interface. */ memset(&ifr, 0, sizeof(struct ifreq)); strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1); ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */ if (ioctl(ioctlSkfd, SIOCGIFHWADDR, &ifr) < 0) { BmfPError("ioctl(SIOCGIFHWADDR) error for interface \"%s\"", ifName); close(capturingSkfd); close(encapsulatingSkfd); free(newIf); return 0; } /* Copy data into TBmfInterface object */ newIf->capturingSkfd = capturingSkfd; newIf->encapsulatingSkfd = encapsulatingSkfd; newIf->listeningSkfd = listeningSkfd; memcpy(newIf->macAddr, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN); memcpy(newIf->ifName, ifName, IFNAMSIZ); newIf->olsrIntf = olsrIntf; if (olsrIntf != NULL) { /* For an OLSR-interface, copy the interface address and broadcast * address from the OLSR interface object. Downcast to correct sockaddr * subtype. */ COPY_IP(&newIf->intAddr, &((struct sockaddr_in *)&olsrIntf->int_addr)->sin_addr.s_addr); COPY_IP(&newIf->broadAddr, &((struct sockaddr_in *)&olsrIntf->int_broadaddr)->sin_addr.s_addr); } else { /* For a non-OLSR interface, retrieve the IP address ourselves */ memset(&ifr, 0, sizeof(struct ifreq)); strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1); ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */ if (ioctl(ioctlSkfd, SIOCGIFADDR, &ifr) < 0) { BmfPError("ioctl(SIOCGIFADDR) error for interface \"%s\"", ifName); newIf->intAddr.v4 = inet_addr("0.0.0.0"); } else { /* Downcast to correct sockaddr subtype */ COPY_IP(&newIf->intAddr, &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr); } /* For a non-OLSR interface, retrieve the IP broadcast address ourselves */ memset(&ifr, 0, sizeof(struct ifreq)); strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1); ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */ if (ioctl(ioctlSkfd, SIOCGIFBRDADDR, &ifr) < 0) { BmfPError("ioctl(SIOCGIFBRDADDR) error for interface \"%s\"", ifName); newIf->broadAddr.v4 = inet_addr("0.0.0.0"); } else { /* Downcast to correct sockaddr subtype */ COPY_IP(&newIf->broadAddr, &((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr.s_addr); } } /* Initialize fragment history table */ memset(&newIf->fragmentHistory, 0, sizeof(newIf->fragmentHistory)); newIf->nextFragmentHistoryEntry = 0; /* Reset counters */ newIf->nBmfPacketsRx = 0; newIf->nBmfPacketsRxDup = 0; newIf->nBmfPacketsTx = 0; /* Add new TBmfInterface object to global list. OLSR interfaces are * added at the front of the list, non-OLSR interfaces at the back. */ if (BmfInterfaces == NULL) { /* First TBmfInterface object in list */ BmfInterfaces = newIf; LastBmfInterface = newIf; } else if (olsrIntf != NULL) { /* Add new TBmfInterface object at front of list */ newIf->next = BmfInterfaces; BmfInterfaces = newIf; } else { /* Add new TBmfInterface object at back of list */ newIf->next = NULL; LastBmfInterface->next= newIf; LastBmfInterface = newIf; } OLSR_PRINTF( 8, "%s: opened %d socket%s on %s interface \"%s\"\n", PLUGIN_NAME_SHORT, nOpened, nOpened == 1 ? "" : "s", olsrIntf != NULL ? "OLSR" : "non-OLSR", ifName); return nOpened;} /* CreateInterface *//* ------------------------------------------------------------------------- * Function : CreateBmfNetworkInterfaces * Description: Create a list of TBmfInterface objects, one for each network * interface on which BMF runs * Input : skipThisIntf - network interface to skip, if seen * Output : none * Return : fail (-1) or success (0) * Data Used : none * ------------------------------------------------------------------------- */int CreateBmfNetworkInterfaces(struct interface* skipThisIntf){ int skfd; struct ifconf ifc; int numreqs = 30; struct ifreq* ifr; int n; int nOpenedSockets = 0; /* Clear input descriptor set */ FD_ZERO(&InputSet); skfd = socket(PF_INET, SOCK_DGRAM, 0); if (skfd < 0) { BmfPError("no inet socket available to retrieve interface list"); return -1; } /* Retrieve the network interface configuration list */ ifc.ifc_buf = NULL; for (;;) { ifc.ifc_len = sizeof(struct ifreq) * numreqs; ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len); if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) { BmfPError("ioctl(SIOCGIFCONF) error"); close(skfd); free(ifc.ifc_buf); return -1; } if ((unsigned)ifc.ifc_len == sizeof(struct ifreq) * numreqs) { /* Assume it overflowed; double the space and try again */ numreqs *= 2; assert(numreqs < 1024); continue; /* for (;;) */ } break; /* for (;;) */ } /* for (;;) */ close(skfd);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -