Diff for /embedaddon/libnet/src/libnet_if_addr.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2021/03/16 23:47:28 version 1.1.1.4, 2023/09/27 11:11:38
Line 30 Line 30
  *   *
  */   */
   
#if (HAVE_CONFIG_H)#include "common.h"
#include "../include/config.h"
#endif 
#if (!(_WIN32) || (__CYGWIN__))  
#include "../include/libnet.h" 
#else 
#include "../include/win32/libnet.h" 
#endif 
 #ifdef HAVE_SYS_SOCKIO_H  #ifdef HAVE_SYS_SOCKIO_H
 #include <sys/sockio.h>  #include <sys/sockio.h>
 #endif  #endif
   
 #include "../include/ifaddrlist.h"  #include "../include/ifaddrlist.h"
   
 #define MAX_IPADDR 512  #define MAX_IPADDR 512
Line 60  libnet_check_iface(libnet_t *l) Line 55  libnet_check_iface(libnet_t *l)
     fd = socket(AF_INET, SOCK_DGRAM, 0);      fd = socket(AF_INET, SOCK_DGRAM, 0);
     if (fd < 0)      if (fd < 0)
     {      {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s() socket: %s\n", __func__,        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s() socket: %s", __func__,
                 strerror(errno));                  strerror(errno));
         return (-1);          return (-1);
     }      }
Line 69  libnet_check_iface(libnet_t *l) Line 64  libnet_check_iface(libnet_t *l)
     ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';      ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
           
     res = ioctl(fd, SIOCGIFFLAGS, (int8_t *)&ifr);      res = ioctl(fd, SIOCGIFFLAGS, (int8_t *)&ifr);
   
     if (res < 0)      if (res < 0)
     {      {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s() ioctl: %s\n", __func__,        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s() ioctl: %s", __func__,
                 strerror(errno));                  strerror(errno));
     }      }
     else      else
     {      {
         if ((ifr.ifr_flags & IFF_UP) == 0)          if ((ifr.ifr_flags & IFF_UP) == 0)
         {          {
            snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): %s is down\n",            snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): %s is down",
                     __func__, l->device);                      __func__, l->device);
             res = -1;              res = -1;
         }          }
     }      }
     close(fd);      close(fd);
   
     return (res);      return (res);
 }  }
   
   #endif
   
   #if defined(__OpenBSD__) ||  defined(__linux__)
   #include <sys/types.h>
       #ifdef __OpenBSD__
       #include <sys/socket.h>
       #endif
   #include <ifaddrs.h>
   
   int
   libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, char *dev, register char *errbuf)
   {
       static struct libnet_ifaddr_list ifaddrlist[MAX_IPADDR];
       struct ifaddrs *ifap, *ifa;
       int i = 0;
       memset (ifaddrlist, 0 , sizeof(ifaddrlist));
   
       if (getifaddrs(&ifap) != 0)
       {
           snprintf(errbuf, LIBNET_ERRBUF_SIZE, "%s(): getifaddrs: %s",
                       __func__, strerror(errno));
           return 0;
       }
       for (ifa = ifap; ifa; ifa = ifa->ifa_next)
       {
           if (ifa->ifa_flags & IFF_LOOPBACK)
               continue;
   
           if (ifa->ifa_addr->sa_family == AF_INET )
           {
               ifaddrlist[i].device = strdup(ifa->ifa_name);
               if (ifaddrlist[i].device == NULL) {
                   snprintf(errbuf, LIBNET_ERRBUF_SIZE, "%s(): OOM", __func__);
                   continue;
               }
               ifaddrlist[i].addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
               ++i;
           }
       }
   
       freeifaddrs(ifap);
       *ipaddrp = ifaddrlist;
       return (i);
   }
   
   
   #else
   #if !(__WIN32__)
   
   
 /*  /*
  *  Return the interface list   *  Return the interface list
  */   */
Line 109  libnet_check_iface(libnet_t *l) Line 153  libnet_check_iface(libnet_t *l)
 #endif  #endif
   
 int  int
libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, char *dev,libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, char *dev, register char *errbuf)
register char *errbuf) 
 {  {
     register struct libnet_ifaddr_list *al;      register struct libnet_ifaddr_list *al;
     struct ifreq *ifr, *lifr, *pifr, nifr;      struct ifreq *ifr, *lifr, *pifr, nifr;
Line 130  register char *errbuf) Line 173  register char *errbuf)
     fd = socket(AF_INET, SOCK_DGRAM, 0);      fd = socket(AF_INET, SOCK_DGRAM, 0);
     if (fd < 0)      if (fd < 0)
     {      {
        snprintf(errbuf, LIBNET_ERRBUF_SIZE, "%s(): socket error: %s\n",        snprintf(errbuf, LIBNET_ERRBUF_SIZE, "%s(): socket error: %s",
                 __func__, strerror(errno));                  __func__, strerror(errno));
         return (-1);          return (-1);
     }      }
   
 #ifdef HAVE_LINUX_PROCFS  #ifdef HAVE_LINUX_PROCFS
    if ((fp = fopen(PROC_DEV_FILE, "r")) == NULL)    fp = fopen(PROC_DEV_FILE, "r");
     if (!fp)
     {      {
         snprintf(errbuf, LIBNET_ERRBUF_SIZE,          snprintf(errbuf, LIBNET_ERRBUF_SIZE,
                "%s(): fopen(proc_dev_file) failed: %s\n",  __func__,                "%s(): fopen(proc_dev_file) failed: %s",  __func__,
                 strerror(errno));                  strerror(errno));
        return (-1);        goto bad;
     }      }
 #endif  #endif
   
Line 149  register char *errbuf) Line 193  register char *errbuf)
     ifc.ifc_len = sizeof(ibuf);      ifc.ifc_len = sizeof(ibuf);
     ifc.ifc_buf = (caddr_t)ibuf;      ifc.ifc_buf = (caddr_t)ibuf;
   
    if(ioctl(fd, SIOCGIFCONF, &ifc) < 0)    if (ioctl(fd, SIOCGIFCONF, &ifc) < 0)
     {      {
         snprintf(errbuf, LIBNET_ERRBUF_SIZE,          snprintf(errbuf, LIBNET_ERRBUF_SIZE,
                "%s(): ioctl(SIOCGIFCONF) error: %s\n",                 "%s(): ioctl(SIOCGIFCONF) error: %s", 
                 __func__, strerror(errno));                  __func__, strerror(errno));
#ifdef HAVE_LINUX_PROCFS        goto bad;
        fclose(fp); 
#endif 
        return(-1); 
     }      }
   
     pifr = NULL;      pifr = NULL;
Line 169  register char *errbuf) Line 210  register char *errbuf)
 #ifdef HAVE_LINUX_PROCFS  #ifdef HAVE_LINUX_PROCFS
     while (fgets(buf, sizeof(buf), fp))      while (fgets(buf, sizeof(buf), fp))
     {      {
        if ((p = strchr(buf, ':')) == NULL)        p = strchr(buf, ':');
        {        if (!p)
             continue;              continue;
        }
         *p = '\0';          *p = '\0';
        for(p = buf; *p == ' '; p++) ;        for (p = buf; *p == ' '; p++)
             ;
                   
         strncpy(nifr.ifr_name, p, sizeof(nifr.ifr_name) - 1);          strncpy(nifr.ifr_name, p, sizeof(nifr.ifr_name) - 1);
         nifr.ifr_name[sizeof(nifr.ifr_name) - 1] = '\0';          nifr.ifr_name[sizeof(nifr.ifr_name) - 1] = '\0';
Line 184  register char *errbuf) Line 226  register char *errbuf)
     for (ifr = ifc.ifc_req; ifr < lifr; ifr = NEXTIFR(ifr))      for (ifr = ifc.ifc_req; ifr < lifr; ifr = NEXTIFR(ifr))
     {      {
         /* XXX LINUX SOLARIS ifalias */          /* XXX LINUX SOLARIS ifalias */
        if((p = strchr(ifr->ifr_name, ':')))        p = strchr(ifr->ifr_name, ':');
        {        if (p)
            *p='\0';            *p = '\0';
        }
         if (pifr && strcmp(ifr->ifr_name, pifr->ifr_name) == 0)          if (pifr && strcmp(ifr->ifr_name, pifr->ifr_name) == 0)
         {  
             continue;              continue;
        }
         strncpy(nifr.ifr_name, ifr->ifr_name, sizeof(nifr.ifr_name) - 1);          strncpy(nifr.ifr_name, ifr->ifr_name, sizeof(nifr.ifr_name) - 1);
         nifr.ifr_name[sizeof(nifr.ifr_name) - 1] = '\0';          nifr.ifr_name[sizeof(nifr.ifr_name) - 1] = '\0';
 #endif  #endif
Line 224  register char *errbuf) Line 265  register char *errbuf)
             if (errno != EADDRNOTAVAIL)              if (errno != EADDRNOTAVAIL)
             {              {
                 snprintf(errbuf, LIBNET_ERRBUF_SIZE,                  snprintf(errbuf, LIBNET_ERRBUF_SIZE,
                        "%s(): SIOCGIFADDR: dev=%s: %s\n", __func__, device,                        "%s(): SIOCGIFADDR: dev=%s: %s", __func__, device,
                         strerror(errno));                          strerror(errno));
                close(fd);                goto bad;
#ifdef HAVE_LINUX_PROCFS 
                fclose(fp); 
#endif 
                return (-1); 
             }              }
             else /* device has no IP address => set to 0 */              else /* device has no IP address => set to 0 */
             {              {
Line 243  register char *errbuf) Line 280  register char *errbuf)
         }          }
                   
         free(al->device);          free(al->device);
         al->device = NULL;  
   
        if ((al->device = strdup(device)) == NULL)        al->device = strdup(device);
         if (al->device == NULL)
         {          {
             snprintf(errbuf, LIBNET_ERRBUF_SIZE,               snprintf(errbuf, LIBNET_ERRBUF_SIZE, 
                    "%s(): strdup not enough memory\n", __func__);                    "%s(): strdup not enough memory", __func__);
#ifdef HAVE_LINUX_PROCFS            goto bad;
            fclose(fp); 
#endif 
            return(-1); 
         }          }
   
         ++al;          ++al;
