⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 networkinterfaces.c

📁 wifi 无线网络路由协议OLSR linux下C代码
💻 C
📖 第 1 页 / 共 5 页
字号:
{  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 + -