深入理解iputils网络工具-第2篇 ping:通路检测程序

本文详细介绍了ping程序的工作原理和使用方法,包括ICMP报文结构、IP报文选项、时间戳和路由记录。通过分析ping的命令行选项和程序流程,揭示了报文发送间隔、预发机制以及回复等待计时的实现。同时,探讨了socket选项、全局变量的作用以及重要函数的功能,为理解网络通信和故障排查提供了深入见解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2.1       引言

   “ping”这个名字源于声纳定位操作。Ping程序由Mike Muuss编写,目的是为了测试另一台主机是否可达。该程序发送一份ICMP回显请求报文给主机,并等待返回ICMP回显应答。

2.2       ping程序的使用

    敲入命令:

lixi@lixi-desktop:~$ ping -V
ping utility, iputils-sss20071127

    说明本机中安装的ping程序和本文研究的ping程序一样,是最新版本。

lixi@lixi-desktop:~$ ping -T tsonly www.ustc.edu.cn -c 1
PING www.ustc.edu.cn (202.38.64.9) 56(124) bytes of data.
64 bytes from 202.38.64.9: icmp_seq=1 ttl=62 time=0.795 ms
TS: 	6123570 absolute
	493
	364
	-857378
	0
	857378
	-363
	-493


--- www.ustc.edu.cn ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.795/0.795/0.795/0.000 ms

    6123570是时间戳的绝对值,而输出的其他时间戳是相对上一个时间戳的差别。在北京时间9:42做的测试,北京时区为UTC+8,故此有9+42/60-8=1.7

而6123570/60/60/1000=1.7。故此出现这个结果是非常有道理的。

lixi@lixi-desktop:~$ ping www.ustc.edu.cn -R -c 1
PING www.ustc.edu.cn (202.38.64.9) 56(124) bytes of data.
64 bytes from 202.38.64.9: icmp_seq=1 ttl=62 time=0.852 ms
RR: 	lixi-desktop.local (210.45.74.25)
	202.38.96.36
	local-gw.ustc.edu.cn (202.38.64.126)
	202.38.64.9
	202.38.64.9
	202.38.96.33
	210.45.74.1
	lixi-desktop.local (210.45.74.25)

    对照上面的路由信息,我们就可以分析出为什么时间戳信息里会有对称的现象,而对称轴的值是0了。

   产生对称性的另一个条件是RTT很小,这里只有0.8ms。

    我们可以还可以分析出202.38.64.9的系统时间和其他路由的系统时间相差很大,大约有-14分钟。

lixi@lixi-desktop:~$ ping -T tsandaddr www.ustc.edu.cn -c 1
PING www.ustc.edu.cn (202.38.64.9) 56(124) bytes of data.
64 bytes from 202.38.64.9: icmp_seq=1 ttl=62 time=1.66 ms
TS: 	lixi-desktop.local (210.45.74.25)	7375300 absolute
	210.45.74.1	828
	local-gw.ustc.edu.cn (202.38.64.126)	26
	202.38.64.9	-857405
Unrecorded hops: 3


--- www.ustc.edu.cn ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.664/1.664/1.664/0.000 ms
   上面是同时记录路由和时间戳信息。不过这里由于IP选项长度的限制,只能存储4个路由和它对应的时间戳。

lixi@lixi-desktop:~$ ping -T tsprespec 202.38.64.9 202.38.96.33 210.45.74.1 www.ustc.edu.cn -c 1
PING www.ustc.edu.cn (202.38.64.9) 56(124) bytes of data.
64 bytes from 202.38.64.9: icmp_seq=1 ttl=62 time=0.893 ms
TS: 	202.38.64.9	6741320 absolute
	202.38.96.33	0
	210.45.74.1	857353
Unrecorded hops: 1


