http://blog.csdn.net/pi9nc/article/details/12399633
二、SOCK_RAW 应用
1、packet sniffer
1
2 3 4 5 6 7 |
sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_TCP);
while( 1) { data_size = recvfrom(sock_raw , buffer , 65535 , 0 , &saddr , &saddr_size); //Now process the packet ProcessPacket(buffer , data_size); } |
上述程序只可以接收tcp 包,当然udp 和 icmp 可以这样写:
1
2 |
sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_UDP);
sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_ICMP); |
但是不能以为 sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_IP); 就能接收所有种类的IP包,如前所述,这是错误的。
上述程序只能监测到输入的数据包,而且读取的数据包中已经没有了以太网头部。
只需要稍稍改进一下:
1
|
sock_raw = socket( AF_PACKET , SOCK_RAW , htons(ETH_P_ALL)) ;
|
ETH_P_IP 0X0800只接收发往目的MAC是本机的IP类型的数据帧
ETH_P_ARP 0X0806只接收发往目的MAC是本机的ARP类型的数据帧
ETH_P_RARP 0X8035只接受发往目的MAC是本机的RARP类型的数据帧
ETH_P_ALL 0X0003接收发往目的MAC是本机的所有类型(ip,arp,rarp)的数据帧,同时还可以接收从本机发出去的所有数据帧。在混杂模式打开的情况下,还会接收到发往目的MAC为非本地硬件地址的数据帧。
注意family 是AF_PACKET,这样就能监测所有输入和输出的数据包,而且不仅限于IP包(tcp/udp/icmp),如arp/rarp 包也可以监测,并且数据包还包含以太网头部。最后提一点,packet sniffer 也可以使用libpcap 库实现,著名的tcpdump 就使用了此库。