2 * copyright (c) 2001-2014 Emil Mikulic.
4 * cap.c: capture packets, and hand them off to decode and acct.
6 * You may use, modify and redistribute this file under the terms of the
7 * GNU General Public License version 2. (see COPYING.GPL)
24 #include <sys/ioctl.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
28 #ifdef HAVE_SYS_FILIO_H
29 # include <sys/filio.h> /* Solaris' FIONBIO hides here */
38 char *title_interfaces
= NULL
; /* for html.c */
40 /* The cap process life-cycle:
41 * - cap_add_ifname() one or more times
42 * - cap_add_filter() zero or more times
43 * - cap_start() once to start listening
45 * - cap_fd_set() to update the select() set
46 * - cap_poll() to read from ready pcap fds
52 STAILQ_ENTRY(strnode
) entries
;
57 STAILQ_ENTRY(cap_iface
) entries
;
63 const struct linkhdr
*linkhdr
;
64 struct local_ips local_ips
;
67 static STAILQ_HEAD(cli_ifnames_head
, strnode
) cli_ifnames
=
68 STAILQ_HEAD_INITIALIZER(cli_ifnames
);
70 static STAILQ_HEAD(cli_filters_head
, strnode
) cli_filters
=
71 STAILQ_HEAD_INITIALIZER(cli_filters
);
73 static STAILQ_HEAD(cap_ifs_head
, cap_iface
) cap_ifs
=
74 STAILQ_HEAD_INITIALIZER(cap_ifs
);
76 /* The read timeout passed to pcap_open_live() */
77 #define CAP_TIMEOUT_MSEC 500
79 void cap_add_ifname(const char *ifname
) {
80 struct strnode
*n
= xmalloc(sizeof(*n
));
82 STAILQ_INSERT_TAIL(&cli_ifnames
, n
, entries
);
85 void cap_add_filter(const char *filter
) {
86 struct strnode
*n
= xmalloc(sizeof(*n
));
88 STAILQ_INSERT_TAIL(&cli_filters
, n
, entries
);
91 static void cap_set_filter(pcap_t
*pcap
, const char *filter
) {
92 struct bpf_program prog
;
98 tmp_filter
= xstrdup(filter
);
106 errx(1, "pcap_compile(): %s", pcap_geterr(pcap
));
108 if (pcap_setfilter(pcap
, &prog
) == -1)
109 errx(1, "pcap_setfilter(): %s", pcap_geterr(pcap
));
111 pcap_freecode(&prog
);
115 /* Start capturing on just one interface. Called from cap_start(). */
116 static void cap_start_one(struct cap_iface
*iface
, const int promisc
) {
117 char errbuf
[PCAP_ERRBUF_SIZE
], *tmp_device
;
118 int linktype
, snaplen
, waited
;
120 /* pcap wants a non-const interface name string */
121 tmp_device
= xstrdup(iface
->name
);
123 verbosef("capturing on interface '%s' with filter '%s'",
124 tmp_device
, iface
->filter
);
126 verbosef("capturing on interface '%s' with no filter", tmp_device
);
128 /* Open packet capture descriptor. */
131 errbuf
[0] = '\0'; /* zero length string */
132 iface
->pcap
= pcap_open_live(
134 1, /* snaplen, irrelevant at this point */
135 0, /* promisc, also irrelevant */
138 if (iface
->pcap
!= NULL
)
139 break; /* success! */
141 if ((opt_wait_secs
!= -1) && strstr(errbuf
, "device is not up")) {
142 if ((opt_wait_secs
> 0) && (waited
>= opt_wait_secs
))
143 errx(1, "waited %d secs, giving up: pcap_open_live(): %s",
146 verbosef("waited %d secs, interface is not up", waited
);
150 else errx(1, "pcap_open_live(): %s", errbuf
);
153 /* Work out the linktype and what snaplen we need. */
154 linktype
= pcap_datalink(iface
->pcap
);
155 verbosef("linktype is %d", linktype
);
156 if ((linktype
== DLT_EN10MB
) && opt_want_macs
)
157 hosts_db_show_macs
= 1;
158 iface
->linkhdr
= getlinkhdr(linktype
);
159 if (iface
->linkhdr
== NULL
)
160 errx(1, "unknown linktype %d", linktype
);
161 if (iface
->linkhdr
->decoder
== NULL
)
162 errx(1, "no decoder for linktype %d", linktype
);
163 snaplen
= getsnaplen(iface
->linkhdr
);
164 if (opt_want_pppoe
) {
165 snaplen
+= PPPOE_HDR_LEN
;
166 if (linktype
!= DLT_EN10MB
)
167 errx(1, "can't do PPPoE decoding on a non-Ethernet linktype");
169 verbosef("calculated snaplen minimum %d", snaplen
);
171 /* FIXME: actually due to libpcap moving to mmap (!!!)
172 * work out which version and fix the way we do capture
176 /* Ubuntu 9.04 has a problem where requesting snaplen <= 60 will
177 * give us 42 bytes, and we need at least 54 for TCP headers.
179 * Hack to set minimum snaplen to tcpdump's default:
181 snaplen
= MAX(snaplen
, 96);
183 if (opt_want_snaplen
> -1)
184 snaplen
= opt_want_snaplen
;
185 verbosef("using snaplen %d", snaplen
);
187 /* Close and re-open pcap to use the new snaplen. */
188 pcap_close(iface
->pcap
);
189 errbuf
[0] = '\0'; /* zero length string */
190 iface
->pcap
= pcap_open_live(
197 if (iface
->pcap
== NULL
)
198 errx(1, "pcap_open_live(): %s", errbuf
);
200 if (errbuf
[0] != '\0') /* not zero length anymore -> warning */
201 warnx("pcap_open_live() warning: %s", errbuf
);
206 verbosef("capturing in promiscuous mode");
208 verbosef("capturing in non-promiscuous mode");
210 cap_set_filter(iface
->pcap
, iface
->filter
);
211 iface
->fd
= pcap_fileno(iface
->pcap
);
213 /* set non-blocking */
215 if (pcap_setnonblock(iface
->pcap
, 1, errbuf
) == -1)
216 errx(1, "pcap_setnonblock(): %s", errbuf
);
220 if (ioctl(iface
->fd
, FIONBIO
, &one
) == -1)
221 err(1, "ioctl(iface->fd, FIONBIO)");
227 /* Deny all writes to the socket */
228 struct bpf_insn bpf_wfilter
[] = { BPF_STMT(BPF_RET
+BPF_K
, 0) };
229 int wf_len
= sizeof(bpf_wfilter
) / sizeof(struct bpf_insn
);
230 struct bpf_program pr
;
233 pr
.bf_insns
= bpf_wfilter
;
235 if (ioctl(iface
->fd
, BIOCSETWF
, &pr
) == -1)
236 err(1, "ioctl(iface->fd, BIOCSETFW)");
237 verbosef("filtered out BPF writes");
242 /* set "locked" flag (no reset) */
243 if (ioctl(iface
->fd
, BIOCLOCK
) == -1)
244 err(1, "ioctl(iface->fd, BIOCLOCK)");
245 verbosef("locked down BPF for security");
249 void cap_start(const int promisc
) {
250 struct str
*ifs
= str_make();
252 assert(STAILQ_EMPTY(&cap_ifs
));
253 if (STAILQ_EMPTY(&cli_ifnames
))
254 errx(1, "no interfaces specified");
256 /* For each ifname */
257 while (!STAILQ_EMPTY(&cli_ifnames
)) {
258 struct strnode
*ifname
, *filter
= NULL
;
259 struct cap_iface
*iface
= xmalloc(sizeof(*iface
));
261 ifname
= STAILQ_FIRST(&cli_ifnames
);
262 STAILQ_REMOVE_HEAD(&cli_ifnames
, entries
);
264 if (!STAILQ_EMPTY(&cli_filters
)) {
265 filter
= STAILQ_FIRST(&cli_filters
);
266 STAILQ_REMOVE_HEAD(&cli_filters
, entries
);
269 iface
->name
= ifname
->str
;
270 iface
->filter
= (filter
== NULL
) ? NULL
: filter
->str
;
273 iface
->linkhdr
= NULL
;
274 localip_init(&iface
->local_ips
);
275 STAILQ_INSERT_TAIL(&cap_ifs
, iface
, entries
);
276 cap_start_one(iface
, promisc
);
279 if (filter
) free(filter
);
281 if (str_len(ifs
) == 0)
282 str_append(ifs
, iface
->name
);
284 str_appendf(ifs
, ", %s", iface
->name
);
286 verbosef("all capture interfaces prepared");
288 /* Deallocate extra filters, if any. */
289 while (!STAILQ_EMPTY(&cli_filters
)) {
290 struct strnode
*filter
= STAILQ_FIRST(&cli_filters
);
292 verbosef("ignoring extraneous filter '%s'", filter
->str
);
293 STAILQ_REMOVE_HEAD(&cli_filters
, entries
);
297 str_appendn(ifs
, "", 1); /* NUL terminate */
300 str_extract(ifs
, &_
, &title_interfaces
);
305 # define _unused_on_linux_ _unused_
306 # define _unused_otherwise_
308 # define _unused_on_linux_
309 # define _unused_otherwise_ _unused_
313 * Set pcap_fd in the given fd_set.
315 void cap_fd_set(fd_set
*read_set _unused_on_linux_
,
316 int *max_fd _unused_on_linux_
,
317 struct timeval
*timeout _unused_otherwise_
,
319 assert(*need_timeout
== 0); /* we're first to get a shot at the fd_set */
323 * Linux's BPF is immediate, so don't select() as it will lead to horrible
324 * performance. Instead, use a timeout for buffering.
328 timeout
->tv_usec
= CAP_TIMEOUT_MSEC
* 1000;
331 struct cap_iface
*iface
;
332 STAILQ_FOREACH(iface
, &cap_ifs
, entries
) {
333 /* We have a BSD-like BPF, we can select() on it. */
334 FD_SET(iface
->fd
, read_set
);
335 *max_fd
= MAX(*max_fd
, iface
->fd
);
341 unsigned int cap_pkts_recv
= 0, cap_pkts_drop
= 0;
343 static void cap_stats_update(void) {
344 struct cap_iface
*iface
;
348 STAILQ_FOREACH(iface
, &cap_ifs
, entries
) {
350 if (pcap_stats(iface
->pcap
, &ps
) != 0) {
351 warnx("pcap_stats('%s'): %s", iface
->name
, pcap_geterr(iface
->pcap
));
354 cap_pkts_recv
+= ps
.ps_recv
;
355 cap_pkts_drop
+= ps
.ps_drop
;
359 /* Print hexdump of received packet to stdout, for debugging. */
360 static void hexdump(const u_char
*buf
,
362 const struct linkhdr
*linkhdr
) {
365 printf("packet of %u bytes:\n", len
);
366 for (i
=0, col
=0; i
<len
; i
++) {
367 if (col
== 0) printf(" ");
368 printf("%02x", buf
[i
]);
369 if (i
+1 == linkhdr
->hdrlen
)
370 printf("|"); /* marks end of link headers (e.g. ethernet) */
379 if (col
!= 0) printf("\n");
383 /* Callback function for pcap_dispatch() which chains to the decoder specified
384 * in the linkhdr struct.
386 static void callback(u_char
*user
,
387 const struct pcap_pkthdr
*pheader
,
388 const u_char
*pdata
) {
389 const struct cap_iface
* const iface
= (struct cap_iface
*)user
;
390 struct pktsummary sm
;
392 if (opt_want_hexdump
)
393 hexdump(pdata
, pheader
->caplen
, iface
->linkhdr
);
394 memset(&sm
, 0, sizeof(sm
));
395 if (iface
->linkhdr
->decoder(pheader
, pdata
, &sm
))
396 acct_for(&sm
, &iface
->local_ips
);
399 /* Process any packets currently in the capture buffer.
400 * Returns 0 on error (usually means the interface went down).
402 int cap_poll(fd_set
*read_set _unused_on_linux_
) {
403 struct cap_iface
*iface
;
406 STAILQ_FOREACH(iface
, &cap_ifs
, entries
) {
407 /* Once per capture poll, check our IP address. It's used in accounting
408 * for traffic graphs.
410 localip_update(iface
->name
, &iface
->local_ips
);
411 if (!told
&& iface
->local_ips
.num_addrs
== 0) {
412 verbosef("interface '%s' has no addresses, "
413 "your graphs will be blank",
415 verbosef("please read the darkstat manpage, "
416 "and consider using the -l option");
427 -1, /* count = entire buffer */
429 (u_char
*)iface
); /* user = struct to pass to callback */
431 2 * CAP_TIMEOUT_MSEC
* 1000000,
432 "pcap_dispatch took too long");
435 warnx("pcap_dispatch('%s'): %s",
436 iface
->name
, pcap_geterr(iface
->pcap
));
440 #if 0 /* debugging */
441 verbosef("iface '%s' got %d pkts", iface
->name
, ret
);
445 /* keep looping until we've dispatched all the outstanding packets */
449 /* we get them all on the first shot */
458 void cap_stop(void) {
459 while (!STAILQ_EMPTY(&cap_ifs
)) {
460 struct cap_iface
*iface
= STAILQ_FIRST(&cap_ifs
);
462 STAILQ_REMOVE_HEAD(&cap_ifs
, entries
);
463 pcap_close(iface
->pcap
);
464 localip_free(&iface
->local_ips
);
467 free(title_interfaces
);
468 title_interfaces
= NULL
;
471 /* This is only needed by the DNS child. In the main process, the deallocation
472 * happens in cap_start().
474 void cap_free_args(void) {
475 while (!STAILQ_EMPTY(&cli_ifnames
)) {
476 struct strnode
*ifname
= STAILQ_FIRST(&cli_ifnames
);
477 STAILQ_REMOVE_HEAD(&cli_ifnames
, entries
);
481 while (!STAILQ_EMPTY(&cli_filters
)) {
482 struct strnode
*filter
= STAILQ_FIRST(&cli_filters
);
483 STAILQ_REMOVE_HEAD(&cli_filters
, entries
);
488 /* Run through entire capfile. */
489 void cap_from_file(const char *capfile
) {
490 char errbuf
[PCAP_ERRBUF_SIZE
];
492 struct cap_iface iface
;
498 iface
.linkhdr
= NULL
;
499 localip_init(&iface
.local_ips
);
501 /* Process cmdline filters. */
502 if (!STAILQ_EMPTY(&cli_filters
))
503 iface
.filter
= STAILQ_FIRST(&cli_filters
)->str
;
504 while (!STAILQ_EMPTY(&cli_filters
)) {
505 struct strnode
*n
= STAILQ_FIRST(&cli_filters
);
506 STAILQ_REMOVE_HEAD(&cli_filters
, entries
);
510 /* Open packet capture descriptor. */
511 errbuf
[0] = '\0'; /* zero length string */
512 iface
.pcap
= pcap_open_offline(capfile
, errbuf
);
514 if (iface
.pcap
== NULL
)
515 errx(1, "pcap_open_offline(): %s", errbuf
);
517 if (errbuf
[0] != '\0') /* not zero length anymore -> warning */
518 warnx("pcap_open_offline() warning: %s", errbuf
);
520 /* Work out the linktype. */
521 linktype
= pcap_datalink(iface
.pcap
);
522 iface
.linkhdr
= getlinkhdr(linktype
);
523 if (iface
.linkhdr
== NULL
)
524 errx(1, "unknown linktype %d", linktype
);
525 if (iface
.linkhdr
->decoder
== NULL
)
526 errx(1, "no decoder for linktype %d", linktype
);
528 cap_set_filter(iface
.pcap
, iface
.filter
);
533 -1, /* count, -1 = entire buffer */
535 (u_char
*)&iface
); /* user */
538 errx(1, "pcap_dispatch(): %s", pcap_geterr(iface
.pcap
));
540 localip_free(&iface
.local_ips
);
541 pcap_close(iface
.pcap
);
544 /* vim:set ts=3 sw=3 tw=78 expandtab: */