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("
");
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:
");
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("
frame type: 0x%x
", 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:
");
73 print_buf(pData, 20);
74
75 /* parse ip header */
76 IPHeader_t* pIpHeader = (IPHeader_t*)pData;
77 printf(" version : %02x
"
78 " tos : %02x
"
79 " total length: %d(0x%02x)
"
80 " id : %d(0x%02x)
"
81 " segment flag: %d(0x%02x)
"
82 " ttl : %02x
"
83 " protocol : %02x
"
84 " checksum : %d(0x%02x)
"
85 " src ip : %d.%d.%d.%d
"
86 " dst ip : %d.%d.%d.%d
",
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:
");
107 print_buf(pData, 40);
108
109 /* parse ipv6 header */
110 IPv6Header_t* pIpv6Header = (IPv6Header_t*)pData;
111 printf(" version : %x
"
112 " traffic class : %x
"
113 " flow label : %x
"
114 " payload length : %x
"
115 " next header : %x
"
116 " hop limit : %x
"
117 " source : %x
"
118 " destination : %x
",
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
", ftype);
155 break;
156 }
157
158 printf("
");
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("--------------------------------------------
");
166 printf("Packet Count: %d
", ++(*counter));
167 printf("Received Packet Size: %d
", pkthdr->len);
168 printf("Payload:
");
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("
");
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
", 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