在C中编写基本的traceroute脚本

时间:2011-02-03 13:27:25

标签: c udp raw-sockets icmp traceroute

我必须写一个trceroute脚本,但我不确定我的尝试是否正确。

现在我就这样做(如果我做错了或笨拙,请纠正我):

  1. 获得了ip-和udpheader的结构
  2. 校验和功能
  3. 打开2个套接字:一个用于在SOCK_RAW模式下发送UDP数据包(用于操作ttl),另一个用于从路由器接收ICMP应答。
  4. 使用sendto()发送UDP数据包
  5. 不知道如何接收和处理ICMP答案
  6. 有没有更方便的方法来改变TTL而不是使用sock_raw,我必须自己定义所有的标题内容? 打开ICMP袜子时,我应该为socket()使用什么参数? 如何收到ICMP答案?

2 个答案:

答案 0 :(得分:2)

您定位的是什么平台?这是来自OpenBSD source的BSD风格:

if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
    err(5, "icmp socket");
if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
    err(5, "raw socket");

在Linux上,我相信,您需要将IP_RECVERRrecvmsg(2)MSG_ERRQUEUE一起使用,请参阅ip(7)

答案 1 :(得分:2)

就设置TTL而言,您可以使用setsockopt()。以下是Linux上ping的iputils源代码的摘录:

if (setsockopt(icmp_sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, 1) == -1) {
    perror ("ping: can't set multicast time-to-live");
    exit(2);
}

if (setsockopt(icmp_sock, IPPROTO_IP, IP_TTL, &ittl, sizeof(ittl)) == -1) {
    perror ("ping: can't set unicast time-to-live");
    exit(2);
}