如何了解C?

问题描述 投票:0回答:6

LletSay我正在运行一个名为ipaddresses.c的程序。我希望该程序获得该设备根据每个接口具有的所有IP地址。就像config。我该怎么办? 我对

ioctl

的了解不多,但是我读到它可能会对我有所帮助。 Just Just使用

GetifAddrs()
c interface ip-address ioctl
6个回答
46
投票

#include <arpa/inet.h> #include <sys/socket.h> #include <ifaddrs.h> #include <stdio.h> int main () { struct ifaddrs *ifap, *ifa; struct sockaddr_in *sa; char *addr; getifaddrs (&ifap); for (ifa = ifap; ifa; ifa = ifa->ifa_next) { if (ifa->ifa_addr && ifa->ifa_addr->sa_family==AF_INET) { sa = (struct sockaddr_in *) ifa->ifa_addr; addr = inet_ntoa(sa->sin_addr); printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, addr); } } freeifaddrs(ifap); return 0; } 这是我在计算机上获得的输出:

Interface: lo   Address: 127.0.0.1
Interface: eth0 Address: 69.72.234.7
Interface: eth0:1       Address: 10.207.9.3

there是一些可能会帮助您的示例代码。
#include <stdio.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>

#define INT_TO_ADDR(_addr) \
(_addr & 0xFF), \
(_addr >> 8 & 0xFF), \
(_addr >> 16 & 0xFF), \
(_addr >> 24 & 0xFF)

int main()
{
    struct ifconf ifc;
    struct ifreq ifr[10];
    int sd, ifc_num, addr, bcast, mask, network, i;

    /* Create a socket so we can use ioctl on the file 
     * descriptor to retrieve the interface info. 
     */

    sd = socket(PF_INET, SOCK_DGRAM, 0);
    if (sd > 0)
    {
        ifc.ifc_len = sizeof(ifr);
        ifc.ifc_ifcu.ifcu_buf = (caddr_t)ifr;

        if (ioctl(sd, SIOCGIFCONF, &ifc) == 0)
        {
            ifc_num = ifc.ifc_len / sizeof(struct ifreq);
            printf("%d interfaces found\n", ifc_num);

            for (i = 0; i < ifc_num; ++i)
            {
                if (ifr[i].ifr_addr.sa_family != AF_INET)
                {
                    continue;
                }

                /* display the interface name */
                printf("%d) interface: %s\n", i+1, ifr[i].ifr_name);

                /* Retrieve the IP address, broadcast address, and subnet mask. */
                if (ioctl(sd, SIOCGIFADDR, &ifr[i]) == 0)
                {
                    addr = ((struct sockaddr_in *)(&ifr[i].ifr_addr))->sin_addr.s_addr;
                    printf("%d) address: %d.%d.%d.%d\n", i+1, INT_TO_ADDR(addr));
                }
                if (ioctl(sd, SIOCGIFBRDADDR, &ifr[i]) == 0)
                {
                    bcast = ((struct sockaddr_in *)(&ifr[i].ifr_broadaddr))->sin_addr.s_addr;
                    printf("%d) broadcast: %d.%d.%d.%d\n", i+1, INT_TO_ADDR(bcast));
                }
                if (ioctl(sd, SIOCGIFNETMASK, &ifr[i]) == 0)
                {
                    mask = ((struct sockaddr_in *)(&ifr[i].ifr_netmask))->sin_addr.s_addr;
                    printf("%d) netmask: %d.%d.%d.%d\n", i+1, INT_TO_ADDR(mask));
                }                

                /* Compute the current network value from the address and netmask. */
                network = addr & mask;
                printf("%d) network: %d.%d.%d.%d\n", i+1, INT_TO_ADDR(network));
            }                      
        }

        close(sd);
    }

    return 0;
}


9
投票

使用GetifAddrs()的解决方案很棒。我建议只有一个改进:

--- chrisaycock
+++ normando
@@ -11,7 +11,7 @@

     getifaddrs (&ifap);
     for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
-        if (ifa->ifa_addr->sa_family==AF_INET) {
+        if (ifa->ifa_addr && ifa->ifa_addr->sa_family==AF_INET) {
             sa = (struct sockaddr_in *) ifa->ifa_addr;
             addr = inet_ntoa(sa->sin_addr);
             printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, addr);


2
投票
ioctl(SIOCGIFCONF)

->传统的ioctl getifaddrs()->来自BSDI,现在也在Linux和BSD'S.S. rtnetlink(linux)

    您可以尝试这样的事情:
  • struct ifreq ifr[MAX_INTERFACES];
    struct ifconf ifc;
    memset(ifr, 0, sizeof(ifr));
    ifc.ifc_len = sizeof(ifr);
    ifc.ifc_req = ifr;
    
    // Get the list of interfaces
    if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) {
        fprintf(stderr, "ioctl SIOCGIFCONF failed: %d", errno);
    }
    
    struct ifreq *ifr_iterator = ifc.ireq;
    int i = 0;
    size_t len;
    while (i < ifc.ifc_len) {
       /* DO STUFF */
       // Maybe some more filtering based on SIOCGIFFLAGS 
       // Your code
       // Use ifr_iterator-> ...
    
       len = IFNAMSIZ + ifr_iterator->ifr_addr.sa_len;
       ifr_iterator = (struct ifreq *)((char *)ifr_iterator + len);
       i += len;
    }
    
  • 检查(特定于windows的
  • IP助手API
  • -幸运的是,您不需要Windows上的此。

1
投票

ioctl


with @

0
投票
答案,我在FreeBSD 4.9和14.0中使用了其他标头。

#include <arpa/inet.h> #include <ifaddrs.h> #include <stdio.h> #include <netdb.h> int main() { struct ifaddrs *ifap; getifaddrs(&ifap); for (struct ifaddrs *ifa = ifap; ifa; ifa = ifa->ifa_next) { if (ifa->ifa_addr && (ifa->ifa_addr->sa_family == AF_INET6)) { char addr[INET6_ADDRSTRLEN]; getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6), addr, sizeof(addr), NULL, 0, NI_NUMERICHOST); printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, addr); } else if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) { struct sockaddr_in *sa = (struct sockaddr_in *)ifa->ifa_addr; char *addr = inet_ntoa(sa->sin_addr); printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, addr); } } freeifaddrs(ifap); return 0; }

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.