ICMP协议之tracert实现

1. 相关ICMP协议概述
    这里只讲解与tracert有关的ICMP消息类型,网关发送超时报文(type = 11),主机发送目标不可达报文(type = 3),基本格式如下:
    超时报文

        

         其中code = 0,表示由网关发送
    目标主机不可达报文

        

         其中code = 3,表示在目的主机,端口不可用

 

2. Tracert流程
     首先明确TTL是IP报头中的字段,TTL表示了数据包的time to live,即还能经由多少跳,所以TTL = 1表示数据包将在下个路由或主机被丢弃,并发送超时报文;
     其次为了明确已到达主机,发送时目的端口设为非法端口(如58127),这样主机收到报文后会发送目标不可达报文。
下面是tracert的流程:
     1> 构造UDP数据包,设置TTL = 1
     2> 发送UDP数据包,记录发送时间t1
     3> 接收ICMP差错包,如果是超时报文,则是经过的中间路由,记录路由信息,记录接收时间t2,计算时间(t2 - t1);如果是目标不可达报文,则抵达目的主机,记录势头收时间t2,打印信息,退出
     4> 构造UDP数据包,设置TTL += 1,返回第二步
其中,TTL的每个数值(如TTL = 1)发送3次UDP包,即重复2~3步3次;
   接收超时,打印"*"表示报文丢失

 

3. 模拟tracert实现tracerty
     • 发送使用UDP报文,每次发送只需设置IP报头的TTL字段

  

    • 接收使用SOCK_RAW

       

    • 对收到数据包处理
      首先从IP报头得到IP报头长度

int hlen = ip->ip_hl << 2;       // total ip header length

      然后定位到ICMP报头,检查各字段合法性,对超时报文处理

       

     对目标不可达报文处理

    

 

4. 程序源代码

     http://download.csdn.net/source/2194656


5. 最终效果

   

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在C++中,使用ICMP(Internet Control Message Protocol)实现traceroute(也称为tracert或路径跟踪)需要使用socket编程,特别是套接字的底层网络功能。ICMP协议主要用于错误报告和路由信息查询,而traceroute利用ICMP的"Time to Live" (TTL)字段来追踪数据包从源到目的地的路径。 以下是一个简单的traceroute实现步骤概述: 1. 包含必要的头文件: ```cpp #include <iostream> #include <string> #include <vector> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <net/ethernet.h> #include <net/if.h> ``` 2. 创建套接字并绑定本地地址: ```cpp int sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if (sock < 0) { // 处理错误 } struct sockaddr_in sa; sa.sin_family = AF_INET; sa.sin_port = htons(0); // 不关心端口 if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) { // 处理错误 } ``` 3. 发送ICMP Echo Request(用于探测目的主机): ```cpp std::string host_ip = "目标IP地址"; struct iphdr *iph = (struct iphdr *) sendmsg(sock, &msg, 0, sizeof(msg), NULL, 0, NULL); ``` 这里`msg`包含ICMP请求报文,包括目的IP地址。 4. 接收ICMP Echo Reply并处理数据: ```cpp char buffer[2048]; while (true) { ssize_t len = recvfrom(sock, buffer, sizeof(buffer), 0, NULL, NULL); if (len < 0) { break; } // 解析ICMP报文,提取TTL值,并记录路径 // ... } close(sock); ``` 5. 在`while`循环中,你需要检查ICMP报文的类型和代码,通常使用`ping()`库或者第三方库来解析这些信息,并根据TTL递减更新路径记录。 请注意,这个过程涉及到复杂的网络编程和协议解析,而且在某些系统上可能受到权限限制。实际编写代码时,你可能需要查阅相关的技术文档和库(如libpcap)来辅助实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值