getifaddrs(3) Library Functions Manual getifaddrs(3) getifaddrs, freeifaddrs - LIBRARY Standard C library (libc, -lc) #include #include int getifaddrs(struct ifaddrs **ifap); void freeifaddrs(struct ifaddrs *ifa); getifaddrs() , , *ifap. ifaddrs: struct ifaddrs { struct ifaddrs *ifa_next; /* . */ char *ifa_name; /* */ unsigned int ifa_flags; /* SIOCGIFFLAGS */ struct sockaddr *ifa_addr; /* */ struct sockaddr *ifa_netmask; /* */ union { struct sockaddr *ifu_broadaddr; /* */ struct sockaddr *ifu_dstaddr; /* - */ } ifa_ifu; #define ifa_broadaddr ifa_ifu.ifu_broadaddr #define ifa_dstaddr ifa_ifu.ifu_dstaddr void *ifa_data; /* . */ }; ifa_next NULL, . ifa_name ( null). ifa_flags , SIOCGIFFLAGS ioctl(2) ( netdevice(7)). ifa_addr , ( sa_family). null. ifa_netmask , ifa_addr ( ). null. IFF_BROADCAST IFF_POINTOPOINT ifa_flags ( - ), ifa_broadaddr ifa_addr ( ) ifa_dstaddr -. ifa_data , , ; NULL, . , getifaddrs(), freeifaddrs(), . On success, getifaddrs() returns zero; on error, -1 is returned, and errno is set to indicate the error. getifaddrs() errno , socket(2), bind(2), getsockname(2), recvmsg(2), sendto(2), malloc(3) realloc(3). attributes(7). +----------------------------+----------------------------------------------------------+--------------------------+ | | | | +----------------------------+----------------------------------------------------------+--------------------------+ |getifaddrs(), freeifaddrs() | | MT-Safe | +----------------------------+----------------------------------------------------------+--------------------------+ None. This function first appeared in BSDi and is present on the BSD systems, but with slightly different semantics documented--returning one entry per interface, not per address. This means ifa_addr and other fields can actually be NULL if the interface has no address, and no link-level address is returned if the interface has an IP address assigned. Also, the way of choosing either ifa_broadaddr or ifa_dstaddr differs on various systems. getifaddrs() first appeared in glibc 2.3, but before glibc 2.3.3, the implementation supported only IPv4 addresses; IPv6 support was added in glibc 2.3.3. Support of address families other than IPv4 is available only on kernels that support netlink. , Linux, , IPv4 IPv6, , AF_PACKET , . ifa_data struct rtnl_link_stats, ( Linux 2.4 -- struct net_device_stats, ), . , , getifaddrs(), freeifaddrs(), getnameinfo(3). : $ ./a.out lo AF_PACKET (17) tx_packets = 524; rx_packets = 524 tx_bytes = 38788; rx_bytes = 38788 wlp3s0 AF_PACKET (17) tx_packets = 108391; rx_packets = 130245 tx_bytes = 30420659; rx_bytes = 94230014 em1 AF_PACKET (17) tx_packets = 0; rx_packets = 0 tx_bytes = 0; rx_bytes = 0 lo AF_INET (2) : <127.0.0.1> wlp3s0 AF_INET (2) : <192.168.235.137> lo AF_INET6 (10) : <::1> wlp3s0 AF_INET6 (10) : #define _GNU_SOURCE /* To get defns of NI_MAXSERV and NI_MAXHOST */ #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { struct ifaddrs *ifaddr; 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 (struct ifaddrs *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("%-8s %s (%d)\n", ifa->ifa_name, (family == AF_PACKET) ? "AF_PACKET" : (family == AF_INET) ? "AF_INET" : (family == AF_INET6) ? "AF_INET6" : "???", family); /* 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\n", gai_strerror(s)); exit(EXIT_FAILURE); } printf("\t\taddress: <%s>\n", host); } else if (family == AF_PACKET && ifa->ifa_data != NULL) { struct rtnl_link_stats *stats = ifa->ifa_data; printf("\t\ttx_packets = %10u; rx_packets = %10u\n" "\t\ttx_bytes = %10u; rx_bytes = %10u\n", stats->tx_packets, stats->rx_packets, stats->tx_bytes, stats->rx_bytes); } } freeifaddrs(ifaddr); exit(EXIT_SUCCESS); } . bind(2), getsockname(2), socket(2), packet(7), ifconfig(8) Azamat Hackimov , Dmitry Bolkhovskikh , Vladislav , Yuri Kozlov ; GNU 3 , . . , , . Linux man-pages 6.06 31 2023 . getifaddrs(3)