ping,telnet,traceroute原理

1 ping

ping发送的是ICMP报文,ICMP报文是和tcp报文处在同一层次,嵌套在IP报文内(报文头中的Protocol=1,在IP报文中通过Protocol的值决定接下来应当将数据交给哪个协议层进行进一步处理,tcp协议Protocol=6,ICMP协议Protocol=1)
tcp协议报文必须指定源端口和目的端口
ICMP协议报文不需要指定端口,这也是为什么我们使用ping命令时不需要端口

tcp报文和icmp报文对比如下:

icmp报文

    +-----------------------------------------------------+
    | IP Header (至少20字节)                         |
    +-----------------------------------------------------+
    | ICMP Header (8字节)                                |
    +-----------------------------------------------------+
    | ICMP Data / Payload (根据需要可变长度)        |
    +-----------------------------------------------------+

tcp报文

    +-----------------------------------------------------+
    | IP Header (至少20字节)                              |
    +-----------------------------------------------------+
    | TCP Header (至少20字节)                             |
    +-----------------------------------------------------+
    | TCP Segment Payload (根据需要可变长度)              |
    +-----------------------------------------------------+

我们再看看icmp报文详情

    +-----------------------------------------------------+
    | IP Header (至少20字节)                         |
    +-----------------------------------------------------+
    | ICMP Header (8字节)                                |
    +-----------------------------------------------------+
    | ICMP Data / Payload (根据需要可变长度)        |
    +-----------------------------------------------------+

ICMP Header:
    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Type      |     Code      |          Checksum             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |           Identifier          |        Sequence Number        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         (various fields based on the type and code)         |
   +---------------------------------------------------------------+

- Type: 8位,标识ICMP报文的类型,如Echo Request(8),Echo Reply(0),Destination Unreachable(3)等。
- Code: 8位,进一步细化ICMP类型中的错误或状态信息。
- Checksum: 16位,用于校验整个ICMP报文的完整性。
- Identifier 和 Sequence Number: 在某些类型的ICMP报文中(如Ping请求与回应)使用,作为识别请求和响应报文的依据。
- ICMP Data / Payload: 根据ICMP类型不同而变化,可能包含额外的信息,例如在Ping请求和回应中,这部分会携带原始发送的数据。

我们所使用的ping命令,发送报文Type=8(Echo Request),响应报文Type=0(Echo Reply)。ping命令检测目的地址的可达性。

ping命令的详细过程
当我们执行ping命令时,ping程序会准备好一个icmp报文,然后发起系统调用socket(ip地址, SOCK_RAW, IPPROTO_ICMP),内核会处理tcpip协议栈报文的封装,比如icmp报文会封装成一个ip报文,ip报文还会继续封装成以太网帧等等
然后到达主机的网络接口卡(NIC)接收到来自数据链路层的以太网帧,将报文发送出去
经过复杂的网络环境比如防火墙、路由器,到达目的主机的网卡,目的主机网卡接收到以太网帧,通过本机的tcpip协议栈,最终还原为icmp报文。
目的主机内核处理过程中,期间会有多个钩子函数,用于调用本机防火墙配置,如果配置不可ping,则目的主机将不响应这个报文。
当目的主机没有相关的限制,将发送响应报文给源主机
源主机收到响应报文,网络通路。

2 telnet

telnet的设计初衷是进行远程登陆,同时还可以进行协议模拟、网络服务测试。举例

2.1 远程登陆

执行如下命令打开telnet命令行

C:\Users\aaabbbccc>telnet

然后打开连接,默认远程登陆端口是23端口

Microsoft Telnet> open 192.168.108.128 23

输入账号密码

连接成功

当然也可以在cmd命令行中这样连接

telnet 192.168.108.128 23

2.2 协议模拟

由于telnet可以发送原始的数据流至远程主机,因此它也可以用来模拟客户端与服务器之间的通信,帮助开发者测试或调试自己的网络应用程序或服务

尽管有专门的协议调试工具(如Wireshark、Postman等)提供了更为丰富的功能和易用性,但telnet的简单、直接和通用性使其在特定场景下仍具有一定的实用价值。

下面介绍使用telnet发送原始http报文

要注意的一点是,telnet报文(这里是http报文)是嵌套在tcp报文中的,走的tcp协议

目前在192.168.160.7的8080端口部署了一个web服务,我们首先需要连接到这个端口

我们要发送如下报文

GET /pms/auth/code?appKey=FPkMS0kV HTTP/1.1
Host: localhost

