1.原始套接字使用场景
我们平常所用到的网络编程都是在应用层收发数据,每个程序只能收到发给自己的数据,即每个程序只能收到来自该程序绑定的端口的数据。收到的数据往往只包括应用层数据,原有的头部信息在传递过程中被隐藏了。某些情况下我们需要执行更底层的操作,比如监听所有本机收发的数据、修改报头等,而像SOCK_STREAM、SOCK_DGRAMZ则通常用于应用层,并不能满足该需求。
通过原始套接字,我们可以抓取所有发送到本机的IP包(包括IP头和TCP/UDP/ICMP包头),也可以抓取所有本机收到的帧(包括数据链路层协议头)。普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以。利用原始套接字,我们可以自己构造IP头。
2.原始套接字分类及套接字函数简介
有两种原始套接字:
一种是处理IP层及其上的数据,通过指定socket第一个参数为AF_INET来创建这种套接字。
另一种是处理数据链路层及其上的数据,通过指定socket第一个参数为PF_PACKET来创建这种套接字。
socket函数简介:
int socket(int domain, int type, int proto) | |||
#include <sys/types.h> #include <sys/socket.h> |
|||
参数 | 选项 | 作用 | 注 |
domain | AF_INET | 获取用网络层开始的数据(完整的IP数据包) | |
PF_PACKET | 获取数据链路层开始的数据(链路层头+IP 数据包) | ||
... ... | 其他domain选项暂未使用,不予说明 | ||
type | SOCK_STREAM | 面向连接的流式套接字 | |
S |