ある実験のためにCでソケットを使ったプログラムを書いています。
それは次のようなものです。
1. 適当なサーバとTCPコネクションを確立する。
2. そのコネクションの上でサーバにメッセージを送る。
3. 続けてもう一度メッセージを送る。
ただし、前のものとはTTLの値を変える。
4. わけあってTTLを2で送ったものの値に戻す。
5. コネクションを切断する。
サーバからの応答などは気にしないことにします。
これを実装した(つもりの)ものが下のプログラムです。
Webサーバを例にしました。簡単のためエラーチェックは行っていません。
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
int main(void)
{
int s, ttl1, ttl2;
struct sockaddr_in sa = { 0 };
const char request[] = "GET / HTTP/1.0\r\n\r\n";
size_t len = sizeof(request) - 1;
s = socket(PF_INET, SOCK_STREAM, 0);
sa.sin_family = PF_INET;
sa.sin_port = htons(80);
inet_pton(PF_INET, "適当なWebサーバのIPアドレス", &sa.sin_addr);
connect(s, (struct sockaddr *)&sa, sizeof(struct sockaddr_in));
ttl1 = 20;
ttl2 = 10;
setsockopt(s, IPPROTO_IP, IP_TTL, &ttl1, sizeof(int));
write(s, request, len); /* (1) */
setsockopt(s, IPPROTO_IP, IP_TTL, &ttl2, sizeof(int));
write(s, request, len); /* (2) */
setsockopt(s, IPPROTO_IP, IP_TTL, &ttl1, sizeof(int));
close(s);
return 0;
}
これを Red Hat Linux 7.3 (kernel 2.4.20-20.7, glibc 2.2.5-43) で
実行し、そのホスト上でパケットのキャプチャを行いました。
すると、(1)と(2)で送られたパケットのTTLの値が共に20に
なっていました。(2)の直後に試しに sleep(1) を入れてみると、
(2)でのパケットのTTLが10に変わっていたことから、
実際にパケットが作られるまで間があり、その間に次のsetsockopt()での
TTLの変更が有効になってしまったのではないかと推測しました。
この解釈は妥当でしょうか?
また、上記の仕様の通りにするにはどのようにしたらよいでしょうか?
できれば、sleep()を入れるなどの時間かせぎは使いたくありません。
よろしくお願い致します。
----
MAEDA Tooru <m506...@u-aizu.ac.jp>