C言語で自分のIPアドレスを知る

 Ruby自分のIPアドレスを知るってのを見た。元ネタの解説によると、アドレスやポート番号がダミーのUDPソケットを作成してconnect()すると、getsockname()で自分のアドレスが取得できるというもの。
 connectのマニュアルページによると、UDPソケットをconnectすると特に何もパケットが送出されず、そのソケットのデフォルトのパケット送信先/唯一の受信先となるっていう仕様があるとのことで、これを利用しているらしい。
 てな訳で、C言語でこれを実装してみた。記述が面倒だけど、実質的に関数側が求める仕様に合わせて書いてるだけ。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc,char *argv[]) {
	int fd;
	struct sockaddr_in dst_addr={0};
	struct sockaddr_in src_addr={0};
	socklen_t addrlen;
	char str[16];

	fd=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
	dst_addr.sin_family=AF_INET;
	dst_addr.sin_port=htons(7);
	inet_aton("128.0.0.0",&dst_addr.sin_addr);
	connect(fd,(struct sockaddr *)&dst_addr,sizeof(dst_addr));
	addrlen=sizeof(src_addr);
	getsockname(fd,(struct sockaddr *)&src_addr,&addrlen);
	inet_ntop(AF_INET,&src_addr.sin_addr,str,sizeof(str));
	printf("%s\n",str);
	close(fd);
	return 0;
}

追記:@saltheads氏のRuby版の元ネタとなったNeoCat氏のPerl版のさらに元ネタがリンク切れだったので見てなかったんだけど、ふとインターネットアーカイブで見れるんじゃないかと思って見てみたら、SHIROYAMA Takayuki氏がC言語で書かれていた(汗)
まあ、2001年の投稿なので記述が若干古いけど、基本的には今回自分で書いたものと同じだった。ただ、BSD系で必要なincludeと、相手と自分のアドレスを格納するのに同じ構造体使ってたり、構造体の初期化をしていなかった部分を元ソースを見て気になったので修正した。