虚拟机中具有小TTL的UDP数据包无法接收ICMP TTL超出数据包

时间:2013-07-02 11:46:17

标签: c sockets network-programming icmp traceroute

我编写了一个程序,它使用原始套接字发送TTL = 1的UDP数据包, 当我在本地主机上运行此程序时,我可以收到ICMP数据包。 但是当我在Planetlab节点上运行它时,它无法接收ICMP数据包。

在planetlab节点上,每个节点由许多用户共享,并且每个用户仅分配一个虚拟切片。因此,通常情况下,只有当您将进程绑定到特定端口时,才能从该端口接收数据包,否则系统无法将随机数据包传递到您的切片。

但我下载了traceroute源代码并在planetlab节点上运行它,它可以接收超过ICMP TTL的数据包。

即:我使用tcpdump在Planetlab节点上捕获ICMP数据包。当我运行我的程序发送TTL = 1的UDP数据包时,tcpdump无法捕获ICMP数据包,但是当我使用traceroute发送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);

0 个答案:

没有答案