1.ping命令全链路分析(2)
2.安装smokeping后提示500错误,监控监控求大神指点迷津
ping命令全链路分析(2)
本文使用 Zhihu On VSCode 创作并发布
上篇文章对开源网络协议栈实现 tapip 触发进行了分析,源码源码探讨了执行 ping 命令时,平台数据包是监控监控如何到达网络协议栈的。本文将继续探讨 ping 命令与网络协议栈的源码源码联系。目前广泛使用的平台梦幻奇缘源码网络协议栈是五层协议划分:应用层、传输层、监控监控网络层、源码源码链路层和物理层。平台ping 命令采用的监控监控 ICMP 协议位于网络层,但特别之处在于 ICMP 报文是源码源码封装在 IP 报文之内的。下文将从 ICMP 协议开始分析。平台
ICMP 协议
ping 命令的监控监控执行过程实际上包含了源端向目的端发送 ICMP 请求报文和目的端向源端发送 ICMP 回复报文的过程。ICMP 报文头包含了 ICMP type、源码源码code、平台id、seq 等字段,报文头部为 字节,payload 部分数据长度为可变长度。
ICMP 报文头部包含 8bit 类型码 type、8bit 代码 code 和 bit 校验和 checksum,uip-1.0源码其余部分内容和类型码 type 相关。ICMP 报文中定义 type 字段包含以下几种,type 字段与 code 的详细对应关系见附录 1:
其中,ping 命令使用的报文类型为响应请求和响应应答,其报文格式如图:
ICMP 响应请求
在 tapip 中,ICMP 响应请求报文构造是在 ping.c:send_packet() 函数中完成的。ICMP 报文填充构建代码如下:
根据上一篇文章的分析,tapip 采用一个 tap 设备作为虚拟网卡,ICMP 数据报文最终通过 wirte() 接口写入 tap 设备文件中,最终被 Linux 内核中的流氓软件源码网络协议栈处理。这里还是先从 tapip 出发,研究下网络协议栈中如何处理 ICMP 响应请求报文。在 tapip 源码中,处理 ICMP 响应请求报文在函数 icmp_echo_request() 中,其函数调用栈如下:
在 Linux 系统中,数据包到达网络设备后会触发中断,网卡驱动程序将对应数据包传递到内核网络协议栈处理,处理结果通过系统调用接口返回给应用程序(ping 应用)。
tapip 作为一种用户态实现,网络设备 net device 是5.0教程网源码通过 tap 设备模拟的,tap 设备文件描述符中被写入数据包就相当于网卡设备接收到网络数据包;
网卡驱动程序的工作对应 tapip 中 netdev_interrupt() 到 veth_rx() 之间的过程:首先在中断处理函数中调用 veth_poll() 函数采用轮询的方式检查 tap 设备的文件描述符是否有写入事件;当发生写入事件时,veth_rx() 函数被调用,从文件描述符中读取数据包,并传递到网络协议栈中处理,此时,网络协议栈处理的入口 net_in() 被调用。
网络协议栈按照网络分层模型进行处理:
ICMP 响应回复
ICMP 响应回复的处理过程与接收侧处理 ICMP 响应请求的流程基本一致,不同点在于最后 icmp 报文响应的处理,其 type 为 0,对应的android 源码生成apk处理函数为 icmp_echo_reply(),具体函数调用栈如下:
总结
本文主要分析了用户态网络协议栈 tapip 处理 ping 命令对应的 ICMP 报文的过程,后续将结合 Linux 内核分析这个过程在内核中是如何处理的,另外还会分析下 ARP 协议的实现。
学海无涯,感觉 tapip 的实现逻辑清晰,读起来非常舒服,非常推荐对网络感兴趣的同学学习参考。
(最近特别水逆,希望能早日走出困境,迎来光明吧。)
附录 1: ICMP 报文类型表
markdown
| 类型 Type | 代码 Code | 描述 |
| :------: | :------: | :--------------------------: |
| 0 | 0 | 回显应答(ping 应答) |
| 3 | 0 | 网络不可达 |
| 3 | 1 | 主机不可达 |
| 3 | 2 | 协议不可达 |
| 3 | 3 | 端口不可达 |
| ... | ... | ... |
TODO:
安装smokeping后提示错误,求大神指点迷津
1. 在安装smokeping监控时,使用yum命令安装必要的依赖包,包括httpd、rrdtool、fping、echoping、curly、perl及其相关模块。
2. 解压缩smokeping源码包,并执行配置脚本准备编译环境。
3. 编译安装smokeping,并在编译过程中根据提示安装缺失的Perl模块。
4. 创建smokeping所需的目录,并修改目录权限。
5. 修改smokeping的配置文件,包括通用设置、警报设置、数据库设置、展示设置、探测设置、从属设置、目标设置等。
6. 修改httpd服务器配置文件,添加smokeping相关的Alias和Directory指令。
7. 重启httpd服务,并启动smokeping服务。
8. 尝试访问smokeping监控页面,观察是否出现错误,并检查进程状态,若需要关闭smokeping,可以查找对应进程号并使用kill命令终止。
请检查每一步是否按照上述描述正确执行,特别是配置文件是否按照实际路径和需求进行了正确设置。如果问题依旧,可能需要进一步检查Perl模块安装路径和httpd配置文件的正确性。