getifiaddrs()とstruct ifaddrsについての説明

4926 ワード

1,struct ifaddrsについての説明:
struct ifaddrs
{
    struct ifaddrs  *ifa_next;   /* Next item in list */
    char            *ifa_name;   /* Name of interface */
    unsigned int     ifa_flags;  /* Flags from SIOCGIFFLAGS */
    struct sockaddr *ifa_addr;   /* Address of interface */
    struct sockaddr *ifa_netmask;/* Netmask of interface */
    union
    {
        struct sockaddr *ifu_broadaddr;/* Broadcast address of interface */
        struct sockaddr *ifu_dstaddr;/* Point-to-point destination address */
    } ifa_ifu;
    #define              ifa_broadaddr ifa_ifu.ifu_broadaddr
    #define              ifa_dstaddr   ifa_ifu.ifu_dstaddr
    void            *ifa_data;   /* Address-specific data */
};
2,getifiaddrs()について
The getifaddrs() function creates a linked list of structures describing the network interfaces of the local system, and stores the address of the first
item of the list in *ifap. 
The list consists of ifaddrs structures, defined as follows:
       The ifa_next field contains a pointer to the next structure on the list, or
       NULL if this is the last item of the list.
       The ifa_name points to the null-terminated interface name.
       The ifa_flags field contains the interface flags
       The ifa_addr field points to a structure containing the interface address.
       The ifa_netmask field points to a structure containing the netmask associated with ifa_addr, if applicable for the address family.
       Depending on whether the bit IFF_BROADCAST or IFF_POINTOPOINT is set in ifa_flags (only one can be set at a time), either ifa_broadaddr will contain the broadcast address associated with ifa_addr (if applicable for the address family) or ifa_dstaddr will contain the destination address of the point-to-point interface.
       The ifa_data field points to a buffer containing address-family-specific data;this field may be NULL if there is no such data for this interface.
戻り値:
On success, getifaddrs() returns zero; on error, -1 is returned, and errno is set appropriately.
3、注意:
       The data returned by getifaddrs() is dynamically allocated and should be freed using freeifaddrs() when no longer needed.
4、小さな例:

#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int
main(int argc, char *argv[])
{
    struct ifaddrs *ifaddr, *ifa;
    int family, s;
    char host[NI_MAXHOST];

    if (getifaddrs(&ifaddr) == -1) 
    {
        perror("getifaddrs");
        exit(EXIT_FAILURE);
    }

    /* Walk through linked list, maintaining head pointer so we
       can free list later */

    for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) 
    {
        if (ifa->ifa_addr == NULL)
            continue;

        family = ifa->ifa_addr->sa_family;

        /* Display interface name and family (including symbolic
           form of the latter for the common families) */

        printf("%s  address family: %d%s
", ifa->ifa_name, family, (family == AF_PACKET) ? " (AF_PACKET)" : (family == AF_INET) ? " (AF_INET)" : (family == AF_INET6) ? " (AF_INET6)" : ""); /* For an AF_INET* interface address, display the address */ if (family == AF_INET || family == AF_INET6) { s = getnameinfo(ifa->ifa_addr, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if (s != 0) { printf("getnameinfo() failed: %s
", gai_strerror(s)); exit(EXIT_FAILURE); } printf("\taddress: <%s>
", host); } } freeifaddrs(ifaddr); // exit(EXIT_SUCCESS); }

出力:
参照
$ ./a.out
lo      address family: 17 (AF_PACKET)
eth0    address family: 17 (AF_PACKET)
lo      address family: 2 (AF_INET)
        address: <127.0.0.1>
eth0    address family: 2 (AF_INET)
        address: <10.1.1.4>
lo      address family: 10 (AF_INET6)
        address: <::1>
eth0    address family: 10 (AF_INET6)
                   address: