现在进入第二步,捕获数据包。从第20行开始,我们进入了一个死循环,while(1),在第24行,recvfrom(sock, buffer, sizeof buffer, 0, (struct sockaddr *)&from, &fromlen),这个函数要做的就是接收数据,冰把接收到的数据放入buffer中。就是这么简单,已经完成了我们要捕获数据包的任务。
到了第三步,分析数据包。27行,ip = (struct ip *)buffer,使我们在头文件中的IP结构对应于所接收到的数据,接下来判断在网络层中是否使用的是TCP协议,if(ip-> ip_protocol == 6) ,如果答案是,tcp信息包从整个IP/TCP包 buffer + (4*ip-> ip_length) 地址处开始,所以31行 tcp = (struct tcp *)(buffer + (4*ip-> ip_length)),然后对应结构把你所需要的信息输出。
/*************************headers.h**************************/
/*structure of an ip header*/
struct ip {
unsigned int ip_length:4; /*little-endian*/
unsigned int ip_version:4;
unsigned char ip_tos;
unsigned short ip_total_length;
unsigned short ip_id;
unsigned short ip_flags;
unsigned char ip_ttl;
unsigned char ip_protocol;
unsigned short ip_cksum;
unsigned int ip_source; unsigned int ip_dest;
};
/* Structure of a TCP header */
struct tcp {
unsigned short tcp_source_port;
unsigned short tcp_dest_port;
unsigned int tcp_seqno;
unsigned int tcp_ackno;
unsigned int tcp_res1:4, /*little-endian*/
tcp_hlen:4,
tcp_fin:1,
tcp_syn:1,
tcp_rst:1,
tcp_psh:1,
tcp_ack:1,
tcp_urg:1,
tcp_res2:2;
unsigned short tcp_winsize;
unsigned short tcp_cksum;
unsigned short tcp_urgent;
};
/*********************EOF***********************************/
另外一个例子:
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
int sock, n;
char buffer[2048];
unsigned char *iphead, *ethhead;
if ( (sock=socket(PF_PACKET, SOCK_RAW,htons(ETH_P_IP))) <0)
{
perror( "socket ");
exit(1);
}
while (1) {
printf( "----------\n ");
n = recvfrom(sock,buffer,2048,0,NULL,NULL);
printf( "%d bytes read\n ",n);
/* Check to see if the packet contains at least
* complete Ethernet (14), IP (20) and TCP/UDP
* (8) headers.
*/
if (n <42) {
perror( "recvfrom(): ");
printf( "Incomplete packet (errno is %d)\n ",
errno);
close(sock);
exit(0);
}
ethhead = buffer;
printf( "Source MAC address: "
"%02x:%02x:%02x:%02x:%02x:%02x\n ",
ethhead[0],ethhead[1],ethhead[2],
ethhead[3],ethhead[4],ethhead[5]);
printf( "Destination MAC address: "
"%02x:%02x:%02x:%02x:%02x:%02x\n ",
ethhead[6],ethhead[7],ethhead[8],
ethhead[9],ethhead[10],ethhead[11]);
iphead = buffer+14; /* Skip Ethernet header */
if (*iphead==0x45) { /* Double check for IPv4
* and no options present */
printf( "Source host %d.%d.%d.%d\n ",
iphead[12],iphead[13],
iphead[14],iphead[15]);
printf( "Dest host %d.%d.%d.%d\n ",
iphead[16],iphead[17],
iphead[18],iphead[19]);
printf( "Source,Dest ports %d,%d\n ",
(iphead[20] < <8)+iphead[21],
(iphead[22] < <8)+iphead[23]);
printf( "Layer-4 protocol %d\n ",iphead[9]);
}
}