raw ソケットを使用して TTL=1 で UDP パケットを送信するプログラムを作成しました。ローカル ホストでこのプログラムを実行すると、ICMP パケットを受信できます。しかし、Planetlab ノードで実行すると、ICMP パケットを受信できません。
Planetlab ノードでは、各ノードは多くのユーザーによって共有され、各ユーザーには仮想スライスのみが割り当てられます。したがって、一般的に、プロセスが特定のポートにバインドされている場合にのみ、そのポートからパケットを受信できます。そうでない場合、システムはランダムなパケットをスライスに配信できません。
しかし、traceroute のソース コードをダウンロードして、planetlab ノードで実行したところ、ICMP TTL を超えたパケットを受信できました。
つまり、tcpdump を使用して、Planetlab ノードで ICMP パケットをキャプチャします。プログラムを実行して TTL=1 で UDP パケットを送信すると、tcpdump は ICMP パケットをキャプチャできませんが、tcpdump を使用して TTL=1 で UDP パケットを送信すると、tcpdump は ICMP パケットをキャプチャできます。
この違いの潜在的な理由は何ですか?
ありがとう!
私のソースコードのいくつか:
if ((sendfd = socket(PF_INET, SOCK_RAW, IPPROTO_UDP)) < 0) {
perror("Failed in creating socket\n");
exit(1);
}
if ((recvfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
perror("Failed in creating socket\n");
exit(1);
}
memset(&local_addr, 0, sizeof(local_addr));
local_addr.sin_port = htons(src_port);
if ((bind(sendfd, (struct sockaddr *)& local_addr, sizeof(local_addr))) < 0) {
perror("Failed in binding socket\n");
exit(1);
}
if (setsockopt(sendfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0) {
perror("Failed in setsockopt!\n");
exit(1);
}
if ((bind(recvfd, (struct sockaddr *)& local_addr, sizeof(local_addr))) < 0) {
perror("Failed in binding socket\n");
exit(1);
}
if (setsockopt(recvfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0) {
perror("Failed in setsockopt!\n");
exit(1);
}
memset(&dst_addr, 0, sizeof(dst_addr));
dst_addr.sin_family = AF_INET;
dst_addr.sin_addr.s_addr = inet_addr(dst_ip);
dst_addr.sin_port = htons(dst_port);
nr_bytes = sendto(sendfd, UDPpacket, pkt_len, 0, (struct sockaddr *)&dst_addr, sizeof(dst_addr));
nr_bytes = recvfrom(recvfd, buf, 2000, 0, (struct sockaddr *)&dst_addr, &len);