2 * Routines for packet capture windows
4 * $Id: capture.c,v 1.99 2000/03/21 06:51:58 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>
61 #ifdef HAVE_SYS_SOCKET_H
62 #include <sys/socket.h>
65 #ifdef HAVE_SYS_IOCTL_H
66 #include <sys/ioctl.h>
76 #ifdef NEED_SNPRINTF_H
82 # include "snprintf.h"
90 #include "gtk/gtkglobals.h"
95 #include "simple_dialog.h"
99 #include "packet-eth.h"
100 #include "packet-fddi.h"
101 #include "packet-null.h"
102 #include "packet-ppp.h"
103 #include "packet-raw.h"
104 #include "packet-tr.h"
106 int sync_mode; /* fork a child to do the capture, and sync between them */
107 static int sync_pipe[2]; /* used to sync father */
108 int quit_after_cap; /* Makes a "capture only mode". Implies -k */
109 gboolean capture_child; /* if this is the child for "-S" */
110 static guint cap_input_id;
112 static void cap_file_input_cb(gpointer, gint, GdkInputCondition);
113 static void capture_delete_cb(GtkWidget *, GdkEvent *, gpointer);
114 static void capture_stop_cb(GtkWidget *, gpointer);
115 static void capture_pcap_cb(u_char *, const struct pcap_pkthdr *,
117 static float pct(gint, gint);
119 typedef struct _loop_data {
124 packet_counts counts;
128 /* Win32 needs the O_BINARY flag for open() */
133 /* Open a specified file, or create a temporary file, and start a capture
134 to the file in question. */
136 do_capture(char *capfile_name)
139 gboolean is_tempfile;
145 int capture_succeeded;
147 if (capfile_name != NULL) {
148 /* Try to open/create the specified file for use as a capture buffer. */
149 cf.save_file_fd = open(capfile_name, O_RDWR|O_BINARY|O_TRUNC|O_CREAT, 0600);
152 /* Choose a random name for the capture buffer */
153 cf.save_file_fd = create_tempfile(tmpname, sizeof tmpname, "ether");
154 capfile_name = g_strdup(tmpname);
157 if (cf.save_file_fd == -1) {
158 simple_dialog(ESD_TYPE_WARN, NULL,
159 "The file to which the capture would be saved (\"%s\")"
160 "could not be opened: %s.", capfile_name, strerror(errno));
163 close_cap_file(&cf, info_bar);
164 g_assert(cf.save_file == NULL);
165 cf.save_file = capfile_name;
167 if (sync_mode) { /* use fork() for capture */
171 char scount[24]; /* need a constant for len of numbers */
172 char save_file_fd[24];
174 sprintf(ssnap,"%d",cf.snap); /* in lieu of itoa */
175 sprintf(scount,"%d",cf.count);
176 sprintf(save_file_fd,"%d",cf.save_file_fd);
177 signal(SIGCHLD, SIG_IGN);
179 if ((fork_child = fork()) == 0) {
181 * Child process - run Ethereal with the right arguments to make
182 * it just pop up the live capture dialog box and capture with
183 * the specified capture parameters, writing to the specified file.
185 * args: -i interface specification
187 * -W file descriptor to write
188 * -c count to capture
191 * -f "filter expression"
196 execlp(ethereal_path, CHILD_NAME, "-i", cf.iface,
197 "-w", cf.save_file, "-W", save_file_fd,
198 "-c", scount, "-s", ssnap,
199 "-m", medium_font, "-b", bold_font,
200 (cf.cfilter == NULL)? 0 : "-f",
201 (cf.cfilter == NULL)? 0 : cf.cfilter,
204 /* Parent process - read messages from the child process over the
208 /* Read a byte count from "sync_pipe[0]", terminated with a
209 colon; if the count is 0, the child process created the
210 capture file and we should start reading from it, otherwise
211 the capture couldn't start and the count is a count of bytes
212 of error message, and we should display the message. */
215 i = read(sync_pipe[0], &c, 1);
217 /* EOF - the child process died.
218 Close the read side of the sync pipe, remove the capture file,
219 and report the failure.
220 XXX - reap the child process and report the status in detail. */
222 unlink(cf.save_file);
223 g_free(cf.save_file);
225 simple_dialog(ESD_TYPE_WARN, NULL, "Capture child process died");
231 /* Child process handed us crap.
232 Close the read side of the sync pipe, remove the capture file,
233 and report the failure. */
235 unlink(cf.save_file);
236 g_free(cf.save_file);
238 simple_dialog(ESD_TYPE_WARN, NULL,
239 "Capture child process sent us a bad message");
242 byte_count = byte_count*10 + c - '0';
244 if (byte_count == 0) {
245 /* Success. Open the capture file, and set up to read it. */
246 err = start_tail_cap_file(cf.save_file, is_tempfile, &cf);
248 /* We were able to open and set up to read the capture file;
249 arrange that our callback be called whenever it's possible
250 to read from the sync pipe, so that it's called when
251 the child process wants to tell us something. */
252 cap_input_id = gtk_input_add_full(sync_pipe[0],
253 GDK_INPUT_READ|GDK_INPUT_EXCEPTION,
259 /* We weren't able to open the capture file; complain, and
260 close the sync pipe. */
261 simple_dialog(ESD_TYPE_WARN, NULL,
262 file_open_error_message(err, FALSE), cf.save_file);
264 /* Close the sync pipe. */
267 /* Don't unlink the save file - leave it around, for debugging
269 g_free(cf.save_file);
273 /* Failure - the child process sent us a message indicating
274 what the problem was. */
275 msg = g_malloc(byte_count + 1);
277 simple_dialog(ESD_TYPE_WARN, NULL,
278 "Capture child process failed, but its error message was too big.");
280 i = read(sync_pipe[0], msg, byte_count);
282 simple_dialog(ESD_TYPE_WARN, NULL,
283 "Capture child process failed: Error %s reading its error message.",
286 simple_dialog(ESD_TYPE_WARN, NULL,
287 "Capture child process failed: EOF reading its error message.");
289 simple_dialog(ESD_TYPE_WARN, NULL, msg);
292 /* Close the sync pipe. */
295 /* Get rid of the save file - the capture never started. */
296 unlink(cf.save_file);
297 g_free(cf.save_file);
305 capture_succeeded = capture();
306 if (quit_after_cap) {
307 /* DON'T unlink the save file. Presumably someone wants it. */
310 if (capture_succeeded) {
311 /* Capture succeeded; read in the capture file. */
312 if ((err = open_cap_file(cf.save_file, is_tempfile, &cf)) == 0) {
313 /* Set the read filter to NULL. */
315 err = read_cap_file(&cf);
318 /* We're not doing a capture any more, so we don't have a save
320 g_free(cf.save_file);
326 /* There's stuff to read from the sync pipe, meaning the child has sent
327 us a message, or the sync pipe has closed, meaning the child has
328 closed it (perhaps because it exited). */
330 cap_file_input_cb(gpointer data, gint source, GdkInputCondition condition)
332 capture_file *cf = (capture_file *)data;
333 char buffer[256+1], *p = buffer, *q = buffer;
336 gboolean exit_loop = FALSE;
342 char sigmsg_buf[6+1+3+1];
345 /* avoid reentrancy problems and stack overflow */
346 gtk_input_remove(cap_input_id);
348 if ((nread = read(sync_pipe[0], buffer, 256)) <= 0) {
349 /* The child has closed the sync pipe, meaning it's not going to be
350 capturing any more packets. Pick up its exit status, and
351 complain if it died of a signal. */
352 if (wait(&wstatus) != -1) {
353 /* XXX - are there any platforms on which we can run that *don't*
354 support POSIX.1's <sys/wait.h> and macros therein? */
355 wsignal = wstatus & 0177;
357 if (wstatus == 0177) {
358 /* It stopped, rather than exiting. "Should not happen." */
360 wsignal = (wstatus >> 8) & 0xFF;
364 coredumped = " - core dumped";
374 sigmsg = "Interrupted";
382 sigmsg = "Illegal instruction";
386 sigmsg = "Trace trap";
394 sigmsg = "Arithmetic exception";
402 sigmsg = "Bus error";
406 sigmsg = "Segmentation violation";
409 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
410 Linux is POSIX compliant. These are not POSIX-defined signals ---
411 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
413 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
414 were omitted from POSIX.1 because their behavior is
415 implementation dependent and could not be adequately catego-
416 rized. Conforming implementations may deliver these sig-
417 nals, but must document the circumstances under which they
418 are delivered and note any restrictions concerning their
424 sigmsg = "Bad system call";
429 sigmsg = "Broken pipe";
433 sigmsg = "Alarm clock";
437 sigmsg = "Terminated";
441 sprintf(sigmsg_buf, "Signal %d", wsignal);
445 simple_dialog(ESD_TYPE_WARN, NULL,
446 "Child capture process %s: %s%s", msg, sigmsg, coredumped);
450 /* Read what remains of the capture file, and finish the capture.
451 XXX - do something if this fails? */
452 err = finish_tail_cap_file(cf);
454 /* We're not doing a capture any more, so we don't have a save
456 g_free(cf->save_file);
457 cf->save_file = NULL;
462 buffer[nread] = '\0';
465 /* look for (possibly multiple) '*' */
473 /* XXX should handle the case of a pipe full (i.e. no star found) */
482 /* Read from the capture file the number of records the child told us
484 XXX - do something if this fails? */
485 err = continue_tail_cap_file(cf, to_read);
487 /* restore pipe handler */
488 cap_input_id = gtk_input_add_full (sync_pipe[0],
489 GDK_INPUT_READ|GDK_INPUT_EXCEPTION,
498 * Timeout, in milliseconds, for reads from the stream of captured packets.
500 #define CAP_READ_TIMEOUT 250
502 /* Do the low-level work of a capture.
503 Returns TRUE if it succeeds, FALSE otherwise. */
507 GtkWidget *cap_w, *main_vb, *count_lb, *tcp_lb, *udp_lb, *icmp_lb,
508 *ospf_lb, *gre_lb, *netbios_lb, *ipx_lb, *vines_lb, *other_lb, *stop_bt;
510 gchar err_str[PCAP_ERRBUF_SIZE], label_str[32];
512 bpf_u_int32 netnum, netmask;
513 time_t upd_time, cur_time;
518 struct timeval timeout;
522 WORD wVersionRequested;
526 /* Initialize Windows Socket if we are in a WIN32 OS
527 This needs to be done before querying the interface for network/netmask */
529 wVersionRequested = MAKEWORD( 1, 1 );
530 err = WSAStartup( wVersionRequested, &wsaData );
532 snprintf(errmsg, sizeof errmsg,
533 "Couldn't initialize Windows Sockets.");
542 ld.linktype = WTAP_ENCAP_UNKNOWN;
550 ld.counts.netbios = 0;
555 /* Open the network interface to capture from it. */
556 pch = pcap_open_live(cf.iface, cf.snap, 1, CAP_READ_TIMEOUT, err_str);
559 /* Well, we couldn't start the capture.
560 If this is a child process that does the capturing in sync
561 mode or fork mode, it shouldn't do any UI stuff until we pop up the
562 capture-progress window, and, since we couldn't start the
563 capture, we haven't popped it up. */
564 if (!capture_child) {
565 while (gtk_events_pending()) gtk_main_iteration();
567 snprintf(errmsg, sizeof errmsg,
568 "The capture session could not be initiated (%s).\n"
569 "Please check to make sure you have sufficient permissions, and that\n"
570 "you have the proper interface specified.", err_str);
575 /* A capture filter was specified; set it up. */
576 if (pcap_lookupnet (cf.iface, &netnum, &netmask, err_str) < 0) {
577 snprintf(errmsg, sizeof errmsg,
578 "Can't use filter: Couldn't obtain netmask info (%s).", err_str);
581 if (pcap_compile(pch, &cf.fcode, cf.cfilter, 1, netmask) < 0) {
582 snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
586 if (pcap_setfilter(pch, &cf.fcode) < 0) {
587 snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
593 /* Set up to write to the capture file. */
594 ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_datalink(pch));
595 if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
596 strcpy(errmsg, "The network you're capturing from is of a type"
597 " that Ethereal doesn't support.");
600 ld.pdh = wtap_dump_fdopen(cf.save_file_fd, WTAP_FILE_PCAP,
601 ld.linktype, pcap_snapshot(pch), &err);
603 if (ld.pdh == NULL) {
604 /* We couldn't set up to write to the capture file. */
607 case WTAP_ERR_CANT_OPEN:
608 strcpy(errmsg, "The file to which the capture would be saved"
609 " couldn't be created for some unknown reason.");
612 case WTAP_ERR_SHORT_WRITE:
613 strcpy(errmsg, "A full header couldn't be written to the file"
614 " to which the capture would be saved.");
619 sprintf(errmsg, "The file to which the capture would be"
620 " saved (\"%s\") could not be opened: Error %d.",
623 sprintf(errmsg, "The file to which the capture would be"
624 " saved (\"%s\") could not be opened: %s.",
625 cf.save_file, strerror(err));
633 /* Well, we should be able to start capturing.
635 This is the child process for a sync mode capture, so sync out
636 the capture file, so the header makes it to the file system,
637 and send a "capture started successfully and capture file created"
638 message to our parent so that they'll open the capture file and
639 update its windows to indicate that we have a live capture in
641 fflush(wtap_dump_file(ld.pdh));
645 cap_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
646 gtk_window_set_title(GTK_WINDOW(cap_w), "Ethereal: Capture / Playback");
648 /* Container for capture display widgets */
649 main_vb = gtk_vbox_new(FALSE, 1);
650 gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
651 gtk_container_add(GTK_CONTAINER(cap_w), main_vb);
652 gtk_widget_show(main_vb);
654 count_lb = gtk_label_new("Count: 0");
655 gtk_box_pack_start(GTK_BOX(main_vb), count_lb, FALSE, FALSE, 3);
656 gtk_widget_show(count_lb);
658 tcp_lb = gtk_label_new("TCP: 0 (0.0%)");
659 gtk_box_pack_start(GTK_BOX(main_vb), tcp_lb, FALSE, FALSE, 3);
660 gtk_widget_show(tcp_lb);
662 udp_lb = gtk_label_new("UDP: 0 (0.0%)");
663 gtk_box_pack_start(GTK_BOX(main_vb), udp_lb, FALSE, FALSE, 3);
664 gtk_widget_show(udp_lb);
666 icmp_lb = gtk_label_new("ICMP: 0 (0.0%)");
667 gtk_box_pack_start(GTK_BOX(main_vb), icmp_lb, FALSE, FALSE, 3);
668 gtk_widget_show(icmp_lb);
670 ospf_lb = gtk_label_new("OSPF: 0 (0.0%)");
671 gtk_box_pack_start(GTK_BOX(main_vb), ospf_lb, FALSE, FALSE, 3);
672 gtk_widget_show(ospf_lb);
674 gre_lb = gtk_label_new("GRE: 0 (0.0%)");
675 gtk_box_pack_start(GTK_BOX(main_vb), gre_lb, FALSE, FALSE, 3);
676 gtk_widget_show(gre_lb);
678 netbios_lb = gtk_label_new("NetBIOS: 0 (0.0%)");
679 gtk_box_pack_start(GTK_BOX(main_vb), netbios_lb, FALSE, FALSE, 3);
680 gtk_widget_show(netbios_lb);
682 ipx_lb = gtk_label_new("IPX: 0 (0.0%)");
683 gtk_box_pack_start(GTK_BOX(main_vb), ipx_lb, FALSE, FALSE, 3);
684 gtk_widget_show(ipx_lb);
686 vines_lb = gtk_label_new("VINES: 0 (0.0%)");
687 gtk_box_pack_start(GTK_BOX(main_vb), vines_lb, FALSE, FALSE, 3);
688 gtk_widget_show(vines_lb);
690 other_lb = gtk_label_new("Other: 0 (0.0%)");
691 gtk_box_pack_start(GTK_BOX(main_vb), other_lb, FALSE, FALSE, 3);
692 gtk_widget_show(other_lb);
694 /* allow user to either click a stop button, or the close button on
695 the window to stop a capture in progress. */
696 stop_bt = gtk_button_new_with_label ("Stop");
697 gtk_signal_connect(GTK_OBJECT(stop_bt), "clicked",
698 GTK_SIGNAL_FUNC(capture_stop_cb), (gpointer) &ld);
699 gtk_signal_connect(GTK_OBJECT(cap_w), "delete_event",
700 GTK_SIGNAL_FUNC(capture_delete_cb), (gpointer) &ld);
701 gtk_box_pack_end(GTK_BOX(main_vb), stop_bt, FALSE, FALSE, 3);
702 GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
703 gtk_widget_grab_default(stop_bt);
704 GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
705 gtk_widget_grab_default(stop_bt);
706 gtk_widget_show(stop_bt);
708 gtk_widget_show(cap_w);
711 upd_time = time(NULL);
713 pcap_fd = pcap_fileno(pch);
716 while (gtk_events_pending()) gtk_main_iteration();
719 * Sigh. The semantics of the read timeout argument to
720 * "pcap_open_live()" aren't particularly well specified by
721 * the "pcap" man page - at least with the BSD BPF code, the
722 * intent appears to be, at least in part, a way of cutting
723 * down the number of reads done on a capture, by blocking
724 * until the buffer fills or a timer expires - and the Linux
725 * libpcap doesn't actually support it, so we can't use it
726 * to break out of the "pcap_dispatch()" every 1/4 of a second
729 * Thus, on Linux, we do a "select()" on the file descriptor for the
730 * capture, with a timeout of CAP_READ_TIMEOUT milliseconds, or
731 * CAP_READ_TIMEOUT*1000 microseconds.
734 FD_SET(pcap_fd, &set1);
736 timeout.tv_usec = CAP_READ_TIMEOUT*1000;
737 if (select(pcap_fd+1, &set1, NULL, NULL, &timeout) != 0) {
739 * "select()" says we can read from it without blocking; go for
742 inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
746 inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
749 ld.sync_packets += inpkts;
750 /* Only update once a second so as not to overload slow displays */
751 cur_time = time(NULL);
752 if (cur_time > upd_time) {
755 sprintf(label_str, "Count: %d", ld.counts.total);
756 gtk_label_set(GTK_LABEL(count_lb), label_str);
758 sprintf(label_str, "TCP: %d (%.1f%%)", ld.counts.tcp,
759 pct(ld.counts.tcp, ld.counts.total));
760 gtk_label_set(GTK_LABEL(tcp_lb), label_str);
762 sprintf(label_str, "UDP: %d (%.1f%%)", ld.counts.udp,
763 pct(ld.counts.udp, ld.counts.total));
764 gtk_label_set(GTK_LABEL(udp_lb), label_str);
766 sprintf(label_str, "ICMP: %d (%.1f%%)", ld.counts.icmp,
767 pct(ld.counts.icmp, ld.counts.total));
768 gtk_label_set(GTK_LABEL(icmp_lb), label_str);
770 sprintf(label_str, "OSPF: %d (%.1f%%)", ld.counts.ospf,
771 pct(ld.counts.ospf, ld.counts.total));
772 gtk_label_set(GTK_LABEL(ospf_lb), label_str);
774 sprintf(label_str, "GRE: %d (%.1f%%)", ld.counts.gre,
775 pct(ld.counts.gre, ld.counts.total));
776 gtk_label_set(GTK_LABEL(gre_lb), label_str);
778 sprintf(label_str, "NetBIOS: %d (%.1f%%)", ld.counts.netbios,
779 pct(ld.counts.netbios, ld.counts.total));
780 gtk_label_set(GTK_LABEL(netbios_lb), label_str);
782 sprintf(label_str, "IPX: %d (%.1f%%)", ld.counts.ipx,
783 pct(ld.counts.ipx, ld.counts.total));
784 gtk_label_set(GTK_LABEL(ipx_lb), label_str);
786 sprintf(label_str, "VINES: %d (%.1f%%)", ld.counts.vines,
787 pct(ld.counts.vines, ld.counts.total));
788 gtk_label_set(GTK_LABEL(vines_lb), label_str);
790 sprintf(label_str, "Other: %d (%.1f%%)", ld.counts.other,
791 pct(ld.counts.other, ld.counts.total));
792 gtk_label_set(GTK_LABEL(other_lb), label_str);
794 /* do sync here, too */
795 fflush(wtap_dump_file(ld.pdh));
796 if (capture_child && ld.sync_packets) {
797 /* This is the child process for a sync mode capture, so send
798 our parent a message saying we've written out "ld.sync_packets"
799 packets to the capture file. */
801 sprintf(tmp, "%d*", ld.sync_packets);
802 write(1, tmp, strlen(tmp));
808 if (!wtap_dump_close(ld.pdh, &err)) {
809 /* XXX - in fork mode, this may not pop up, or, if it does,
810 it may disappear as soon as we exit.
812 We should have the parent process, while it's reading
813 the packet count update messages, catch error messages
814 and pop up a message box if it sees one. */
817 case WTAP_ERR_CANT_CLOSE:
818 simple_dialog(ESD_TYPE_WARN, NULL,
819 "The file to which the capture was being saved"
820 " couldn't be closed for some unknown reason.");
823 case WTAP_ERR_SHORT_WRITE:
824 simple_dialog(ESD_TYPE_WARN, NULL,
825 "Not all the data could be written to the file"
826 " to which the capture was being saved.");
830 simple_dialog(ESD_TYPE_WARN, NULL,
831 "The file to which the capture was being"
832 " saved (\"%s\") could not be closed: %s.",
833 cf.save_file, wtap_strerror(err));
839 gtk_grab_remove(GTK_WIDGET(cap_w));
840 gtk_widget_destroy(GTK_WIDGET(cap_w));
845 /* We couldn't even start the capture, so get rid of the capture
847 unlink(cf.save_file); /* silently ignore error */
848 g_free(cf.save_file);
851 /* This is the child process for a sync mode capture.
852 Send the error message to our parent, so they can display a
853 dialog box containing it. */
854 int msglen = strlen(errmsg);
856 sprintf(lenbuf, "%u;", msglen);
857 write(1, lenbuf, strlen(lenbuf));
858 write(1, errmsg, msglen);
860 /* Display the dialog box ourselves; there's no parent. */
861 simple_dialog(ESD_TYPE_WARN, NULL, errmsg);
870 pct(gint num, gint denom) {
872 return (float) num * 100.0 / (float) denom;
879 capture_delete_cb(GtkWidget *w, GdkEvent *event, gpointer data) {
880 capture_stop_cb(NULL, data);
884 capture_stop_cb(GtkWidget *w, gpointer data) {
885 loop_data *ld = (loop_data *) data;
891 capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
893 struct wtap_pkthdr whdr;
894 loop_data *ld = (loop_data *) user;
897 if ((++ld->counts.total >= ld->max) && (ld->max > 0))
902 /* "phdr->ts" may not necessarily be a "struct timeval" - it may
903 be a "struct bpf_timeval", with member sizes wired to 32
904 bits - and we may go that way ourselves in the future, so
905 copy the members individually. */
906 whdr.ts.tv_sec = phdr->ts.tv_sec;
907 whdr.ts.tv_usec = phdr->ts.tv_usec;
908 whdr.caplen = phdr->caplen;
909 whdr.len = phdr->len;
910 whdr.pkt_encap = ld->linktype;
912 /* XXX - do something if this fails */
913 wtap_dump(ld->pdh, &whdr, pd, &err);
916 /* Set the initial payload to the packet length, and the initial
917 captured payload to the capture length (other protocols may
918 reduce them if their headers say they're less). */
920 pi.captured_len = phdr->caplen;
922 switch (ld->linktype) {
923 case WTAP_ENCAP_ETHERNET:
924 capture_eth(pd, 0, &ld->counts);
926 case WTAP_ENCAP_FDDI:
927 case WTAP_ENCAP_FDDI_BITSWAPPED:
928 capture_fddi(pd, &ld->counts);
931 capture_tr(pd, 0, &ld->counts);
933 case WTAP_ENCAP_NULL:
934 capture_null(pd, &ld->counts);
937 capture_ppp(pd, &ld->counts);
939 case WTAP_ENCAP_RAW_IP:
940 capture_raw(pd, &ld->counts);
942 /* XXX - FreeBSD may append 4-byte ATM pseudo-header to DLT_ATM_RFC1483,
943 with LLC header following; we should implement it at some
948 #endif /* HAVE_LIBPCAP */