--- www.ustc.edu.cn ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.893/0.893/0.893/0.000 ms

    如果我们一定要得到以后的几个路由和时间戳,我们可以采用上述的办法。

    这里在北京时间10:07分的时候进行的测试,202.38.64.9的时间戳是6741320,而我们上面的分析,202.38.64.9的系统时间大约比北京时间晚14分钟。10-8-14/60=1.87。6741320/60/60/1000=1.87。故此出现这个时间戳也是很有道理的。

    ping程序的选项解释如下:

    -a   

        可听见的ping。

        所谓可听见,不过是在ping.c文件的parse_reply的函数中,输出ASCII码'/a',beep一下。

   -A

        自适应的ping。调整报文间隔时间,使其适应于RTT,这样非常有效率地使得网络中传输的不超过一个(如果-l参数设置了就为多个)。对于非超级用户,最小的时间间隔为200毫秒,在一个RTT比较得下的网络中,这个模式和-f的洪泛模式基本相同。

        为了调整报文时间间隔,使用update_interval()函数来调整时间间隔。

    -b

        允许ping广播地址。

        设置broadcast_pings为1,当判断到这个选项设为1之后,且地址是广播地址,那么就设置setsockopt(icmp_sock, SOL_SOCKET, SO_BROADCAST,&broadcast_pings, sizeof(broadcast_pings))。

    -B

        不允许ping改变报文的源主机地址,该地址在ping开始运行的时候就已经指定了。

        为了指定源主机地址,ping.c使用函数bind()来把套接字和本地套接字地址绑定,即在已创建的套接字上加上本地套接字地址。

    -c <count>

        在发送<count>个ECHO_REQUEST报文。当和-w <deadline>一起设置时,ping等待收到<count>个ECHO_REPLY报文,直到超出时间限制为止。

        设置npackets选项为<count>就可以了。在没有设置deadline的情况下,当nreceived + nerrors >=npackets时就可以退出循环,完成ping的任务了。

    -d

        设置socket中的SO_DEBUG选项,使能调试跟踪。实质上Linux内核中没有使用这个套接字选项。

        设置方法:setsockopt(icmp_sock,SOL_SOCKET, SO_DEBUG, (char *)&hold, sizeof(hold));

    -F <flow> <label>

       这个选项只有ping6才有。

    -f

      洪泛模式。对每一个ECHO_REQUEST报文的发送,打印一个“.”,当接受到ECHO_REPLY报文时,打印一个backspace字符。这样能够快速地表明网络丢失了多少个报文。如果interval没有设置,则设置interval为0,并按照报文接受的速度和一百次每秒的速度来发送报文(看哪个速度快)。只有超级用户能够和-i 0选项一起使用这个选项。

    -i <interval>

       在发送每个报文之间等待<interval>秒。默认设置是等待一秒,在洪泛模式下则不等待。只有超级用户才能将<interval>设置为小于0.2秒的数。

       interval为<interval>*1000,程序的实现决定了<interval>输入整型数和浮点数都能被正确接受。

    -I <interface/address>

        设置发送的地址或者网络设备。

        程序首先尝试用intinet_pton(int af, const char *src, void *dst)函数由将src代表的字符串转化为dst中的IP地址。如果不能正确转换,则意味着这个选项不是地址,例如210.45.74.25,而是设备名如eth0。如果是后者,则设置device为<interface>,并用bind(icmp_sock, (structsockaddr*)&source, sizeof(source))      setsockopt(probe_fd,SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)+1)来将套接字和本地套接字地址进行绑定。

    -l <preload>

        <preload>是在没有接受到回复报文之前能发送的最多报文。非超级用户最多只能设置为3。

        尽可能快地发送预载的报文,然后再返回到正常发送模式。

        将<preload>值赋到preload变量中。如果不赋值preload默认为1。

    -L

        禁止多播数据包的回环,只有在ping的目的主机是广播地址时才管用。

    -n

        只有数字形式ip地址值的输出,不通过查询DNS获知IP地址对应的主机名,以节省时间。

        设置F_NUMERIC,不用调用gethostbyaddr来查询DNS主机名了。

        用gethostbyaddr的由查询目的主机的IP地址。

    -p <pattern>

        允许为传输的回显报文中包含的内容指定字节模式。这对于诊断与传输数据有关的网络问题可能很有用。数据采用16进制,例如“-p ff”可将传输的报文填充为全1。

    -Q <tos>

        用来设置服务质量(Quality of Service )

        例如最小开销、 可靠性、吞吐量、低延迟。

        IP协议有一个8bit的DS区分服务(以前叫服务类型)。前三位是优先(precedence)字段(在目前,优先字段并未被大家使用),接着4bit是TOS位,最后1bit没有使用,但必须置0。

        4比特TOS位的意义分别为D(最小时延)、T(最大吞吐量)、R(最高可靠性)、C(最小代价)。要设置TOS位为对应意义,可以设置-Q <tos>分别为0x10,0x08,0x04,0x02。TOS的各个位不能同时置1。

    -q

        静默模式。这种模式下,出了开始的提示和结束的数据统计,不会输出任何东西。

    -R

        记录路由信息。在发送的IP报文首部选项中放入记录路由选项,在接到到报文回复之后,打印出回复报文的路由信息。

        注意:IP报文的选项中最多只能计算9个路由信息,计算方式如下:

        首部长度HLEN。这4bit字段用来定义首部的长度,以4字节为单位。由于首部长度可变,默认长度是20字节,此时4bit字段值为5。4bit的字段最大可以表示的数为15,

