ファイヤープロジェクト
ネットワーク情報
2003-07-20T15:13+09:00   matsu
PF_INETの前にネットワーク情報について記述してみる.
x86はリトルエンディアンでネットワークではビックエンディアンらしい.アーキテクチャによってバイトオーダは異なるので,お行儀良く変換しておいた方が互換性が上がる.バイトオーダの変換には,
  • uint32_t htonl(uint32_t hostlong);
  • uint16_t htons(uint16_t hostshort);
  • uint32_t ntohl(uint32_t netlong);
  • uint16_t ntohs(uint16_t netshort);
などを使用する.以下サンプル.
x86マシンで実行すると以下のようになる.
$ ./byte-order 1234
-----------------------------------------
                ld              0x
-----------------------------------------
1234            1234            000004d2
htonl(1234)     -771489792      d2040000
/ets/host.conf,/ets/hostsなどを設定したことのない人はいないだろう.ここではその設定情報をCプログラムから取得する方法を示す.ホスト名からIPなどを取得するには
struct hostent *gethostbyname(const char *name);
を使用する.そして返されるstruct hostentから情報を取得する.以下man gethostbynameより.
struct hostent {
   char    *h_name;        /* official name of host */
   char    **h_aliases;    /* alias list */
   int     h_addrtype;     /* host address type */
   int     h_length;       /* length of address */
   char    **h_addr_list;  /* list of addresses */
}
h_addrtypeはAF_INETになっているはず.で,ちょっとうっとおしいのがh_addr_listである.これはホストのネットワークアドレスを,ネットワークバイトオーダなので,表示するにはホストバイトオーダに直したい.この変換は先述のntohlでもよいのだが,10進数とドットの表現にいっきに変換する
char *inet_ntoa(struct in_addr in);
が便利かもしれない.以下サンプル.
実行結果.
# printf "192.168.111.111\thoge.org\thoge\n" >> /etc/hosts
# printf "192.168.111.112\thoge.org\tfuga\n" >> /etc/hosts
# ./host-info hoge.org
name: hoge.org
aliases: hoge
aliases: fuga
length of address: 4
address: 192.168.111.111
address: 192.168.111.112

# ./host-info hoge
name: hoge.org
aliases: hoge
length of address: 4
address: 192.168.111.111

# ./host-info fuga
name: hoge.org
aliases: fuga
length of address: 4
address: 192.168.111.112
このように/etc/hostsに同じ名前で複数のIPを持っていたりすると,addressが二つ表示されたりする(aliasesやホスト名についても同様).
/etc/servicesを見たことがない人はいないだろう.ここではその情報をCで取得する方法を示す.それには
struct servent *getservbyname(const char *name, const char *proto);
を使用する.そして返されるstruct serventから情報を取得する.以下man getserbynameより.
struct servent {
   char    *s_name;        /* official service name */
   char    **s_aliases;    /* alias list */
   int     s_port;         /* port number */
   char    *s_proto;       /* protocol to use */
}
s_portはネットワークバイトオーダで入っているので,表示するときなどはntohsで変換する必要がある.
以下実行結果.
$ ./service-info ssh udp
service name:   ssh
port:   22
protocol:       udp

$ ./service-info http tcp
service name:   www
alias:  http
port:   80
protocol:       tcp
/etc/servicesの内容が異なれば結果は異なる(/etc/servicesの内容が異なっていいのかどうかは別として).
matsu(C)
Since 2002
Mail to matsu