getifaddrs のどのエントリが AF_PACKET ファミリーに属しているかを確認できます。すべてのインターフェースをリストしているように見える私のシステムでは:
struct ifaddrs *addrs,*tmp;
getifaddrs(&addrs);
tmp = addrs;
while (tmp)
{
if (tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_PACKET)
printf("%s\n", tmp->ifa_name);
tmp = tmp->ifa_next;
}
freeifaddrs(addrs);
getifaddrs() は、インターフェイス自体ではなく、インターフェイス アドレスのみを返します。
「AF_PACKET」で提案されているように、インターフェイスのいずれかにアドレスがない場合、または要求されたファミリのアドレスがない場合はどうなりますか?
これは、トンネル インターフェース (OpenVPN 接続を使用) を取得し、ネットワーク インターフェースごとに getifaddrs() からのすべてのエントリを一覧表示する例です:
[0] 1: lo address family: 17 (AF_PACKET) b4:11:00:00:00:01
address family: 2 (AF_INET) address: <127.0.0.1>
address family: 10 (AF_INET6) address: <::1>
[...]
[5] 10: tun0 address family: 2 (AF_INET) address: <172.16.0.14>
[EOF]
バム。 「tun0」インターフェイスに AF_PACKET はありませんが、システムには存在します。
代わりに、必要なことを正確に実行する if_nameindex() syscall を使用する必要があります。つまり、引数なしで、システム上のすべてのインターフェースのリストを返します:
#include <net/if.h>
#include <stdio.h>
int main (void)
{
struct if_nameindex *if_nidxs, *intf;
if_nidxs = if_nameindex();
if ( if_nidxs != NULL )
{
for (intf = if_nidxs; intf->if_index != 0 || intf->if_name != NULL; intf++)
{
printf("%s\n", intf->if_name);
}
if_freenameindex(if_nidxs);
}
return 0;
}