1 #include <string.h> 2 #include <stdlib.h> 3 #include <pcap.h> 4 #include <netinet/in.h> 5 #include "packet_header.h" 6 7 #define MAXBYTE2CAPTURE 2048 8 9 int isprint(char c) 10 { 11 return 0; 12 } 13 14 void print_buf(u_char* pBuf, u_int32 len) 15 { 16 if (!pBuf) 17 { 18 return; 19 } 20 21 for(int i=0; i<len; i++) 22 { 23 printf("%02x ", (u_char*)pBuf[i]); 24 25 if ((i%16 == 0 && i!=0) || i == len-1) 26 { 27 printf("\r\n"); 28 } 29 } 30 } 31 32 void parse_ethII(u_char* pData, u_int32 len) 33 { 34 if (!pData || len <14) 35 { 36 return; 37 } 38 39 printf("eth II frame: \r\n"); 40 print_buf(pData, 14); 41 42 /* parse src mac and dst mac */ 43 EthHeader_t* pEth = (EthHeader_t*)pData; 44 printf("destination: %02x:%02x:%02x:%02x:%02x:%02x ", 45 pEth->dest_hwaddr[0], 46 pEth->dest_hwaddr[1], 47 pEth->dest_hwaddr[2], 48 pEth->dest_hwaddr[3], 49 pEth->dest_hwaddr[4], 50 pEth->dest_hwaddr[5]); 51 52 printf("source : %02x:%02x:%02x:%02x:%02x:%02x", 53 pEth->source_hwaddr[0], 54 pEth->source_hwaddr[1], 55 pEth->source_hwaddr[2], 56 pEth->source_hwaddr[3], 57 pEth->source_hwaddr[4], 58 pEth->source_hwaddr[5]); 59 60 /* parse frame type */ 61 printf("\r\nframe type: 0x%x\r\n", ntohs(pEth->frame_type)); 62 } 63 64 65 void parse_ipheader(u_char* pData, u_int32 len) 66 { 67 if (!pData || len <14) 68 { 69 return; 70 } 71 72 printf("ip header: \r\n"); 73 print_buf(pData, 20); 74 75 /* parse ip header */ 76 IPHeader_t* pIpHeader = (IPHeader_t*)pData; 77 printf("\tversion : %02x\r\n" 78 "\ttos : %02x\r\n" 79 "\ttotal length: %d(0x%02x)\r\n" 80 "\tid : %d(0x%02x)\r\n" 81 "\tsegment flag: %d(0x%02x)\r\n" 82 "\tttl : %02x\r\n" 83 "\tprotocol : %02x\r\n" 84 "\tchecksum : %d(0x%02x)\r\n" 85 "\tsrc ip : %d.%d.%d.%d\r\n" 86 "\tdst ip : %d.%d.%d.%d\r\n", 87 pIpHeader->Ver_HLen, 88 pIpHeader->TOS, 89 ntohs(pIpHeader->TotalLen), ntohs(pIpHeader->TotalLen), 90 ntohs(pIpHeader->ID), ntohs(pIpHeader->ID), 91 ntohs(pIpHeader->Flag_Segment), ntohs(pIpHeader->Flag_Segment), 92 pIpHeader->TTL, 93 pIpHeader->Protocol, 94 ntohs(pIpHeader->Checksum), ntohs(pIpHeader->Checksum), 95 pIpHeader->SrcIP[0],pIpHeader->SrcIP[1],pIpHeader->SrcIP[2],pIpHeader->SrcIP[3], 96 pIpHeader->DstIP[0],pIpHeader->DstIP[1],pIpHeader->DstIP[2],pIpHeader->DstIP[3]); 97 } 98 99 void parse_ip6header(u_char* pData, u_int32 len) 100 { 101 if (!pData || len <14) 102 { 103 return; 104 } 105 106 printf("ipv6 header: \r\n"); 107 print_buf(pData, 40); 108 109 /* parse ipv6 header */ 110 IPv6Header_t* pIpv6Header = (IPv6Header_t*)pData; 111 printf("\tversion : %x\r\n" 112 "\ttraffic class : %x\r\n" 113 "\tflow label : %x\r\n" 114 "\tpayload length : %x\r\n" 115 "\tnext header : %x\r\n" 116 "\thop limit : %x\r\n" 117 "\tsource : %x\r\n" 118 "\tdestination : %x\r\n", 119 pIpv6Header->ip6_ctlun.ip6_un2_vfc, 120 pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_flow, 121 pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_flow, 122 pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_plen, 123 pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_nxt, 124 pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_hlim, 125 pIpv6Header->ip6_src, 126 pIpv6Header->ip6_dst); 127 } 128 129 130 void parse_packet(const u_char* packet, u_int32 len) 131 { 132 u_short ftype = 0; 133 134 if (!packet) 135 { 136 return ; 137 } 138 139 u_char* pMbuf = (u_char*)packet; 140 parse_ethII(pMbuf, len); 141 142 ftype = ntohs(((EthHeader_t*)pMbuf)->frame_type); 143 switch(ftype) 144 { 145 case 0x0800: /* ipv4 */ 146 pMbuf = (u_char*)packet + 14; 147 parse_ipheader(pMbuf, len-14); 148 break; 149 case 0x86dd: /* ipv6 */ 150 pMbuf = (u_char*)packet + 14; 151 parse_ip6header(pMbuf, len-14); 152 break; 153 default: 154 printf("frame type : 0x%x\r\n", ftype); 155 break; 156 } 157 158 printf("\r\n"); 159 } 160 161 void processPacket(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char *packet) 162 { 163 int i = 0, *counter = (int *)arg; 164 165 printf("--------------------------------------------\r\n"); 166 printf("Packet Count: %d\n", ++(*counter)); 167 printf("Received Packet Size: %d\n", pkthdr->len); 168 printf("Payload:\n"); 169 170 #if 1 171 for (i = 0; i < pkthdr->len; i++) 172 { 173 if (isprint(packet[i])) 174 { 175 printf("%02d ", packet[i]); 176 } 177 else 178 { 179 printf("%02x ", packet[i]); 180 } 181 182 if ((i % 16 == 0 && i != 0) || i == pkthdr->len-1) 183 { 184 printf("\n"); 185 } 186 187 } 188 #endif 189 190 parse_packet(packet, pkthdr->len); 191 192 return; 193 } 194 195 int main() 196 { 197 198 int i = 0, count = 0; 199 pcap_t *descr = NULL; 200 char errbuf[PCAP_ERRBUF_SIZE], *device = NULL; 201 memset(errbuf, 0, PCAP_ERRBUF_SIZE); 202 203 /* Get the name of the first device suitable for capture */ 204 device = pcap_lookupdev(errbuf); 205 if (!device) 206 { 207 printf("Open device failed."); 208 return -1; 209 } 210 211 printf("Opening device %s\n", device); 212 213 /* Open device in promiscuous mode */ 214 descr = pcap_open_live(device, MAXBYTE2CAPTURE, 1, 512, errbuf); 215 216 /* Loop forever & call processPacket() for every received packet */ 217 pcap_loop(descr, -1, processPacket, (u_char *)&count); 218 219 return 0;
220 }
#ifndef PACKET_HEADER_H #define PACKET_HEADER_H #ifndef u_char #define u_char unsigned char #endif #ifndef u_int8 #define u_int8 unsigned char #endif #ifndef u_int16 #define u_int16 unsigned short #endif #ifndef u_int32 #define u_int32 unsigned int #endif #ifndef u_int64 #define u_int64 unsigned long long #endif #ifndef u_short #define u_short unsigned short #endif /* 以太帧头 */ typedef struct tagEthHeader_t { //Pcap捕获的数据帧头 u_int8 dest_hwaddr[6]; //目的MAC地址 u_int8 source_hwaddr[6]; //源MAC地址 u_short frame_type; //帧类型 }EthHeader_t; //IP数据报头 typedef struct tagIPHeader_t { //IP数据报头 u_int8 Ver_HLen; //版本+报头长度 u_int8 TOS; //服务类型 u_int16 TotalLen;//总长度 u_int16 ID; //标识 u_int16 Flag_Segment; //标志+片偏移 u_int8 TTL; //生存周期 u_int8 Protocol; //协议类型 u_int16 Checksum;//头部校验和 u_int8 SrcIP[4]; //源IP地址 u_int8 DstIP[4]; //目的IP地址 } IPHeader_t; //IPv6基本首部 #if 0 typedef struct tagIPv6Header_t { u_char version:4; // 4-bit版本号 u_char traffic_class:8; // 8-bit流量等级 u_int32 label:20; // 20-bit流标签 u_short payload_len; // 16-bit 载荷长度 u_char next_header; // 8-bit 下一首部 u_char hop_limit; // 8-bit 跳数限制 struct { u_int64 prefix_subnetid; u_char interface_id[8]; } src_ip; // 128-bit 源地址 struct { u_int64 prefix_subnetid; u_char interface_id[8]; } dst_ip; // 128-bit 目的地址 } IPv6Header_t; typedef struct in6_addr { union { u_char Byte[16]; u_short Word[8]; } u; } IN6_ADDR, *PIN6_ADDR, FAR *LPIN6_ADDR; #endif typedef struct tagIPv6Header_t { union { struct ip6_hdrctl { u_int32_t ip6_unl_flow;/* 4位的版本,8位的传输与分类,20位的流标识符 */ u_int16_t ip6_unl_plen;/* 报头长度 */ u_int8_t ip6_unl_nxt; /* 下一个报头 */ u_int8_t ip6_unl_hlim; /* 跨度限制 */ }ip6_unl ; u_int8_t ip6_un2_vfc;/* 4位的版本号,跨度为4位的传输分类 */ }ip6_ctlun ; #define ip6_vfc ip6_ctlun.ip6_un2_vfc #define ip6_flow ip6_ctlun.ip6_unl.ip6_unl_flow #define ip6_plen ip6_ctlun.ip6_unl.ip6_unl_plen #define ip6_nxt ip6_ctlun.ip6_unl.ip6_unl_nxt #define ip6_hlim ip6_ctlun.ip6_unl.ip6_unl_hlim #define ip6_hops ip6_ctlun.ip6_unl.ip6_unl_hops struct in6_addr ip6_src;/* 发送端地址 */ struct in6_addr ip6_dst;/* 接收端地址 */ }IPv6Header_t; //TCP数据报头 typedef struct tagTCPHeader_t { //TCP数据报头 u_int16 SrcPort; //源端口 u_int16 DstPort; //目的端口 u_int32 SeqNO; //序号 u_int32 AckNO; //确认号 } TCPHeader_t; #endif