参考1:
原始套接字能干什么? https://www.cnblogs.com/tennysonsky/p/4382902.html
参考2:
原始套接字抓包实践:
https://www.cnblogs.com/tennysonsky/p/4383394.html
https://blog.youkuaiyun.com/tennysonsky/article/details/44751997
https://blog.youkuaiyun.com/zgrjkflmkyc/article/details/39207209
https://blog.youkuaiyun.com/weixin_42639771/article/details/90695621
参考3:
各层头结构
https://www.cnblogs.com/shenpengyan/p/5912567.html
通过原始套接字,我们可以抓取所有发送到本机的IP包(包括IP头和TCP/UDP/ICMP包头),也可以抓取所有本机收到的帧(包括数据链路层协议头)。普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以。利用原始套接字,我们可以自己构造IP头。
有两种原始套接字
一种是处理IP层及其上的数据,通过指定socket第一个参数为AF_INET来创建这种套接字。
另一种是处理数据链路层即其上的数据,通过指定socket第一个参数为AF_PACKET来创建这种套接字。
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收到的数据不包括数据链路层协议头。