2 * Routines for packet capture windows
4 * $Id: capture.c,v 1.119 2000/08/14 08:36:39 guy 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.
33 #ifdef HAVE_SYS_TYPES_H
34 # include <sys/types.h>
37 #ifdef HAVE_SYS_STAT_H
38 # include <sys/stat.h>
41 #ifdef HAVE_SYS_WAIT_H
42 # include <sys/wait.h>
64 #ifdef HAVE_SYS_SOCKET_H
65 #include <sys/socket.h>
68 #ifdef HAVE_SYS_IOCTL_H
69 #include <sys/ioctl.h>
79 #ifdef NEED_SNPRINTF_H
80 # include "snprintf.h"
88 #include <process.h> /* For spawning child process */
92 #include "gtk/gtkglobals.h"
97 #include "simple_dialog.h"
101 #include "wiretap/libpcap.h"
102 #include "wiretap/wtap-int.h"
104 #include "packet-clip.h"
105 #include "packet-eth.h"
106 #include "packet-fddi.h"
107 #include "packet-null.h"
108 #include "packet-ppp.h"
109 #include "packet-raw.h"
110 #include "packet-tr.h"
112 int sync_mode; /* fork a child to do the capture, and sync between them */
113 static int sync_pipe[2]; /* used to sync father */
114 enum PIPES { READ, WRITE }; /* Constants 0 and 1 for READ and WRITE */
115 int quit_after_cap; /* Makes a "capture only mode". Implies -k */
116 gboolean capture_child; /* if this is the child for "-S" */
117 static int fork_child; /* In parent, process ID of child */
118 static guint cap_input_id;
121 static guint cap_timer_id;
122 static int cap_timer_cb(gpointer); /* Win32 kludge to check for pipe input */
125 static void cap_file_input_cb(gpointer, gint, GdkInputCondition);
126 static void capture_delete_cb(GtkWidget *, GdkEvent *, gpointer);
127 static void capture_stop_cb(GtkWidget *, gpointer);
128 static void capture_pcap_cb(u_char *, const struct pcap_pkthdr *,
130 static void send_errmsg_to_parent(const char *);
131 static float pct(gint, gint);
133 typedef struct _loop_data {
138 gboolean from_pipe; /* TRUE if we are capturing data from a pipe */
139 gboolean modified; /* TRUE if data in the pipe uses modified pcap headers */
140 gboolean byte_swapped; /* TRUE if data in the pipe is byte swapped */
141 packet_counts counts;
146 static void adjust_header(loop_data *, struct pcap_hdr *, struct pcaprec_hdr *);
147 static int pipe_open_live(char *, struct pcap_hdr *, loop_data *, char *);
148 static int pipe_dispatch(int, loop_data *, struct pcap_hdr *);
151 /* Win32 needs the O_BINARY flag for open() */
157 /* Win32 needs a handle to the child capture process */
161 /* Open a specified file, or create a temporary file, and start a capture
162 to the file in question. */
164 do_capture(char *capfile_name)
167 gboolean is_tempfile;
173 int capture_succeeded;
175 if (capfile_name != NULL) {
176 /* Try to open/create the specified file for use as a capture buffer. */
177 cfile.save_file_fd = open(capfile_name, O_RDWR|O_BINARY|O_TRUNC|O_CREAT, 0600);
180 /* Choose a random name for the capture buffer */
181 cfile.save_file_fd = create_tempfile(tmpname, sizeof tmpname, "ether");
182 capfile_name = g_strdup(tmpname);
185 if (cfile.save_file_fd == -1) {
187 simple_dialog(ESD_TYPE_CRIT, NULL,
188 "The temporary file to which the capture would be saved (\"%s\")"
189 "could not be opened: %s.", capfile_name, strerror(errno));
191 simple_dialog(ESD_TYPE_CRIT, NULL,
192 file_open_error_message(errno, TRUE), capfile_name);
196 close_cap_file(&cfile, info_bar);
197 g_assert(cfile.save_file == NULL);
198 cfile.save_file = capfile_name;
200 if (sync_mode) { /* do the capture in a child process */
202 char scount[24]; /* need a constant for len of numbers */
203 char save_file_fd[24];
207 char sync_pipe_fd[24];
211 sprintf(ssnap,"%d",cfile.snap); /* in lieu of itoa */
212 sprintf(scount,"%d",cfile.count);
213 sprintf(save_file_fd,"%d",cfile.save_file_fd);
216 /* Create a pipe for the child process */
218 if(_pipe(sync_pipe, 512, O_BINARY) < 0) {
219 /* Couldn't create the pipe between parent and child. */
221 unlink(cfile.save_file);
222 g_free(cfile.save_file);
223 cfile.save_file = NULL;
224 simple_dialog(ESD_TYPE_CRIT, NULL, "Couldn't create sync pipe: %s",
229 /* Convert pipe write handle to a string and pass to child */
230 itoa(sync_pipe[WRITE], sync_pipe_fd, 10);
231 /* Convert filter string to a quote delimited string */
232 filterstring = g_new(char, strlen(cfile.cfilter) + 3);
233 sprintf(filterstring, "\"%s\"", cfile.cfilter);
234 filterstring[strlen(cfile.cfilter) + 2] = 0;
236 fork_child = spawnlp(_P_NOWAIT, ethereal_path, CHILD_NAME, "-i", cfile.iface,
237 "-w", cfile.save_file, "-W", save_file_fd,
238 "-c", scount, "-s", ssnap,
240 strlen(cfile.cfilter) == 0 ? (const char *)NULL : "-f",
241 strlen(cfile.cfilter) == 0 ? (const char *)NULL : filterstring,
243 g_free(filterstring);
244 /* Keep a copy for later evaluation by _cwait() */
245 child_process = fork_child;
247 signal(SIGCHLD, SIG_IGN);
248 if (pipe(sync_pipe) < 0) {
249 /* Couldn't create the pipe between parent and child. */
251 unlink(cfile.save_file);
252 g_free(cfile.save_file);
253 cfile.save_file = NULL;
254 simple_dialog(ESD_TYPE_CRIT, NULL, "Couldn't create sync pipe: %s",
258 if ((fork_child = fork()) == 0) {
260 * Child process - run Ethereal with the right arguments to make
261 * it just pop up the live capture dialog box and capture with
262 * the specified capture parameters, writing to the specified file.
264 * args: -i interface specification
266 * -W file descriptor to write
267 * -c count to capture
270 * -f "filter expression"
273 dup(sync_pipe[WRITE]);
274 close(sync_pipe[READ]);
275 execlp(ethereal_path, CHILD_NAME, "-i", cfile.iface,
276 "-w", cfile.save_file, "-W", save_file_fd,
277 "-c", scount, "-s", ssnap,
278 "-m", medium_font, "-b", bold_font,
279 (cfile.cfilter == NULL)? 0 : "-f",
280 (cfile.cfilter == NULL)? 0 : cfile.cfilter,
282 snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
283 ethereal_path, strerror(errno));
284 send_errmsg_to_parent(errmsg);
286 /* Exit with "_exit()", so that we don't close the connection
287 to the X server (and cause stuff buffered up by our parent but
288 not yet sent to be sent, as that stuff should only be sent by
294 /* Parent process - read messages from the child process over the
297 /* Close the write side of the pipe, so that only the child has it
298 open, and thus it completely closes, and thus returns to us
299 an EOF indication, if the child closes it (either deliberately
300 or by exiting abnormally). */
301 close(sync_pipe[WRITE]);
303 /* Close the save file FD, as we won't be using it - we'll be opening
304 it and reading the save file through Wiretap. */
305 close(cfile.save_file_fd);
307 if (fork_child == -1) {
308 /* We couldn't even create the child process. */
310 close(sync_pipe[READ]);
311 unlink(cfile.save_file);
312 g_free(cfile.save_file);
313 cfile.save_file = NULL;
314 simple_dialog(ESD_TYPE_CRIT, NULL, "Couldn't create child process: %s",
319 /* Read a byte count from "sync_pipe[READ]", terminated with a
320 colon; if the count is 0, the child process created the
321 capture file and we should start reading from it, otherwise
322 the capture couldn't start and the count is a count of bytes
323 of error message, and we should display the message. */
326 i = read(sync_pipe[READ], &c, 1);
328 /* EOF - the child process died.
329 Close the read side of the sync pipe, remove the capture file,
330 and report the failure.
331 XXX - reap the child process and report the status in detail. */
332 close(sync_pipe[READ]);
333 unlink(cfile.save_file);
334 g_free(cfile.save_file);
335 cfile.save_file = NULL;
336 simple_dialog(ESD_TYPE_WARN, NULL, "Capture child process died");
342 /* Child process handed us crap.
343 Close the read side of the sync pipe, remove the capture file,
344 and report the failure. */
345 close(sync_pipe[READ]);
346 unlink(cfile.save_file);
347 g_free(cfile.save_file);
348 cfile.save_file = NULL;
349 simple_dialog(ESD_TYPE_WARN, NULL,
350 "Capture child process sent us a bad message");
353 byte_count = byte_count*10 + c - '0';
355 if (byte_count == 0) {
356 /* Success. Open the capture file, and set up to read it. */
357 err = start_tail_cap_file(cfile.save_file, is_tempfile, &cfile);
359 /* We were able to open and set up to read the capture file;
360 arrange that our callback be called whenever it's possible
361 to read from the sync pipe, so that it's called when
362 the child process wants to tell us something. */
364 /* Tricky to use pipes in win9x, as no concept of wait. NT can
365 do this but that doesn't cover all win32 platforms. GTK can do
366 this but doesn't seem to work over processes. Attempt to do
367 something similar here, start a timer and check for data on every
369 cap_timer_id = gtk_timeout_add(1000, cap_timer_cb, NULL);
371 cap_input_id = gtk_input_add_full(sync_pipe[READ],
372 GDK_INPUT_READ|GDK_INPUT_EXCEPTION,
379 /* We weren't able to open the capture file; complain, and
380 close the sync pipe. */
381 simple_dialog(ESD_TYPE_CRIT, NULL,
382 file_open_error_message(err, FALSE), cfile.save_file);
384 /* Close the sync pipe. */
385 close(sync_pipe[READ]);
387 /* Don't unlink the save file - leave it around, for debugging
389 g_free(cfile.save_file);
390 cfile.save_file = NULL;
393 /* Failure - the child process sent us a message indicating
394 what the problem was. */
395 msg = g_malloc(byte_count + 1);
397 simple_dialog(ESD_TYPE_WARN, NULL,
398 "Capture child process failed, but its error message was too big.");
400 i = read(sync_pipe[READ], msg, byte_count);
402 simple_dialog(ESD_TYPE_WARN, NULL,
403 "Capture child process failed: Error %s reading its error message.",
406 simple_dialog(ESD_TYPE_WARN, NULL,
407 "Capture child process failed: EOF reading its error message.");
409 simple_dialog(ESD_TYPE_WARN, NULL, msg);
412 /* Close the sync pipe. */
413 close(sync_pipe[READ]);
415 /* Get rid of the save file - the capture never started. */
416 unlink(cfile.save_file);
417 g_free(cfile.save_file);
418 cfile.save_file = NULL;
423 capture_succeeded = capture();
424 if (quit_after_cap) {
425 /* DON'T unlink the save file. Presumably someone wants it. */
428 if (capture_succeeded) {
429 /* Capture succeeded; read in the capture file. */
430 if ((err = open_cap_file(cfile.save_file, is_tempfile, &cfile)) == 0) {
431 /* Set the read filter to NULL. */
433 switch (read_cap_file(&cfile, &err)) {
437 /* Just because we got an error, that doesn't mean we were unable
438 to read any of the file; we handle what we could get from the
443 /* Exit by leaving the main loop, so that any quit functions
444 we registered get called. */
450 /* We're not doing a capture any more, so we don't have a save
452 g_free(cfile.save_file);
453 cfile.save_file = NULL;
458 /* The timer has expired, see if there's stuff to read from the pipe,
459 if so call the cap_file_input_cb */
461 cap_timer_cb(gpointer data)
465 gboolean result, result1;
468 /* Oddly enough although Named pipes don't work on win9x,
469 PeekNamedPipe does !!! */
470 handle = (HANDLE) _get_osfhandle (sync_pipe[READ]);
471 result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
473 /* Get the child process exit status */
474 result1 = GetExitCodeProcess((HANDLE)child_process, &childstatus);
476 /* If the Peek returned an error, or there are bytes to be read
477 or the childwatcher thread has terminated then call the normal
479 if (!result || avail > 0 || childstatus != STILL_ACTIVE) {
481 /* avoid reentrancy problems and stack overflow */
482 gtk_timeout_remove(cap_timer_id);
484 /* And call the real handler */
485 cap_file_input_cb((gpointer) &cfile, 0, 0);
487 /* Return false so that the timer is not run again */
491 /* No data so let timer run again */
497 /* There's stuff to read from the sync pipe, meaning the child has sent
498 us a message, or the sync pipe has closed, meaning the child has
499 closed it (perhaps because it exited). */
501 cap_file_input_cb(gpointer data, gint source, GdkInputCondition condition)
503 capture_file *cf = (capture_file *)data;
504 char buffer[256+1], *p = buffer, *q = buffer;
507 gboolean exit_loop = FALSE;
513 char sigmsg_buf[6+1+3+1];
517 /* avoid reentrancy problems and stack overflow */
518 gtk_input_remove(cap_input_id);
521 if ((nread = read(sync_pipe[READ], buffer, 256)) <= 0) {
522 /* The child has closed the sync pipe, meaning it's not going to be
523 capturing any more packets. Pick up its exit status, and
524 complain if it died of a signal. */
526 /* XXX - analyze the wait stuatus and display more information
527 in the dialog box? */
528 if (_cwait(&wstatus, child_process, _WAIT_CHILD) == -1) {
529 simple_dialog(ESD_TYPE_WARN, NULL, "Child capture process stopped unexpectedly");
532 if (wait(&wstatus) != -1) {
533 /* XXX - are there any platforms on which we can run that *don't*
534 support POSIX.1's <sys/wait.h> and macros therein? */
535 wsignal = wstatus & 0177;
537 if (wstatus == 0177) {
538 /* It stopped, rather than exiting. "Should not happen." */
540 wsignal = (wstatus >> 8) & 0xFF;
544 coredumped = " - core dumped";
554 sigmsg = "Interrupted";
562 sigmsg = "Illegal instruction";
566 sigmsg = "Trace trap";
574 sigmsg = "Arithmetic exception";
582 sigmsg = "Bus error";
586 sigmsg = "Segmentation violation";
589 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
590 Linux is POSIX compliant. These are not POSIX-defined signals ---
591 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
593 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
594 were omitted from POSIX.1 because their behavior is
595 implementation dependent and could not be adequately catego-
596 rized. Conforming implementations may deliver these sig-
597 nals, but must document the circumstances under which they
598 are delivered and note any restrictions concerning their
604 sigmsg = "Bad system call";
609 sigmsg = "Broken pipe";
613 sigmsg = "Alarm clock";
617 sigmsg = "Terminated";
621 sprintf(sigmsg_buf, "Signal %d", wsignal);
625 simple_dialog(ESD_TYPE_WARN, NULL,
626 "Child capture process %s: %s%s", msg, sigmsg, coredumped);
631 /* Read what remains of the capture file, and finish the capture.
632 XXX - do something if this fails? */
633 switch (finish_tail_cap_file(cf, &err)) {
637 /* Just because we got an error, that doesn't mean we were unable
638 to read any of the file; we handle what we could get from the
643 /* Exit by leaving the main loop, so that any quit functions
644 we registered get called. */
649 /* We're not doing a capture any more, so we don't have a save
651 g_free(cf->save_file);
652 cf->save_file = NULL;
657 buffer[nread] = '\0';
660 /* look for (possibly multiple) '*' */
668 /* XXX should handle the case of a pipe full (i.e. no star found) */
677 /* Read from the capture file the number of records the child told us
679 XXX - do something if this fails? */
680 switch (continue_tail_cap_file(cf, to_read, &err)) {
684 /* Just because we got an error, that doesn't mean we were unable
685 to read any of the file; we handle what we could get from the
688 XXX - abort on a read error? */
692 /* Kill the child capture process; the user wants to exit, and we
693 shouldn't just leave it running. */
697 kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
702 /* restore pipe handler */
704 cap_timer_id = gtk_timeout_add(1000, cap_timer_cb, NULL);
706 cap_input_id = gtk_input_add_full (sync_pipe[READ],
707 GDK_INPUT_READ|GDK_INPUT_EXCEPTION,
716 * Timeout, in milliseconds, for reads from the stream of captured packets.
718 #define CAP_READ_TIMEOUT 250
721 /* Take carre of byte order in the libpcap headers read from pipes.
722 * (function taken from wiretap/libpcap.c) */
724 adjust_header(loop_data *ld, struct pcap_hdr *hdr, struct pcaprec_hdr *rechdr)
726 if (ld->byte_swapped) {
727 /* Byte-swap the record header fields. */
728 rechdr->ts_sec = BSWAP32(rechdr->ts_sec);
729 rechdr->ts_usec = BSWAP32(rechdr->ts_usec);
730 rechdr->incl_len = BSWAP32(rechdr->incl_len);
731 rechdr->orig_len = BSWAP32(rechdr->orig_len);
734 /* In file format version 2.3, the "incl_len" and "orig_len" fields were
735 swapped, in order to match the BPF header layout.
737 Unfortunately, some files were, according to a comment in the "libpcap"
738 source, written with version 2.3 in their headers but without the
739 interchanged fields, so if "incl_len" is greater than "orig_len" - which
740 would make no sense - we assume that we need to swap them. */
741 if (hdr->version_major == 2 &&
742 (hdr->version_minor < 3 ||
743 (hdr->version_minor == 3 && rechdr->incl_len > rechdr->orig_len))) {
746 temp = rechdr->orig_len;
747 rechdr->orig_len = rechdr->incl_len;
748 rechdr->incl_len = temp;
752 /* Mimic pcap_open_live() for pipe captures
753 * We check if "pipename" is "-" (stdin) or a FIFO, open it, and read the
755 * N.B. : we can't read the libpcap formats used in RedHat 6.1 or SuSE 6.3
756 * because we can't seek on pipes (see wiretap/libpcap.c for details) */
758 pipe_open_live(char *pipename, struct pcap_hdr *hdr, loop_data *ld, char *ebuf)
760 struct stat pipe_stat;
765 if (strcmp(pipename, "-") == 0) fd = 0; /* read from stdin */
766 else if (stat(pipename, &pipe_stat) == 0 && S_ISFIFO(pipe_stat.st_mode)) {
767 if ((fd = open(pipename, O_RDONLY)) == -1) return -1;
770 ld->from_pipe = TRUE;
771 /* read the pcap header */
772 if (read(fd, &magic, sizeof magic) != sizeof magic) {
779 /* Host that wrote it has our byte order, and was running
780 a program using either standard or ss990417 libpcap. */
781 ld->byte_swapped = FALSE;
782 ld->modified = FALSE;
784 case PCAP_MODIFIED_MAGIC:
785 /* Host that wrote it has our byte order, but was running
786 a program using either ss990915 or ss991029 libpcap. */
787 ld->byte_swapped = FALSE;
790 case PCAP_SWAPPED_MAGIC:
791 /* Host that wrote it has a byte order opposite to ours,
792 and was running a program using either standard or
794 ld->byte_swapped = TRUE;
795 ld->modified = FALSE;
797 case PCAP_SWAPPED_MODIFIED_MAGIC:
798 /* Host that wrote it out has a byte order opposite to
799 ours, and was running a program using either ss990915
800 or ss991029 libpcap. */
801 ld->byte_swapped = TRUE;
805 /* Not a "libpcap" type we know about. */
810 /* Read the rest of the header */
811 bytes_read = read(fd, hdr, sizeof(struct pcap_hdr));
812 if (bytes_read <= 0) {
816 while (bytes_read < sizeof(struct pcap_hdr))
818 b = read(fd, ((char *)&hdr)+bytes_read, sizeof(struct pcap_hdr) - bytes_read);
825 if (ld->byte_swapped) {
826 /* Byte-swap the header fields about which we care. */
827 hdr->version_major = BSWAP16(hdr->version_major);
828 hdr->version_minor = BSWAP16(hdr->version_minor);
829 hdr->snaplen = BSWAP32(hdr->snaplen);
830 hdr->network = BSWAP32(hdr->network);
832 if (hdr->version_major < 2) {
840 /* We read one record from the pipe, take care of byte order in the record
841 * header, write the record in the capture file, and update capture statistics. */
843 pipe_dispatch(int fd, loop_data *ld, struct pcap_hdr *hdr)
845 struct wtap_pkthdr whdr;
846 struct pcaprec_modified_hdr rechdr;
847 int bytes_to_read, bytes_read, b;
848 u_char pd[WTAP_MAX_PACKET_SIZE];
851 /* read the record header */
852 bytes_to_read = ld->modified ? sizeof rechdr : sizeof rechdr.hdr;
853 bytes_read = read(fd, &rechdr, bytes_to_read);
854 if (bytes_read <= 0) {
859 while (bytes_read < bytes_to_read)
861 b = read(fd, ((char *)&rechdr)+bytes_read, bytes_to_read - bytes_read);
869 /* take care of byte order */
870 adjust_header(ld, hdr, &rechdr.hdr);
871 if (rechdr.hdr.incl_len > WTAP_MAX_PACKET_SIZE) {
876 /* read the packet data */
877 bytes_read = read(fd, pd, rechdr.hdr.incl_len);
878 if (bytes_read <= 0) {
883 while (bytes_read < rechdr.hdr.incl_len)
885 b = read(fd, pd+bytes_read, rechdr.hdr.incl_len - bytes_read);
893 /* dump the packet data to the capture file */
894 whdr.ts.tv_sec = rechdr.hdr.ts_sec;
895 whdr.ts.tv_usec = rechdr.hdr.ts_usec;
896 whdr.caplen = rechdr.hdr.incl_len;
897 whdr.len = rechdr.hdr.orig_len;
898 whdr.pkt_encap = ld->linktype;
899 wtap_dump(ld->pdh, &whdr, NULL, pd, &err);
901 /* Set the initial payload to the packet length, and the initial
902 captured payload to the capture length (other protocols may
903 reduce them if their headers say they're less). */
905 pi.captured_len = whdr.caplen;
907 /* update capture statistics */
908 switch (ld->linktype) {
909 case WTAP_ENCAP_ETHERNET:
910 capture_eth(pd, 0, &ld->counts);
912 case WTAP_ENCAP_FDDI:
913 case WTAP_ENCAP_FDDI_BITSWAPPED:
914 capture_fddi(pd, &ld->counts);
917 capture_tr(pd, 0, &ld->counts);
919 case WTAP_ENCAP_NULL:
920 capture_null(pd, &ld->counts);
923 capture_ppp(pd, 0, &ld->counts);
925 case WTAP_ENCAP_RAW_IP:
926 capture_raw(pd, &ld->counts);
928 case WTAP_ENCAP_LINUX_ATM_CLIP:
929 capture_clip(pd, &ld->counts);
931 /* XXX - FreeBSD may append 4-byte ATM pseudo-header to DLT_ATM_RFC1483,
932 with LLC header following; we should implement it at some
940 /* Do the low-level work of a capture.
941 Returns TRUE if it succeeds, FALSE otherwise. */
945 GtkWidget *cap_w, *main_vb, *count_lb, *sctp_lb, *tcp_lb, *udp_lb, *icmp_lb,
946 *ospf_lb, *gre_lb, *netbios_lb, *ipx_lb, *vines_lb, *other_lb, *stop_bt;
950 gchar err_str[PCAP_ERRBUF_SIZE], label_str[32];
952 bpf_u_int32 netnum, netmask;
953 time_t upd_time, cur_time;
957 static const char ppamsg[] = "can't find PPA for ";
961 struct timeval timeout;
966 WORD wVersionRequested;
974 /* Initialize Windows Socket if we are in a WIN32 OS
975 This needs to be done before querying the interface for network/netmask */
977 wVersionRequested = MAKEWORD( 1, 1 );
978 err = WSAStartup( wVersionRequested, &wsaData );
980 snprintf(errmsg, sizeof errmsg,
981 "Couldn't initialize Windows Sockets.");
989 ld.max = cfile.count;
990 ld.linktype = WTAP_ENCAP_UNKNOWN;
991 ld.from_pipe = FALSE;
1000 ld.counts.netbios = 0;
1001 ld.counts.vines = 0;
1002 ld.counts.other = 0;
1005 /* Open the network interface to capture from it. */
1006 pch = pcap_open_live(cfile.iface, cfile.snap, 1, CAP_READ_TIMEOUT, err_str);
1010 /* Well, we couldn't start the capture.
1011 If this is a child process that does the capturing in sync
1012 mode or fork mode, it shouldn't do any UI stuff until we pop up the
1013 capture-progress window, and, since we couldn't start the
1014 capture, we haven't popped it up. */
1015 if (!capture_child) {
1016 while (gtk_events_pending()) gtk_main_iteration();
1019 /* On Win32 OSes, the capture devices are probably available to all
1020 users; don't warn about permissions problems.
1022 Do, however, warn that Token Ring and PPP devices aren't supported. */
1023 snprintf(errmsg, sizeof errmsg,
1024 "The capture session could not be initiated (%s).\n"
1025 "Please check that you have the proper interface specified.\n"
1027 "Note that the driver Ethereal uses for packet capture on Windows\n"
1028 "doesn't support capturing on Token Ring interfaces, and doesn't\n"
1029 "support capturing on PPP/WAN interfaces in Windows NT/2000.\n",
1033 /* try to open cfile.iface as a pipe */
1034 pipe_fd = pipe_open_live(cfile.iface, &hdr, &ld, err_str);
1036 if (pipe_fd == -1) {
1037 /* Well, we couldn't start the capture.
1038 If this is a child process that does the capturing in sync
1039 mode or fork mode, it shouldn't do any UI stuff until we pop up the
1040 capture-progress window, and, since we couldn't start the
1041 capture, we haven't popped it up. */
1042 if (!capture_child) {
1043 while (gtk_events_pending()) gtk_main_iteration();
1046 /* If we got a "can't find PPA for XXX" message, warn the user (who
1047 is running Ethereal on HP-UX) that they don't have a version
1048 of libpcap patched to properly handle HP-UX (the patched version
1049 says "can't find /dev/dlpi PPA for XXX" rather than "can't find
1051 if (strncmp(err_str, ppamsg, sizeof ppamsg - 1) == 0)
1054 "You are running Ethereal with a version of the libpcap library\n"
1055 "that doesn't handle HP-UX network devices well; this means that\n"
1056 "Ethereal may not be able to capture packets.\n"
1058 "To fix this, you will need to download the source to Ethereal\n"
1059 "from ethereal.zing.org if you have not already done so, read\n"
1060 "the instructions in the \"README.hpux\" file in the source\n"
1061 "distribution, download the source to libpcap if you have not\n"
1062 "already done so, patch libpcap as per the instructions, rebuild\n"
1063 "and install libpcap, and then build Ethereal (if you have already\n"
1064 "built Ethereal from source, do a \"make distclean\" and re-run\n"
1065 "configure before building).";
1068 snprintf(errmsg, sizeof errmsg,
1069 "The capture session could not be initiated (%s).\n"
1070 "Please check to make sure you have sufficient permissions, and that\n"
1071 "you have the proper interface or pipe specified.%s", err_str,
1078 /* capture filters only work on real interfaces */
1079 if (cfile.cfilter && !ld.from_pipe) {
1080 /* A capture filter was specified; set it up. */
1081 if (pcap_lookupnet (cfile.iface, &netnum, &netmask, err_str) < 0) {
1082 snprintf(errmsg, sizeof errmsg,
1083 "Can't use filter: Couldn't obtain netmask info (%s).", err_str);
1086 if (pcap_compile(pch, &cfile.fcode, cfile.cfilter, 1, netmask) < 0) {
1087 snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
1091 if (pcap_setfilter(pch, &cfile.fcode) < 0) {
1092 snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
1098 /* Set up to write to the capture file. */
1101 pcap_encap = hdr.network;
1102 snaplen = hdr.snaplen;
1106 pcap_encap = pcap_datalink(pch);
1107 snaplen = pcap_snapshot(pch);
1109 ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_encap);
1110 if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
1111 strcpy(errmsg, "The network you're capturing from is of a type"
1112 " that Ethereal doesn't support.");
1115 ld.pdh = wtap_dump_fdopen(cfile.save_file_fd, WTAP_FILE_PCAP,
1116 ld.linktype, snaplen, &err);
1118 if (ld.pdh == NULL) {
1119 /* We couldn't set up to write to the capture file. */
1122 case WTAP_ERR_CANT_OPEN:
1123 strcpy(errmsg, "The file to which the capture would be saved"
1124 " couldn't be created for some unknown reason.");
1127 case WTAP_ERR_SHORT_WRITE:
1128 strcpy(errmsg, "A full header couldn't be written to the file"
1129 " to which the capture would be saved.");
1134 sprintf(errmsg, "The file to which the capture would be"
1135 " saved (\"%s\") could not be opened: Error %d.",
1136 cfile.save_file, err);
1138 sprintf(errmsg, "The file to which the capture would be"
1139 " saved (\"%s\") could not be opened: %s.",
1140 cfile.save_file, strerror(err));
1147 /* XXX - capture SIGTERM and close the capture, in case we're on a
1148 Linux 2.0[.x] system and you have to explicitly close the capture
1149 stream in order to turn promiscuous mode off? We need to do that
1150 in other places as well - and I don't think that works all the
1151 time in any case, due to libpcap bugs. */
1153 if (capture_child) {
1154 /* Well, we should be able to start capturing.
1156 This is the child process for a sync mode capture, so sync out
1157 the capture file, so the header makes it to the file system,
1158 and send a "capture started successfully and capture file created"
1159 message to our parent so that they'll open the capture file and
1160 update its windows to indicate that we have a live capture in
1162 fflush(wtap_dump_file(ld.pdh));
1166 cap_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1167 gtk_window_set_title(GTK_WINDOW(cap_w), "Ethereal: Capture");
1168 gtk_window_set_modal(GTK_WINDOW(cap_w), TRUE);
1170 /* Container for capture display widgets */
1171 main_vb = gtk_vbox_new(FALSE, 1);
1172 gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
1173 gtk_container_add(GTK_CONTAINER(cap_w), main_vb);
1174 gtk_widget_show(main_vb);
1176 count_lb = gtk_label_new("Count: 0");
1177 gtk_box_pack_start(GTK_BOX(main_vb), count_lb, FALSE, FALSE, 3);
1178 gtk_widget_show(count_lb);
1180 sctp_lb = gtk_label_new("SCTP: 0 (0.0%)");
1181 gtk_box_pack_start(GTK_BOX(main_vb), sctp_lb, FALSE, FALSE, 3);
1182 gtk_widget_show(sctp_lb);
1184 tcp_lb = gtk_label_new("TCP: 0 (0.0%)");
1185 gtk_box_pack_start(GTK_BOX(main_vb), tcp_lb, FALSE, FALSE, 3);
1186 gtk_widget_show(tcp_lb);
1188 udp_lb = gtk_label_new("UDP: 0 (0.0%)");
1189 gtk_box_pack_start(GTK_BOX(main_vb), udp_lb, FALSE, FALSE, 3);
1190 gtk_widget_show(udp_lb);
1192 icmp_lb = gtk_label_new("ICMP: 0 (0.0%)");
1193 gtk_box_pack_start(GTK_BOX(main_vb), icmp_lb, FALSE, FALSE, 3);
1194 gtk_widget_show(icmp_lb);
1196 ospf_lb = gtk_label_new("OSPF: 0 (0.0%)");
1197 gtk_box_pack_start(GTK_BOX(main_vb), ospf_lb, FALSE, FALSE, 3);
1198 gtk_widget_show(ospf_lb);
1200 gre_lb = gtk_label_new("GRE: 0 (0.0%)");
1201 gtk_box_pack_start(GTK_BOX(main_vb), gre_lb, FALSE, FALSE, 3);
1202 gtk_widget_show(gre_lb);
1204 netbios_lb = gtk_label_new("NetBIOS: 0 (0.0%)");
1205 gtk_box_pack_start(GTK_BOX(main_vb), netbios_lb, FALSE, FALSE, 3);
1206 gtk_widget_show(netbios_lb);
1208 ipx_lb = gtk_label_new("IPX: 0 (0.0%)");
1209 gtk_box_pack_start(GTK_BOX(main_vb), ipx_lb, FALSE, FALSE, 3);
1210 gtk_widget_show(ipx_lb);
1212 vines_lb = gtk_label_new("VINES: 0 (0.0%)");
1213 gtk_box_pack_start(GTK_BOX(main_vb), vines_lb, FALSE, FALSE, 3);
1214 gtk_widget_show(vines_lb);
1216 other_lb = gtk_label_new("Other: 0 (0.0%)");
1217 gtk_box_pack_start(GTK_BOX(main_vb), other_lb, FALSE, FALSE, 3);
1218 gtk_widget_show(other_lb);
1220 /* allow user to either click a stop button, or the close button on
1221 the window to stop a capture in progress. */
1222 stop_bt = gtk_button_new_with_label ("Stop");
1223 gtk_signal_connect(GTK_OBJECT(stop_bt), "clicked",
1224 GTK_SIGNAL_FUNC(capture_stop_cb), (gpointer) &ld);
1225 gtk_signal_connect(GTK_OBJECT(cap_w), "delete_event",
1226 GTK_SIGNAL_FUNC(capture_delete_cb), (gpointer) &ld);
1227 gtk_box_pack_end(GTK_BOX(main_vb), stop_bt, FALSE, FALSE, 3);
1228 GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
1229 gtk_widget_grab_default(stop_bt);
1230 GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
1231 gtk_widget_grab_default(stop_bt);
1232 gtk_widget_show(stop_bt);
1234 gtk_widget_show(cap_w);
1236 upd_time = time(NULL);
1238 if (!ld.from_pipe) pcap_fd = pcap_fileno(pch);
1241 while (gtk_events_pending()) gtk_main_iteration();
1246 FD_SET(pipe_fd, &set1);
1248 timeout.tv_usec = CAP_READ_TIMEOUT*1000;
1249 if (select(pipe_fd+1, &set1, NULL, NULL, &timeout) != 0) {
1251 * "select()" says we can read from the pipe without blocking; go for
1252 * it. We are not sure we can read a whole record, but at least the
1253 * begninning of one. pipe_dispatch() will block reading the whole
1256 inpkts = pipe_dispatch(pipe_fd, &ld, &hdr);
1265 * Sigh. The semantics of the read timeout argument to
1266 * "pcap_open_live()" aren't particularly well specified by
1267 * the "pcap" man page - at least with the BSD BPF code, the
1268 * intent appears to be, at least in part, a way of cutting
1269 * down the number of reads done on a capture, by blocking
1270 * until the buffer fills or a timer expires - and the Linux
1271 * libpcap doesn't actually support it, so we can't use it
1272 * to break out of the "pcap_dispatch()" every 1/4 of a second
1275 * Thus, on Linux, we do a "select()" on the file descriptor for the
1276 * capture, with a timeout of CAP_READ_TIMEOUT milliseconds, or
1277 * CAP_READ_TIMEOUT*1000 microseconds.
1280 FD_SET(pcap_fd, &set1);
1282 timeout.tv_usec = CAP_READ_TIMEOUT*1000;
1283 if (select(pcap_fd+1, &set1, NULL, NULL, &timeout) != 0) {
1285 * "select()" says we can read from it without blocking; go for
1288 inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
1292 inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
1296 ld.sync_packets += inpkts;
1297 /* Only update once a second so as not to overload slow displays */
1298 cur_time = time(NULL);
1299 if (cur_time > upd_time) {
1300 upd_time = cur_time;
1302 sprintf(label_str, "Count: %d", ld.counts.total);
1303 gtk_label_set(GTK_LABEL(count_lb), label_str);
1305 sprintf(label_str, "SCTP: %d (%.1f%%)", ld.counts.sctp,
1306 pct(ld.counts.sctp, ld.counts.total));
1307 gtk_label_set(GTK_LABEL(sctp_lb), label_str);
1309 sprintf(label_str, "TCP: %d (%.1f%%)", ld.counts.tcp,
1310 pct(ld.counts.tcp, ld.counts.total));
1311 gtk_label_set(GTK_LABEL(tcp_lb), label_str);
1313 sprintf(label_str, "UDP: %d (%.1f%%)", ld.counts.udp,
1314 pct(ld.counts.udp, ld.counts.total));
1315 gtk_label_set(GTK_LABEL(udp_lb), label_str);
1317 sprintf(label_str, "ICMP: %d (%.1f%%)", ld.counts.icmp,
1318 pct(ld.counts.icmp, ld.counts.total));
1319 gtk_label_set(GTK_LABEL(icmp_lb), label_str);
1321 sprintf(label_str, "OSPF: %d (%.1f%%)", ld.counts.ospf,
1322 pct(ld.counts.ospf, ld.counts.total));
1323 gtk_label_set(GTK_LABEL(ospf_lb), label_str);
1325 sprintf(label_str, "GRE: %d (%.1f%%)", ld.counts.gre,
1326 pct(ld.counts.gre, ld.counts.total));
1327 gtk_label_set(GTK_LABEL(gre_lb), label_str);
1329 sprintf(label_str, "NetBIOS: %d (%.1f%%)", ld.counts.netbios,
1330 pct(ld.counts.netbios, ld.counts.total));
1331 gtk_label_set(GTK_LABEL(netbios_lb), label_str);
1333 sprintf(label_str, "IPX: %d (%.1f%%)", ld.counts.ipx,
1334 pct(ld.counts.ipx, ld.counts.total));
1335 gtk_label_set(GTK_LABEL(ipx_lb), label_str);
1337 sprintf(label_str, "VINES: %d (%.1f%%)", ld.counts.vines,
1338 pct(ld.counts.vines, ld.counts.total));
1339 gtk_label_set(GTK_LABEL(vines_lb), label_str);
1341 sprintf(label_str, "Other: %d (%.1f%%)", ld.counts.other,
1342 pct(ld.counts.other, ld.counts.total));
1343 gtk_label_set(GTK_LABEL(other_lb), label_str);
1345 /* do sync here, too */
1346 fflush(wtap_dump_file(ld.pdh));
1347 if (capture_child && ld.sync_packets) {
1348 /* This is the child process for a sync mode capture, so send
1349 our parent a message saying we've written out "ld.sync_packets"
1350 packets to the capture file. */
1352 sprintf(tmp, "%d*", ld.sync_packets);
1353 write(1, tmp, strlen(tmp));
1354 ld.sync_packets = 0;
1359 if (!wtap_dump_close(ld.pdh, &err)) {
1360 /* XXX - in fork mode, this may not pop up, or, if it does,
1361 it may disappear as soon as we exit.
1363 We should have the parent process, while it's reading
1364 the packet count update messages, catch error messages
1365 and pop up a message box if it sees one. */
1368 case WTAP_ERR_CANT_CLOSE:
1369 simple_dialog(ESD_TYPE_WARN, NULL,
1370 "The file to which the capture was being saved"
1371 " couldn't be closed for some unknown reason.");
1374 case WTAP_ERR_SHORT_WRITE:
1375 simple_dialog(ESD_TYPE_WARN, NULL,
1376 "Not all the data could be written to the file"
1377 " to which the capture was being saved.");
1381 simple_dialog(ESD_TYPE_WARN, NULL,
1382 "The file to which the capture was being"
1383 " saved (\"%s\") could not be closed: %s.",
1384 cfile.save_file, wtap_strerror(err));
1395 gtk_grab_remove(GTK_WIDGET(cap_w));
1396 gtk_widget_destroy(GTK_WIDGET(cap_w));
1401 /* We can't use the save file, and we have no wtap_dump stream
1402 to close in order to close it, so close the FD directly. */
1403 close(cfile.save_file_fd);
1405 /* We couldn't even start the capture, so get rid of the capture
1407 unlink(cfile.save_file); /* silently ignore error */
1408 g_free(cfile.save_file);
1409 cfile.save_file = NULL;
1410 if (capture_child) {
1411 /* This is the child process for a sync mode capture.
1412 Send the error message to our parent, so they can display a
1413 dialog box containing it. */
1414 send_errmsg_to_parent(errmsg);
1416 /* Display the dialog box ourselves; there's no parent. */
1417 simple_dialog(ESD_TYPE_CRIT, NULL, errmsg);
1419 if (pch != NULL && !ld.from_pipe)
1426 send_errmsg_to_parent(const char *errmsg)
1428 int msglen = strlen(errmsg);
1429 char lenbuf[10+1+1];
1431 sprintf(lenbuf, "%u;", msglen);
1432 write(1, lenbuf, strlen(lenbuf));
1433 write(1, errmsg, msglen);
1437 pct(gint num, gint denom) {
1439 return (float) num * 100.0 / (float) denom;
1446 capture_delete_cb(GtkWidget *w, GdkEvent *event, gpointer data) {
1447 capture_stop_cb(NULL, data);
1451 capture_stop_cb(GtkWidget *w, gpointer data) {
1452 loop_data *ld = (loop_data *) data;
1458 capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
1460 struct wtap_pkthdr whdr;
1461 loop_data *ld = (loop_data *) user;
1464 if ((++ld->counts.total >= ld->max) && (ld->max > 0))
1469 /* "phdr->ts" may not necessarily be a "struct timeval" - it may
1470 be a "struct bpf_timeval", with member sizes wired to 32
1471 bits - and we may go that way ourselves in the future, so
1472 copy the members individually. */
1473 whdr.ts.tv_sec = phdr->ts.tv_sec;
1474 whdr.ts.tv_usec = phdr->ts.tv_usec;
1475 whdr.caplen = phdr->caplen;
1476 whdr.len = phdr->len;
1477 whdr.pkt_encap = ld->linktype;
1479 /* XXX - do something if this fails */
1480 wtap_dump(ld->pdh, &whdr, NULL, pd, &err);
1483 /* Set the initial payload to the packet length, and the initial
1484 captured payload to the capture length (other protocols may
1485 reduce them if their headers say they're less). */
1487 pi.captured_len = phdr->caplen;
1489 switch (ld->linktype) {
1490 case WTAP_ENCAP_ETHERNET:
1491 capture_eth(pd, 0, &ld->counts);
1493 case WTAP_ENCAP_FDDI:
1494 case WTAP_ENCAP_FDDI_BITSWAPPED:
1495 capture_fddi(pd, &ld->counts);
1498 capture_tr(pd, 0, &ld->counts);
1500 case WTAP_ENCAP_NULL:
1501 capture_null(pd, &ld->counts);
1503 case WTAP_ENCAP_PPP:
1504 capture_ppp(pd, 0, &ld->counts);
1506 case WTAP_ENCAP_RAW_IP:
1507 capture_raw(pd, &ld->counts);
1509 case WTAP_ENCAP_LINUX_ATM_CLIP:
1510 capture_clip(pd, &ld->counts);
1512 /* XXX - FreeBSD may append 4-byte ATM pseudo-header to DLT_ATM_RFC1483,
1513 with LLC header following; we should implement it at some
1518 #endif /* HAVE_LIBPCAP */