Linux系统抓取数据包

原创 2015年07月10日 11:49:34

  这篇文章介绍了Linux下如何实现定制化的类wireshark程序的一些要点(不需要装pcap,利用Linux 的 socket 自带的一些功能)。

Ethernet frame

参考资料:
  https://en.wikipedia.org/wiki/Ethernet_frame
  http://www.cnblogs.com/uvsjoh/archive/2012/12/31/2840883.html

  以太网链路(Ethernet link )上的数据包(data packet)叫作以太网数据包(Ethernet packet),它包含(装载)了以太网帧(Ethernet frame)。
  真正通过Linux的Raw Socket得到的Ethernet包是到Ethernet frame这个层次(并且不包含CRC,因为系统会对其进行校验,能传给socket接收缓冲区的都是有效的frame,也不需要用CRC信息了),能否到整个Ethernet packet这个层次没有经过验证,不太清楚。
  Ethernet frame前面是preamble 和start frame delimiter (SFD)一共8个字节,属于Ethernet packet 在 physical layer的一部分。而Interpacket gap也不属于Frame的范畴,所以真正有用的信息也就是Frame就够了。可以看到payload 的大小可以到1500 octets(MTU)。可以看如下的表格,加深理解(Markdown编辑器还不太会弄,凑合看吧 - -#):


802.3 Ethernet packet and frame structure:

Layer Preamble Start of frame delimiter MAC destination MAC source 802.1Q tag(optional) Ethertype (Ethernet II) or length (IEEE 802.3) Payload Frame check sequence (32‑bit CRC) Interpacket gap
7 octets 1 octet 6 octets 6 octets (4 octets) 2 octets 46(42)–1500 octets 4 octets 12 octets
Layer 2 Ethernet frame From MAC destination To Frame check sequence (32‑bit CRC) ← 64–1518(1522) octets →
Layer 1 Ethernet packet From Preamble To Frame check sequence (32‑bit CRC)← 72–1526(1530) octets →

AF_INET 与 PF_PACKET

  平常所用到的网络编程都是在应用层收发数据,某些情况下我们需要执行更底层的操作,比如监听所有本机收发的数据、修改报头等。

  通过原始套接字,我们可以抓取本机收到的IP包(包括IP头和TCP/UDP/ICMP包头),也可以抓取本机收到的帧(包括数据链路层协议头)。SOCK_RAW提供了这种可能,利用原始套接字,我们可以自己构造IP头。

  有两种原始套接字:
  一种是处理IP层即其上的数据,通过指定socket第一个参数为AF_INET来创建这种socket。
  另一种是处理数据链路层即其上的数据,通过指定socket第一个参数为AF_PACKET来创建这种socket。

AF_INET表示获取从网络层开始的数据
  socket(AF_INET, SOCK_RAW, …)
当接收包时,表示用户获得完整的包含IP报头的数据包,即数据从IP报头开始算起。
  当发送包时,用户只能发送包含TCP报头或UDP报头或包含其他传输协议的报文,IP报头以及以太网帧头则由内核自动加封。除非是设置了IP_HDRINCL的socket选项。
  如果第二个参数为SOCK_STREAM, SOCK_DGRAM,表示接收的数据直接为应用层数据。

PF_PACKET表示获取的数据是从数据链路层开始的数据
  socket(PF_PACKET,SOCK_RAW,htos(ETH_P_IP)):表示获得IPV4的数据链路层帧,即数据包含以太网帧头。14+20+(8:udp 或 20:tcp)。
  ETH_P_IP: 在 <linux/if_ether.h>中定义,可以查看该文件了解支持的其它协议。
  SOCK_RAW, SOCK_DGRAM两个参数都可以使用,区别在于使用SOCK_DGRAM收到的数据不包括数据链路层协议头。


 socket(AF_INET,SOCK_RAW,IPPROTO_TCP|IPPROTO_UDP|IPPROTO_ICMP)发送接收ip数据包。
能:该套接字可以接收协议类型为(tcp udp icmp等)发往本机的ip数据包。
不能:收到非发往本地ip的数据包(ip软过滤会丢弃这些不是发往本机ip的数据包)。
不能:收到从本机发送出去的数据包。
发送的话需要自己组织tcp udp icmp等头部.可以setsockopt来自己包装ip头部。
这种套接字用来写个ping程序比较适合。

socket(PF_PACKET,SOCK_RAW|SOCK_DGRAM,htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL))发送接收以太网数据帧。

