2 * copyright (c) 2001-2011 Emil Mikulic.
4 * cap.c: interface to libpcap.
6 * You may use, modify and redistribute this file under the terms of the
7 * GNU General Public License version 2. (see COPYING.GPL)
19 #include <sys/ioctl.h>
20 #include <sys/types.h>
21 #include <sys/socket.h>
23 #ifdef HAVE_SYS_FILIO_H
24 # include <sys/filio.h> /* Solaris' FIONBIO hides here */
33 /* The cap process life-cycle:
36 * Fill fd_set - cap_fd_set()
41 /* Globals - only useful within this module. */
42 static pcap_t
*pcap
= NULL
;
43 static int pcap_fd
= -1;
44 static const struct linkhdr
*linkhdr
= NULL
;
46 #define CAP_TIMEOUT 500 /* granularity of capture buffer, in milliseconds */
48 /* ---------------------------------------------------------------------------
49 * Init pcap. Exits on failure.
52 cap_init(const char *device
, const char *filter
, int promisc
)
54 char errbuf
[PCAP_ERRBUF_SIZE
], *tmp_device
;
55 int linktype
, snaplen
, waited
;
57 /* pcap doesn't like device being const */
58 tmp_device
= xstrdup(device
);
60 /* Open packet capture descriptor. */
63 errbuf
[0] = '\0'; /* zero length string */
64 pcap
= pcap_open_live(
66 1, /* snaplen, irrelevant at this point */
67 0, /* promisc, also irrelevant */
70 if (pcap
!= NULL
) break; /* success! */
72 if ((opt_wait_secs
!= -1) && strstr(errbuf
, "device is not up")) {
73 if ((opt_wait_secs
> 0) && (waited
>= opt_wait_secs
))
74 errx(1, "waited %d secs, giving up: pcap_open_live(): %s",
77 verbosef("waited %d secs, interface is not up", waited
);
81 else errx(1, "pcap_open_live(): %s", errbuf
);
84 /* Work out the linktype and what snaplen we need. */
85 linktype
= pcap_datalink(pcap
);
86 verbosef("linktype is %d", linktype
);
87 if ((linktype
== DLT_EN10MB
) && opt_want_macs
)
88 hosts_db_show_macs
= 1;
89 linkhdr
= getlinkhdr(linktype
);
91 errx(1, "unknown linktype %d", linktype
);
92 if (linkhdr
->handler
== NULL
)
93 errx(1, "no handler for linktype %d", linktype
);
94 snaplen
= getsnaplen(linkhdr
);
96 snaplen
+= PPPOE_HDR_LEN
;
97 if (linktype
!= DLT_EN10MB
)
98 errx(1, "can't do PPPoE decoding on a non-Ethernet linktype");
100 verbosef("calculated snaplen minimum %d", snaplen
);
102 /* Ubuntu 9.04 has a problem where requesting snaplen <= 60 will
103 * give us 42 bytes, and we need at least 54 for TCP headers.
105 * Hack to set minimum snaplen to tcpdump's default:
107 snaplen
= MAX(snaplen
, 96);
109 if (opt_want_snaplen
> -1)
110 snaplen
= opt_want_snaplen
;
111 verbosef("using snaplen %d", snaplen
);
113 /* Close and re-open pcap to use the new snaplen. */
115 errbuf
[0] = '\0'; /* zero length string */
116 pcap
= pcap_open_live(
124 errx(1, "pcap_open_live(): %s", errbuf
);
126 if (errbuf
[0] != '\0') /* not zero length anymore -> warning */
127 warnx("pcap_open_live() warning: %s", errbuf
);
132 verbosef("capturing in promiscuous mode");
134 verbosef("capturing in non-promiscuous mode");
136 /* Set filter expression, if any. */
139 struct bpf_program prog
;
140 char *tmp_filter
= xstrdup(filter
);
148 errx(1, "pcap_compile(): %s", pcap_geterr(pcap
));
150 if (pcap_setfilter(pcap
, &prog
) == -1)
151 errx(1, "pcap_setfilter(): %s", pcap_geterr(pcap
));
153 pcap_freecode(&prog
);
157 pcap_fd
= pcap_fileno(pcap
);
159 /* set non-blocking */
161 if (pcap_setnonblock(pcap
, 1, errbuf
) == -1)
162 errx(1, "pcap_setnonblock(): %s", errbuf
);
165 if (ioctl(pcap_fd
, FIONBIO
, &one
) == -1)
166 err(1, "ioctl(pcap_fd, FIONBIO)"); }
171 /* Deny all writes to the socket */
172 struct bpf_insn bpf_wfilter
[] = { BPF_STMT(BPF_RET
+BPF_K
, 0) };
173 int wf_len
= sizeof(bpf_wfilter
) / sizeof(struct bpf_insn
);
174 struct bpf_program pr
;
177 pr
.bf_insns
= bpf_wfilter
;
179 if (ioctl(pcap_fd
, BIOCSETWF
, &pr
) == -1)
180 err(1, "ioctl(pcap_fd, BIOCSETFW)");
181 verbosef("filtered out BPF writes");
186 /* set "locked" flag (no reset) */
187 if (ioctl(pcap_fd
, BIOCLOCK
) == -1)
188 err(1, "ioctl(pcap_fd, BIOCLOCK)");
189 verbosef("locked down BPF for security");
194 * Set pcap_fd in the given fd_set.
199 fd_set
*read_set _unused_
,
200 int *max_fd _unused_
,
201 struct timeval
*timeout
,
205 struct timeval
*timeout _unused_
,
209 assert(*need_timeout
== 0); /* we're first to get a shot at this */
212 * Linux's BPF is immediate, so don't select() as it will lead to horrible
213 * performance. Instead, use a timeout for buffering.
217 timeout
->tv_usec
= CAP_TIMEOUT
* 1000; /* msec->usec */
219 /* We have a BSD-like BPF, we can select() on it. */
220 FD_SET(pcap_fd
, read_set
);
221 *max_fd
= MAX(*max_fd
, pcap_fd
);
225 unsigned int cap_pkts_recv
= 0, cap_pkts_drop
= 0;
228 cap_stats_update(void)
232 if (pcap_stats(pcap
, &ps
) != 0) {
233 warnx("pcap_stats(): %s", pcap_geterr(pcap
));
237 cap_pkts_recv
= ps
.ps_recv
;
238 cap_pkts_drop
= ps
.ps_drop
;
242 * Print hexdump of received packet.
245 hexdump(const u_char
*buf
, const uint32_t len
)
249 printf("packet of %u bytes:\n", len
);
250 for (i
=0, col
=0; i
<len
; i
++) {
251 if (col
== 0) printf(" ");
252 printf("%02x", buf
[i
]);
253 if (i
+1 == linkhdr
->hdrlen
)
255 else if (i
+1 == linkhdr
->hdrlen
+ IP_HDR_LEN
)
264 if (col
!= 0) printf("\n");
269 * Callback function for pcap_dispatch() which chains to the decoder specified
273 callback(u_char
*user
, const struct pcap_pkthdr
*h
, const u_char
*bytes
)
275 if (opt_want_hexdump
) hexdump(bytes
, h
->caplen
);
276 linkhdr
->handler(user
, h
, bytes
);
280 * Process any packets currently in the capture buffer.
283 cap_poll(fd_set
*read_set
291 #ifndef linux /* We don't use select() on Linux. */
292 if (!FD_ISSET(pcap_fd
, read_set
)) {
293 verbosef("cap_poll premature");
299 * Once per capture poll, check our IP address. It's used in accounting
300 * for traffic graphs.
302 localip_update(); /* FIXME: this might even be too often */
308 gettimeofday(&t1
, NULL
);
312 -1, /* count, -1 = entire buffer */
317 warnx("pcap_dispatch(): %s", pcap_geterr(pcap
));
326 gettimeofday(&t2
, NULL
);
327 td
= (t2
.tv_sec
- t1
.tv_sec
) * 1000000 + t2
.tv_usec
- t1
.tv_usec
;
328 if (td
> CAP_TIMEOUT
*1000)
329 warnx("pcap_dispatch blocked for %d usec! (expected <= %d usec)\n",
330 td
, CAP_TIMEOUT
*1000);
334 /* Despite count = -1, Linux will only dispatch one packet at a time. */
338 /* keep looping until we've dispatched all the outstanding packets */
341 /* we get them all on the first shot */
354 /* Run through entire capfile. */
356 cap_from_file(const char *capfile
, const char *filter
)
358 char errbuf
[PCAP_ERRBUF_SIZE
];
361 /* Open packet capture descriptor. */
362 errbuf
[0] = '\0'; /* zero length string */
363 pcap
= pcap_open_offline(capfile
, errbuf
);
366 errx(1, "pcap_open_offline(): %s", errbuf
);
368 if (errbuf
[0] != '\0') /* not zero length anymore -> warning */
369 warnx("pcap_open_offline() warning: %s", errbuf
);
371 /* Work out the linktype. */
372 linktype
= pcap_datalink(pcap
);
373 linkhdr
= getlinkhdr(linktype
);
375 errx(1, "unknown linktype %d", linktype
);
376 if (linkhdr
->handler
== NULL
)
377 errx(1, "no handler for linktype %d", linktype
);
378 if (linktype
== DLT_EN10MB
) /* FIXME: impossible with capfile? */
379 hosts_db_show_macs
= 1;
381 /* Set filter expression, if any. */ /* FIXME: factor! */
384 struct bpf_program prog
;
385 char *tmp_filter
= xstrdup(filter
);
393 errx(1, "pcap_compile(): %s", pcap_geterr(pcap
));
395 if (pcap_setfilter(pcap
, &prog
) == -1)
396 errx(1, "pcap_setfilter(): %s", pcap_geterr(pcap
));
398 pcap_freecode(&prog
);
405 -1, /* count, -1 = entire buffer */
410 errx(1, "pcap_dispatch(): %s", pcap_geterr(pcap
));
413 /* vim:set ts=3 sw=3 tw=78 expandtab: */