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"); } }
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 ====================