libpcap/tcpdump—2—网络信息(listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes)
这条信息在运行tcpdump的时候都会见到,那它到底代表什么,又是怎么产生的。这篇文章就说一下这个事。这条信息共有4个内容,分别是:ens33,EN10MB,Ethernet 和 262144.这是最全的情况,查看tcpdump代码你会发现还有3个内容的情况,那个比这个要简单。忘了说了,我使用的tcpdump是4.9.2,libpcap是1.9.0.下面就把这4个内容分别介绍一下。
ens33
tcpdump中的pcap_findalldevs接口引入,实现在libpcap中。在libpcap中用3种办法确保获取到网卡名。首先是系统函数getifaddrs,这个基本就都成功了。如果不好使,程序会读/sys/class/net,里面每个网卡都有自己的文件夹。如果这个还不好用,那么就读/proc/net/dev。这3种办法应该就能兼容所有linux设备了。关于getifaddrs上网查一下的话会发现有说它bug的文章,内存泄漏,有兴趣可以自己看一下。网上只有一篇文章介绍,不会找错的。
EN10MB 和 Ethernet
这两个是一体的,查看 libpcap 中的pcap.c文件中的 dlt_choices[ ]就会发现。结构体如下所示:
struct dlt_choice {const char *name;const char *description;int dlt;
};#define DLT_CHOICE(code, description) { #code, description, DLT_ ## code }
#define DLT_CHOICE_SENTINEL { NULL, NULL, 0 }static struct dlt_choice dlt_choices[] = {DLT_CHOICE(NULL, "BSD loopback"),DLT_CHOICE(EN10MB, "Ethernet"),DLT_CHOICE(IEEE802, "Token ring"),DLT_CHOICE(ARCNET, "BSD ARCNET"),DLT_CHOICE(SLIP, "SLIP"),... ...
};
其中Ethernet是根据EN10MB拿到的,所以需要知道EN10MB是如何获取到的,查看tcpdump的main函数会发现。我下面把关键函数都列一下。具体情况不赘述,只说一些我认为有价值的地方。
dlt_name 这个字符串指针就是 EN10MB,是 pcap_datalink_val_to_name(dlt) 的返回值。那么关键就转移到了 dlt 这个整型变量上面。dlt 又是 pcap_datalink(pd) 接口的返回值,关键又转移到了 pd ,这个指向 pcap_t 的指针上,这个真的是关键!
Breakpoint 1, map_arphrd_to_dlt (handle=0x555555a04aa0, sock_fd=3, arptype=1, device=0x555555a05800 "ens33", cooked_ok=1) at ./pcap-linux.c:3129
3129 {
(gdb) bt
#0 map_arphrd_to_dlt (handle=0x555555a04aa0, sock_fd=3, arptype=1, device=0x555555a05800 "ens33", cooked_ok=1) at ./pcap-linux.c:3129
#1 0x000055555560a033 in activate_new (handle=0x555555a04aa0) at ./pcap-linux.c:3691
#2 pcap_activate_linux (handle=0x555555a04aa0) at ./pcap-linux.c:1564
#3 0x000055555560e2ed in pcap_activate (p=0x555555a04aa0) at ./pcap.c:2418
#4 0x0000555555594a5c in open_interface (device=0x555555a04a80 "ens33", ndo=<optimized out>, ebuf=0x7fffffffd170 "") at ./tcpdump.c:1036
#5 0x0000555555592514 in main (argc=<optimized out>, argv=0x7fffffffe398) at ./tcpdump.c:1698
pd 是 pd = open_interface(device, ndo, ebuf) 接口的返回值,上面这个栈信息清晰的展现了 pd 中 linktype 这个关键变量赋值的过程!3帧到2帧那里是 activate_op 这个函数指针,在 pcap_create 的时候赋值为 pcap_activate_linux 接口,可以查看 pcap_create_interface 接口。
activate_new 接口里面调用 iface_get_arptype接口,这个是 linktype 赋值的最关键函数!下面贴出 iface_get_arptype 的实现方式。
static int
iface_get_arptype(int fd, const char *device, char *ebuf)
{struct ifreq ifr;memset(&ifr, 0, sizeof(ifr));strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));printf("%s %d %s here fd=%d device=%s ebuf=%s\n", __FILE__, __LINE__, __FUNCTION__,fd,device,ebuf);if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) {pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,errno, "SIOCGIFHWADDR");if (errno == ENODEV) {/** No such device.*/return PCAP_ERROR_NO_SUCH_DEVICE;}return PCAP_ERROR;}printf("%s %d %s ifr.ifr_hwaddr.sa_family=%d\n", __FILE__, __LINE__, __FUNCTION__,ifr.ifr_hwaddr.sa_family);return ifr.ifr_hwaddr.sa_family;
}
ioctl 提供了方法,libpcap 用的是这个。查看 ioctls.h 会发现有很多其它功能的宏,详细介绍的博客也有很多。看其他博客的时候偶然告诉了我 ifconfig 就是基于这个做的!ifconfig 是基于 ioctl 做的!ifconfig 是基于 ioctl 做的!惊不惊喜意不意外~
上面这个接口还有另外一个提高B格的地方。那就是拷贝 device 这个网卡名字的时候用的是 strlcpy 这个字符串拷贝的第三版接口,第一版是strcpy,第二版是strncpy。三者的区分可以看看这篇文章 我做了6年的嵌入式Linux C 开发,在上一家公司 strcpy 已经被摒弃,但也才刚开始三年左右时间,strcpy 确实容易引起问题,都用 strncpy 替换。但 strlcpy 是我第一次见到!在系统不支持的情况下,libpcap 也给出了宏重定义,可以借鉴,如下所示。
<portability.h>#define strlcpy(x, y, z) \(strncpy((x), (y), (z)), \((z) <= 0 ? 0 : ((x)[(z) - 1] = '\0')), \(void) strlen((y)))
map_arphrd_to_dlt 根据 arptype 做 switch 判断赋值。后面过程就比较简单了,这里不再描述。
在 map_arphrd_to_dlt 上面有一大段注释,如下所示。整个 tcpdump 和 libpcap 工程里面有非常多的注释,堪称典范。我还无法完全理解。
/** Linux uses the ARP hardware type to identify the type of an* interface. pcap uses the DLT_xxx constants for this. This* function takes a pointer to a "pcap_t", and an ARPHRD_xxx* constant, as arguments, and sets "handle->linktype" to the* appropriate DLT_XXX constant and sets "handle->offset" to* the appropriate value (to make "handle->offset" plus link-layer* header length be a multiple of 4, so that the link-layer payload* will be aligned on a 4-byte boundary when capturing packets).* (If the offset isn't set here, it'll be 0; add code as appropriate* for cases where it shouldn't be 0.)** If "cooked_ok" is non-zero, we can use DLT_LINUX_SLL and capture* in cooked mode; otherwise, we can't use cooked mode, so we have* to pick some type that works in raw mode, or fail.** Sets the link type to -1 if unable to map the type.*/
262144
这个是包大小的默认值 DEFAULT_SNAPLEN 256KB。可以用 -s 指定,经常用tcpdump解决问题自然会用到这个选项,man手册里面有还算详细的介绍。我另外那篇写抓包的文章好像提到过。这个是链接
到这里关于这一条出现过无数次的信息就算介绍完了。后面的文章会继续深入了解 tcpdump。
下面说一个题外话,年后遇到了一个问题,。。。。。。但这个问题确实勾起了我的兴趣,后面如果有机会让我插手,我会默默排查的。
libpcap/tcpdump—2—网络信息(listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes)相关推荐
- centost查看网络信息_监控io性能、free命令、ps命令、查看网络状态、Linux下抓包...
一.监控io性能 iostat命令 iostat命令被用于监视系统输入输出设备和cpu的使用情况.它的特点是汇报磁盘活动统计情况,同时也会汇报出cpu使用情况.通vmstat一样,iostat也有一个 ...
- MySQL优化系列3-Linux查看CPU、内存、磁盘、网络信息
备注:测试数据库版本为MySQL 8.0 文章目录 一.查看CPU信息 1.1 查看物理CPU个数 1.2 查看每个物理CPU中core的个数(即核数) 1.3 查看逻辑CPU的个数 1.4 查看CP ...
- 使用tcpdump 进行网络包分析
tcpdump介绍 tcpdump 是一个运行在命令行下的抓包工具.它允许用户拦截和显示发送或收到过网络连接到该计算机的TCP/IP和其他数据包.tcpdump 适用于 大多数的类Unix系统操作系统 ...
- 使用tcpdump监控网络消息发送
tcpdump是一个用于截取网络分组,并输出分组内容的工具,简单说就是数据包抓包工具.tcpdump凭借强大的功能和灵活的截取策略,使其成为Linux系统下用于网络分析和问题排查的首选工具. tcpd ...
- tcpdump 侦测网络端口数据
tcpdump 侦测网络端口数据 tcpdump采用命令行方式,它的命令格式为: tcpdump [ -adeflnNOpqStvx ] [ -c 数量 ] [ -F 文件名 ] [ -i 网络接口 ...
- linux netstat 查看网络信息 实例 状态说明
状态 TCP三次握手的过程如下: 主动连接端发送一个SYN包给被动连接端: 被动连接端收到SYN包后,发送一个带ACK和SYN标志的包给主动连接端: 主动连接端发送一个带ACK标志的包给被动连接端,握 ...
- netstat命令查看网络信息
文章出处:http://www.cnblogs.com/ggjucheng/archive/2012/01/08/2316661.html 简介 Netstat 命令用于显示各种网络相关信息,如网络连 ...
- 解决VMware中centos 7虚拟机,主ip地址:网络信息不可用。
解决VMware中centos 7虚拟机,主ip地址:网络信息不可用. 看了很多方法都不适用然后琢磨出来了一个奇奇怪怪的方法(咱也不知道算不算解决了,但是这个方法能ping通外网 查看防火墙是否关闭 ...
- Linux主机IP地址:网络信息不可用
Linux主机IP地址:网络信息不可用 今天使用XShell远程连接到Linux却一直连接失败.经过排查后发现是因为在VMware中安装虚拟机的主机IP的地址:网络信息不可用.网上的答案很杂,导致我找 ...
最新文章
- mysql 函数,关键字,特性
- Python 购物车
- C#垃圾回收机制(GC)
- java中s方法_Java中Arrys数组常用的方法
- Didn't find class cn.jpush.android.service.DownloadProvider on path:
- kali安装nessus_漏洞扫描工具Nessus指南
- 【华为云技术分享】云图说 | 容器交付流水线ContainerOps,助力企业容器化转型
- C++ vector和list的区别
- SpringMVC form:form的一个错误(没有传到前台绑定类)
- 人脸检测(十二)--DDFD算法
- 新书推荐|Windows黑客编程技术详解
- 转:多玩网总裁李学凌:在腾讯阴影下
- 几何平均数与AG不等式
- Day54.XML解析(DOM4J)、Tomcat服务器、HTML协议简介: 请求、响应报文、响应码
- java写入文件中文乱码问题_解决 JAVA 写入文本文件时中文乱码
- iconst、bipush、sipush、ldc指令的区别
- SQL实战(9)--从titles表获取按照title进行分组
- mysql sql语句 编辑器_技巧:三个非常实用的开源SQL编辑器
- 1.ShowWindow
- 《计算机网络管理》 期末考试