raw socket中文叫原始套接字,它和其他的套接字的不同之处在于它工作在网络层或数据链路层,而其他类型的套接字工作在传输层,只能进行传输层数据操作。
raw socket的工作规则
因为工作在网络层上的rawsocket不使用udp和tcp协议,所以系统收到tcp和udp协议的数据包不会发送到工作在网络层上的raw socket。而如果raw socket工作在链路层上,那包系统会将所以收到的数据包都复制一份发送给raw socket。
因为工作在网络层上的rawsocket经常使用ICMP,EGP等协议,所以如果系统收到ICMP和EGP等使用IP数据包承载数据但又在传输层之下的协议类型的数据包,系统会将这些包复制一份发送给对应协议类型的raw socket进行处理(也就是说如果raw socket没有使用bind和connect函数,那么系统会将所以符合raw socket协议的数据包送给raw socket处理)
ip头什么域可以被raw socket修改
使用setsockopt设置socket的选项,其中IP_HDRINCL用来设置是否手动处理ip包头,如果设置为真,那么需要自己创建IP包头,然后发送,如果没有设置,那么系统会自动为raw socket设置IP包头附加在我们自己的数据之前。当然使用raw socket接收的数据包总是包含有IP包头。因为有这样的可以使用虚假的源地址等操作,所以需要root权限。
raw的使用与创建
像其他类型的socket一样,raw socket的创建非常简单,直接使用socket函数进行创建
int socketfd = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);/*在网络层使用的原始套接字*/
int socketfd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_IP));/*在链路层使用*/