<think>我们正在解决一个网络连接问题,用户试图诊断与server.cs-xf.com的连接,但在容器或环境中发现缺少 ping命令。因此,我们需要提供在缺少ping命令的环境下进行网络诊断的替代方法。步骤:1.确认问题:无法使用 ping命令,需要其他方法测试与server.cs-xf.com的网络连通性。2.替代方案:我们可以使用其他命令或工具,如 curl,wget, telnet,nc (netcat)等,或者使用编程方式(如Python)来测试连接。3.具体操作:提供几种替代方法,并说明如何操作。注意:由于环境可能没有安装这些工具,所以需要提供多种选择,包括可能已经存在的工具。方法一:使用curl测试 HTTP连通性如果目标是一个Web服务器,我们可以使用 curl来测试 HTTP连接。方法二:使用telnet或nc测试 TCP端口连通性如果知道目标服务器的端口(如80、443等),可以使用 telnet或 netcat测试TCP连接。方法三:使用 wget测试类似于curl,使用 wget尝试下载一个很小的文件(如首页)。方法四:使用编程方式(如Python)测试如果环境中没有上述命令,但安装了Python,我们可以编写一个简单的Python脚本来测试 TCP连接。方法五:使用 traceroute或 tracepath(如果可用)进行路由跟踪(但同样可能不存在)由于用户的环境缺少ping,很可能也缺少其他网络工具,因此我们重点放在可能存在的工具上,特别是curl和 Python。另外,我们也可以尝试安装 ping命令,但需要知道容器的操作系统类型(如基于Debian还是 Alpine)。因此,回答结构如下:1.尝试使用curl进行连通性测试2.尝试使用telnet或netcat3.尝试使用 wget4.使用 Python脚本测试5.如果上述都不可行,考虑安装 ping命令(提供不同系统的安装命令)同时,生成相关问题。注意:用户的目标是诊断与server.cs-xf.com的网络连接。</think>### 容器环境中诊断网络连接问题(缺少 ping 命令) 当容器环境中缺少 `ping` 命令时,可通过以下替代方法诊断与 `server.cs-xf.com` 的网络连接问题: #### 1. **使用 curl 测试基础连通性** ```bash # 测试 HTTP 连接 curl -I http://server.cs-xf.com # 测试 HTTPS 连接 curl -I https://server.cs-xf.com ``` - ✅ **成功响应**:显示 `HTTP/1.1 200 OK` 或 `HTTP/2 200` - ❌ **失败表现**: - `Could not resolve host` → DNS 解析失败 - `Connection timed out` → 网络阻断 - `SSL certificate problem` → 证书错误 #### 2. **使用 telnet 测试端口连通性** ```bash telnet server.cs-xf.com 80 # 测试 HTTP 端口 telnet server.cs-xf.com 443 # 测试 HTTPS 端口 ``` - ✅ **成功表现**:显示 `Connected to server.cs-xf.com` - ❌ **失败表现**:`Connection refused` 或超时 #### 3. **使用 netcat (nc) 进行高级测试** ```bash # 测试端口开放性 nc -zv server.cs-xf.com 80 # 发送 HTTP 请求 echo -e "GET / HTTP/1.1\nHost: server.cs-xf.com\n\n" | nc server.cs-xf.com 80 ``` - ✅ **成功响应**:收到服务器返回的 HTTP 头信息 #### 4. **Python 内置网络诊断** ```python import socket try: # 测试 TCP 连接 s = socket.create_connection(("server.cs-xf.com", 80), timeout=5) print("[SUCCESS] Connection established") s.close() except socket.error as err: print(f"[FAILURE] {err}") ``` - ✅ **执行方式**:`python3 network_test.py` #### 5. **容器内安装网络工具** 若需长期使用网络工具: ```bash # Alpine 容器 apk add iputils curl netcat-openbsd # Debian/Ubuntu 容器 apt update && apt install -y iputils-ping curl netcat ``` #### 网络诊断流程图 ```mermaid graph TD A[开始诊断] --> B{curl 可用?} B -->|是| C[curl 测试] B -->|否| D{telnet/nc 可用?} D -->|是| E[端口测试] D -->|否| F[Python 脚本测试] C --> G[分析响应头] E --> H[检查连接状态] F --> I[捕获socket错误] G --> J[结论] H --> J I --> J ``` > **关键提示**:若出现 `Connection refused`,检查目标服务器防火墙规则;若出现 `Name or service not known`,检查容器 DNS 配置(`/etc/resolv.conf`)[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值