Provided by: manpages-ja-dev_0.5.0.0.20131015+dfsg-2_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 は NULL 終端されたインターフェース名を指す。 ifa_flags フィールドには、 SIOCGIFFLAGS ioctl(2) 操作で返されるインターフェースのフラグが 格納される (これらのフラグのリストについては netdevice(7) を参照)。 ifa_addr フィールドは、インターフェースのアドレスを格納した構造体へのポインタである (sa_family サブフィールドを参照して、アドレス構造体の形式を判別すべきである)。 このフィー ルドは NULL ポインタとなる場合がある。 ifa_netmask フィールドには、 ネットマスクがあるアドレスファミリーであれば、 ifa_addr に関 連付けられたネットマスクを格納した構造体へのポインタが入る。 このフィールドは NULL ポイン タとなる場合がある。 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 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: <fe80::2d0:59ff:feda:eb51%eth0> プログラムのソース #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\n", 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\n", gai_strerror(s)); exit(EXIT_FAILURE); } printf("\taddress: <%s>\n", host); } } freeifaddrs(ifaddr); exit(EXIT_SUCCESS); }
関連項目
bind(2), getsockname(2), socket(2), packet(7), ifconfig(8)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.54 の一部 である。プロジェクト の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。