Provided by: manpages-ja-dev_0.5.0.0.20210215+dfsg-1_all
名前
getifaddrs, freeifaddrs - インターフェースのアドレスを取得する
書式
#include <sys/types.h> #include <ifaddrs.h> int getifaddrs(struct ifaddrs **ifap); void freeifaddrs(struct ifaddrs *ifa);
説明
getifaddrs() 関数は、ローカルシステムのネットワークインターフェース情報を表す構造体の連結 リストを作成し、 リストの先頭の要素のアドレスを *ifap に格納する。 リストは ifaddrs 構造体 で構成される。 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 */ }; ifa_next フィールドにはリストの次の構造体へのポインターが格納される。 この要素がリストの最 後の場合には NULL が入る。 ifa_name はヌル終端されたインターフェース名を指す。 ifa_flags フィールドには、 SIOCGIFFLAGS ioctl(2) 操作で返されるインターフェースのフラグが 格納される (これらのフラグのリストについては netdevice(7) を参照)。 ifa_addr フィールドは、インターフェースのアドレスを格納した構造体へのポインターである (sa_family サブフィールドを参照して、アドレス構造体の形式を判別すべきである)。 このフィー ルドはヌルポインターとなる場合がある。 ifa_netmask フィールドには、 ネットマスクがあるアドレスファミリーであれば、 ifa_addr に関 連付けられたネットマスクを格納した構造体へのポインターが入る。 このフィールドはヌルポイン ターとなる場合がある。 ifa_flags にビット IFF_BROADCAST か IFF_POINTOPOINT のどちらが設定されているかにより (同時 にはこれらのどちらか一方だけが設定される)、 ifa_broadaddr に ifa_addr に対応するブロード キャストが入るか (そのアドレスファミリーでブロードキャストがある場合)、 ifa_dstaddr に point-to-point インターフェースの宛先アドレスが入るかが決まる。 ifa_data フィールドは、 アドレスファミリー固有のデータが入ったバッファーへのポインターであ る。 そのインターフェースでこのようなデータがない場合には、 このフィールドは NULL となる。 getifaddrs() が返すデータは動的に確保される。 必要なくなった際には freeifaddrs() を使って 解放すべきである。
返り値
成功すると、 getifaddrs は 0 を返す。 エラーの場合、 -1 が返り、 errno が適切に設定され る。
エラー
getifaddrs() は失敗する場合があり、その場合には errno には socket(2), bind(2), getsockname(2), recvmsg(2), sendto(2), malloc(3), realloc(3) に対して規定されているエラー のいずれかが設定される。
バージョン
getifaddrs() 関数は glibc 2.3 で初めて登場したが、 glibc 2.3.3 より前のバージョンの実装で は IPv4 アドレスだけがサポートされていた。 IPv6 のサポートは glibc 2.3.3 で追加された。 IPv4 以外のアドレスファミリーが getifaddrs で利用できるのは、 netlink をサポートするカーネ ルの場合だけである。
準拠
POSIX.1-2001 にはない。 この関数は BSDi で初めて登場し、 BSD 系のシステムに存在するが、 ド キュメント上はかなり動作が異なり、アドレス毎ではなくインターフェース毎に 1 エントリーを返 す。 このことは、 インターフェースがアドレスを持たない場合には ifa_addr や他のフィールドは 実際に NULL になり、 インターフェースに IP アドレスが割り当てられている場合には リンクレベ ルのアドレスは返されない、ということを意味する。 また、 ifa_broadaddr と ifa_dstaddr のど ちらを選択するかを決める方法は、 システムにより異なる。
注意
Linux では、 返されるアドレスは通常インターフェースに割り当てられた IPv4 アドレスと IPv6 アドレスになるが、 これ以外にインターフェース毎に一つ AF_PACKET アドレスも返される。 AF_PACKET アドレスには、 インターフェースとその物理層に関する低レベルの詳細が格納される。 この場合、 ifa_data フィールドには、 <linux/if_link.h> で定義される struct rtnl_link_stats (Linux 2.4 以前では <linux/netdevice.h> で定義される 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) address: <127.0.0.1> wlp3s0 AF_INET (2) address: <192.168.235.137> lo AF_INET6 (10) address: <::1> wlp3s0 AF_INET6 (10) address: <fe80::7ee9:d3ff:fef5:1a91%wlp3s0> プログラムのソース #define _GNU_SOURCE /* To get defns of NI_MAXSERV and NI_MAXHOST */ #include <arpa/inet.h> #include <sys/socket.h> #include <netdb.h> #include <ifaddrs.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <linux/if_link.h> int main(int argc, char *argv[]) { struct ifaddrs *ifaddr, *ifa; int family, s, n; 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, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) { 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)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクト の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。