1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <pcap.h>
4 #include <errno.h>
5 #include <sys/socket.h>
6 #include <netinet/
in.h>
7 #include <arpa/inet.h>
8
9 int main(
int argc,
char **
argv)
10 {
11 char *
dev;
12 char *
net;
13 char *
mask;
14 int ret;
15 char errbuf[PCAP_ERRBUF_SIZE];
16 bpf_u_int32 netp;
17 bpf_u_int32 maskp;
18 struct in_addr addr;
19
20
21 dev =
pcap_lookupdev(errbuf);
22
23
24 if(dev ==
NULL)
25 {
26 printf(
"%s\n",errbuf);
27 exit(
1);
28 }
29
30
31 printf(
"DEV: %s\n",dev);
32
33
34 ret = pcap_lookupnet(dev,&netp,&
maskp,errbuf);
35
36 if(ret == -
1)
37 {
38 printf(
"%s\n",errbuf);
39 exit(
1);
40 }
41
42
43 addr.s_addr =
netp;
44 net =
inet_ntoa(addr);
45
46 if(net ==
NULL)
47 {
48 perror(
"inet_ntoa");
49 exit(
1);
50 }
51
52 printf(
"NET: %s\n",net);
53
54
55 addr.s_addr =
maskp;
56 mask =
inet_ntoa(addr);
57
58 if(mask ==
NULL)
59 {
60 perror(
"inet_ntoa");
61 exit(
1);
62 }
63
64 printf(
"MASK: %s\n",mask);
65
66 return 0;
67 }
68 然后gcc -o pcap_1 pcap_1.c -lpcap(一定要-
lpcap参数)
69 编译ok~,执行./
pcap_1,可以看到:
70 DEV: eth0
71 NET:
192.168.
12.0
72 MASK:
255.255.
255.0
73 好了,第一个pcap程序出炉了。。。。。
74
75 但是(当然有但是了,要不然我后面写啥),上面那个程序除了向我们展现pcap_lookupdev和pcap_lookupnet之外什么都没有干,好,我们接着来,动手编写我们的第一个抓包程序。
76
77 #include <stdio.h>
78 #include <stdlib.h>
79 #include <pcap.h>
80 #include <errno.h>
81 #include <sys/socket.h>
82 #include <netinet/
in.h>
83 #include <arpa/inet.h>
84 #include <netinet/if_ether.h>
85
86 int main(
int argc,
char **
argv)
87 {
88 int i;
89 char *
dev;
90 char errbuf[PCAP_ERRBUF_SIZE];
91 pcap_t*
descr;
92 const u_char *
packet;
93 struct pcap_pkthdr hdr;
94 struct ether_header *
eptr;
95
96 u_char *
ptr;
97
98
99 dev =
pcap_lookupdev(errbuf);
100
101 if(dev ==
NULL)
102 {
103 printf(
"%s\n",errbuf);
104 exit(
1);
105 }
106
107 printf(
"DEV: %s\n",dev);
108
109
110
111 descr = pcap_open_live(dev,BUFSIZ,
0,-
1,errbuf);
112
113 if(descr ==
NULL)
114 {
115 printf(
"pcap_open_live(): %s\n",errbuf);
116 exit(
1);
117 }
118
119
120
121
122 packet = pcap_next(descr,&
hdr);
123
124 if(packet ==
NULL)
125 {
126 printf(
"Didn't grab packet\n");
127 exit(
1);
128 }
129
130
131
132 printf(
"Grabbed packet of length %d\n",hdr.len);
133 printf(
"Recieved at ..... %s\n",ctime((
const time_t*)&
hdr.ts.tv_sec));
134 printf(
"Ethernet address length is %d\n",ETHER_HDR_LEN);
135
136
137 eptr = (
struct ether_header *
) packet;
138
139
140 if (ntohs (eptr->ether_type) ==
ETHERTYPE_IP)
141 {
142 printf(
"Ethernet type hex:%x dec:%d is an IP packet\n",
143 ntohs(eptr->
ether_type),
144 ntohs(eptr->
ether_type));
145 }
else if (ntohs (eptr->ether_type) ==
ETHERTYPE_ARP)
146 {
147 printf(
"Ethernet type hex:%x dec:%d is an ARP packet\n",
148 ntohs(eptr->
ether_type),
149 ntohs(eptr->
ether_type));
150 }
else {
151 printf(
"Ethernet type %x not IP", ntohs(eptr->
ether_type));
152 exit(
1);
153 }
154
155
156 ptr = eptr->
ether_dhost;
157 i =
ETHER_ADDR_LEN;
158 printf(
" Destination Address: ");
159 do{
160 printf(
"%s%x",(i == ETHER_ADDR_LEN) ?
" " :
":",*ptr++
);
161 }
while(--i>
0);
162 printf(
"\n");
163
164 ptr = eptr->
ether_shost;
165 i =
ETHER_ADDR_LEN;
166 printf(
" Source Address: ");
167 do{
168 printf(
"%s%x",(i == ETHER_ADDR_LEN) ?
" " :
":",*ptr++
);
169 }
while(--i>
0);
170 printf(
"\n");
171
172 return 0;
173 }
174
175 好了,编译运行!
176 [root@norman libpcap]# ./
pcap_2
177 DEV: eth0
178 Grabbed packet of length
76
179 Recieved at time..... Mon Mar
12 22:
23:
29 2001
180
181 Ethernet address length
is 14
182 Ethernet type hex:
800 dec:
2048 is an IP packet
183 Destination Address:
0:
20:
78:d1:e8:
1
184 Source Address:
0:a0:cc:
56:c2:
91
185 [root@pepe libpcap]#
186
187 可能有人等了半天都没有一个包过来,有个好办法,再开一个控制台,ping一下某个网站,比如google~~
,呵呵
188 马上就有反应了~~
189
190 这个程序是一个老外写的,大家看看注释应该没有问题吧~
191 但是大家也发现了一个问题,就是上面的程序只能捕捉一个包,要不停的捕捉包怎么办,用循环??libpcap提供了一个更好的方法:
192 int pcap_loop(pcap_t *p,
int cnt, pcap_handler callback, u_char *
user);
193 这个函数能够不停的捕捉以太网的包,cnt就是捕捉的次数,callback是处理函数,这个处理函数怎么写,看看pcap_3.c就知道了。user参数是干什么的?不要问我,我也不知道。
194
195 #include <pcap.h>
196 #include <stdio.h>
197 #include <stdlib.h>
198 #include <errno.h>
199 #include <sys/socket.h>
200 #include <netinet/
in.h>
201 #include <arpa/inet.h>
202 #include <netinet/if_ether.h>
203
204
205 void my_callback(u_char *useless,
const struct pcap_pkthdr* pkthdr,
const u_char*
206 packet)
207 {
208 static int count =
1;
209 fprintf(stdout,
"%d, ",count);
210 if(count ==
4)
211 fprintf(stdout,
"Come on baby sayyy you love me!!! ");
212 if(count ==
7)
213 fprintf(stdout,
"Tiiimmmeesss!! ");
214 fflush(stdout);
215 count++
;
216 }
217
218 int main(
int argc,
char **
argv)
219 {
220 int i;
221 char *
dev;
222 char errbuf[PCAP_ERRBUF_SIZE];
223 pcap_t*
descr;
224 const u_char *
packet;
225 struct pcap_pkthdr hdr;
226 struct ether_header *
eptr;
227
228 if(argc !=
2){ fprintf(stdout,
"Usage: %s numpackets\n",argv[
0]);
return 0;}
229
230
231 dev =
pcap_lookupdev(errbuf);
232 if(dev ==
NULL)
233 { printf(
"%s\n",errbuf); exit(
1); }
234
235 descr = pcap_open_live(dev,BUFSIZ,
0,-
1,errbuf);
236 if(descr ==
NULL)
237 { printf(
"pcap_open_live(): %s\n",errbuf); exit(
1); }
238
239
240
241 pcap_loop(descr,atoi(argv[
1]),my_callback,NULL);
242
243 fprintf(stdout,
"\nDone processing packets... wheew!\n");
244 return 0;
245 }
246
247 运行./pcap_3
7
248 1,
2,
3,
4, Come on baby sayyy you love me!!!
5,
6,
7, Tiiimmmeesss!!
249 Done processing packets... wheew!
250
251 pcap_loop确实很好用,但是如果没有包包过来,只有干等在那里,pcap_dispatch就含有一个超时的功能,下面是man里面的一段话:
252 pcap_dispatch()
is used to collect and process packets. cnt specifies the maximum number of packets to process before returning. A cnt of -
1 processes all the packets received
in one buffer. A cnt of
0 processes all packets until an error occurs, EOF
is reached, or the read times
out (when doing live reads and a non-zero read timeout
is specified). callback specifies a routine to be called with three arguments: a u_char pointer which
is passed
in from pcap_dispatch(), a pointer to the pcap_pkthdr
struct (which precede the actual network headers and data), and a u_char pointer to the packet data. The number of packets read
is returned. Zero
is returned when EOF
is reached
in a ``savefile.
'' A
return of -
1 indicates an error
in which
case pcap_perror() or pcap_geterr() may be used to display the error text.
253
254 另外的问题是,我们可能对抓取的包包太多而很头痛,可能很多都不是我们感兴趣的包,别急,pcap_compile和pcap_setfilter能帮我们解决问题。
255
256 #include <pcap.h>
257 #include <stdio.h>
258 #include <stdlib.h>
259 #include <errno.h>
260 #include <sys/socket.h>
261 #include <netinet/
in.h>
262 #include <arpa/inet.h>
263 #include <netinet/if_ether.h>
264
265
266 void my_callback(u_char *useless,
const struct pcap_pkthdr* pkthdr,
const u_char*
267 packet)
268 {
269 static int count =
1;
270 fprintf(stdout,
"%d, ",count);
271 fflush(stdout);
272 count++
;
273 }
274
275 int main(
int argc,
char **
argv)
276 {
277 int i;
278 char *
dev;
279 char errbuf[PCAP_ERRBUF_SIZE];
280 pcap_t*
descr;
281 const u_char *
packet;
282 struct pcap_pkthdr hdr;
283 struct ether_header *
eptr;
284 struct bpf_program fp;
285 bpf_u_int32 maskp;
286 bpf_u_int32 netp;
287
288
289 if(argc !=
2){ fprintf(stdout,
"Usage: %s \"filter program\"\n"
290 ,argv[
0]);
return 0;}
291
292
293 dev =
pcap_lookupdev(errbuf);
294 if(dev ==
NULL)
295 { fprintf(stderr,
"%s\n",errbuf); exit(
1); }
296
297
298 pcap_lookupnet(dev,&netp,&
maskp,errbuf);
299
300
301 descr = pcap_open_live(dev,BUFSIZ,
1,-
1,errbuf);
302 if(descr ==
NULL)
303 { printf(
"pcap_open_live(): %s\n",errbuf); exit(
1); }
304
305
306 if(pcap_compile(descr,&fp,argv[
1],
0,netp) == -
1)
307 { fprintf(stderr,
"Error calling pcap_compile\n"); exit(
1); }
308
309
310 if(pcap_setfilter(descr,&fp) == -
1)
311 { fprintf(stderr,
"Error setting filter\n"); exit(
1); }
312
313
314 pcap_loop(descr,-
1,my_callback,NULL);
315
316 return 0;
317 }
318
319 运行./pcap_4.c
"host www.google.com"
320 然后在另外一个控制台下面ping www.baidu.com
321 哈哈
322 没有反应吧
323 接着再ping www.google.com
324 就看到1,
2,
3,
4,
5,
6,
325 ok
326 you got it!!
View Code
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <pcap.h>
4 #include <errno.h>
5 #include <sys/socket.h>
6 #include <netinet/
in.h>
7 #include <arpa/inet.h>
8
9 int main(
int argc,
char **
argv)
10 {
11 char *
dev;
12 char *
net;
13 char *
mask;
14 int ret;
15 char errbuf[PCAP_ERRBUF_SIZE];
16 bpf_u_int32 netp;
17 bpf_u_int32 maskp;
18 struct in_addr addr;
19
20
21 dev =
pcap_lookupdev(errbuf);
22
23
24 if(dev ==
NULL)
25 {
26 printf(
"%s\n",errbuf);
27 exit(
1);
28 }
29
30
31 printf(
"DEV: %s\n",dev);
32
33
34 ret = pcap_lookupnet(dev,&netp,&
maskp,errbuf);
35
36 if(ret == -
1)
37 {
38 printf(
"%s\n",errbuf);
39 exit(
1);
40 }
41
42
43 addr.s_addr =
netp;
44 net =
inet_ntoa(addr);
45
46 if(net ==
NULL)
47 {
48 perror(
"inet_ntoa");
49 exit(
1);
50 }
51
52 printf(
"NET: %s\n",net);
53
54
55 addr.s_addr =
maskp;
56 mask =
inet_ntoa(addr);
57
58 if(mask ==
NULL)
59 {
60 perror(
"inet_ntoa");
61 exit(
1);
62 }
63
64 printf(
"MASK: %s\n",mask);
65
66 return 0;
67 }
68 然后gcc -o pcap_1 pcap_1.c -lpcap(一定要-
lpcap参数)
69 编译ok~,执行./
pcap_1,可以看到:
70 DEV: eth0
71 NET:
192.168.
12.0
72 MASK:
255.255.
255.0
73 好了,第一个pcap程序出炉了。。。。。
74
75 但是(当然有但是了,要不然我后面写啥),上面那个程序除了向我们展现pcap_lookupdev和pcap_lookupnet之外什么都没有干,好,我们接着来,动手编写我们的第一个抓包程序。
76
77 #include <stdio.h>
78 #include <stdlib.h>
79 #include <pcap.h>
80 #include <errno.h>
81 #include <sys/socket.h>
82 #include <netinet/
in.h>
83 #include <arpa/inet.h>
84 #include <netinet/if_ether.h>
85
86 int main(
int argc,
char **
argv)
87 {
88 int i;
89 char *
dev;
90 char errbuf[PCAP_ERRBUF_SIZE];
91 pcap_t*
descr;
92 const u_char *
packet;
93 struct pcap_pkthdr hdr;
94 struct ether_header *
eptr;
95
96 u_char *
ptr;
97
98
99 dev =
pcap_lookupdev(errbuf);
100
101 if(dev ==
NULL)
102 {
103 printf(
"%s\n",errbuf);
104 exit(
1);
105 }
106
107 printf(
"DEV: %s\n",dev);
108
109
110
111 descr = pcap_open_live(dev,BUFSIZ,
1,0,errbuf);
112
113 if(descr ==
NULL)
114 {
115 printf(
"pcap_open_live(): %s\n",errbuf);
116 exit(
1);
117 }
118
119
120
121
122 packet = pcap_next(descr,&
hdr);
123
124 if(packet ==
NULL)
125 {
126 printf(
"Didn't grab packet\n");
127 exit(
1);
128 }
129
130
131
132 printf(
"Grabbed packet of length %d\n",hdr.len);
133 printf(
"Recieved at ..... %s\n",ctime((
const time_t*)&
hdr.ts.tv_sec));
134 printf(
"Ethernet address length is %d\n",ETHER_HDR_LEN);
135
136
137 eptr = (
struct ether_header *
) packet;
138
139
140 if (ntohs (eptr->ether_type) ==
ETHERTYPE_IP)
141 {
142 printf(
"Ethernet type hex:%x dec:%d is an IP packet\n",
143 ntohs(eptr->
ether_type),
144 ntohs(eptr->
ether_type));
145 }
else if (ntohs (eptr->ether_type) ==
ETHERTYPE_ARP)
146 {
147 printf(
"Ethernet type hex:%x dec:%d is an ARP packet\n",
148 ntohs(eptr->
ether_type),
149 ntohs(eptr->
ether_type));
150 }
else {
151 printf(
"Ethernet type %x not IP", ntohs(eptr->
ether_type));
152 exit(
1);
153 }
154
155
156 ptr = eptr->
ether_dhost;
157 i =
ETHER_ADDR_LEN;
158 printf(
" Destination Address: ");
159 do{
160 printf(
"%s%x",(i == ETHER_ADDR_LEN) ?
" " :
":",*ptr++
);
161 }
while(--i>
0);
162 printf(
"\n");
163
164 ptr = eptr->
ether_shost;
165 i =
ETHER_ADDR_LEN;
166 printf(
" Source Address: ");
167 do{
168 printf(
"%s%x",(i == ETHER_ADDR_LEN) ?
" " :
":",*ptr++
);
169 }
while(--i>
0);
170 printf(
"\n");
171
172 return 0;
173 }
174
175 好了,编译运行!
176 [root@norman libpcap]# ./
pcap_2
177 DEV: eth0
178 Grabbed packet of length
76
179 Recieved at time..... Mon Mar
12 22:
23:
29 2001
180
181 Ethernet address length
is 14
182 Ethernet type hex:
800 dec:
2048 is an IP packet
183 Destination Address:
0:
20:
78:d1:e8:
1
184 Source Address:
0:a0:cc:
56:c2:
91
185 [root@pepe libpcap]#
186
187 可能有人等了半天都没有一个包过来,有个好办法,再开一个控制台,ping一下某个网站,比如google~~
,呵呵
188 马上就有反应了~~
189
190 这个程序是一个老外写的,大家看看注释应该没有问题吧~
191 但是大家也发现了一个问题,就是上面的程序只能捕捉一个包,要不停的捕捉包怎么办,用循环??libpcap提供了一个更好的方法:
192 int pcap_loop(pcap_t *p,
int cnt, pcap_handler callback, u_char *
user);
193 这个函数能够不停的捕捉以太网的包,cnt就是捕捉的次数,callback是处理函数,这个处理函数怎么写,看看pcap_3.c就知道了。user参数是干什么的?不要问我,我也不知道。
194
195 #include <pcap.h>
196 #include <stdio.h>
197 #include <stdlib.h>
198 #include <errno.h>
199 #include <sys/socket.h>
200 #include <netinet/
in.h>
201 #include <arpa/inet.h>
202 #include <netinet/if_ether.h>
203
204
205 void my_callback(u_char *useless,
const struct pcap_pkthdr* pkthdr,
const u_char*
206 packet)
207 {
208 static int count =
1;
209 fprintf(stdout,
"%d, ",count);
210 if(count ==
4)
211 fprintf(stdout,
"Come on baby sayyy you love me!!! ");
212 if(count ==
7)
213 fprintf(stdout,
"Tiiimmmeesss!! ");
214 fflush(stdout);
215 count++
;
216 }
217
218 int main(
int argc,
char **
argv)
219 {
220 int i;
221 char *
dev;
222 char errbuf[PCAP_ERRBUF_SIZE];
223 pcap_t*
descr;
224 const u_char *
packet;
225 struct pcap_pkthdr hdr;
226 struct ether_header *
eptr;
227
228 if(argc !=
2){ fprintf(stdout,
"Usage: %s numpackets\n",argv[
0]);
return 0;}
229
230
231 dev =
pcap_lookupdev(errbuf);
232 if(dev ==
NULL)
233 { printf(
"%s\n",errbuf); exit(
1); }
234
235 descr = pcap_open_live(dev,BUFSIZ,
0,-
1,errbuf);
236 if(descr ==
NULL)
237 { printf(
"pcap_open_live(): %s\n",errbuf); exit(
1); }
238
239
240
241 pcap_loop(descr,atoi(argv[
1]),my_callback,NULL);
242
243 fprintf(stdout,
"\nDone processing packets... wheew!\n");
244 return 0;
245 }
246
247 运行./pcap_3
7
248 1,
2,
3,
4, Come on baby sayyy you love me!!!
5,
6,
7, Tiiimmmeesss!!
249 Done processing packets... wheew!
250
251 pcap_loop确实很好用,但是如果没有包包过来,只有干等在那里,pcap_dispatch就含有一个超时的功能,下面是man里面的一段话:
252 pcap_dispatch()
is used to collect and process packets. cnt specifies the maximum number of packets to process before returning. A cnt of -
1 processes all the packets received
in one buffer. A cnt of
0 processes all packets until an error occurs, EOF
is reached, or the read times
out (when doing live reads and a non-zero read timeout
is specified). callback specifies a routine to be called with three arguments: a u_char pointer which
is passed
in from pcap_dispatch(), a pointer to the pcap_pkthdr
struct (which precede the actual network headers and data), and a u_char pointer to the packet data. The number of packets read
is returned. Zero
is returned when EOF
is reached
in a ``savefile.
'' A
return of -
1 indicates an error
in which
case pcap_perror() or pcap_geterr() may be used to display the error text.
253
254 另外的问题是,我们可能对抓取的包包太多而很头痛,可能很多都不是我们感兴趣的包,别急,pcap_compile和pcap_setfilter能帮我们解决问题。
255
256 #include <pcap.h>
257 #include <stdio.h>
258 #include <stdlib.h>
259 #include <errno.h>
260 #include <sys/socket.h>
261 #include <netinet/
in.h>
262 #include <arpa/inet.h>
263 #include <netinet/if_ether.h>
264
265
266 void my_callback(u_char *useless,
const struct pcap_pkthdr* pkthdr,
const u_char*
267 packet)
268 {
269 static int count =
1;
270 fprintf(stdout,
"%d, ",count);
271 fflush(stdout);
272 count++
;
273 }
274
275 int main(
int argc,
char **
argv)
276 {
277 int i;
278 char *
dev;
279 char errbuf[PCAP_ERRBUF_SIZE];
280 pcap_t*
descr;
281 const u_char *
packet;
282 struct pcap_pkthdr hdr;
283 struct ether_header *
eptr;
284 struct bpf_program fp;
285 bpf_u_int32 maskp;
286 bpf_u_int32 netp;
287
288
289 if(argc !=
2){ fprintf(stdout,
"Usage: %s \"filter program\"\n"
290 ,argv[
0]);
return 0;}
291
292
293 dev =
pcap_lookupdev(errbuf);
294 if(dev ==
NULL)
295 { fprintf(stderr,
"%s\n",errbuf); exit(
1); }
296
297
298 pcap_lookupnet(dev,&netp,&
maskp,errbuf);
299
300
301 descr = pcap_open_live(dev,BUFSIZ,
1,-
1,errbuf);
302 if(descr ==
NULL)
303 { printf(
"pcap_open_live(): %s\n",errbuf); exit(
1); }
304
305
306 if(pcap_compile(descr,&fp,argv[
1],
0,netp) == -
1)
307 { fprintf(stderr,
"Error calling pcap_compile\n"); exit(
1); }
308
309
310 if(pcap_setfilter(descr,&fp) == -
1)
311 { fprintf(stderr,
"Error setting filter\n"); exit(
1); }
312
313
314 pcap_loop(descr,-
1,my_callback,NULL);
315
316 return 0;
317 }
318
319 运行./pcap_4.c
"host www.google.com"
320 然后在另外一个控制台下面ping www.baidu.com
321 哈哈
322 没有反应吧
323 接着再ping www.google.com
324 就看到1,
2,
3,
4,
5,
6,
325 ok
326 you got it!!
转载于:https://www.cnblogs.com/meihao1989/p/4210623.html
相关资源:libpcap编程-编写自己的网络嗅探程序