ネットワーク情報
PF_INETの前にネットワーク情報について記述してみる.
x86はリトルエンディアンでネットワークではビックエンディアンらしい.アーキテクチャによってバイトオーダは異なるので,お行儀良く変換しておいた方が互換性が上がる.バイトオーダの変換には,
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);
$ ./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の内容が異なっていいのかどうかは別として).

