How to enumerate all IP addresses attached to a machine, in POSIX C?

前端 未结 6 886
遥遥无期
遥遥无期 2021-01-03 03:25

Background:

I\'m writing a daemon that makes outgoing TCP/IP connections. It will be running on machines with multiple (non-loopback) IP addresses.

6条回答
  •  南方客
    南方客 (楼主)
    2021-01-03 03:58

    Here's my proof of concept code using caskey's accepted answer, for posterity's sake:

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    
    static const char * flags(int sd, const char * name)
    {
        static char buf[1024];
    
        static struct ifreq ifreq;
        strcpy(ifreq.ifr_name, name);
    
        int r = ioctl(sd, SIOCGIFFLAGS, (char *)&ifreq);
        assert(r == 0);
    
        int l = 0;
    #define FLAG(b) if(ifreq.ifr_flags & b) l += snprintf(buf + l, sizeof(buf) - l, #b " ")
        FLAG(IFF_UP);
        FLAG(IFF_BROADCAST);
        FLAG(IFF_DEBUG);
        FLAG(IFF_LOOPBACK);
        FLAG(IFF_POINTOPOINT);
        FLAG(IFF_RUNNING);
        FLAG(IFF_NOARP);
        FLAG(IFF_PROMISC);
        FLAG(IFF_NOTRAILERS);
        FLAG(IFF_ALLMULTI);
        FLAG(IFF_MASTER);
        FLAG(IFF_SLAVE);
        FLAG(IFF_MULTICAST);
        FLAG(IFF_PORTSEL);
        FLAG(IFF_AUTOMEDIA);
        FLAG(IFF_DYNAMIC);
    #undef FLAG
    
        return buf;
    }
    
    int main(void)
    {
        static struct ifreq ifreqs[32];
        struct ifconf ifconf;
        memset(&ifconf, 0, sizeof(ifconf));
        ifconf.ifc_req = ifreqs;
        ifconf.ifc_len = sizeof(ifreqs);
    
        int sd = socket(PF_INET, SOCK_STREAM, 0);
        assert(sd >= 0);
    
        int r = ioctl(sd, SIOCGIFCONF, (char *)&ifconf);
        assert(r == 0);
    
        for(int i = 0; i < ifconf.ifc_len/sizeof(struct ifreq); ++i)
        {
            printf("%s: %s\n", ifreqs[i].ifr_name, inet_ntoa(((struct sockaddr_in *)&ifreqs[i].ifr_addr)->sin_addr));
            printf(" flags: %s\n", flags(sd, ifreqs[i].ifr_name));
        }
    
        close(sd);
    
        return 0;
    }
    

    Works like a charm!

提交回复
热议问题