1
情報ネットワーク演習
村川猛彦
2006年10月12日(木)
2
本日の内容
課題1 低水準入出力 課題2 名前解決 (ホスト名⇔IPアドレス) 課題3 ソケットを用いた プロセス間通信 課題4 HTTPサーバのビルド 課題5 HTTPクライアント ハイパーテキストへのアクセス3
第2回課題
●実施内容と意図
– IPアドレスとホスト名の相互変換をするプログラムを拡張す る. – この課題を通じて,IPv4における名前解決の方法,および 関連するライブラリルーチンや構造体の仕様を学ぶ.4
ホスト名とは
●例
– nachi00 – nachi00.sys.wakayama-u.ac.jp – www.wakayama-u.ac.jp – www.google.co.jp – localhost ●書式
– 英数字等を「.」でつなぐ. 演習室内では これらは同じ計算機 (ホスト,ノード) を指す FQDN (Fully Qualified Domain Name)と呼ば れる5
IPアドレスとは(文字列)
●例
– 133.42.159.1 – 66.249.89.104 – 127.0.0.1 ●書式
– 0~255の整数を4つ書き,「.」でつなぐ.●
ドット付き10進記法(dotted decimal notation)
ともいう.
6
IPアドレス(バイナリ)
●例
– 10000110 00101010 10011111 00000001 ●文字列によるIPアドレスを4オクテット(4バイト)で
表現し,順番に(ネットワークバイトオーダ,または
ビッグエンディアン)メモリに格納する.
●プロセス間通信(課題3)で,connectシステムコー
ルを使って接続先ホストを指定する際に,この形式が
不可欠!
7
IPアドレスとホスト名を知るコマンド
●host
– Vine Linuxでも利用可 – host nachi00 – host 133.42.159.1 – host www.google.co.jp ●nslookup
– 古い(obsolete)コマンド.最近のLinuxでは非推奨8
DNS (Domain Name System)
●
インターネットにおけるホスト名とIPアドレスとを対
応させるシステム
– ホスト名 ⇒ IPアドレス を「正引き」, IPアドレス ⇒ ホスト名 を「逆引き」という. ●「DNSサーバ」に「リゾルバ(resolver)」が問い合
わせて情報を得る.
– DNSサーバ間で情報交換をすることも – 演習室環境で,通信するDNSサーバを知りたければ cat /etc/resolv.conf●
ソフトウェアではBIND (Berkeley Internet Name
9
ホスト名とIPアドレスは多対多(1)
mail.sys.wakayama-u.ac.jp ntp.sys.wakayama-u.ac.jp dns.sys.wakayama-u.ac.jp www.l.google.com www.google.com www.google.co.jp 66.249.89.104 66.249.89.99 一つのホスト名に 複数のIPアドレス ホスト名とIPアドレスは 一対多 「多対多」は 二つの 「一対多」に 分ける 133.42.159.1 一つのIPアドレスに 複数のホスト名 IPアドレスとホスト名は 一対多 ns.sys.wakayama-u.ac.jpホスト名とIPアドレスは多対多(2)
●実用上は
– ホスト名からIPアドレスの一つ, IPアドレスからホスト名の一つ(正式なホスト名) を求めれば十分 ●利用例は
– クライアント: サーバのホスト名 ⇒ IPアドレス – サーバ: 例えばアクセスをログに記録する際, クライアントのIPアドレス ⇒ ホスト名11
IPv4とIPv6
●本演習では,IPv4のみを対象とする.
●IPv4
– アドレス長: 32ビット (アドレス空間: 232) ●IPv6
– アドレス長: 128ビット (アドレス空間: 2128) – IPアドレスは「.」ではなく「:」で区切って表記する. 省略記法もある. – IPv6に移行しても,ホスト名は変わらない12
相互変換プログラムをCで書くには
●数個のライブラリルーチンと構造体を理解すること
– ライブラリ関数: gethostbyname, gethostbyaddr, inet_aton, inet_ntoa – 構造体: hostent, inet_addr – DNSサーバへの通信などは,ライブラリルーチンに任せる13
ライブラリルーチン(1)
●
struct hostent *
gethostbyaddr
(const void
*addr, int len, int type);
– ネットワーク上のホストのエントリを取得する.
– “get host by address”
●
struct hostent *
gethostbyname
(const char
*name);
– 与えられたホスト名に対応するエントリを取得する.
– “get host by name”
– 文字列形式のIPアドレスを与えても,一応,情報は得られ
る.
14
ライブラリルーチン(2)
●
int
inet_aton
(const char *cp, struct in_addr
*inp);
– IPアドレスをドット付き10進記法からバイナリ値へ変換す
る.
– “internet: ascii string to network address”
●
char *
inet_ntoa
(struct in_addr in);
– IPアドレスをバイナリ値からドット付き10進記法へ変換す
る.
– “internet: network address to ascii string”
15
hostent構造体
●gethostbyname,gethostbyaddrで問い合わせが成
功したら,この構造体のポインタを返す.
●char **型のメンバは?
– h_aliasesは文字列の配列を指すポインタ – h_addr_listはバイト列(バイナリ形式のIPアドレス)の配 列を指すポインタ – いずれもNULLで終端(argvと同様) struct hostent { char *h_name; /* 正式なホスト名 */ char **h_aliases; /* ホスト名の別名(0個以上) */ int h_addrtype; /* ホストアドレスの種類 */int h_length; /* アドレス長(IPv4なら4) */ char **h_addr_list; /* IPアドレス(1個以上) */ }
16
in_addr構造体
●inet_atonではポインタ渡し
– 変換に成功したら,参照先に格納される. ●inet_ntoaでは値渡し
●メンバs_addrの値をchar *型に変換(キャスト)し
てから使うことが多い.
struct in_addr {unsigned long int s_addr; }
17
ホスト情報獲得の留意点
●gethostbyname,gethostbyaddrは
– 呼び出してから値を得るまでに時間がかかる ● 特に,値の獲得に失敗するとき ● /etc/hostsを参照したり,/etc/resolv.confで指示された DNSサーバに問い合わせたりしているため ●gethostbyname,gethostbyaddt,inet_ntoaは
– 連続して呼び出してはいけない ● 実体は(例えばstatic領域にあって)使い回されるため18
相互変換プログラムの方針
①文字列は,IPアドレスか?
– inet_atonの戻り値を調べる.もしそうであれば,ついで に,バイナリ形式の情報を格納する. – gethostbyaddrにより,バイナリ形式のIPアドレスからホ スト情報を獲得する.獲得に失敗したら,エラー終了.②文字列は,ホスト名か?
– gethostbynameにより,ホスト情報を獲得する.獲得に失 敗したら,エラー終了. – inet_ntoaにより文字列のIPアドレスを求め,出力する. 逆順にはできない.文字列のIPアドレスに対しても, gethostbynameで(一般には不完全な)ホスト情報を 獲得できてしまうため.19
課題2(1)
●~takehiko/network-enshu2006/2/ip-host
は,
引数がIPアドレスならホスト名に,ホスト名ならばIP
アドレスに変換して出力する.
– cd ~takehiko/network-enshu-2006/2 – ./ip-host nachi00.sys.wakayama-u.ac.jp ● 133.42.125.50 – ./ip-host 133.42.125.50 ● nachi00.sys.wakayama-u.ac.jp – ./ip-host www.google.com ● 66.249.89.99 – host www.google.com ...結果は各自確認のこと20
課題2(2)
●~takehiko/network-enshu2006/2/ip-host.c
をコ
ピーして
~/network-enshu2006/2/ip-host.c
と
し,以下の仕様を満たすよう,修正をしなさい.
– 複数のコマンドライン引数を処理する. n番目の引数の結果は,標準出力のn行目に出力する. – 引数が「ホスト名」で,その「IPアドレス」が複数あるとき は,セミコロンで区切って出力する.逆も同様. – ホスト情報獲得に失敗したときは「invalid」を標準出力に 出力する(標準エラー出力には何も出力しない). – コメントを変更(作成者,作成日時)し,作業メモを残 す. – ディレクトリのパーミッションは705,ファイルは604にし ておくこと.21
課題2の追加事項とヒント
●機能ごとに関数分割してもよいし,main関数のみでも
よい.
●課題はこれでできた,と思ったら,
~takehiko/network-enshu2006/bin/validator2
を実行してみよう.
●余裕があれば,実行時間を短縮するアイデアを考えよ
う.作業メモに記録してあれば加点する.仕様に反し
ない限り,その機能をコード化してもよい.
– 実行時間を知るには,コマンド名の前にtime22
期限
●2006年10月18日(水)19:30の回収までに完成させ
ておくこと.
●それ以降の提出は,経過時間に応じて減点する.
●期限後のプログラム修正は?
– 最終的な回収までの修正(コメントの充実,デバッグな ど)はOK.23
テストプログラムについて
●~takehiko/network-enshu2006/bin/validatorα
でテストする.
– 実行中に参照するファイル ● ~/network-enshu2006/α/ソースファイル.c ● ~takehiko/network-enshu2006/α/commandβ ● ~takehiko/network-enshu2006/α/commandβ-answer – 生成されるファイル ● ~/network-enshu2006/α/ソースファイル ● ~/network-enshu2006/α/ソースファイル_code.c ● ~/network-enshu2006/α/ソースファイル_comment.c ● ~/network-enshu2006/α/error+warning– 「Everything is just fine!」を目指せ!
課題番号