ネットワークプログラム(1) ネットワークインターフェースの情報を取得する
int getifaddrs(struct ifaddrs ** ifap)
は、ローカルシステムのネットワークインターフェースの構造体リストを取得することができます。リストの最初を*ifapに格納します。
リストは動的に確保されるので、使い終わったら、freeifaddrs()で開放する必要があります
ヘッダファイル
#include <sys/types.h>
#include <ifaddrs.h>
戻り値
0:成功
-1:失敗
構造体 struct ifaddrs
struct ifaddrs
{
struct ifaddrs *ifa_next; /* 次の構造体へのポインタ */
char *ifa_name; /* インターフェース名 */
unsigned int ifa_flags; /* SIOCGIFFLAGS からのフラグ */
struct sockaddr *ifa_addr; /* このインターフェースのIPアドレス*/
struct sockaddr *ifa_netmask; /* このインターフェースのサブネットマスク */
union
{
struct sockaddr *ifu_broadaddr; /* ブロードキャストアドレス */
struct sockaddr *ifu_dstaddr; /* PtoPアドレス */
} ifa_ifu;
#define ifa_broadaddr ifa_ifu.ifu_broadaddr
#define ifa_dstaddr ifa_ifu.ifu_dstaddr
void *ifa_data; /* (may be unused). */
};
サンプルソース
#include<iostream>
#include<sys/types.h>
#include<ifaddrs.h>
#include<string>
#include<netinet/in.h>
#include <arpa/inet.h>
using namespace std;
int main(void){
struct ifaddrs * addrs = nullptr;
int ret = getifaddrs(&addrs);
if(ret != 0) {
fprintf(stderr, "!!! getifaddrs [%s:L%d]\n", __FILE__, __LINE__);
return 1;
}
for(auto p = addrs; p!=nullptr; p=p->ifa_next){
string interface_name = string(p->ifa_name);
string disp_ipaddress;
string disp_netmask;
sa_family_t address_family = p->ifa_addr->sa_family;
if(address_family==AF_INET){ // IPv4
char buffer[INET_ADDRSTRLEN]={0,0,0,0};
if(p->ifa_addr != nullptr){
inet_ntop(address_family, &((struct sockaddr_in*)p->ifa_addr)->sin_addr,
buffer, INET_ADDRSTRLEN);
disp_ipaddress = string(buffer);
}
if(p->ifa_netmask!=nullptr){
char buffer[INET_ADDRSTRLEN]={0,0,0,0};
inet_ntop(address_family, &((struct sockaddr_in*)(p->ifa_netmask))->sin_addr,
buffer, INET_ADDRSTRLEN);
disp_netmask = string(buffer);
}
printf("IF:%s IPv4: %s mask:%s\n",
interface_name.c_str(), disp_ipaddress.c_str(), disp_netmask.c_str());
}
else if(address_family == AF_INET6){ // IPv6
uint32_t scope_id=0;
if(p->ifa_addr!=nullptr){
char buffer[INET6_ADDRSTRLEN] = {0,0,0,0};
inet_ntop(address_family, &((struct sockaddr_in6*)(p->ifa_addr))->sin6_addr,
buffer, INET6_ADDRSTRLEN);
disp_ipaddress = string(buffer);
scope_id = ((struct sockaddr_in6*)(p->ifa_addr))->sin6_scope_id;
}
if(p->ifa_netmask!=nullptr){
char buffer[INET6_ADDRSTRLEN] = {0,};
inet_ntop(address_family, &((struct sockaddr_in6*)(p->ifa_netmask))->sin6_addr,
buffer, INET6_ADDRSTRLEN);
disp_netmask = string(buffer);
}
printf("IF:%s IPv6: %s mask:%s scope id:%d\n",
interface_name.c_str(), disp_ipaddress.c_str(), disp_netmask.c_str(), scope_id);
}
}
freeifaddrs(addrs);
return 0;
}
実行結果
$: ~/000-getifaddr$ ./a.out
IF:lo IPv4: 127.0.0.1 mask:255.0.0.0
IF:wlp3s0 IPv4: 192.168.11.8 mask:255.255.255.0
IF:pan1 IPv4: 10.189.161.1 mask:255.255.255.0
IF:lo IPv6: ::1 mask:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff scope id:0
IF:wlp3s0 IPv6: fe80::60b:a952:40ad:de1a mask:ffff:ffff:ffff:ffff:: scope id:2
アドレスファミリ(sa_family)
通信の種類を表します。
AF_INET: IPv4
AF_INET6: IPv6
この記事が気に入ったらサポートをしてみませんか?