这种socket可以监听网卡上的所有数据帧。

能: 接收发往本地mac的数据帧
能: 接收从本机发送出去的数据帧(第3个参数需要设置为ETH_P_ALL)
能: 接收非发往本地mac的数据帧(网卡需要设置为promisc混杂模式)

协议类型一共有四个:
ETH_P_IP 0x800 只接收发往本机mac的ip类型的数据帧
ETH_P_ARP 0x806 只接受发往本机mac的arp类型的数据帧
ETH_P_RARP 0x8035 只接受发往本机mac的rarp类型的数据帧
ETH_P_ALL 0x3 接收发往本机mac的所有类型ip arp rarp的数据帧,

  接收从本机发出的所有类型的数据帧.(混杂模式打开的情况下,会接收到非发往本地mac的数据帧)。

  理解一下SOCK_RAW的原理,比如网卡收到了一个 14+20+8+100+4 bytes的udp的以太网数据帧。
  首先,网卡对该数据帧进行硬过滤(根据网卡的模式不同会有不同的动作,如果设置了promisc混杂模式的话,则不做任何过滤直接交给下一层输入例程,否则非本机mac或者广播mac会被直接丢弃)。按照上面的ip例子,如果网卡关通过的话,会进入ip输入例程。但是在进入ip输入例程之前,会检查ip是否跟系统相匹配,另外系统会检查数据中是否有该socket所需要的套接字的协议。如果有,系统就给每个这样的socket接收缓冲区发送一个数据拷贝。然后进入下一步,用户便可以使用这块数据。
  ps:如果校验和出错,内核会直接丢弃该数据包。不会拷贝给sock_raw的套接字,因为校验和都出错了,数据肯定有问题,其包括所有信息都没有意义了。

Tips:设置网卡混杂模式的命令为:
在终端输入 sudo ifconfig eth0 promisc
并且重新启动电脑之后,网卡就取消了混杂模式,开机需要重新设置它为混杂模式。
可以使用ifconfig 查看eth0是否有了promisc这个混杂模式的标志。
取消混杂模式的命令为:sudo ifconfig eth0 -promisc

版权声明:本文为博主原创文章,未经博主允许不得转载。

Linux系统高效获取数据包

  • 2013年05月03日 22:19
  • 122KB
  • 下载

Linux系统捕获数据包流程

Linux系统捕获数据包流程 为了提高数据包的捕获效率,瓶颈问题是一个需要非常关注的焦点。减少在捕获数据包过程中的瓶颈,就能够提高数据包捕获的整体性能。下面本文将以Linux操作系统为平台,分析捕获...
  • lcgweb
  • lcgweb
  • 2014年05月19日 19:17
  • 444

运维笔记40 Linux系统监控之Cacti(Cacti搭建,自动抓取cacti统计图片脚本)

概述:监控系统在一个系统中十分重要,它会将很多重要的信息,诸如内存信息,cpu信息,硬盘信息集合在一起显示出来,当系统出现问题的时候我们能及时定位并修复错误。今天介绍的监控系统是一款轻量级的监控系统C...
  • No_red
  • No_red
  • 2017年04月09日 00:19
  • 418

查看返回接收到UDP数据包的宿地址结构--(适用于LINUX和BSD系统)

/* * recvfromto Like recvfrom, but also stores the destination * IP address. Useful on multihomed h...

使用tcpdump抓取Android系统手机数据包

一说到抓包工具大家可能会想到wireshark、tcpdump、fiddle等工具。wireshark功能很强大在windows下使用很方便,对linux下进行抓包可以使用tcpdump进行抓包后用w...

linux下使用iptables ulog+netlink在内核中抓取特定数据包

前言     iptables是linux下基于Netfilter框架实现的防火墙软件。通过iptables我们可以方便的对内核中流动的数据包进行一些处理。iptables拥有强大的log(...
  • l1902090
  • l1902090
  • 2014年05月15日 19:45
  • 10521

Linux使用tcpdump抓取网络数据包示例

原文地址::http://blog.csdn.net/kobejayandy/article/details/17208137/ tcpdump是Linux命令行下常用的的一个抓包工具,记录一...

Linux使用tcpdump抓取网络数据包示例

tcpdump是linux命令行下常用的的一个抓包工具,记录一下平时常用的方式,测试机器系统是ubuntu 12.04。 tcpdump的命令格式 tcpdump的参数众多,通过man t...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux系统抓取数据包
举报原因:
原因补充:

(最多只允许输入30个字)