由于最近要做一些没有传输层以及应用层的协议探测程序,所需普通的socket就无法用了,因为这些协议是没有端口的,比如ping,就是用的ip层的icmp,而arp和rarp是在数据链路层上的应用,所以我只能用raw socket。下面用一个实例来解释raw socket的应用。才开始学,蛮肤浅的。
#include <stdio.h> #include <unistd.h> #include <sys/socket.h> #include <sys/types.h> #include <linux/if_ether.h> #include <linux/in.h> #define BUFFER_MAX 1500 #define get_u32(X,O) (*(__u32 *)(X + O)) #define get_u16(X,O) (*(__u16 *)(X + O)) #define get_u8(X,O) (*(__u8 *)(X + O)) int main(int argc, char *argv[]) { int sock, n_read, proto; char buffer[BUFFER_MAX]; char ip[1024]={'\0'}; char *ethhead, *iphead, *tcphead, *udphead, *icmphead, *p; if((sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP))) < 0) { fprintf(stdout, "create socket error\n"); exit(0); } while(1) { n_read = recvfrom(sock, buffer, 2048, 0, NULL, NULL); if(n_read < 42) { fprintf(stdout, "Incomplete header, packet corrupt\n"); continue; } ethhead = buffer; p = ethhead; int n = 0XFF; iphead=buffer+26; unsigned long source_ip=get_u32(iphead,0); if(inet_addr("172.18.4.155")==source_ip) { if(get_u8(buffer+23,0)==0x06) { printf("tcp package\n"); } } } }
上面这个程序就是打印所有经过我们网卡的,源地址是172.18.4.155 的tcp 包。
从raw socket 接受过来的buffer 的地址是数据链路层的地址,具体我们获取的东西就是通过偏移量来,这个偏移量我们需要查看网络书或者抓个包分析下链路层的数据格式等等。
其实从这个程序来看,我们可以获取所有经过我们网卡的信息,比如QQ的文件传输等。
比如我们的防火墙上加这样一个程序,就可以获取所有通过我们墙的信息,比如封堵qq 等。
当然正式的强不可能是这样些,效率低下。