如下所示

P_bc_qsub 15:31:44 ~ JY
$ telnet localhost 8080
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'. -----------------------------------连接上了
GET /pms/auth/code?appKey=FPkMS0kV HTTP/1.1 --------------------------要发送的报文
Host: localhost

HTTP/1.1 200 -------------------------------------------http响应行和响应头
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Tue, 16 Apr 2024 07:31:48 GMT

4f -------------------------------------------------------------http响应体
{"code":200,"message":"操作成功","data":"2c2333e9226146d5b36bf09f50b96371"}
0

Connection closed by foreign host.
P_bc_qsub 15:31:48 ~ JY

我们看到,这样发送报文,发送了什么内容我们一目了然,比纯粹使用curl更直观

同样的道理,我们也可以发送POST请求。需要注意的是,发送POST请求需要指定Content-Length,表示请求体的字节数

举例

P_bc_qsub 16:30:36 ~ JY
$ telnet localhost 8080
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'. --------------------------------------------------------连接上了
POST /pms/projectList/queryPage HTTP/1.1 -----------------------------------------开始发送http报文
Host: localhost
Content-Type: application/json
Content-Length: 48
Authorization: xxxx.xxxx.xxxx

{"uid":"szj","pageNum":1,"pageSize":10}
HTTP/1.1 200 --------------------------------------------------------------------http响应报文
New_token: xxxx.xxxx.Kyfl60DBI-xxxx-2E
Access-Control-Expose-Headers: New_token
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Tue, 16 Apr 2024 08:30:40 GMT

9f1
{"code":200,"message":"操作成功","data":{"total":2,"totalPage":1,"pageSize":10,"list":[{"subprojectId":"xxx","subprojectName":"test","projectId":"Demo"},{...}],"pageNum":1}}
0

 

发送form请求,示例

POST /pms/phoenix/callback/taskStatus HTTP/1.1
Host: 192.168.160.7
Content-Type: multipart/form-data;charset=UTF-8; boundary=----BoundaryStringXYZ
Content-Length: 908
Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJGUGtNUzBrViIsImV4cCI6NDg0MDE4NTYwMH0.Pe0Iy8lIMAHBrsdtbTW211y5NE3sNWmmgxDNBoxW3Z0

------BoundaryStringXYZ
Content-Disposition: form-data; name="bean"

xxxxxxxxxxxxxxxxxxxxxxxxfdfdfaaa
------BoundaryStringXYZ--

其中Content-Length字段标识的是请求体的字节数,包括了BoundaryStringXYZ长度和结束标志--以及回车换行符。

 

注意,使用window powershell时,使用方式有所不同。telnet 192.168.160.7 8080 后,按 Ctrl + ],然后回车,进入命令模式。在命令模式下在输入http报文(注意不能使用ctrl+insert快捷键黏贴)

2.3 网络服务测试

用于探测端口的连通性,有了2.2的介绍,这里很简单了,略

3 traceroute

traceroute(跟踪路由)命令的原理利用了IP数据包头中的Time to Live(TTL,生存时间)字段以及Internet Control Message Protocol(ICMP,互联网控制消息协议)来确定数据包从源主机到目标主机所经过的各个路由器及其路径延迟。

每个IP数据包都有一个TTL字段,这是一个8位的计数器,初始值可以由发送方设置。数据包在网络中每经过一个路由器,TTL值就会减1。当数据包的TTL减少到0时,该数据包会在当前路由器被丢弃,并且该路由器会向源主机发送一个ICMP Time Exceeded(超时)错误消息,表明数据包因为TTL耗尽而被丢弃。

traceroute命令通过向目标主机发送一系列的IP数据包,每次发送时将TTL值从1开始逐渐递增(如1、2、3、...)。这样,第一轮发送的数据包会在经过第一个路由器时因TTL为1而被丢弃,源主机因此得知第一个跃点的信息;第二轮数据包会在经过第二个路由器时TTL为0而被丢弃,从而得到第二个跃点的信息;依此类推,直至数据包达到目标主机或TTL足够大以至于数据包能完成整个旅程。

traceroute通过巧妙地利用IP协议栈中的TTL机制和ICMP协议错误反馈,实现了对数据包在网络中传输路径的可视化追踪。

下面举例

同网段查看路由跳数

$ traceroute 192.168.160.8
traceroute to 192.168.160.8 (192.168.160.8), 30 hops max, 60 byte packets
1 wh2-login-2-2.wh.blc.genomics.cn (192.168.160.8) 0.507 ms 0.424 ms 0.388 ms

这里没有经过路由器,只1跳就到达目的地了,需要注意的是:每次会发送3个探测包,因此,我们看到3个往返时间。

较简单的网络架构下

$ traceroute 10.176.41.12
traceroute to 10.176.41.12 (10.176.41.12), 30 hops max, 60 byte packets
 1  10.26.68.249 (10.26.68.249)  0.466 ms  0.615 ms 10.26.68.248 (10.26.68.248)  0.420 ms
 2  wh-login-b07-2.wh.hpc (10.176.41.12)  0.149 ms  0.135 ms  0.111 ms

这里经过两跳就到达目的地。需要注意的是:第一跳有两个路由器ip,因为这通常意味着在发送的三个探测包中,至少有一个包通过了不同的路径。这种情况可能是由于负载均衡或者网络配置导致的路径变化。网络设备可能根据不同的算法(如轮询、哈希或者流量负载)将流量分配到多个路径上。

更复杂的网络环境

$ traceroute 10.64.38.1
traceroute to 10.64.38.1 (10.64.38.1), 30 hops max, 60 byte packets
 1  192.168.160.253 (192.168.160.253)  1.124 ms  1.260 ms  1.450 ms
 2  172.28.1.81 (172.28.1.81)  0.345 ms  0.339 ms  0.313 ms
 3  172.28.1.20 (172.28.1.20)  7.058 ms  7.238 ms  7.023 ms
 4  172.22.0.89 (172.22.0.89)  1.165 ms  1.269 ms  1.383 ms
 5  * * *
 6  * * *
 7  * * *
 8  172.16.0.126 (172.16.0.126)  39.008 ms *  41.919 ms
 9  172.16.0.118 (172.16.0.118)  41.913 ms  42.102 ms 172.16.0.108 (172.16.0.108)  42.004 ms
10  * * *
11  * * *
12  * * *
13  172.20.0.77 (172.20.0.77)  52.330 ms  52.923 ms  52.125 ms
14  172.20.0.145 (172.20.0.145)  48.910 ms  50.191 ms  50.190 ms
15  172.20.0.158 (172.20.0.158)  51.308 ms  50.327 ms  50.647 ms
16  10.64.38.1 (10.64.38.1)  50.093 ms !X  51.071 ms !X  51.068 ms !X

需要注意的是,上述输出中的* * *表示在特定跃点未能成功获取到沿途路由器响应。出现该情况通常有如下几种可能

  • 1. 数据包在到达该跃点之前就已经超时,没有收到相应的 ICMP Time Exceeded 或 ICMP Echo Reply 消息。
  • 2. 路由器配置为不回应traceroute请求,可能是出于安全策略或管理设置的原因。
  • 3. 网络路径中存在防火墙或其他网络设备阻止了traceroute的数据包。

traceroute工具使用的是特殊构造的数据包(通常是基于 ICMP 协议的 Echo 请求或 UDP 数据包),其目的是探测从源主机到目标主机间的路由路径和响应时间。这些数据包可能受到与普通网络流量不同的处理方式,特别是在涉及安全策略、防火墙规则和路由器配置的情况下。

对于实际的网络请求(如 HTTP、HTTPS、TCP 连接等),它们遵循正常的网络路由机制,即依据 IP 分组的转发规则(主要是基于 IP 头部的目的 IP 地址和路由表信息)在网络中传输。如果一个路由器能够正确转发traceroute数据包,理论上它也应该能够正确转发正常的网络请求数据包。

虽然实际网络请求不会像traceroute那样发送带有特定 TTL 和等待响应的探测数据包,但它们仍可能受到相同或相似的网络条件影响,如链路故障、设备性能问题、路由变更等。如果traceroute中的某个跃点确实存在网络问题(如路由器故障或链路中断),那么实际网络请求在经过该路径时也可能遇到同样的问题,表现为延迟增加、丢包或完全无法到达目标。

traceroute中的 * * * 只是表明在执行traceroute命令时,特定类型的探测数据包在该跃点未收到预期响应,这可能会影响(但不绝对)实际网络请求的传输。实际请求的成功与否和性能表现取决于当时整个网络环境的状态,包括但不限于路由器、防火墙、链路质量等因素。

 

posted @ 2024-04-10 15:05  zhenjingcool  阅读(186)  评论(0编辑  收藏  举报