Line 268  register char *errbuf) Line 302  register char *errbuf)
     if (ferror(fp))      if (ferror(fp))
     {      {
         snprintf(errbuf, LIBNET_ERRBUF_SIZE,          snprintf(errbuf, LIBNET_ERRBUF_SIZE,
                "%s(): ferror: %s\n", __func__, strerror(errno));                "%s(): ferror: %s", __func__, strerror(errno));
        fclose(fp);        goto bad;
        return (-1); 
     }      }
     fclose(fp);      fclose(fp);
 #endif  #endif
   
       close(fd);
     *ipaddrp = ifaddrlist;      *ipaddrp = ifaddrlist;
   
     return (nipaddr);      return (nipaddr);
   
       bad:
   #ifdef HAVE_LINUX_PROCFS
       if (fp)
           fclose(fp);
   #endif
       close(fd);
       return (-1);
 }  }
 #else  #else
   /* WIN32 support *
    * TODO move win32 support into win32 specific source file */
   
 /* From tcptraceroute, convert a numeric IP address to a string */  /* From tcptraceroute, convert a numeric IP address to a string */
 #define IPTOSBUFFERS    12  #define IPTOSBUFFERS    12
 static int8_t *iptos(uint32_t in)  static int8_t *iptos(uint32_t in)
Line 295  static int8_t *iptos(uint32_t in) Line 341  static int8_t *iptos(uint32_t in)
 }  }
   
 int  int
libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, char *dev,libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, char *dev_unused, register char *errbuf)
register char *errbuf) 
 {  {
    int nipaddr = 0;    int i = 0;    int nipaddr = 0;
    int i = 0;
     static struct libnet_ifaddr_list ifaddrlist[MAX_IPADDR];      static struct libnet_ifaddr_list ifaddrlist[MAX_IPADDR];
    pcap_if_t *alldevs;    pcap_if_t *devlist = NULL;
    pcap_if_t *d;    pcap_if_t *dev = NULL;
     int8_t err[PCAP_ERRBUF_SIZE];      int8_t err[PCAP_ERRBUF_SIZE];
   
     /* Retrieve the interfaces list */      /* Retrieve the interfaces list */
    if (pcap_findalldevs(&alldevs, err) == -1)    if (pcap_findalldevs(&devlist, err) == -1)
     {      {
         snprintf(errbuf, LIBNET_ERRBUF_SIZE,           snprintf(errbuf, LIBNET_ERRBUF_SIZE, 
                "%s(): error in pcap_findalldevs: %s\n", __func__, err);                "%s(): error in pcap_findalldevs: %s", __func__, err);
         return (-1);          return (-1);
     }      }
   
    /* Scan the list printing every entry */    for (dev = devlist; dev; dev = dev->next)
        for (d = alldevs; d; d = d->next) 
     {      {
                if((!d->addresses) || (d->addresses->addr->sa_family != AF_INET))        struct pcap_addr* pcapaddr;
            continue;        for(pcapaddr = dev->addresses; pcapaddr; pcapaddr = pcapaddr->next) {
        if(d->flags & PCAP_IF_LOOPBACK)            struct sockaddr* addr = pcapaddr->addr;
            continue;#if 0
                printf("if name '%s' description '%s' loop? %d\n", dev->name, dev->description, dev->flags);
                /* XXX - strdup */            {
        ifaddrlist[i].device = strdup(d->name);                char p[NI_MAXHOST] = "";
        ifaddrlist[i].addr = (uint32_t)                int sz = sizeof(struct sockaddr_storage);
                strdup(iptos(((struct sockaddr_in *)                int r;
                d->addresses->addr)->sin_addr.s_addr));                r = getnameinfo(addr, sz, p, sizeof(p), NULL,0, NI_NUMERICHOST);
        ++i;                printf("  addr %s\n", r ? gai_strerror(r) : p);
        ++nipaddr;            }
 #endif
 
             if (dev->flags & PCAP_IF_LOOPBACK)
                 continue;
 
             /* this code ignores IPv6 addresses, a limitation of the libnet_ifaddr_list struct */
 
             if (addr->sa_family == AF_INET) {
                 ifaddrlist[i].device = strdup(dev->name);
                 ifaddrlist[i].addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
                 ++i;
                 ++nipaddr;
             }
         }
     }      }
   
    pcap_freealldevs(alldevs);    pcap_freealldevs(devlist);
   
     *ipaddrp = ifaddrlist;      *ipaddrp = ifaddrlist;
    return (nipaddr);
     return nipaddr;
 }  }
 #endif /* __WIN32__ */  #endif /* __WIN32__ */
   
   #endif /* __OpenBSD__ */
   
 int  int
 libnet_select_device(libnet_t *l)  libnet_select_device(libnet_t *l)
 {  {
Line 368  libnet_select_device(libnet_t *l) Line 429  libnet_select_device(libnet_t *l)
     c = libnet_ifaddrlist(&address_list, l->device, l->err_buf);      c = libnet_ifaddrlist(&address_list, l->device, l->err_buf);
     if (c < 0)      if (c < 0)
     {      {
         /* err msg set in libnet_ifaddrlist() */  
         return (-1);          return (-1);
     }      }
     else if (c == 0)      else if (c == 0)
     {      {
         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,          snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                "%s(): no network interface found\n", __func__);                "%s(): no network interface found", __func__);
         return (-1);          return (-1);
     }      }
                   
     al = address_list;      al = address_list;
     if (l->device)      if (l->device)
     {      {
        /*        addr = libnet_name2addr4(l, l->device, LIBNET_DONT_RESOLVE);
         *  Then we have an IP address in l->device => do lookup 
         */ 
        addr = libnet_name2addr4(l, l->device, 0); 
   
         for (i = c; i; --i, ++address_list)          for (i = c; i; --i, ++address_list)
         {          {
            if (((addr == -1) && !(strncmp(l->device, address_list->device,            if (
                   strlen(l->device)))) ||                     0 == strcmp(l->device, address_list->device)
                    (address_list->addr == addr))                    || 
                     address_list->addr == addr
                )
             {              {
                 /* free the "user supplied device" - see libnet_init() */                  /* free the "user supplied device" - see libnet_init() */
                 free(l->device);                  free(l->device);
Line 401  libnet_select_device(libnet_t *l) Line 460  libnet_select_device(libnet_t *l)
         if (i <= 0)          if (i <= 0)
         {          {
             snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,              snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    "%s(): can't find interface for IP %s\n", __func__,                    "%s(): can't find interface for IP %s", __func__,
                     l->device);                      l->device);
             goto bad;              goto bad;
         }          }
Line 428  bad: Line 487  bad:
     return (-1);      return (-1);
 }  }
   
/* EOF *//**
  * Local Variables:
  *  indent-tabs-mode: nil
  *  c-file-style: "stroustrup"
  * End:
  */

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>