读取pcap文件,过滤非tcp包,获取IP及tcp端口信息

1 // OpenAndFilterAndPres.cpp : Defines the entry point for the console application.
2  //
3  
4 #include "stdafx.h"
5 #include "pcap.h"
6 #include "remote-ext.h"
7 #include"stdlib.h"
8
9  /* 4 bytes IP address */
10 typedef struct ip_address{
11 u_char byte1;
12 u_char byte2;
13 u_char byte3;
14 u_char byte4;
15 }ip_address;
16
17 /* IPv4 header */
18 typedef struct ip_header{
19 u_char ver_ihl; // Version (4 bits) + Internet header length (4 bits)
20 u_char tos; // Type of service
21 u_short tlen; // Total length
22 u_short identification; // Identification
23 u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits)
24 u_char ttl; // Time to live
25 u_char proto; // Protocol
26 u_short crc; // Header checksum
27 ip_address saddr; // Source address
28 ip_address daddr; // Destination address
29 u_int op_pad; // Option + Padding
30 }ip_header;
31
32 /* UDP header*/
33 typedef struct udp_header{
34 u_short sport; // Source port
35 u_short dport; // Destination port
36 u_short len; // Datagram length
37 u_short crc; // Checksum
38 }udp_header;
39
40 // TCP首部
41 typedef struct tcp_header{
42 WORD source_port; // (16 bits) Winsock 内置函数 ntohs(),主要作用将大端转换为小端!
43 WORD destination_port; // (16 bits) Winsock 内置函数 ntohs(),主要作用将大端转换为小端!
44 DWORD seq_number; // Sequence Number (32 bits) 大小端原因,高低位4个8bit的存放顺序是反的,intel使用小端模式
45 DWORD ack_number; // Acknowledgment Number (32 bits) 大小端原因,高低位4个8bit的存放顺序是反的,intel使用小端模式
46 WORD info_ctrl; // Data Offset (4 bits), Reserved (6 bits), Control bits (6 bits) intel使用小端模式
47 WORD window; // (16 bits)
48 WORD checksum; // (16 bits)
49 WORD urgent_pointer; // (16 bits)
50 } tcp_header;
51
52 /* prototype of the packet handler */
53 void dispatcher_handler(u_char *temp1,
54 const struct pcap_pkthdr *header, const u_char *pkt_data);
55
56
57 int main(int argc, char* argv[])
58 {
59 pcap_t *fp;
60 char errbuf[PCAP_ERRBUF_SIZE];
61 char source[PCAP_BUF_SIZE];
62 //char packet_filter[] = "tcp";
63 //有tcp必有ip
64 char packet_filter[] = "ip and tcp";
65 struct bpf_program fcode;
66 u_int netmask;
67
68 if(argc != 2){
69 printf("usage: %s filename", argv[0]);
70 return -1;
71 }
72
73 /* Create the source string according to the new WinPcap syntax */
74 if ( pcap_createsrcstr( source, // variable that will keep the source string
75 PCAP_SRC_FILE, // we want to open a file
76 NULL, // remote host
77 NULL, // port on the remote host
78 argv[1], // name of the file we want to open
79 errbuf // error buffer
80 ) != 0)
81 {
82 fprintf(stderr,"\nError creating a source string\n");
83 return -1;
84 }
85
86 /* Open the capture file */
87 if ( (fp= pcap_open(source, // name of the device
88 65536, // portion of the packet to capture
89 // 65536 guarantees that the whole packet will be captured on all the link layers
90 PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
91 1000, // read timeout
92 NULL, // authentication on the remote machine
93 errbuf // error buffer
94 ) ) == NULL)
95 {
96 fprintf(stderr,"\nUnable to open the file %s.\n", source);
97 return -1;
98 }
99
100 netmask=0xffffff;
101
102 //compile the filter
103 if (pcap_compile(fp, &fcode, packet_filter, 1, netmask) <0 )
104 {
105 fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n");
106 return -1;
107 }
108
109 //set the filter
110 if (pcap_setfilter(fp, &fcode)<0)
111 {
112 fprintf(stderr,"\nError setting the filter.\n");
113 return -1;
114 }
115
116 // read and dispatch packets until EOF is reached
117 pcap_loop(fp, 0, dispatcher_handler, NULL);
118
119 return 0;
120 }
121
122 void dispatcher_handler(u_char *temp1,
123 const struct pcap_pkthdr *header, const u_char *pkt_data)
124 {
125 struct tm *ltime;
126 char timestr[16];
127 ip_header *ih;
128 tcp_header *th;
129 u_int ip_len;
130 u_short sport,dport;
131 time_t local_tv_sec;
132
133 /* convert the timestamp to readable format */
134 local_tv_sec = header->ts.tv_sec;
135 ltime=localtime(&local_tv_sec);
136 strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
137
138 /* print timestamp and length of the packet */
139 printf("%s.%.6d len:%d ", timestr, header->ts.tv_usec, header->len);
140
141 /* retireve the position of the ip header */
142 ih = (ip_header *) (pkt_data +
143 14); //length of ethernet header
144
145 /* retireve the position of the tcp header */
146 //从IPV4首部中取出"首部长度(4 bits)"
147 ip_len = (ih->ver_ihl & 0xf) * 4;
148 //强制类型转换,便于用自己的命名处理
149 th = (tcp_header *) ((u_char*)ih + ip_len);
150
151 /* convert from network byte order to host byte order */
152 sport = ntohs( th->source_port );
153 dport = ntohs( th->destination_port );
154
155 /* print ip addresses and udp ports */
156 printf("%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\n",
157 ih->saddr.byte1,
158 ih->saddr.byte2,
159 ih->saddr.byte3,
160 ih->saddr.byte4,
161 sport,
162 ih->daddr.byte1,
163 ih->daddr.byte2,
164 ih->daddr.byte3,
165 ih->daddr.byte4,
166 dport);
167 }

实现截图:

posted @ 2011-07-10 20:39  ErinFlyingFish  阅读(6001)  评论(1编辑  收藏  举报