2 * Routines for packet capture windows
4 * $Id: capture.c,v 1.136 2001/01/13 03:17:15 gram Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@zing.org>
8 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 #ifdef HAVE_SYS_TYPES_H
33 # include <sys/types.h>
36 #ifdef HAVE_SYS_STAT_H
37 # include <sys/stat.h>
40 #ifdef HAVE_SYS_WAIT_H
41 # include <sys/wait.h>
46 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
47 * macros) on UNIX systems that don't have them.
50 # define WIFEXITED(status) (((status) & 0177) == 0)
53 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
56 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
59 # define WEXITSTATUS(status) ((status) >> 8)
62 # define WTERMSIG(status) ((status) & 0177)
65 # define WCOREDUMP(status) ((status) & 0200)
68 # define WSTOPSIG(status) ((status) >> 8)
92 #ifdef HAVE_SYS_SOCKET_H
93 #include <sys/socket.h>
96 #ifdef HAVE_SYS_IOCTL_H
97 #include <sys/ioctl.h>
103 #ifdef NEED_SNPRINTF_H
104 # include "snprintf.h"
112 #include <process.h> /* For spawning child process */
116 * XXX - the various BSDs appear to define BSD in <sys/param.h>; we don't
117 * want to include it if it's not present on this platform, however.
119 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__)
123 #endif /* defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) */
126 * We don't want to do a "select()" on the pcap_t's file descriptor on
127 * BSD (because "select()" doesn't work correctly on BPF devices on at
128 * least some releases of some flavors of BSD), and we don't want to do
129 * it on Windows (because "select()" is something for sockets, not for
130 * arbitrary handles).
132 * We *do* want to do it on other platforms, as, on other platforms (with
133 * the possible exception of Ultrix and Digital UNIX), the read timeout
134 * doesn't expire if no packets have arrived, so a "pcap_dispatch()" call
135 * will block until packets arrive, causing the UI to hang.
137 #if !defined(BSD) && !defined(_WIN32)
138 # define MUST_DO_SELECT
141 #include "gtk/main.h"
142 #include "gtk/gtkglobals.h"
147 #include "simple_dialog.h"
151 #include "wiretap/libpcap.h"
152 #include "wiretap/wtap.h"
154 #include "packet-clip.h"
155 #include "packet-eth.h"
156 #include "packet-fddi.h"
157 #include "packet-null.h"
158 #include "packet-ppp.h"
159 #include "packet-raw.h"
160 #include "packet-sll.h"
161 #include "packet-tr.h"
162 #include "packet-ieee80211.h"
164 int promisc_mode = TRUE; /* capture in promiscuous mode */
165 int sync_mode; /* fork a child to do the capture, and sync between them */
166 static int sync_pipe[2]; /* used to sync father */
167 enum PIPES { READ, WRITE }; /* Constants 0 and 1 for READ and WRITE */
168 int quit_after_cap; /* Makes a "capture only mode". Implies -k */
169 gboolean capture_child; /* if this is the child for "-S" */
170 static int fork_child; /* In parent, process ID of child */
171 static guint cap_input_id;
174 static guint cap_timer_id;
175 static int cap_timer_cb(gpointer); /* Win32 kludge to check for pipe input */
178 static void cap_file_input_cb(gpointer, gint, GdkInputCondition);
179 static void wait_for_child(gboolean);
181 static char *signame(int);
183 static void capture_delete_cb(GtkWidget *, GdkEvent *, gpointer);
184 static void capture_stop_cb(GtkWidget *, gpointer);
185 static void capture_pcap_cb(u_char *, const struct pcap_pkthdr *,
187 static void send_errmsg_to_parent(const char *);
188 static float pct(gint, gint);
189 static void stop_capture(int signo);
191 typedef struct _loop_data {
196 gboolean from_pipe; /* TRUE if we are capturing data from a pipe */
197 gboolean modified; /* TRUE if data in the pipe uses modified pcap headers */
198 gboolean byte_swapped; /* TRUE if data in the pipe is byte swapped */
199 packet_counts counts;
204 static void adjust_header(loop_data *, struct pcap_hdr *, struct pcaprec_hdr *);
205 static int pipe_open_live(char *, struct pcap_hdr *, loop_data *, char *);
206 static int pipe_dispatch(int, loop_data *, struct pcap_hdr *);
209 /* Win32 needs the O_BINARY flag for open() */
215 /* Win32 needs a handle to the child capture process */
219 /* Add a string pointer to a NULL-terminated array of string pointers. */
221 add_arg(char **args, int *argc, char *arg)
223 /* Grow the array; "*argc" currently contains the number of string
224 pointers, *not* counting the NULL pointer at the end, so we have
225 to add 2 in order to get the new size of the array, including the
226 new pointer and the terminating NULL pointer. */
227 args = g_realloc(args, (*argc + 2) * sizeof (char *));
229 /* Stuff the pointer into the penultimate element of the array, which
230 is the one at the index specified by "*argc". */
233 /* Now bump the count. */
236 /* We overwrite the NULL pointer; put it back right after the
244 /* Given a string, return a pointer to a quote-encapsulated version of
245 the string, so we can pass it as an argument with "spawnvp" even
246 if it contains blanks. */
248 quote_encapsulate(const char *string)
250 char *encapsulated_string;
252 encapsulated_string = g_new(char, strlen(string) + 3);
253 sprintf(encapsulated_string, "\"%s\"", string);
254 return encapsulated_string;
258 /* Open a specified file, or create a temporary file, and start a capture
259 to the file in question. */
261 do_capture(char *capfile_name)
264 gboolean is_tempfile;
270 int capture_succeeded;
272 if (capfile_name != NULL) {
273 /* Try to open/create the specified file for use as a capture buffer. */
274 cfile.save_file_fd = open(capfile_name, O_RDWR|O_BINARY|O_TRUNC|O_CREAT, 0600);
277 /* Choose a random name for the capture buffer */
278 cfile.save_file_fd = create_tempfile(tmpname, sizeof tmpname, "ether");
279 capfile_name = g_strdup(tmpname);
282 if (cfile.save_file_fd == -1) {
284 simple_dialog(ESD_TYPE_CRIT, NULL,
285 "The temporary file to which the capture would be saved (\"%s\")"
286 "could not be opened: %s.", capfile_name, strerror(errno));
288 simple_dialog(ESD_TYPE_CRIT, NULL,
289 file_open_error_message(errno, TRUE), capfile_name);
293 close_cap_file(&cfile, info_bar);
294 g_assert(cfile.save_file == NULL);
295 cfile.save_file = capfile_name;
297 if (sync_mode) { /* do the capture in a child process */
299 char scount[24]; /* need a constant for len of numbers */
300 char save_file_fd[24];
306 char sync_pipe_fd[24];
311 /* Allocate the string pointer array with enough space for the
312 terminating NULL pointer. */
314 argv = g_malloc(sizeof (char *));
317 /* Now add those arguments used on all platforms. */
318 argv = add_arg(argv, &argc, CHILD_NAME);
320 argv = add_arg(argv, &argc, "-i");
321 argv = add_arg(argv, &argc, cfile.iface);
323 argv = add_arg(argv, &argc, "-w");
324 argv = add_arg(argv, &argc, cfile.save_file);
326 argv = add_arg(argv, &argc, "-W");
327 sprintf(save_file_fd,"%d",cfile.save_file_fd); /* in lieu of itoa */
328 argv = add_arg(argv, &argc, save_file_fd);
330 argv = add_arg(argv, &argc, "-c");
331 sprintf(scount,"%d",cfile.count);
332 argv = add_arg(argv, &argc, scount);
334 argv = add_arg(argv, &argc, "-s");
335 sprintf(ssnap,"%d",cfile.snap);
336 argv = add_arg(argv, &argc, ssnap);
339 argv = add_arg(argv, &argc, "-p");
342 /* Create a pipe for the child process */
344 if(_pipe(sync_pipe, 512, O_BINARY) < 0) {
345 /* Couldn't create the pipe between parent and child. */
347 unlink(cfile.save_file);
348 g_free(cfile.save_file);
349 cfile.save_file = NULL;
350 simple_dialog(ESD_TYPE_CRIT, NULL, "Couldn't create sync pipe: %s",
355 /* Convert font name to a quote-encapsulated string and pass to child */
356 argv = add_arg(argv, &argc, "-m");
357 fontstring = quote_encapsulate(prefs.gui_font_name);
358 argv = add_arg(argv, &argc, fontstring);
360 /* Convert pipe write handle to a string and pass to child */
361 argv = add_arg(argv, &argc, "-Z");
362 itoa(sync_pipe[WRITE], sync_pipe_fd, 10);
363 argv = add_arg(argv, &argc, sync_pipe_fd);
365 /* Convert filter string to a quote delimited string and pass to child */
366 if (cfile.cfilter != NULL && strlen(cfile.cfilter) != 0) {
367 argv = add_arg(argv, &argc, "-f");
368 filterstring = quote_encapsulate(cfile.cfilter);
369 argv = add_arg(argv, &argc, filterstring);
373 fork_child = spawnvp(_P_NOWAIT, ethereal_path, argv);
375 g_free(filterstring);
376 /* Keep a copy for later evaluation by _cwait() */
377 child_process = fork_child;
379 signal(SIGCHLD, SIG_IGN);
380 if (pipe(sync_pipe) < 0) {
381 /* Couldn't create the pipe between parent and child. */
383 unlink(cfile.save_file);
384 g_free(cfile.save_file);
385 cfile.save_file = NULL;
386 simple_dialog(ESD_TYPE_CRIT, NULL, "Couldn't create sync pipe: %s",
391 argv = add_arg(argv, &argc, "-m");
392 argv = add_arg(argv, &argc, prefs.gui_font_name);
394 if (cfile.cfilter != NULL && strlen(cfile.cfilter) != 0) {
395 argv = add_arg(argv, &argc, "-f");
396 argv = add_arg(argv, &argc, cfile.cfilter);
399 if ((fork_child = fork()) == 0) {
401 * Child process - run Ethereal with the right arguments to make
402 * it just pop up the live capture dialog box and capture with
403 * the specified capture parameters, writing to the specified file.
405 * args: -i interface specification
407 * -W file descriptor to write
408 * -c count to capture
411 * -f "filter expression"
414 dup(sync_pipe[WRITE]);
415 close(sync_pipe[READ]);
416 execvp(ethereal_path, argv);
417 snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
418 ethereal_path, strerror(errno));
419 send_errmsg_to_parent(errmsg);
421 /* Exit with "_exit()", so that we don't close the connection
422 to the X server (and cause stuff buffered up by our parent but
423 not yet sent to be sent, as that stuff should only be sent by
429 /* Parent process - read messages from the child process over the
431 g_free(argv); /* free up arg array */
433 /* Close the write side of the pipe, so that only the child has it
434 open, and thus it completely closes, and thus returns to us
435 an EOF indication, if the child closes it (either deliberately
436 or by exiting abnormally). */
437 close(sync_pipe[WRITE]);
439 /* Close the save file FD, as we won't be using it - we'll be opening
440 it and reading the save file through Wiretap. */
441 close(cfile.save_file_fd);
443 if (fork_child == -1) {
444 /* We couldn't even create the child process. */
446 close(sync_pipe[READ]);
447 unlink(cfile.save_file);
448 g_free(cfile.save_file);
449 cfile.save_file = NULL;
450 simple_dialog(ESD_TYPE_CRIT, NULL, "Couldn't create child process: %s",
455 /* Read a byte count from "sync_pipe[READ]", terminated with a
456 colon; if the count is 0, the child process created the
457 capture file and we should start reading from it, otherwise
458 the capture couldn't start and the count is a count of bytes
459 of error message, and we should display the message. */
462 i = read(sync_pipe[READ], &c, 1);
464 /* EOF - the child process died.
465 Close the read side of the sync pipe, remove the capture file,
466 and report the failure. */
467 close(sync_pipe[READ]);
468 unlink(cfile.save_file);
469 g_free(cfile.save_file);
470 cfile.save_file = NULL;
471 wait_for_child(TRUE);
477 /* Child process handed us crap.
478 Close the read side of the sync pipe, remove the capture file,
479 and report the failure. */
480 close(sync_pipe[READ]);
481 unlink(cfile.save_file);
482 g_free(cfile.save_file);
483 cfile.save_file = NULL;
484 simple_dialog(ESD_TYPE_WARN, NULL,
485 "Capture child process sent us a bad message");
488 byte_count = byte_count*10 + c - '0';
490 if (byte_count == 0) {
491 /* Success. Open the capture file, and set up to read it. */
492 err = start_tail_cap_file(cfile.save_file, is_tempfile, &cfile);
494 /* We were able to open and set up to read the capture file;
495 arrange that our callback be called whenever it's possible
496 to read from the sync pipe, so that it's called when
497 the child process wants to tell us something. */
499 /* Tricky to use pipes in win9x, as no concept of wait. NT can
500 do this but that doesn't cover all win32 platforms. GTK can do
501 this but doesn't seem to work over processes. Attempt to do
502 something similar here, start a timer and check for data on every
504 cap_timer_id = gtk_timeout_add(1000, cap_timer_cb, NULL);
506 cap_input_id = gtk_input_add_full(sync_pipe[READ],
507 GDK_INPUT_READ|GDK_INPUT_EXCEPTION,
514 /* We weren't able to open the capture file; complain, and
515 close the sync pipe. */
516 simple_dialog(ESD_TYPE_CRIT, NULL,
517 file_open_error_message(err, FALSE), cfile.save_file);
519 /* Close the sync pipe. */
520 close(sync_pipe[READ]);
522 /* Don't unlink the save file - leave it around, for debugging
524 g_free(cfile.save_file);
525 cfile.save_file = NULL;
528 /* Failure - the child process sent us a message indicating
529 what the problem was. */
530 msg = g_malloc(byte_count + 1);
532 simple_dialog(ESD_TYPE_WARN, NULL,
533 "Capture child process failed, but its error message was too big.");
535 i = read(sync_pipe[READ], msg, byte_count);
537 simple_dialog(ESD_TYPE_WARN, NULL,
538 "Capture child process failed: Error %s reading its error message.",
541 simple_dialog(ESD_TYPE_WARN, NULL,
542 "Capture child process failed: EOF reading its error message.");
543 wait_for_child(FALSE);
545 simple_dialog(ESD_TYPE_WARN, NULL, msg);
548 /* Close the sync pipe. */
549 close(sync_pipe[READ]);
551 /* Get rid of the save file - the capture never started. */
552 unlink(cfile.save_file);
553 g_free(cfile.save_file);
554 cfile.save_file = NULL;
559 capture_succeeded = capture();
560 if (quit_after_cap) {
561 /* DON'T unlink the save file. Presumably someone wants it. */
564 if (capture_succeeded) {
565 /* Capture succeeded; read in the capture file. */
566 if ((err = open_cap_file(cfile.save_file, is_tempfile, &cfile)) == 0) {
567 /* Set the read filter to NULL. */
569 switch (read_cap_file(&cfile, &err)) {
573 /* Just because we got an error, that doesn't mean we were unable
574 to read any of the file; we handle what we could get from the
579 /* Exit by leaving the main loop, so that any quit functions
580 we registered get called. */
586 /* We're not doing a capture any more, so we don't have a save
588 g_free(cfile.save_file);
589 cfile.save_file = NULL;
594 /* The timer has expired, see if there's stuff to read from the pipe,
595 if so call the cap_file_input_cb */
597 cap_timer_cb(gpointer data)
601 gboolean result, result1;
604 /* Oddly enough although Named pipes don't work on win9x,
605 PeekNamedPipe does !!! */
606 handle = (HANDLE) _get_osfhandle (sync_pipe[READ]);
607 result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
609 /* Get the child process exit status */
610 result1 = GetExitCodeProcess((HANDLE)child_process, &childstatus);
612 /* If the Peek returned an error, or there are bytes to be read
613 or the childwatcher thread has terminated then call the normal
615 if (!result || avail > 0 || childstatus != STILL_ACTIVE) {
617 /* avoid reentrancy problems and stack overflow */
618 gtk_timeout_remove(cap_timer_id);
620 /* And call the real handler */
621 cap_file_input_cb((gpointer) &cfile, 0, 0);
623 /* Return false so that the timer is not run again */
627 /* No data so let timer run again */
633 /* There's stuff to read from the sync pipe, meaning the child has sent
634 us a message, or the sync pipe has closed, meaning the child has
635 closed it (perhaps because it exited). */
637 cap_file_input_cb(gpointer data, gint source, GdkInputCondition condition)
639 capture_file *cf = (capture_file *)data;
640 char buffer[256+1], *p = buffer, *q = buffer;
643 gboolean exit_loop = FALSE;
647 /* avoid reentrancy problems and stack overflow */
648 gtk_input_remove(cap_input_id);
651 if ((nread = read(sync_pipe[READ], buffer, 256)) <= 0) {
652 /* The child has closed the sync pipe, meaning it's not going to be
653 capturing any more packets. Pick up its exit status, and
654 complain if it did anything other than exit with status 0. */
655 wait_for_child(FALSE);
657 /* Read what remains of the capture file, and finish the capture.
658 XXX - do something if this fails? */
659 switch (finish_tail_cap_file(cf, &err)) {
663 /* Just because we got an error, that doesn't mean we were unable
664 to read any of the file; we handle what we could get from the
669 /* Exit by leaving the main loop, so that any quit functions
670 we registered get called. */
675 /* We're not doing a capture any more, so we don't have a save
677 g_free(cf->save_file);
678 cf->save_file = NULL;
683 buffer[nread] = '\0';
686 /* look for (possibly multiple) '*' */
694 /* XXX should handle the case of a pipe full (i.e. no star found) */
703 /* Read from the capture file the number of records the child told us
705 XXX - do something if this fails? */
706 switch (continue_tail_cap_file(cf, to_read, &err)) {
710 /* Just because we got an error, that doesn't mean we were unable
711 to read any of the file; we handle what we could get from the
714 XXX - abort on a read error? */
718 /* Kill the child capture process; the user wants to exit, and we
719 shouldn't just leave it running. */
723 kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
728 /* restore pipe handler */
730 cap_timer_id = gtk_timeout_add(1000, cap_timer_cb, NULL);
732 cap_input_id = gtk_input_add_full (sync_pipe[READ],
733 GDK_INPUT_READ|GDK_INPUT_EXCEPTION,
742 wait_for_child(gboolean always_report)
747 /* XXX - analyze the wait stuatus and display more information
748 in the dialog box? */
749 if (_cwait(&wstatus, child_process, _WAIT_CHILD) == -1) {
750 simple_dialog(ESD_TYPE_WARN, NULL, "Child capture process stopped unexpectedly");
753 if (wait(&wstatus) != -1) {
754 if (WIFEXITED(wstatus)) {
755 /* The child exited; display its exit status, if it's not zero,
756 and even if it's zero if "always_report" is true. */
757 if (always_report || WEXITSTATUS(wstatus) != 0) {
758 simple_dialog(ESD_TYPE_WARN, NULL,
759 "Child capture process exited: exit status %d",
760 WEXITSTATUS(wstatus));
762 } else if (WIFSTOPPED(wstatus)) {
763 /* It stopped, rather than exiting. "Should not happen." */
764 simple_dialog(ESD_TYPE_WARN, NULL,
765 "Child capture process stopped: %s",
766 signame(WSTOPSIG(wstatus)));
767 } else if (WIFSIGNALED(wstatus)) {
768 /* It died with a signal. */
769 simple_dialog(ESD_TYPE_WARN, NULL,
770 "Child capture process died: %s%s",
771 signame(WTERMSIG(wstatus)),
772 WCOREDUMP(wstatus) ? " - core dumped" : "");
774 /* What? It had to either have exited, or stopped, or died with
775 a signal; what happened here? */
776 simple_dialog(ESD_TYPE_WARN, NULL,
777 "Child capture process died: wait status %#o", wstatus);
788 static char sigmsg_buf[6+1+3+1];
797 sigmsg = "Interrupted";
805 sigmsg = "Illegal instruction";
809 sigmsg = "Trace trap";
817 sigmsg = "Arithmetic exception";
825 sigmsg = "Bus error";
829 sigmsg = "Segmentation violation";
832 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
833 Linux is POSIX compliant. These are not POSIX-defined signals ---
834 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
836 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
837 were omitted from POSIX.1 because their behavior is
838 implementation dependent and could not be adequately catego-
839 rized. Conforming implementations may deliver these sig-
840 nals, but must document the circumstances under which they
841 are delivered and note any restrictions concerning their
844 So we only check for SIGSYS on those systems that happen to
845 implement them (a system can be POSIX-compliant and implement
846 them, it's just that POSIX doesn't *require* a POSIX-compliant
847 system to implement them).
852 sigmsg = "Bad system call";
857 sigmsg = "Broken pipe";
861 sigmsg = "Alarm clock";
865 sigmsg = "Terminated";
869 sprintf(sigmsg_buf, "Signal %d", sig);
878 * Timeout, in milliseconds, for reads from the stream of captured packets.
880 #define CAP_READ_TIMEOUT 250
883 /* Take carre of byte order in the libpcap headers read from pipes.
884 * (function taken from wiretap/libpcap.c) */
886 adjust_header(loop_data *ld, struct pcap_hdr *hdr, struct pcaprec_hdr *rechdr)
888 if (ld->byte_swapped) {
889 /* Byte-swap the record header fields. */
890 rechdr->ts_sec = BSWAP32(rechdr->ts_sec);
891 rechdr->ts_usec = BSWAP32(rechdr->ts_usec);
892 rechdr->incl_len = BSWAP32(rechdr->incl_len);
893 rechdr->orig_len = BSWAP32(rechdr->orig_len);
896 /* In file format version 2.3, the "incl_len" and "orig_len" fields were
897 swapped, in order to match the BPF header layout.
899 Unfortunately, some files were, according to a comment in the "libpcap"
900 source, written with version 2.3 in their headers but without the
901 interchanged fields, so if "incl_len" is greater than "orig_len" - which
902 would make no sense - we assume that we need to swap them. */
903 if (hdr->version_major == 2 &&
904 (hdr->version_minor < 3 ||
905 (hdr->version_minor == 3 && rechdr->incl_len > rechdr->orig_len))) {
908 temp = rechdr->orig_len;
909 rechdr->orig_len = rechdr->incl_len;
910 rechdr->incl_len = temp;
914 /* Mimic pcap_open_live() for pipe captures
915 * We check if "pipename" is "-" (stdin) or a FIFO, open it, and read the
917 * N.B. : we can't read the libpcap formats used in RedHat 6.1 or SuSE 6.3
918 * because we can't seek on pipes (see wiretap/libpcap.c for details) */
920 pipe_open_live(char *pipename, struct pcap_hdr *hdr, loop_data *ld, char *ebuf)
922 struct stat pipe_stat;
927 if (strcmp(pipename, "-") == 0) fd = 0; /* read from stdin */
928 else if (stat(pipename, &pipe_stat) == 0 && S_ISFIFO(pipe_stat.st_mode)) {
929 if ((fd = open(pipename, O_RDONLY)) == -1) return -1;
932 ld->from_pipe = TRUE;
933 /* read the pcap header */
934 if (read(fd, &magic, sizeof magic) != sizeof magic) {
941 /* Host that wrote it has our byte order, and was running
942 a program using either standard or ss990417 libpcap. */
943 ld->byte_swapped = FALSE;
944 ld->modified = FALSE;
946 case PCAP_MODIFIED_MAGIC:
947 /* Host that wrote it has our byte order, but was running
948 a program using either ss990915 or ss991029 libpcap. */
949 ld->byte_swapped = FALSE;
952 case PCAP_SWAPPED_MAGIC:
953 /* Host that wrote it has a byte order opposite to ours,
954 and was running a program using either standard or
956 ld->byte_swapped = TRUE;
957 ld->modified = FALSE;
959 case PCAP_SWAPPED_MODIFIED_MAGIC:
960 /* Host that wrote it out has a byte order opposite to
961 ours, and was running a program using either ss990915
962 or ss991029 libpcap. */
963 ld->byte_swapped = TRUE;
967 /* Not a "libpcap" type we know about. */
972 /* Read the rest of the header */
973 bytes_read = read(fd, hdr, sizeof(struct pcap_hdr));
974 if (bytes_read <= 0) {
978 while (bytes_read < sizeof(struct pcap_hdr))
980 b = read(fd, ((char *)&hdr)+bytes_read, sizeof(struct pcap_hdr) - bytes_read);
987 if (ld->byte_swapped) {
988 /* Byte-swap the header fields about which we care. */
989 hdr->version_major = BSWAP16(hdr->version_major);
990 hdr->version_minor = BSWAP16(hdr->version_minor);
991 hdr->snaplen = BSWAP32(hdr->snaplen);
992 hdr->network = BSWAP32(hdr->network);
994 if (hdr->version_major < 2) {
1002 /* We read one record from the pipe, take care of byte order in the record
1003 * header, write the record in the capture file, and update capture statistics. */
1005 pipe_dispatch(int fd, loop_data *ld, struct pcap_hdr *hdr)
1007 struct wtap_pkthdr whdr;
1008 struct pcaprec_modified_hdr rechdr;
1009 int bytes_to_read, bytes_read, b;
1010 u_char pd[WTAP_MAX_PACKET_SIZE];
1013 /* read the record header */
1014 bytes_to_read = ld->modified ? sizeof rechdr : sizeof rechdr.hdr;
1015 bytes_read = read(fd, &rechdr, bytes_to_read);
1016 if (bytes_read <= 0) {
1021 while (bytes_read < bytes_to_read)
1023 b = read(fd, ((char *)&rechdr)+bytes_read, bytes_to_read - bytes_read);
1031 /* take care of byte order */
1032 adjust_header(ld, hdr, &rechdr.hdr);
1033 if (rechdr.hdr.incl_len > WTAP_MAX_PACKET_SIZE) {
1038 /* read the packet data */
1039 bytes_read = read(fd, pd, rechdr.hdr.incl_len);
1040 if (bytes_read <= 0) {
1045 while (bytes_read < rechdr.hdr.incl_len)
1047 b = read(fd, pd+bytes_read, rechdr.hdr.incl_len - bytes_read);
1055 /* dump the packet data to the capture file */
1056 whdr.ts.tv_sec = rechdr.hdr.ts_sec;
1057 whdr.ts.tv_usec = rechdr.hdr.ts_usec;
1058 whdr.caplen = rechdr.hdr.incl_len;
1059 whdr.len = rechdr.hdr.orig_len;
1060 whdr.pkt_encap = ld->linktype;
1061 wtap_dump(ld->pdh, &whdr, NULL, pd, &err);
1063 /* Set the initial payload to the packet length, and the initial
1064 captured payload to the capture length (other protocols may
1065 reduce them if their headers say they're less). */
1067 pi.captured_len = whdr.caplen;
1069 /* update capture statistics */
1070 switch (ld->linktype) {
1071 case WTAP_ENCAP_ETHERNET:
1072 capture_eth(pd, 0, &ld->counts);
1074 case WTAP_ENCAP_FDDI:
1075 case WTAP_ENCAP_FDDI_BITSWAPPED:
1076 capture_fddi(pd, &ld->counts);
1078 case WTAP_ENCAP_TOKEN_RING:
1079 capture_tr(pd, 0, &ld->counts);
1081 case WTAP_ENCAP_NULL:
1082 capture_null(pd, &ld->counts);
1084 case WTAP_ENCAP_PPP:
1085 capture_ppp(pd, 0, &ld->counts);
1087 case WTAP_ENCAP_RAW_IP:
1088 capture_raw(pd, &ld->counts);
1090 case WTAP_ENCAP_LINUX_ATM_CLIP:
1091 capture_clip(pd, &ld->counts);
1093 case WTAP_ENCAP_IEEE_802_11:
1094 capture_ieee80211(pd,0,&ld->counts);
1096 /* XXX - FreeBSD may append 4-byte ATM pseudo-header to DLT_ATM_RFC1483,
1097 with LLC header following; we should implement it at some
1106 * This needs to be static, so that the SIGUSR1 handler can clear the "go"
1109 static loop_data ld;
1111 /* Do the low-level work of a capture.
1112 Returns TRUE if it succeeds, FALSE otherwise. */
1116 GtkWidget *cap_w, *main_vb, *stop_bt, *counts_tb;
1120 gchar err_str[PCAP_ERRBUF_SIZE], label_str[64];
1121 bpf_u_int32 netnum, netmask;
1122 time_t upd_time, cur_time;
1124 char errmsg[4096+1];
1126 static const char ppamsg[] = "can't find PPA for ";
1130 struct timeval timeout;
1131 #ifdef MUST_DO_SELECT
1135 WORD wVersionRequested;
1140 struct pcap_hdr hdr;
1145 GtkWidget *label, *value, *percent;
1147 { "Total", &ld.counts.total },
1148 { "SCTP", &ld.counts.sctp },
1149 { "TCP", &ld.counts.tcp },
1150 { "UDP", &ld.counts.udp },
1151 { "ICMP", &ld.counts.icmp },
1152 { "OSPF", &ld.counts.ospf },
1153 { "GRE", &ld.counts.gre },
1154 { "NetBIOS", &ld.counts.netbios },
1155 { "IPX", &ld.counts.ipx },
1156 { "VINES", &ld.counts.vines },
1157 { "Other", &ld.counts.other }
1160 #define N_STATS (sizeof stats / sizeof stats[0])
1162 /* Initialize Windows Socket if we are in a WIN32 OS
1163 This needs to be done before querying the interface for network/netmask */
1165 wVersionRequested = MAKEWORD( 1, 1 );
1166 err = WSAStartup( wVersionRequested, &wsaData );
1168 snprintf(errmsg, sizeof errmsg,
1169 "Couldn't initialize Windows Sockets.");
1176 ld.counts.total = 0;
1177 ld.max = cfile.count;
1178 ld.linktype = WTAP_ENCAP_UNKNOWN;
1179 ld.from_pipe = FALSE;
1180 ld.sync_packets = 0;
1188 ld.counts.netbios = 0;
1189 ld.counts.vines = 0;
1190 ld.counts.other = 0;
1193 /* Open the network interface to capture from it. */
1194 pch = pcap_open_live(cfile.iface, cfile.snap, promisc_mode,
1195 CAP_READ_TIMEOUT, err_str);
1199 /* Well, we couldn't start the capture.
1200 If this is a child process that does the capturing in sync
1201 mode or fork mode, it shouldn't do any UI stuff until we pop up the
1202 capture-progress window, and, since we couldn't start the
1203 capture, we haven't popped it up. */
1204 if (!capture_child) {
1205 while (gtk_events_pending()) gtk_main_iteration();
1208 /* On Win32 OSes, the capture devices are probably available to all
1209 users; don't warn about permissions problems.
1211 Do, however, warn that Token Ring and PPP devices aren't supported. */
1212 snprintf(errmsg, sizeof errmsg,
1213 "The capture session could not be initiated (%s).\n"
1214 "Please check that you have the proper interface specified.\n"
1216 "Note that the driver Ethereal uses for packet capture on Windows\n"
1217 "doesn't support capturing on Token Ring interfaces, and doesn't\n"
1218 "support capturing on PPP/WAN interfaces in Windows NT/2000.\n",
1222 /* try to open cfile.iface as a pipe */
1223 pipe_fd = pipe_open_live(cfile.iface, &hdr, &ld, err_str);
1225 if (pipe_fd == -1) {
1226 /* Well, we couldn't start the capture.
1227 If this is a child process that does the capturing in sync
1228 mode or fork mode, it shouldn't do any UI stuff until we pop up the
1229 capture-progress window, and, since we couldn't start the
1230 capture, we haven't popped it up. */
1231 if (!capture_child) {
1232 while (gtk_events_pending()) gtk_main_iteration();
1235 /* If we got a "can't find PPA for XXX" message, warn the user (who
1236 is running Ethereal on HP-UX) that they don't have a version
1237 of libpcap patched to properly handle HP-UX (the patched version
1238 says "can't find /dev/dlpi PPA for XXX" rather than "can't find
1240 if (strncmp(err_str, ppamsg, sizeof ppamsg - 1) == 0)
1243 "You are running Ethereal with a version of the libpcap library\n"
1244 "that doesn't handle HP-UX network devices well; this means that\n"
1245 "Ethereal may not be able to capture packets.\n"
1247 "To fix this, you will need to download the source to Ethereal\n"
1248 "from www.ethereal.com if you have not already done so, read\n"
1249 "the instructions in the \"README.hpux\" file in the source\n"
1250 "distribution, download the source to libpcap if you have not\n"
1251 "already done so, patch libpcap as per the instructions, rebuild\n"
1252 "and install libpcap, and then build Ethereal (if you have already\n"
1253 "built Ethereal from source, do a \"make distclean\" and re-run\n"
1254 "configure before building).";
1257 snprintf(errmsg, sizeof errmsg,
1258 "The capture session could not be initiated (%s).\n"
1259 "Please check to make sure you have sufficient permissions, and that\n"
1260 "you have the proper interface or pipe specified.%s", err_str,
1267 /* capture filters only work on real interfaces */
1268 if (cfile.cfilter && !ld.from_pipe) {
1269 /* A capture filter was specified; set it up. */
1270 if (pcap_lookupnet (cfile.iface, &netnum, &netmask, err_str) < 0) {
1272 * Well, we can't get the netmask for this interface; it's used
1273 * only for filters that check for broadcast IP addresses, so
1274 * we just punt and use 0. It might be nice to warn the user,
1275 * but that's a pain in a GUI application, as it'd involve popping
1276 * up a message box, and it's not clear how often this would make
1277 * a difference (only filters that check for IP broadcast addresses
1282 if (pcap_compile(pch, &cfile.fcode, cfile.cfilter, 1, netmask) < 0) {
1283 snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
1287 if (pcap_setfilter(pch, &cfile.fcode) < 0) {
1288 snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
1294 /* Set up to write to the capture file. */
1297 pcap_encap = hdr.network;
1298 snaplen = hdr.snaplen;
1302 pcap_encap = pcap_datalink(pch);
1303 snaplen = pcap_snapshot(pch);
1305 ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_encap);
1306 if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
1307 snprintf(errmsg, sizeof errmsg,
1308 "The network you're capturing from is of a type"
1309 " that Ethereal doesn't support (data link type %d).", pcap_encap);
1312 ld.pdh = wtap_dump_fdopen(cfile.save_file_fd, WTAP_FILE_PCAP,
1313 ld.linktype, snaplen, &err);
1315 if (ld.pdh == NULL) {
1316 /* We couldn't set up to write to the capture file. */
1319 case WTAP_ERR_CANT_OPEN:
1320 strcpy(errmsg, "The file to which the capture would be saved"
1321 " couldn't be created for some unknown reason.");
1324 case WTAP_ERR_SHORT_WRITE:
1325 strcpy(errmsg, "A full header couldn't be written to the file"
1326 " to which the capture would be saved.");
1331 snprintf(errmsg, sizeof(errmsg),
1332 "The file to which the capture would be"
1333 " saved (\"%s\") could not be opened: Error %d.",
1334 cfile.save_file, err);
1336 snprintf(errmsg, sizeof(errmsg),
1337 "The file to which the capture would be"
1338 " saved (\"%s\") could not be opened: %s.",
1339 cfile.save_file, strerror(err));
1346 /* XXX - capture SIGTERM and close the capture, in case we're on a
1347 Linux 2.0[.x] system and you have to explicitly close the capture
1348 stream in order to turn promiscuous mode off? We need to do that
1349 in other places as well - and I don't think that works all the
1350 time in any case, due to libpcap bugs. */
1352 if (capture_child) {
1353 /* Well, we should be able to start capturing.
1355 This is the child process for a sync mode capture, so sync out
1356 the capture file, so the header makes it to the file system,
1357 and send a "capture started successfully and capture file created"
1358 message to our parent so that they'll open the capture file and
1359 update its windows to indicate that we have a live capture in
1361 fflush(wtap_dump_file(ld.pdh));
1365 cap_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1366 gtk_window_set_title(GTK_WINDOW(cap_w), "Ethereal: Capture");
1367 gtk_window_set_modal(GTK_WINDOW(cap_w), TRUE);
1369 /* Container for capture display widgets */
1370 main_vb = gtk_vbox_new(FALSE, 1);
1371 gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
1372 gtk_container_add(GTK_CONTAINER(cap_w), main_vb);
1373 gtk_widget_show(main_vb);
1375 /* Individual statistic elements */
1376 counts_tb = gtk_table_new(N_STATS, 3, TRUE);
1377 gtk_box_pack_start(GTK_BOX(main_vb), counts_tb, TRUE, TRUE, 3);
1378 gtk_widget_show(counts_tb);
1380 for (i = 0; i < N_STATS; i++) {
1381 stats[i].label = gtk_label_new(stats[i].title);
1382 gtk_misc_set_alignment(GTK_MISC(stats[i].label), 0.0f, 0.0f);
1384 stats[i].value = gtk_label_new("0");
1385 gtk_misc_set_alignment(GTK_MISC(stats[i].value), 0.0f, 0.0f);
1387 stats[i].percent = gtk_label_new("0.0%");
1388 gtk_misc_set_alignment(GTK_MISC(stats[i].percent), 0.0f, 0.0f);
1390 gtk_table_attach_defaults(GTK_TABLE(counts_tb),
1391 stats[i].label, 0, 1, i, i + 1);
1393 gtk_table_attach(GTK_TABLE(counts_tb),
1395 1, 2, i, i + 1, 0, 0, 5, 0);
1397 gtk_table_attach_defaults(GTK_TABLE(counts_tb),
1398 stats[i].percent, 2, 3, i, i + 1);
1400 gtk_widget_show(stats[i].label);
1401 gtk_widget_show(stats[i].value);
1402 gtk_widget_show(stats[i].percent);
1405 /* allow user to either click a stop button, or the close button on
1406 the window to stop a capture in progress. */
1407 stop_bt = gtk_button_new_with_label ("Stop");
1408 gtk_signal_connect(GTK_OBJECT(stop_bt), "clicked",
1409 GTK_SIGNAL_FUNC(capture_stop_cb), (gpointer) &ld);
1410 gtk_signal_connect(GTK_OBJECT(cap_w), "delete_event",
1411 GTK_SIGNAL_FUNC(capture_delete_cb), (gpointer) &ld);
1412 gtk_box_pack_end(GTK_BOX(main_vb), stop_bt, FALSE, FALSE, 3);
1413 GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
1414 gtk_widget_grab_default(stop_bt);
1415 GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
1416 gtk_widget_grab_default(stop_bt);
1417 gtk_widget_show(stop_bt);
1419 gtk_widget_show(cap_w);
1421 upd_time = time(NULL);
1422 #ifdef MUST_DO_SELECT
1423 if (!ld.from_pipe) pcap_fd = pcap_fileno(pch);
1428 * Catch SIGUSR1, so that we exit cleanly if the parent process
1429 * kills us with it due to the user selecting "Capture->Stop".
1431 signal(SIGUSR1, stop_capture);
1434 while (gtk_events_pending()) gtk_main_iteration();
1439 FD_SET(pipe_fd, &set1);
1441 timeout.tv_usec = CAP_READ_TIMEOUT*1000;
1442 if (select(pipe_fd+1, &set1, NULL, NULL, &timeout) != 0) {
1444 * "select()" says we can read from the pipe without blocking; go for
1445 * it. We are not sure we can read a whole record, but at least the
1446 * begninning of one. pipe_dispatch() will block reading the whole
1449 inpkts = pipe_dispatch(pipe_fd, &ld, &hdr);
1456 #ifdef MUST_DO_SELECT
1458 * Sigh. The semantics of the read timeout argument to
1459 * "pcap_open_live()" aren't particularly well specified by
1460 * the "pcap" man page - at least with the BSD BPF code, the
1461 * intent appears to be, at least in part, a way of cutting
1462 * down the number of reads done on a capture, by blocking
1463 * until the buffer fills or a timer expires - and the Linux
1464 * libpcap doesn't actually support it, so we can't use it
1465 * to break out of the "pcap_dispatch()" every 1/4 of a second
1466 * or so. Linux's libpcap is not the only libpcap that doesn't
1467 * support the read timeout.
1469 * Furthermore, at least on Solaris, the bufmod STREAMS module's
1470 * read timeout won't go off if no data has arrived, i.e. it cannot
1471 * be used to guarantee that a read from a DLPI stream will return
1472 * within a specified amount of time regardless of whether any
1473 * data arrives or not.
1475 * Thus, on all platforms other than BSD, we do a "select()" on the
1476 * file descriptor for the capture, with a timeout of CAP_READ_TIMEOUT
1477 * milliseconds, or CAP_READ_TIMEOUT*1000 microseconds.
1479 * "select()", on BPF devices, doesn't work as you might expect;
1480 * at least on some versions of some flavors of BSD, the timer
1481 * doesn't start until a read is done, so it won't expire if
1482 * only a "select()" or "poll()" is posted.
1485 FD_SET(pcap_fd, &set1);
1487 timeout.tv_usec = CAP_READ_TIMEOUT*1000;
1488 if (select(pcap_fd+1, &set1, NULL, NULL, &timeout) != 0) {
1490 * "select()" says we can read from it without blocking; go for
1493 inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
1497 inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
1501 ld.sync_packets += inpkts;
1502 /* Only update once a second so as not to overload slow displays */
1503 cur_time = time(NULL);
1504 if (cur_time > upd_time) {
1505 upd_time = cur_time;
1507 for (i = 0; i < N_STATS; i++) {
1508 snprintf(label_str, sizeof(label_str), "%d",
1509 *stats[i].value_ptr);
1511 gtk_label_set(GTK_LABEL(stats[i].value), label_str);
1513 snprintf(label_str, sizeof(label_str), "(%.1f%%)",
1514 pct(*stats[i].value_ptr, ld.counts.total));
1516 gtk_label_set(GTK_LABEL(stats[i].percent), label_str);
1519 /* do sync here, too */
1520 fflush(wtap_dump_file(ld.pdh));
1521 if (capture_child && ld.sync_packets) {
1522 /* This is the child process for a sync mode capture, so send
1523 our parent a message saying we've written out "ld.sync_packets"
1524 packets to the capture file. */
1526 sprintf(tmp, "%d*", ld.sync_packets);
1527 write(1, tmp, strlen(tmp));
1528 ld.sync_packets = 0;
1533 if (!wtap_dump_close(ld.pdh, &err)) {
1534 /* XXX - in fork mode, this may not pop up, or, if it does,
1535 it may disappear as soon as we exit.
1537 We should have the parent process, while it's reading
1538 the packet count update messages, catch error messages
1539 and pop up a message box if it sees one. */
1542 case WTAP_ERR_CANT_CLOSE:
1543 simple_dialog(ESD_TYPE_WARN, NULL,
1544 "The file to which the capture was being saved"
1545 " couldn't be closed for some unknown reason.");
1548 case WTAP_ERR_SHORT_WRITE:
1549 simple_dialog(ESD_TYPE_WARN, NULL,
1550 "Not all the data could be written to the file"
1551 " to which the capture was being saved.");
1555 simple_dialog(ESD_TYPE_WARN, NULL,
1556 "The file to which the capture was being"
1557 " saved (\"%s\") could not be closed: %s.",
1558 cfile.save_file, wtap_strerror(err));
1570 /* Shut down windows sockets */
1574 gtk_grab_remove(GTK_WIDGET(cap_w));
1575 gtk_widget_destroy(GTK_WIDGET(cap_w));
1580 /* We can't use the save file, and we have no wtap_dump stream
1581 to close in order to close it, so close the FD directly. */
1582 close(cfile.save_file_fd);
1584 /* We couldn't even start the capture, so get rid of the capture
1586 unlink(cfile.save_file); /* silently ignore error */
1587 g_free(cfile.save_file);
1588 cfile.save_file = NULL;
1589 if (capture_child) {
1590 /* This is the child process for a sync mode capture.
1591 Send the error message to our parent, so they can display a
1592 dialog box containing it. */
1593 send_errmsg_to_parent(errmsg);
1595 /* Display the dialog box ourselves; there's no parent. */
1596 simple_dialog(ESD_TYPE_CRIT, NULL, errmsg);
1598 if (pch != NULL && !ld.from_pipe)
1605 send_errmsg_to_parent(const char *errmsg)
1607 int msglen = strlen(errmsg);
1608 char lenbuf[10+1+1];
1610 sprintf(lenbuf, "%u;", msglen);
1611 write(1, lenbuf, strlen(lenbuf));
1612 write(1, errmsg, msglen);
1616 pct(gint num, gint denom) {
1618 return (float) num * 100.0 / (float) denom;
1625 stop_capture(int signo)
1631 capture_delete_cb(GtkWidget *w, GdkEvent *event, gpointer data) {
1632 capture_stop_cb(NULL, data);
1636 capture_stop_cb(GtkWidget *w, gpointer data) {
1637 loop_data *ld = (loop_data *) data;
1646 * XXX - find some way of signaling the child in Win32.
1649 if (fork_child != -1)
1650 kill(fork_child, SIGUSR1);
1655 capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
1657 struct wtap_pkthdr whdr;
1658 loop_data *ld = (loop_data *) user;
1661 if ((++ld->counts.total >= ld->max) && (ld->max > 0))
1666 /* "phdr->ts" may not necessarily be a "struct timeval" - it may
1667 be a "struct bpf_timeval", with member sizes wired to 32
1668 bits - and we may go that way ourselves in the future, so
1669 copy the members individually. */
1670 whdr.ts.tv_sec = phdr->ts.tv_sec;
1671 whdr.ts.tv_usec = phdr->ts.tv_usec;
1672 whdr.caplen = phdr->caplen;
1673 whdr.len = phdr->len;
1674 whdr.pkt_encap = ld->linktype;
1676 /* XXX - do something if this fails */
1677 wtap_dump(ld->pdh, &whdr, NULL, pd, &err);
1680 /* Set the initial payload to the packet length, and the initial
1681 captured payload to the capture length (other protocols may
1682 reduce them if their headers say they're less). */
1684 pi.captured_len = phdr->caplen;
1686 switch (ld->linktype) {
1687 case WTAP_ENCAP_ETHERNET:
1688 capture_eth(pd, 0, &ld->counts);
1690 case WTAP_ENCAP_FDDI:
1691 case WTAP_ENCAP_FDDI_BITSWAPPED:
1692 capture_fddi(pd, &ld->counts);
1694 case WTAP_ENCAP_TOKEN_RING:
1695 capture_tr(pd, 0, &ld->counts);
1697 case WTAP_ENCAP_NULL:
1698 capture_null(pd, &ld->counts);
1700 case WTAP_ENCAP_PPP:
1701 capture_ppp(pd, 0, &ld->counts);
1703 case WTAP_ENCAP_RAW_IP:
1704 capture_raw(pd, &ld->counts);
1706 case WTAP_ENCAP_SLL:
1707 capture_sll(pd, &ld->counts);
1709 case WTAP_ENCAP_LINUX_ATM_CLIP:
1710 capture_clip(pd, &ld->counts);
1712 /* XXX - FreeBSD may append 4-byte ATM pseudo-header to DLT_ATM_RFC1483,
1713 with LLC header following; we should implement it at some
1718 #endif /* HAVE_LIBPCAP */