微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C 中的 traceroute,响应中的 ICMP id 错误

如何解决C 中的 traceroute,响应中的 ICMP id 错误

我正在用 C 编写简单的 traceroute 程序。响应即将到来,但现在我想检查从这个特定程序发送的响应。我的问题是我从 ICMP 标头中获取的 ID 值与我从路径上的路由器设置的 ID 值不同。 ID 仅在来自目的地的响应中匹配。我正在为 PID 在 ICMP 标头中设置 id。

struct icmp header;
header.icmp_type = ICMP_ECHO;
header.icmp_code = 0;
header.icmp_hun.ih_idseq.icd_id = getpid();
header.icmp_hun.ih_idseq.icd_seq = seq;
header.icmp_cksum = 0;
header.icmp_cksum = compute_icmp_checksum((u_int16_t*)&header,sizeof(header));

我的做法是在每次发送包裹后将 ttl 加 1。这是发送代码

struct sockaddr_in recipent;
bzero (&recipent,sizeof(recipent));
recipent.sin_family = AF_INET;
inet_pton(AF_INET,address,&recipent.sin_addr);

ssize_t bytes_sent = sendto(
  sockfd,&header,sizeof(header),(struct sockaddr*)&recipent,sizeof(recipent)
); 

其中 address 是目标 IP。 根据我在 ICMP 标头中回复的理解,id 应该与发送的包中的相同 - 我的程序的 PID,但对于路径上的每个路由器,它都是 0,而 id = PID 仅来自目标路由器。这是接收包和打印 id 的代码

ssize_t packet_len = recvfrom (sockfd,buffer,4096,(struct sockaddr*)&sender,&sender_len);

char sender_ip_str[20]; 
inet_ntop(AF_INET,&(sender.sin_addr),sender_ip_str,sizeof(sender_ip_str));

struct iP*          ip_header = (struct iP*) buffer;
ssize_t             ip_header_len = 4 * ip_header->ip_hl;
u_int8_t*           icmp_packet = buffer + ip_header_len;
struct icmP*        icmp_header = (struct icmP*) icmp_packet;

printf("icd_id: %d,icd_seq: %d ---\n",icmp_header->icmp_hun.ih_idseq.icd_id,icmp_header->icmp_hun.ih_idseq.icd_seq); 

这是我为 address = 8.8.8.8

运行我的程序时得到的示例响应
1936  <---- PID

icd_id: 0,icd_seq: 0
192.168.1.1 0.13ms

icd_id: 0,icd_seq: 0
83.1.5.1 0.09ms

icd_id: 0,icd_seq: 0
80.50.18.65 0.05ms

icd_id: 0,icd_seq: 0
193.251.248.153 0.16ms

icd_id: 0,icd_seq: 0
193.251.255.168 0.21ms

icd_id: 0,icd_seq: 0
108.170.231.245 0.12ms

icd_id: 4352,icd_seq: 0
142.250.46.245 0.18ms

icd_id: 1936,icd_seq: 49629
8.8.8.8 0.16ms

解决方法

我找到了问题,如果有人发现同样的问题,请发布此答案。

https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol#Control_messages

问题是 id 在其他地方,以防 rospone 超过时间限制。

if (resp->type == ICMP_TIMXCEED){
    icmpHeader = (void*)icmpHeader + 8 + ipHeaderLen;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。