使用ping命令定位网络延迟问题
一、背景
使用ping命令发现局域网内延迟大,且变化较大。需要分析耗时在那一层。
二、分析
上图可以看出,本机ping延时非常低。在本机网络 IO 的过程中,流程会有一些差别。有差异的地方总共有两个,分别是路由和驱动程序。
路由:
对于本机网络 IO 来说,特殊之处在于在 local 路由表中就能找到路由项,对应的设备都将使用 loopback 网卡,也就是我们常见的 lO。
驱动程序:
网络设备子系统的入口函数是 dev_queue_xmit。对于真的有队列的物理设备,在该函数中进行了一系列复杂的排队等处理以后,才调用 dev_hard_start_xmit,从这个函数再进入驱动程序来发送。
但是对于启动状态的回环设备来说(q->enqueue 判断为 false),就简单多了:没有队列的问题,直接进入 dev_hard_start_xmit。接着进入回环设备的“驱动”里的发送回调函数 loopback_xmit,将 skb “发送”出去。
因此,可以从上面两层入手,排查问题!
驱动:
监控icmp包发送和接受的时刻,看时间是否过大。
但有一个问题,链路上运行的不一定只有ICMP数据包。因此,我们需要在每一层对我们发送和接收的ICMP包进行过滤。
路由:
三、ICMP
ICMP报文包含在IP数据报中,IP报头在ICMP报文的最前面。一个ICMP报文包括IP报头(至少20字节)、ICMP报头(至少八字节)和ICMP报文(属于ICMP报文的数据部分)。当IP报头中的协议字段值为1时,就说明这是一个ICMP报文。ICMP报头如下图所示。
这里只讲解与ping有关的ICMP消息类型,主机发送回送消息(Type = 8),被请求主机回送响应消息(Type = 0),基本格式如下:
回送消息[ECHO]
回送响应消息[ECHO REPLY]
•CheckSum为校验和,重点注意从ICMP的头部(即Type开始),到data结束(即到整个数据包结束)
•Identifier为标识符,由主机设定,一般设置为进程号,回送响应消息与回送消息中identifier保持一致
•Sequence Number为序列号,由主机设定,一般设为由0递增的序列,回送响应消息与回送消息中Sequence Number保持一致
•data为数据,由主机设定,回送响应消息与回送消息中data保持一致
///include/uapi/linux/icmp.hstruct icmphdr {__u8 type;__u8 code;__sum16 checksum;union {struct {__be16 id;__be16 sequence;} echo;__be32 gateway;struct {__be16 __unused;__be16 mtu;} frag;__u8 reserved[4];} un;
};
四、实现
#ifndef _LINUX_IP_H
#define _LINUX_IP_H#include <linux/skbuff.h>
#include <uapi/linux/ip.h>static inline struct iphdr *ip_hdr(const struct sk_buff *skb)
{return (struct iphdr *)skb_network_header(skb);
}static inline struct iphdr *inner_ip_hdr(const struct sk_buff *skb)
{return (struct iphdr *)skb_inner_network_header(skb);
}static inline struct iphdr *ipip_hdr(const struct sk_buff *skb)
{return (struct iphdr *)skb_transport_header(skb);
}
#endif /* _LINUX_IP_H */struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)__u8 ihl:4,version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)__u8 version:4,ihl:4;
#else
#error "Please fix <asm/byteorder.h>"
#endif__u8 tos;__be16 tot_len;__be16 id;__be16 frag_off;__u8 ttl;__u8 protocol;__sum16 check;__be32 saddr;__be32 daddr;/*The options start here. */
};
///include/uapi/linux/in.henum {IPPROTO_IP = 0, /* Dummy protocol for TCP */
#define IPPROTO_IP IPPROTO_IPIPPROTO_ICMP = 1, /* Internet Control Message Protocol */
#define IPPROTO_ICMP IPPROTO_ICMPIPPROTO_IGMP = 2, /* Internet Group Management Protocol */
#define IPPROTO_IGMP IPPROTO_IGMPIPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
#define IPPROTO_IPIP IPPROTO_IPIPIPPROTO_TCP = 6, /* Transmission Control Protocol */
#define IPPROTO_TCP IPPROTO_TCPIPPROTO_EGP = 8, /* Exterior Gateway Protocol */
#define IPPROTO_EGP IPPROTO_EGPIPPROTO_PUP = 12, /* PUP protocol */
#define IPPROTO_PUP IPPROTO_PUPIPPROTO_UDP = 17, /* User Datagram Protocol */
#define IPPROTO_UDP IPPROTO_UDPIPPROTO_IDP = 22, /* XNS IDP protocol */
#define IPPROTO_IDP IPPROTO_IDPIPPROTO_TP = 29, /* SO Transport Protocol Class 4 */
#define IPPROTO_TP IPPROTO_TPIPPROTO_DCCP = 33, /* Datagram Congestion Control Protocol */
#define IPPROTO_DCCP IPPROTO_DCCPIPPROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */
#define IPPROTO_IPV6 IPPROTO_IPV6IPPROTO_RSVP = 46, /* RSVP Protocol */
#define IPPROTO_RSVP IPPROTO_RSVPIPPROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */
#define IPPROTO_GRE IPPROTO_GREIPPROTO_ESP = 50, /* Encapsulation Security Payload protocol */
#define IPPROTO_ESP IPPROTO_ESPIPPROTO_AH = 51, /* Authentication Header protocol */
#define IPPROTO_AH IPPROTO_AHIPPROTO_MTP = 92, /* Multicast Transport Protocol */
#define IPPROTO_MTP IPPROTO_MTPIPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */
#define IPPROTO_BEETPH IPPROTO_BEETPHIPPROTO_ENCAP = 98, /* Encapsulation Header */
#define IPPROTO_ENCAP IPPROTO_ENCAPIPPROTO_PIM = 103, /* Protocol Independent Multicast */
#define IPPROTO_PIM IPPROTO_PIMIPPROTO_COMP = 108, /* Compression Header Protocol */
#define IPPROTO_COMP IPPROTO_COMPIPPROTO_SCTP = 132, /* Stream Control Transport Protocol */
#define IPPROTO_SCTP IPPROTO_SCTPIPPROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */
#define IPPROTO_UDPLITE IPPROTO_UDPLITEIPPROTO_MPLS = 137, /* MPLS in IP (RFC 4023) */
#define IPPROTO_MPLS IPPROTO_MPLSIPPROTO_RAW = 255, /* Raw IP packets */
#define IPPROTO_RAW IPPROTO_RAWIPPROTO_MAX
};
驱动层如何识别ICMP报文?
在.ndo_start_xmit = esp_hard_start_xmit,函数中,将邻居子系统传递下来的skb使用ip_hdr函数即可转换!
#include <linux/ip.h>
#include <linux/in.h>
#include <linux/icmp.h>struct iphdr *iph;
struct icmphdr *icmpph = NULL;iph = ip_hdr(skb);
if(iph->protocol==IPPROTO_ICMP ) {//如果是ICMP报文icmpph = (struct icmphdr *) ((u8 *) iph + (iph->ihl << 2));printk("ESP type:%d, code:%d\n", icmpph->type, icmpph->code);if(icmpph->type==8 && icmpph->code==0) {//ping 请求printk(KERN_ERR "ping RQ:%d\n",icmpph->un.echo.sequence);}
}
ref:
不为人知的网络编程(十三):深入操作系统,彻底搞懂127.0.0.1本机网络通信 - 知乎
linux内核协议栈 icmp 报文收发流程_老王不让用的博客-CSDN博客
ping命令全链路分析(4) - 数据包内核态处理 - 知乎
Linux内核:从skb获取udp头,udp_hdr()获取到是错误的udp头_kanguolaikanguolaik的博客-CSDN博客
网络-ICMP协议、Ping命令实现与ICMP攻击_51CTO博客_icmp ping
ICMP协议之ping实现_yo-yo的博客-CSDN博客
使用ping命令定位网络延迟问题相关推荐
- 使用ping命令查看网络延迟--用Enki学Linux系列(7)
使用ping命令查看网络延迟 Using ping To Measure Network Latency ping命令持续发送少量互联网流量到远程地址并报告收到回应的总时间.如果流量因为网络故障或者错 ...
- ping 延迟 linux,使用ping命令查看网络延迟--用Enki学Linux系列(7)
使用ping命令查看网络延迟 Using ping To Measure Network Latency ping命令持续发送少量互联网流量到远程地址并报告收到回应的总时间.如果流量因为网络故障或者错 ...
- linux怎么用ping通测试连接,ping网络是否连通的步骤_使用ping命令检查网络连通性的方法-系统城...
2015-03-23 10:34:59 浏览量:775 Ping属于一个通信协议,利用Ping命令可以检查网络是否连通,可以很好地帮助我们分析和判定网络故障,然而在WinXP系统的局域网下我们如果要 ...
- 计算机不能上网怎么检查,电脑不能上网如何通过Ping命令检查网络
电脑系统工作时间一长,就会不可避免地遇到网络故障;在排除网络故障之前,用户首先应该弄清楚在网络服务.网络设备.网络资源工作状态正常的情况下,究竟是什么样的表现形式,之后对照发生故障时的状态,分辨出网络 ...
- ping命令测试网络_如何执行计算机Ping测试命令以检查网络连接?
ping命令测试网络 Computer networking provides a lot of features for remote usage. But remote access may ha ...
- 使用ping命令检查网络是否通畅或网络连接连接速度
使用ping命令检查网络是否通畅或网络连接连接速度 Ping是Windows.Unix和Linux系统下的一个命令.ping也属于一个通信协议,是TCP/IP协议的一部分.利用ping命令可以检查网络 ...
- 使用C#调用外部Ping命令获取网络连接情况
以前在玩Windows 98的时候,几台电脑连起来,需要测试网络连接是否正常,经常用的一个命令就是Ping.exe.感觉相当实用. 现在 .Net为我们提供了强大的功能来调用外部工具,并通过重定向输入 ...
- 如何使用ping命令检查网络故障
如果网络不通,可以按照以下步骤来诊断网络状况:依次点击:开始-允许-输入CMD,进入DOS窗口后用ping命令来诊断网络连接的状况. ping是Windows系列自带的一个可执行命令.利用它可以检查网 ...
- linux使用ping命令ping本机,Linux下使用ping命令判断网络的好坏
简介 在Linux系统里面如果想判断网络的好坏,脑海中蹦出的第一个命令就是ping了. ping命令基本是最常用的网络命令,它可以用来测试与目标主机的连通性. ping通过发送ICMP ECHO_RE ...
最新文章
- c#运行shell命令
- 在OpenCV中图像边界扩展 copyMakeBorder 的实现
- 《研磨设计模式》chap6 工厂模式factory(2)案例实现
- webpack4配置基础
- 全市场等权中位数_A股市场周内效应研究
- windows缺少dll文件检测dll文件
- jquery学习笔记之选择器
- Java中的class类和对象总结(思维导图)
- bootice添加linux_用BOOTICE工具在U盘上实现SYSLINUX与GRUB4DOS双启动 - 图文
- Java开发手册!java项目描述模板,挥泪整理面经
- 千住焊锡丝RMA98,ESC21参数解读:金属含量、焊剂成分、质保期、Lot No. 等
- Week1.3-金融会计指标案例分析
- 笔记本电脑网络服务无法使用,打开网络共享中心,一直卡在打开界面或者插入网线后右下角为红叉
- office钓鱼学习
- 基础测绘1:10000成果检验需注意的问题
- 杰里之. 输出 3 路 PMW【篇】
- 北洋大时代:大师们的理想国札记-随想篇
- 互联网公司招聘--奇虎360--技术类--2013年笔试题
- 一步一步搭建一个图片上传网站(后台服务器用nodejs)
- Windows 10 卸载 Qt 5.9.9