1. 示例程序
此示例程序捕获本地包,即发往127.0.0.1的包,若要捕获外地包,之需要修改device的值为eth0或使用pcap_lookupdev函数查找可用网卡。
#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef unsigned char UCHAR;
typedef unsigned short USHORT;
void pcap_handle(u_char *user,const struct pcap_pkthdr *header, const u_char *pkt_data);
typedef struct{ //以太网帧首部
UCHAR DestMac[6];
UCHAR SrcMac[6];
UCHAR Etype[2];
}ETHHEADER;
typedef struct { //IP头部
UCHAR header_len:4;
UCHAR version:4;
UCHAR tos:8; // type of service
USHORT total_len:16; // length of the packet
USHORT ident:16; // unique identifier
USHORT flags:16;
UCHAR ttl:8;
UCHAR proto:8; // protocol ( IP , TCP, UDP etc)
USHORT checksum:16;
UCHAR sourceIP[4];
UCHAR destIP[4];
}IPHEADER;
typedef struct { //TCP头部
USHORT srcPort:16;
USHORT decPort:16;
UCHAR id[4];
UCHAR ackId[4];
UCHAR unused1:4;
UCHAR header_len:4;
UCHAR unused2:2;
UCHAR flag:6;
}TCPHEADER;
typedef struct { //端口号
USHORT srcPort;
USHORT decPort;
}PORT;
char *Proto[] = {"Reserved", "ICMP", "IGMP", "GGP", "IP", "ST", "TCP",
"UCL", "EGP", "IGP", "BBN-RCC-MON", "NVP-II", "PUP",
"ARGUS", "EMCON", "XNET", "CHAOS", "UDP", "MUX",
"DCN-MEAS", "HMP", "PRM", "XNS-IDP", "TRUNK-1",
"TRUNK-2", "LEAF-1", "LEAF-2", "RDP", "IRTP", "ISO-TP4", "NETBLT","MFE-NSP",
"MERIT-INP", "SEP", "3PC", "IDPR", "XTP", "DDP", "IDPR-CMTP", "TP++", "IL", "SIP",
"SDRP", "SIP-SR", "SIP-FRAG", "IDRP", "RSVP", "GRE", "MHRP", "BNA", "SIPP-ESP",
"SIPP-AH", "I-NLSP", "SWIPE", "NHRP", "unassigned", "unassigned","unassigned",
"unassigned", "unassigned", "unassigned","any host internal protocol", "CFTP", "any local network", "SAT-EXPAK", "KRYPTOLAN", "RVD", "IPPC", "any distributed file system",
"SAT-MON", "VISA", "IPCV", "CPNX", "CPHB", "WSN", "PVP", "BR-SAT-MON", "SUN-ND",
"WB-MON", "WB-EXPAK", "ISO-IP", "VMTP", "SECURE-VMTP", "VINES", "TTP",
"NSFNET-IGP", "DGP", "TCF", "IGRP", "OSPFIGP", "Sprite-RPC", "LARP", "MTP", "AX.25",
"IPIP", "MICP", "SCC-SP", "ETHERIP", "ENCAP", "any private encryption scheme", "GMTP"};
int npacketnum;
int main(void)
{
char *device = "lo";
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t *phandle;
bpf_u_int32 ipaddress, ipmask;
struct bpf_program fcode;
int datalink;
/* if ((device = pcap_lookupdev(errbuf)) == NULL)
{
perror(errbuf);
return 0;
}
else
{
printf("device: %s\n", device);
}
*/
phandle = pcap_open_live(device, 200, 0, 500, errbuf);
if (phandle == NULL)
{
perror(errbuf);
return 0;
}
if (pcap_lookupnet(device, &ipaddress, &ipmask, errbuf) == -1)
{
perror(errbuf);
return 0;
}
else
{
char net[INET_ADDRSTRLEN], mask[INET_ADDRSTRLEN];
if (inet_ntop(AF_INET, &ipaddress, net, sizeof(net)) == NULL)
{
perror("inet_ntop");
}
else if (inet_ntop(AF_INET, &ipmask, mask, sizeof(net)) == NULL)
{
perror("inet_ntop");
}
printf("NET Address: %s, Network Mask: %s\n", net, mask);
}
int bflag = 1;
while(bflag)
{
printf("Input Packet Filter:>");
char filterString[1024];
fgets(filterString, 1024, stdin);
//编译过滤规则
if (pcap_compile(phandle, &fcode, filterString, 0, ipmask) == -1) {
fprintf(stderr, "pcap_compile: %s,please input again......\n", pcap_geterr(phandle));
}
else
bflag = 0;
}
//设定过滤规则
if (pcap_setfilter(phandle, &fcode) == -1)
{
fprintf(stderr, "pcap_setfilter: %s\n", pcap_geterr(phandle));
return 0;
}
if ((datalink = pcap_datalink(phandle)) == -1)
{
fprintf(stderr, "pcap_datalink: %s\n", pcap_geterr(phandle));
return 0;
}
printf("datalink = %d\n", datalink);
npacketnum = 0;
//捕获并处理数据包,使用pcap_handle函数处理数据包
pcap_loop(phandle, 0, pcap_handle, NULL);//
return 1;
}
void pcap_handle(u_char *user,const struct pcap_pkthdr *header, const u_char *pkt_data)
{
ETHHEADER *eth_header = (ETHHEADER *)pkt_data;//以太网帧头部
printf("================Begin Analysis [%d] Packet ====================\n",npacketnum++);
printf("packet length:%ld \n",header->len);
if (header->len >= 14)// IP数据报头部
{
IPHEADER *ip_header=(IPHEADER *)(pkt_data+14);
int iph_len = ip_header->header_len;
iph_len <<= 2;//IP首部大小,单位4字节
char strtype[100];
if (ip_header->proto > 99)
strcpy(strtype ,"IP/UNKNOWN");
else
strcpy(strtype, Proto[ip_header->proto]);
printf("Source MAC:%02X-%02X-%02X-%02X-%02X-%02X ==>", eth_header->SrcMac[0],
eth_header->SrcMac[1], eth_header->SrcMac[2], eth_header->SrcMac[3],
eth_header->SrcMac[4], eth_header->SrcMac[5]);// ÌáÈ¡ÔŽMACµØÖ·
printf("Dest MAC:%02X-%02X-%02X-%02X-%02X-%02X \n", eth_header->DestMac[0],
eth_header->DestMac[1], eth_header->DestMac[2], eth_header->DestMac[3],
eth_header->DestMac[4], eth_header->DestMac[5]);//ÌáÈ¡Ä¿µÄMACµØÖ·
printf("Source IP:%d.%d.%d.%d==>",ip_header->sourceIP[0] ,ip_header->sourceIP[1],ip_header->sourceIP[2],
ip_header->sourceIP[3]);
printf("Dest IP:%d.%d.%d.%d\n",ip_header->destIP[0] ,ip_header->destIP[1],ip_header->destIP[2],
ip_header->destIP[3]);
printf("Protocol:%s\n",strtype);
if((strcmp("TCP",strtype)==0)
||(strcmp("UDP",strtype)==0))
{
PORT *port=(PORT *)(pkt_data+14+iph_len);
printf("Source Port:%d==>",ntohs(port->srcPort));
printf("Dest Port:%d\n",ntohs(port->decPort ));
}
if(!(strcmp("TCP",strtype)==0))
return;
TCPHEADER *tcp_header = (TCPHEADER*)(pkt_data+14+iph_len);
int tcph_len = tcp_header->header_len;
tcph_len <<= 2;
u_char *p = pkt_data;
int i;
printf("\r\nheader YiTaiWang:\r\n");
for( i= 0; i < 14; i++)
{
printf("%02X ", *p++);
if( (i + 1) % 25== 0)
printf("\r\n");
}
printf("\r\nheader IP:(%d bytes)\r\n", iph_len);
for( i= 14; i < 14+iph_len; i++)
{
printf("%02X ", *p++);
if( (i + 1 -14) % 25== 0)
printf("\r\n");
}
printf("\r\nheader TCP:(%d bytes)\r\n", tcph_len);
for( i= 14+iph_len; i < 14+iph_len+tcph_len; i++)
{
printf("%02X ", *p++);
if( (i + 1 - 14 -iph_len) % 25== 0)
printf("\r\n");
}
printf("\r\nData:\r\n");
for( i= 14+iph_len+tcph_len; i < (int)header->len; i++)
{
printf("%02X ", *p++);
if( (i + 1 - 14 -iph_len - tcph_len) % 25== 0)
printf("\r\n");
}
printf("\n================END Analysis Packet ====================\n");
}
}
2. 编译
gcc -o ltest libpcaptest.c -lpcap
3. 运行结果
客户端给服务器发送了2个整数,服务器端返回了其和。
root@ubuntu:~/下载/Linux_C/chp16/libpcap# ./lpacket
NET Address: 127.0.0.0, Network Mask: 255.0.0.0
Input Packet Filter:>tcp
datalink = 1
================Begin Analysis [0] Packet ====================
packet length:74
Source MAC:00-00-00-00-00-00 ==>Dest MAC:00-00-00-00-00-00
Source IP:211.69.205.233==>Dest IP:211.69.205.233
Protocol:TCP
Source Port:60842==>Dest Port:9877
header YiTaiWang:
00 00 00 00 00 00 00 00 00 00 00 00 08 00
header IP:(20 bytes)
45 00 00 3C 79 4C 40 00 40 06 7F 11 D3 45 CD E9 D3 45 CD E9
header TCP:(32 bytes)
ED AA 26 95 C8 5C 06 FB 5D 79 AE 29 80 18 02 01 42 8D 00 00 01 01 08 0A 00
2E EC 83 00 2C 66 F2
Data:
01 00 00 00 02 00 00 00
================END Analysis Packet ====================
================Begin Analysis [1] Packet ====================
packet length:70
Source MAC:00-00-00-00-00-00 ==>Dest MAC:00-00-00-00-00-00
Source IP:211.69.205.233==>Dest IP:211.69.205.233
Protocol:TCP
Source Port:9877==>Dest Port:60842
header YiTaiWang:
00 00 00 00 00 00 00 00 00 00 00 00 08 00
header IP:(20 bytes)
45 00 00 38 D1 90 40 00 40 06 26 D1 D3 45 CD E9 D3 45 CD E9
header TCP:(32 bytes)
26 95 ED AA 5D 79 AE 29 C8 5C 07 03 80 18 02 00 42 89 00 00 01 01 08 0A 00
2E EC 83 00 2E EC 83
Data:
03 00 00 00
================END Analysis Packet ====================