C中的traceroute,响应中的ICMP id错误
Posted
技术标签:
【中文标题】C中的traceroute,响应中的ICMP id错误【英文标题】:traceroute in C, wrong ICMP id's in responses 【发布时间】:2021-06-30 16:39:13 【问题描述】:我正在用 C 语言制作简单的 traceroute 程序。响应即将到来,但现在我想检查从这个特定程序发送的响应。我的问题是我从 ICMP 标头中获得的 ID 值与我从路径上的路由器设置的 ID 值不同。 ID 仅在来自目的地的响应中匹配。我在 ICMP 标头中为 PID 设置 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 增加一。这是发送代码:
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),
0,
(struct sockaddr*)&recipent,
sizeof(recipent)
);
address
是目标 IP。
根据我在 ICMP 标头中回复的理解,id 应该与发送的包中的相同 - 我的程序的 PID,但路径上的每个路由器都为 0,而 id = PID
仅来自目标路由器。这是接收包并打印 id 的代码:
ssize_t packet_len = recvfrom (sockfd, buffer, 4096, 0, (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
【问题讨论】:
【参考方案1】:我找到了问题,如果有人发现相同的问题,请发布此答案。
https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol#Control_messages
问题是 id 在其他地方,以防 rospone 超过时间限制。
if (resp->type == ICMP_TIMXCEED)
icmpHeader = (void*)icmpHeader + 8 + ipHeaderLen;
【讨论】:
以上是关于C中的traceroute,响应中的ICMP id错误的主要内容,如果未能解决你的问题,请参考以下文章