这条信息在运行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) 接口的返回值,上面这个栈信息清晰的展现了 pdlinktype 这个关键变量赋值的过程!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 上面有一大段注释,如下所示。整个 tcpdumplibpcap 工程里面有非常多的注释,堪称典范。我还无法完全理解。

/**  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)相关推荐

  1. centost查看网络信息_监控io性能、free命令、ps命令、查看网络状态、Linux下抓包...

    一.监控io性能 iostat命令 iostat命令被用于监视系统输入输出设备和cpu的使用情况.它的特点是汇报磁盘活动统计情况,同时也会汇报出cpu使用情况.通vmstat一样,iostat也有一个 ...

  2. MySQL优化系列3-Linux查看CPU、内存、磁盘、网络信息

    备注:测试数据库版本为MySQL 8.0 文章目录 一.查看CPU信息 1.1 查看物理CPU个数 1.2 查看每个物理CPU中core的个数(即核数) 1.3 查看逻辑CPU的个数 1.4 查看CP ...

  3. 使用tcpdump 进行网络包分析

    tcpdump介绍 tcpdump 是一个运行在命令行下的抓包工具.它允许用户拦截和显示发送或收到过网络连接到该计算机的TCP/IP和其他数据包.tcpdump 适用于 大多数的类Unix系统操作系统 ...

  4. 使用tcpdump监控网络消息发送

    tcpdump是一个用于截取网络分组,并输出分组内容的工具,简单说就是数据包抓包工具.tcpdump凭借强大的功能和灵活的截取策略,使其成为Linux系统下用于网络分析和问题排查的首选工具. tcpd ...

  5. tcpdump 侦测网络端口数据

    tcpdump 侦测网络端口数据 tcpdump采用命令行方式,它的命令格式为: tcpdump [ -adeflnNOpqStvx ] [ -c 数量 ] [ -F 文件名 ] [ -i 网络接口 ...

  6. linux netstat 查看网络信息 实例 状态说明

    状态 TCP三次握手的过程如下: 主动连接端发送一个SYN包给被动连接端: 被动连接端收到SYN包后,发送一个带ACK和SYN标志的包给主动连接端: 主动连接端发送一个带ACK标志的包给被动连接端,握 ...

  7. netstat命令查看网络信息

    文章出处:http://www.cnblogs.com/ggjucheng/archive/2012/01/08/2316661.html 简介 Netstat 命令用于显示各种网络相关信息,如网络连 ...

  8. 解决VMware中centos 7虚拟机,主ip地址:网络信息不可用。

    解决VMware中centos 7虚拟机,主ip地址:网络信息不可用. 看了很多方法都不适用然后琢磨出来了一个奇奇怪怪的方法(咱也不知道算不算解决了,但是这个方法能ping通外网 查看防火墙是否关闭 ...

  9. Linux主机IP地址:网络信息不可用

    Linux主机IP地址:网络信息不可用 今天使用XShell远程连接到Linux却一直连接失败.经过排查后发现是因为在VMware中安装虚拟机的主机IP的地址:网络信息不可用.网上的答案很杂,导致我找 ...

最新文章

  1. mysql 函数,关键字,特性
  2. Python 购物车
  3. C#垃圾回收机制(GC)
  4. java中s方法_Java中Arrys数组常用的方法
  5. Didn't find class cn.jpush.android.service.DownloadProvider on path:
  6. kali安装nessus_漏洞扫描工具Nessus指南
  7. 【华为云技术分享】云图说 | 容器交付流水线ContainerOps,助力企业容器化转型
  8. C++ vector和list的区别
  9. SpringMVC form:form的一个错误(没有传到前台绑定类)
  10. 人脸检测(十二)--DDFD算法
  11. 新书推荐|Windows黑客编程技术详解
  12. 转:多玩网总裁李学凌:在腾讯阴影下
  13. 几何平均数与AG不等式
  14. Day54.XML解析(DOM4J)、Tomcat服务器、HTML协议简介: 请求、响应报文、响应码
  15. java写入文件中文乱码问题_解决 JAVA 写入文本文件时中文乱码
  16. iconst、bipush、sipush、ldc指令的区别
  17. SQL实战(9)--从titles表获取按照title进行分组
  18. mysql sql语句 编辑器_技巧:三个非常实用的开源SQL编辑器
  19. 1.ShowWindow
  20. 《计算机网络管理》 期末考试

热门文章

  1. OpenGL中投影函数glOrtho()、glFrustum()以及gluPerspective()以及函数的用法
  2. word表格插入多行
  3. 计算机视觉CV-骨干网络Backbone
  4. 魔兽世界角色换装分析
  5. 只看这一个侧脸,猜一猜,这是哪个动漫里的人物?
  6. 熟悉GRASP并撰写心得
  7. python tkinter button 透明图片_Tkinter-按钮图像透明背景
  8. 前端如何提升To B产品用户体验
  9. linux la 的使用方法,libtool使用方法
  10. 用xstart远程连接linux图形用户界面