为什么我的TTL值每次增加2?(C套接字编程)

为什么我的TTL值每次增加2?(C套接字编程),c,linux,sockets,icmp,traceroute,C,Linux,Sockets,Icmp,Traceroute,我试图实现一个Traceroute程序,但我遇到了两个问题,一个是TTL和RTT打印错误;尽管它们在作为ping程序实现时打印正确。最后,我的主要问题是,当我增加TTL时,它会增加2,而不是1 我只包含了我认为必要的代码,谢谢 提前感谢:) void 回应(内部信号){ 结构sockaddr\u存储对等地址; socklen_t peer_addrlen; 地址中的结构sockaddr\u; dstaddr中的结构sockaddr_; 结构iphdr*ip; 结构icmphdr*icmp; 已发

我试图实现一个Traceroute程序,但我遇到了两个问题,一个是TTL和RTT打印错误;尽管它们在作为ping程序实现时打印正确。最后,我的主要问题是,当我增加TTL时,它会增加2,而不是1

我只包含了我认为必要的代码,谢谢

提前感谢:)

void
回应(内部信号){
结构sockaddr\u存储对等地址;
socklen_t peer_addrlen;
地址中的结构sockaddr\u;
dstaddr中的结构sockaddr_;
结构iphdr*ip;
结构icmphdr*icmp;
已发送struct timeval*;
int skt;
int序列;
长整数长度;
fd_集rdfds;
int就绪;
int rtt;
字符buff[BUF_SIZE];
/*创建并检查插座编号*/
skt=插座(AF_INET、SOCK_RAW、IPPROTO_ICMP);
int ttl=0;
setsockopt(skt、IPPROTO_IP、IP_TTL和TTL、sizeof(TTL))小于0;
/*启动发送循环*/
int i;
对于(i=0;i<4;i++){
ttl+=1;
setsockopt(skt、IPPROTO_IP、IP_TTL和TTL、sizeof(TTL));
/*检查插座*/
if(skt<0){
perror(“socket()”);
出口(1);
}
/*设置IP地址*/
addr.sin_family=AF_INET;
地址sin_端口=0;
addr.sin\u addr.s\u addr=INADDR\u ANY;
/*检查套接字绑定*/
if(绑定(skt,(struct sockaddr*)和addr,sizeof(struct sockaddr_in))){
perror(“无法绑定套接字”);
出口(1);
}
/*IP缓冲区*/
ip=(结构iphdr*)buff;
对等地址=(socklen)sizeof(结构sockaddr\u存储);
memset(&dstaddr,0,sizeof(struct sockaddr_in));
dstaddr.sin_addr.s_addr=inet_addr(主机地址);
dstaddr.sin_family=AF_INET;
ip->ttl=(ttl++);
/*ICMP缓冲区*/
memset(buff,0,sizeof(buff));
icmp=(结构icmphdr*)buff;
icmp->type=ECHO\u-REQ;
icmp->id=htons(getpid()&0xffff);
icmp->seqNum=htons(序列++);
/*检查发送时间*/
if(gettimeofday((struct timeval*)icmp->data,NULL)){
perror(“无法确定发送时间”);
出口(1);
}
/*计算数据包大小*/
长度=sizeof(struct-icmphdr)+sizeof(struct-timeval);
icmp->checksum=~(sum(0,buff,length));
/*数据包太小,错误
发送请求*/
如果(发送到)(skt,buff,长度,0,
(struct sockaddr*)和dstaddr,sizeof(struct sockaddr_in))协议!=ICMP)
出口(1);
/*获取IP有效负载长度和ICMP地址*/
length=ntohs(ip->length)-ip->hdrlen*4;//ip有效负载的长度
icmp=(struct icmphdr*)((uint32_t*)ip+ip->hdrlen);//查找icmp hdr
/*检查ICMP响应类型*/
如果(icmp->type==11){
printf(“第11类:ICMP…”);
}
/*如果(icmp->type!=ECHO_REPL | | sum(0,icmp,长度)!=0xffff){
fprintf(stderr,“已接收%s\n”,消息[icmp->type]);
//出口(1);
} */
/*在10毫秒内找出发送和结束时间之间的差异*/
发送=(struct timeval*)icmp->data;
如果((rtt=(end.tv\u usec-sent->tv\u usec)/100)<0)
rtt+=10000;//我们已循环到一个新的秒
rtt+=(end.tv_sec-sent->tv_sec)*10000;//添加任何秒数
/*打印ICMP回复*/
printf(“%ld字节来自%s:icmp_请求=%d ttl=%d时间=%0.1f毫秒\n”,
长度,
iptos(NTOLL(ip->srcip)),
ntohs(icmp->seqNum),
/*设置初始TTL*/
ip->ttl,
((浮动)rtt)/10);
}/*结束发送循环
/*返回无效信号*/
if(signum==SIGINT){
printf(“\nGoodbye!\n”);
出口(0);
}
/*3秒探针*/
警报(3);
}
这里你再增加一次。如果它是1,那么在这一行之后它将是2。但是,一旦循环迭代,您将再次增加它,因此现在它将是3。这就是为什么您的ttl在每次迭代中增加两个


ip->ttl=(ttl++)
的意思是:取
ttl
的值并将其复制到
ip->ttl
,然后在执行此操作后,将
ttl
增加一次。

在该循环中将ttl增加两次。当for循环开始时:

    ttl+=1;
然后在将其分配给结构时再次执行

   ip->ttl=(ttl++);

至于rtt,在我看来,这段代码似乎是错的。

谢谢,我完全忽略了这一点(以前把它放在那里了)!!当这个程序ping时,RTT正在工作,只是不再工作了:/RTT让我觉得奇怪的是,你减去了一个应该大于(或等于)的数字,然后除以100,结果总是大于等于0。然而,当你检查结果是否小于0并加上10000(这似乎同样不正确,因为你已经除以100,所以你不应该只加10吗?),然后在下一行你再次将其转换为useconds而不是十分之一。
 ip->ttl=(ttl++);
    ttl+=1;
   ip->ttl=(ttl++);