- BPF(Berkeley Packet Filter)
- DLPI(Data Link Provider Interface)
- SOCKET_PACKET type sockets(Linux only)
- using pcap library
- We begin by determining which interface we want to sniff on!也就是我们得确定我们嗅探的接口
- Initialize pcap.This is where we actually tell pcap what device we are sniffing no.初始化pcap,也就是告诉pcap我们选择那个接口进行嗅探!
- we must set a rule what we want to sniff specific traffic(eg.only TCP/IP packets,only packets going to port 23 etc..),'complie' it ,and apply it.Then we tell pcap to apply it to whichever session we wish for it to filter.设置嗅探规则(过滤器)并应用!顾名思义:告知pcap库,我们需要嗅探什么样的数据:是TCP/IP数据、是仅仅通过23端口的数据等等..
- we tell pcap to enter it's primary execution loop.In this state ,pcap waits data packets or grabs packets! 进入pcap的主循环!等待数据或者是获得数据并送至相应的函数处理
- After our sniffing needs are statisfied,we close our session and are complete!关闭!!
-
- #include <stdio.h>
- #include <pcap.h>
-
- int main(int argc,char **argv)
- {
- char *dev;
- char errbuf[PCAP_ERRBUF_SIZE];
- dev = pcap_lookupdev(errbuf);
- if(dev == NULL){
- fprintf(stderr,"Couldn't find default device %s:\n",errbuf);
- return 1;
- }
- return 0;
- }
- 编译:
- [#15#caopeng@laptop ~/pcap]$gcc device.c -o device -lpcap
- 执行:
- [#19#caopeng@laptop ~/pcap]$sudo ./device
- Device :eth0
- #include <stdio.h>
- /*Find the properties for the device*/
- if(pcap_lookupnet(dev,&net,&mask,errbuf) == -1){
- fprintf(stderr,"Couldn't get netmask for device :%s :%s\n",dev,errbuf);
- net = 0;
- mask = 0;
- }
- /*Open the session in promiscuous mode*/
- handle = pcap_open_live(dev,BUFSIZ,1,1000,errbuf);
- if(handle == NULL){
- fprintf(stderr,"Couldn't open device %s : %s\n",dev,errbuf);
- return 2;
- }
- /*complie and apply the filter*/
- if(pcap_compile(handle,&fp,filter_exp,0,net) == -1){
- fprintf(stderr,"Couldn't parse filter %s:%s\n",filter_exp,pcap_geterr(handle));
- return 2;
- }
-
- if(pcap_setfilter(handle,&fp) == -1){
- fprintf(stderr,"Couldn't install filter %s:%s\n",filter_exp,pcap_geterr(handle));
- return 2;
- }
- /*Grab a pcaket*/
- pcaket = pcap_next(handle,&hander);
For the sake of simplicity, we'll say that the address this pointer is set to is the value X. Well, if our three structures are just sitting in line, the first of them (sniff_ethernet) being located in memory at the address X, then we can easily find the address of the structure after it; that address is X plus the length of the Ethernet header, which is 14, or SIZE_ETHERNET.
Similarly if we have the address of that header, the address of the structure after it is the address of that header plus the length of that header. The IP header, unlike the Ethernet header, does not have a fixed length; its length is given, as a count of 4-byte words, by the header length field of the IP header. As it's a count of 4-byte words, it must be multiplied by 4 to give the size in bytes. The minimum length of that header is 20 bytes.
The TCP header also has a variable length; its length is given, as a number of 4-byte words, by the "data offset" field of the TCP header, and its minimum length is also 20 bytes.
So let's make a chart:
Variable | Location (in bytes) |
sniff_ethernet | X |
sniff_ip | X + SIZE_ETHERNET |
sniff_tcp | X + SIZE_ETHERNET + {IP header length} |
payload | X + SIZE_ETHERNET + {IP header length} + {TCP header length} |