名 前
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/ に 書 か れ て い る 。