raw socket使用

转载地址:http://blog.163.com/tianle_han/blog/static/661782620094214229813/

一、raw socket介绍

 

    1、raw socket中文叫原始套接字,它和其他的套接字的不同之处在于它工作在网络层或数据链路层,而其他类型的套接字工作在传输层,只能进行传输层数据操作。

 

    我们常使用rawsocket进行数据监听,在网卡处在混杂模式下时,可以接收所有经过网卡的数据,包括广播的数据包和发向自己的数据包,当然在共享式网络中(典型的hub组建的局域网),所有的数据包都是广播的,所以都能接收到,在交换式网络中只能接收到发向自己的包和以广播方式发的包。我们还可以设置是否手动处理要发送的数据的IP包头(通过设置socket选项),当然一般是需要设置成手动处理的。

 

    2、内核接收网络数据后在rawsocket上处理原则:

 

    a、因为工作在网络层上的rawsocket不使用udp和tcp协议,所以系统收到tcp和udp协议的数据包不会发送到工作在网络层上的raw socket。而如果raw socket工作在链路层上,那包系统会将所以收到的数据包都复制一份发送给raw socket。

 

    b、因为工作在网络层上的rawsocket经常使用ICMP,EGP等协议,所以如果系统收到ICMP和EGP等使用IP数据包承载数据但又在传输层之下的协议类型的数据包,系统会将这些包复制一份发送给对应协议类型的raw socket进行处理(也就是说如果raw socket没有使用bind和connect函数,那么系统会将所以符合raw socket协议的数据包送给raw socket处理)。

 

    c、如果工作在网络层上的rawsocket使用bind绑定了一个地址,那么系统只将收到目的地址为bind所绑定地址的ICMP和EGP等传输层之下的协议的数据包发送给raw socket处理

 

    d、如果工作在网络层上的rawsocket使用connect函数远程连接到其他机器地址的话,那么系统只将收到的源地址为connect地址的且协议为ICMP等传输层之下的协议的数据包发送给raw socket处理。

 

    e、对于不能识别协议类型的数据包,系统会进行必要的较验,然后检查有没有匹配协议类型的raw socket,如果有的话,就复制一份给raw socket,如果没有就简单的丢弃。并返回一个主机不可达的ICMP给源主机。

 

    3、选项

 

    使用setsockopt设置socket的选项,其中IP_HDRINCL用来设置是否手动处理ip包头,如果设置为真,那么需要自己创建IP包头,然后发送,如果没有设置,那么系统会自动为raw socket设置IP包头附加在我们自己的数据之前。当然使用raw socket接收的数据包总是包含有IP包头。因为有这样的可以使用虚假的源地址等操作,所以需要root权限。

 

    二、raw socket的创建和使用

 

    1、像其他类型的socket一样,raw socket的创建非常简单,直接使用socket函数进行创建

 

   int socketfd = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);/*在网络层使用的原始套接字*/

 

   int socketfd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_IP));/*在链路层使用*/

 

    注意:在指定协议的时候,不能向其他套接字一样简单的指定为0(IPPROTO_IP),因为其他套字字会根据套接字的类型自动选择其协议,比如stream类型的协议会选择为tcp的协议,而原始套接字不行。这些协议在unix里面定义在文件里,当然要使用这些协议还需要内核对该协议的支持。


你可能感兴趣的:(Ethernet,协议学习)