Shammer's Philosophy

My private adversaria

特定NICのIPアドレスを取得する関数

NIC の IP Address を取得する - Shammerismの内容を少し変更して作成。実際にやってみると、どういうものか詳細はわからないがAF_PACKETの情報もあるようで、綺麗に取得するのは難しい印象。そのため、情報を返すのではなく渡された入れ物に結果を入れるという実装にした。改善の余地はたくさんあるかもしれないけれどもとりあえずメモ。

#include <stdio.h>      
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h> 
#include <arpa/inet.h>

void getifipv4addr(char * value, const char * device) {
    struct ifaddrs * if_list = NULL;
    struct ifaddrs * ifa = NULL;
    void * tmp = NULL;
    getifaddrs(&if_list);
    for( ifa = if_list ; ifa != NULL ; ifa = ifa->ifa_next ){
	if( strcmp(ifa->ifa_name, device) == 0 ){ // Target device
	    if( !ifa->ifa_addr ){
		// This interface is NOT assigned IP Address? or not linked up?
		continue;
	    }
	    else {
		if( ifa->ifa_addr->sa_family == AF_INET ) { // Check IPv4 Address
		    tmp = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
		    inet_ntop(AF_INET, tmp, value, INET_ADDRSTRLEN);
		    break;
		}
		else {
		    // For example, reach here the cases
		    // sa_family is AF_PACKET(17).
		    // sa_family is AF_INET6(23).
		}
	    }
	}
    }
    freeifaddrs(if_list);
}
int main(int argc, const char * args[]){
    char ipv4_addr[INET_ADDRSTRLEN];
    memset(ipv4_addr, 0, sizeof(ipv4_addr));
    getifipv4addr(ipv4_addr, args[1]);
    printf("%s IPv4 address is %s.\n", args[1], ipv4_addr);
    return 0;
}

実行結果は以下。

$ ./a.out eth0
eth0 IPv4 address is 192.168.128.118.
$