我正在编写一个简单的traceroute程序使用ICMP数据包。验证传入的数据包时遇到问题。在发送icmp数据包之前,我将hcmp header id设置为进程ID。当我收到回复时,我只能在重播响应时获得icmp标头ID。问题是当时间超过响应时,因为我得到0作为icmp标题id。当超过时间时,我该怎么做才能获得icmp标头ID?或者也许还有另一种方法来识别响应?我需要知道响应是针对我的流程的。有人能帮助我吗?
我的设置icmp标题:
struct icmphdr setIcmpHdr(int sequence){
struct icmphdr icmp_header;
icmp_header.type = ICMP_ECHO;
icmp_header.code = 0;
icmp_header.un.echo.id = getpid(); // here I set the id
icmp_header.un.echo.sequence = sequence;
icmp_header.checksum = 0;
icmp_header.checksum = compute_icmp_checksum((u_int16_t*)&icmp_header,
sizeof(icmp_header));
return icmp_header;
}
发送请求:
int sequence = hop;
struct icmphdr icmp_header = setIcmpHdr(sequence);
struct sockaddr_in recipeint = setRecipient(destination);
int ttl = hop;
setTTLOption(ttl, sockfd);
ssize_t bytes_sent = sendto(sockfd, &icmp_header, sizeof(icmp_header), 0,
(struct sockaddr*)&recipeint,sizeof(recipeint));
接收:
//receiving
struct sockaddr_in sender;
socklen_t sender_len = sizeof(sender);
u_int8_t buffer[IP_MAXPACKET];
ssize_t packet_len = recvfrom(sockfd, buffer, IP_MAXPACKET, 0, (struct
sockaddr*)&sender, &sender_len);
char ip_str[20];
inet_ntop(AF_INET, &(sender.sin_addr), ip_str, sizeof(ip_str));
struct iphdr* ip_header = (struct iphdr*) buffer;
ssize_t ip_header_len = 4*ip_header->ihl;
u_int8_t* icmp_packet = (buffer + 4 * ip_header->ihl);
struct icmphdr *icmp_header2 = (struct icmphdr *) icmp_packet;
printf("pid: %d\n", icmp_header2->un.echo.id); //here is zero when it is time exceeded ;/
if(icmp_header2->type != 0){
printf("IP packet with ICMP content from %s, hop %d\n\n", ip_str,
hop);
}else if(icmp_header2->type == 0){
printf("Reached destination: %s with %d hops.\n", destination, hop);
exit(EXIT_SUCCESS);
}
我将不胜感激任何帮助。 :)