diff options
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | capture.c | 350 | ||||
-rw-r--r-- | doc/ethereal.pod.template | 34 | ||||
-rw-r--r-- | wiretap/libpcap.c | 64 | ||||
-rw-r--r-- | wiretap/libpcap.h | 64 |
5 files changed, 396 insertions, 117 deletions
@@ -132,6 +132,7 @@ Olivier Abad <oabad@cybercable.fr> { and HP-UX nettl traces LAPB, X.25 Plugins support + Support for capturing packet data from pipes } Thierry Andry <Thierry.Andry@advalvas.be> { @@ -1,7 +1,7 @@ /* capture.c * Routines for packet capture windows * - * $Id: capture.c,v 1.113 2000/07/21 15:56:15 gram Exp $ + * $Id: capture.c,v 1.114 2000/07/30 16:53:53 oabad Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -100,6 +100,9 @@ #include "prefs.h" #include "globals.h" +#include "wiretap/libpcap.h" +#include "wiretap/wtap-int.h" + #include "packet-clip.h" #include "packet-eth.h" #include "packet-fddi.h" @@ -134,6 +137,9 @@ typedef struct _loop_data { gint max; gint linktype; gint sync_packets; + gboolean from_pipe; /* TRUE if we are capturing data from a pipe */ + gboolean modified; /* TRUE if data in the pipe uses modified pcap headers */ + gboolean byte_swapped; /* TRUE if data in the pipe is byte swapped */ packet_counts counts; wtap_dumper *pdh; } loop_data; @@ -707,6 +713,226 @@ cap_file_input_cb(gpointer data, gint source, GdkInputCondition condition) */ #define CAP_READ_TIMEOUT 250 +#ifndef _WIN32 +/* Take carre of byte order in the libpcap headers read from pipes. + * (function taken from wiretap/libpcap.c) */ +static void +adjust_header(loop_data *ld, struct pcap_hdr *hdr, struct pcaprec_hdr *rechdr) +{ + if (ld->byte_swapped) { + /* Byte-swap the record header fields. */ + rechdr->ts_sec = BSWAP32(rechdr->ts_sec); + rechdr->ts_usec = BSWAP32(rechdr->ts_usec); + rechdr->incl_len = BSWAP32(rechdr->incl_len); + rechdr->orig_len = BSWAP32(rechdr->orig_len); + } + + /* In file format version 2.3, the "incl_len" and "orig_len" fields were + swapped, in order to match the BPF header layout. + + Unfortunately, some files were, according to a comment in the "libpcap" + source, written with version 2.3 in their headers but without the + interchanged fields, so if "incl_len" is greater than "orig_len" - which + would make no sense - we assume that we need to swap them. */ + if (hdr->version_major == 2 && + (hdr->version_minor < 3 || + (hdr->version_minor == 3 && rechdr->incl_len > rechdr->orig_len))) { + guint32 temp; + + temp = rechdr->orig_len; + rechdr->orig_len = rechdr->incl_len; + rechdr->incl_len = temp; + } +} + +/* Mimic pcap_open_live() for pipe captures + * We check if "pipename" is "-" (stdin) or a FIFO, open it, and read the + * header. + * N.B. : we can't read the libpcap formats used in RedHat 6.1 or SuSE 6.3 + * because we can't seek on pipes (see wiretap/libpcap.c for details) */ +static int +pipe_open_live(char *pipename, struct pcap_hdr *hdr, loop_data *ld, char *ebuf) +{ + struct stat pipe_stat; + int fd; + guint32 magic; + int bytes_read, b; + + if (strcmp(pipename, "-") == 0) fd = 0; /* read from stdin */ + else if (stat(pipename, &pipe_stat) == 0 && S_ISFIFO(pipe_stat.st_mode)) { + if ((fd = open(pipename, O_RDONLY)) == -1) return -1; + } else return -1; + + ld->from_pipe = TRUE; + /* read the pcap header */ + if (read(fd, &magic, sizeof magic) != sizeof magic) { + close(fd); + return -1; + } + + switch (magic) { + case PCAP_MAGIC: + /* Host that wrote it has our byte order, and was running + a program using either standard or ss990417 libpcap. */ + ld->byte_swapped = FALSE; + ld->modified = FALSE; + break; + case PCAP_MODIFIED_MAGIC: + /* Host that wrote it has our byte order, but was running + a program using either ss990915 or ss991029 libpcap. */ + ld->byte_swapped = FALSE; + ld->modified = TRUE; + break; + case PCAP_SWAPPED_MAGIC: + /* Host that wrote it has a byte order opposite to ours, + and was running a program using either standard or + ss990417 libpcap. */ + ld->byte_swapped = TRUE; + ld->modified = FALSE; + break; + case PCAP_SWAPPED_MODIFIED_MAGIC: + /* Host that wrote it out has a byte order opposite to + ours, and was running a program using either ss990915 + or ss991029 libpcap. */ + ld->byte_swapped = TRUE; + ld->modified = TRUE; + break; + default: + /* Not a "libpcap" type we know about. */ + close(fd); + return -1; + } + + /* Read the rest of the header */ + bytes_read = read(fd, hdr, sizeof(struct pcap_hdr)); + if (bytes_read <= 0) { + close(fd); + return -1; + } + while (bytes_read < sizeof(struct pcap_hdr)) + { + b = read(fd, ((char *)&hdr)+bytes_read, sizeof(struct pcap_hdr) - bytes_read); + if (b <= 0) { + close(fd); + return -1; + } + bytes_read += b; + } + if (ld->byte_swapped) { + /* Byte-swap the header fields about which we care. */ + hdr->version_major = BSWAP16(hdr->version_major); + hdr->version_minor = BSWAP16(hdr->version_minor); + hdr->snaplen = BSWAP32(hdr->snaplen); + hdr->network = BSWAP32(hdr->network); + } + if (hdr->version_major < 2) { + close(fd); + return -1; + } + + return fd; +} + +/* We read one record from the pipe, take care of byte order in the record + * header, write the record in the capture file, and update capture statistics. */ +static int +pipe_dispatch(int fd, loop_data *ld, struct pcap_hdr *hdr) +{ + struct wtap_pkthdr whdr; + struct pcaprec_modified_hdr rechdr; + int bytes_to_read, bytes_read, b; + u_char pd[WTAP_MAX_PACKET_SIZE]; + int err; + + /* read the record header */ + bytes_to_read = ld->modified ? sizeof rechdr : sizeof rechdr.hdr; + bytes_read = read(fd, &rechdr, bytes_to_read); + if (bytes_read <= 0) { + close(fd); + ld->go = FALSE; + return 0; + } + while (bytes_read < bytes_to_read) + { + b = read(fd, ((char *)&rechdr)+bytes_read, bytes_to_read - bytes_read); + if (b <= 0) { + close(fd); + ld->go = FALSE; + return 0; + } + bytes_read += b; + } + /* take care of byte order */ + adjust_header(ld, hdr, &rechdr.hdr); + if (rechdr.hdr.incl_len > WTAP_MAX_PACKET_SIZE) { + close(fd); + ld->go = FALSE; + return 0; + } + /* read the packet data */ + bytes_read = read(fd, pd, rechdr.hdr.incl_len); + if (bytes_read <= 0) { + close(fd); + ld->go = FALSE; + return 0; + } + while (bytes_read < rechdr.hdr.incl_len) + { + b = read(fd, pd+bytes_read, rechdr.hdr.incl_len - bytes_read); + if (b <= 0) { + close(fd); + ld->go = FALSE; + return 0; + } + bytes_read += b; + } + /* dump the packet data to the capture file */ + whdr.ts.tv_sec = rechdr.hdr.ts_sec; + whdr.ts.tv_usec = rechdr.hdr.ts_usec; + whdr.caplen = rechdr.hdr.incl_len; + whdr.len = rechdr.hdr.orig_len; + whdr.pkt_encap = ld->linktype; + wtap_dump(ld->pdh, &whdr, NULL, pd, &err); + + /* Set the initial payload to the packet length, and the initial + captured payload to the capture length (other protocols may + reduce them if their headers say they're less). */ + pi.len = whdr.len; + pi.captured_len = whdr.caplen; + + /* update capture statistics */ + switch (ld->linktype) { + case WTAP_ENCAP_ETHERNET: + capture_eth(pd, 0, &ld->counts); + break; + case WTAP_ENCAP_FDDI: + case WTAP_ENCAP_FDDI_BITSWAPPED: + capture_fddi(pd, &ld->counts); + break; + case WTAP_ENCAP_TR: + capture_tr(pd, 0, &ld->counts); + break; + case WTAP_ENCAP_NULL: + capture_null(pd, &ld->counts); + break; + case WTAP_ENCAP_PPP: + capture_ppp(pd, 0, &ld->counts); + break; + case WTAP_ENCAP_RAW_IP: + capture_raw(pd, &ld->counts); + break; + case WTAP_ENCAP_LINUX_ATM_CLIP: + capture_clip(pd, &ld->counts); + break; + /* XXX - FreeBSD may append 4-byte ATM pseudo-header to DLT_ATM_RFC1483, + with LLC header following; we should implement it at some + point. */ + } + + return 1; +} +#endif + /* Do the low-level work of a capture. Returns TRUE if it succeeds, FALSE otherwise. */ int @@ -724,12 +950,16 @@ capture(void) #ifdef linux fd_set set1; struct timeval timeout; - int pcap_fd; + int pcap_fd = 0; #endif #ifdef _WIN32 WORD wVersionRequested; WSADATA wsaData; #endif +#ifndef _WIN32 + int pipe_fd = -1; + struct pcap_hdr hdr; +#endif /* Initialize Windows Socket if we are in a WIN32 OS This needs to be done before querying the interface for network/netmask */ @@ -748,6 +978,7 @@ capture(void) ld.counts.total = 0; ld.max = cfile.count; ld.linktype = WTAP_ENCAP_UNKNOWN; + ld.from_pipe = FALSE; ld.sync_packets = 0; ld.counts.sctp = 0; ld.counts.tcp = 0; @@ -765,6 +996,26 @@ capture(void) pch = pcap_open_live(cfile.iface, cfile.snap, 1, CAP_READ_TIMEOUT, err_str); if (pch == NULL) { +#ifndef _WIN32 + /* try to open cfile.iface as a pipe */ + pipe_fd = pipe_open_live(cfile.iface, &hdr, &ld, err_str); + + if (pipe_fd == -1) { + /* Well, we couldn't start the capture. + If this is a child process that does the capturing in sync + mode or fork mode, it shouldn't do any UI stuff until we pop up the + capture-progress window, and, since we couldn't start the + capture, we haven't popped it up. */ + if (!capture_child) { + while (gtk_events_pending()) gtk_main_iteration(); + } + snprintf(errmsg, sizeof errmsg, + "The capture session could not be initiated (%s).\n" + "Please check to make sure you have sufficient permissions, and that\n" + "you have the proper interface or pipe specified.", err_str); + goto error; + } +#else /* Well, we couldn't start the capture. If this is a child process that does the capturing in sync mode or fork mode, it shouldn't do any UI stuff until we pop up the @@ -774,13 +1025,15 @@ capture(void) while (gtk_events_pending()) gtk_main_iteration(); } snprintf(errmsg, sizeof errmsg, - "The capture session could not be initiated (%s).\n" - "Please check to make sure you have sufficient permissions, and that\n" - "you have the proper interface specified.", err_str); + "The capture session could not be initiated (%s).\n" + "Please check to make sure you have sufficient permissions, and that\n" + "you have the proper interface specified.", err_str); goto error; +#endif } - if (cfile.cfilter) { + /* capture filters only work on real interfaces */ + if (cfile.cfilter && !ld.from_pipe) { /* A capture filter was specified; set it up. */ if (pcap_lookupnet (cfile.iface, &netnum, &netmask, err_str) < 0) { snprintf(errmsg, sizeof errmsg, @@ -800,14 +1053,15 @@ capture(void) } /* Set up to write to the capture file. */ - ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_datalink(pch)); + ld.linktype = wtap_pcap_encap_to_wtap_encap(ld.from_pipe ? hdr.network + : pcap_datalink(pch)); if (ld.linktype == WTAP_ENCAP_UNKNOWN) { strcpy(errmsg, "The network you're capturing from is of a type" " that Ethereal doesn't support."); goto error; } ld.pdh = wtap_dump_fdopen(cfile.save_file_fd, WTAP_FILE_PCAP, - ld.linktype, pcap_snapshot(pch), &err); + ld.linktype, ld.from_pipe ? hdr.snaplen : pcap_snapshot(pch), &err); if (ld.pdh == NULL) { /* We couldn't set up to write to the capture file. */ @@ -929,41 +1183,60 @@ capture(void) upd_time = time(NULL); #ifdef linux - pcap_fd = pcap_fileno(pch); + if (!ld.from_pipe) pcap_fd = pcap_fileno(pch); #endif while (ld.go) { while (gtk_events_pending()) gtk_main_iteration(); + + if (ld.from_pipe) { + FD_ZERO(&set1); + FD_SET(pipe_fd, &set1); + timeout.tv_sec = 0; + timeout.tv_usec = CAP_READ_TIMEOUT*1000; + if (select(pipe_fd+1, &set1, NULL, NULL, &timeout) != 0) { + /* + * "select()" says we can read from the pipe without blocking; go for + * it. We are not sure we can read a whole record, but at least the + * begninning of one. pipe_dispatch() will block reading the whole + * record. + */ + inpkts = pipe_dispatch(pipe_fd, &ld, &hdr); + } else + inpkts = 0; + } + else { #ifdef linux - /* - * Sigh. The semantics of the read timeout argument to - * "pcap_open_live()" aren't particularly well specified by - * the "pcap" man page - at least with the BSD BPF code, the - * intent appears to be, at least in part, a way of cutting - * down the number of reads done on a capture, by blocking - * until the buffer fills or a timer expires - and the Linux - * libpcap doesn't actually support it, so we can't use it - * to break out of the "pcap_dispatch()" every 1/4 of a second - * or so. - * - * Thus, on Linux, we do a "select()" on the file descriptor for the - * capture, with a timeout of CAP_READ_TIMEOUT milliseconds, or - * CAP_READ_TIMEOUT*1000 microseconds. - */ - FD_ZERO(&set1); - FD_SET(pcap_fd, &set1); - timeout.tv_sec = 0; - timeout.tv_usec = CAP_READ_TIMEOUT*1000; - if (select(pcap_fd+1, &set1, NULL, NULL, &timeout) != 0) { /* - * "select()" says we can read from it without blocking; go for - * it. + * Sigh. The semantics of the read timeout argument to + * "pcap_open_live()" aren't particularly well specified by + * the "pcap" man page - at least with the BSD BPF code, the + * intent appears to be, at least in part, a way of cutting + * down the number of reads done on a capture, by blocking + * until the buffer fills or a timer expires - and the Linux + * libpcap doesn't actually support it, so we can't use it + * to break out of the "pcap_dispatch()" every 1/4 of a second + * or so. + * + * Thus, on Linux, we do a "select()" on the file descriptor for the + * capture, with a timeout of CAP_READ_TIMEOUT milliseconds, or + * CAP_READ_TIMEOUT*1000 microseconds. */ - inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld); - } else - inpkts = 0; + FD_ZERO(&set1); + FD_SET(pcap_fd, &set1); + timeout.tv_sec = 0; + timeout.tv_usec = CAP_READ_TIMEOUT*1000; + if (select(pcap_fd+1, &set1, NULL, NULL, &timeout) != 0) { + /* + * "select()" says we can read from it without blocking; go for + * it. + */ + inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld); + } else + inpkts = 0; #else - inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld); + inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld); #endif + } if (inpkts > 0) ld.sync_packets += inpkts; /* Only update once a second so as not to overload slow displays */ @@ -1057,7 +1330,10 @@ capture(void) break; } } - pcap_close(pch); + if (ld.from_pipe) + close(pipe_fd); + else + pcap_close(pch); gtk_grab_remove(GTK_WIDGET(cap_w)); gtk_widget_destroy(GTK_WIDGET(cap_w)); @@ -1083,7 +1359,7 @@ error: /* Display the dialog box ourselves; there's no parent. */ simple_dialog(ESD_TYPE_CRIT, NULL, errmsg); } - if (pch != NULL) + if (pch != NULL && !ld.from_pipe) pcap_close(pch); return FALSE; diff --git a/doc/ethereal.pod.template b/doc/ethereal.pod.template index 5b5fef077d..7ad41d0ff9 100644 --- a/doc/ethereal.pod.template +++ b/doc/ethereal.pod.template @@ -101,9 +101,11 @@ Prints the version and options and exits. =item -i -Sets the name of the network interface to use for live packet capture. -It should match one of the names listed in "B<netstat -i>" or -"B<ifconfig -a>". +Sets the name of the network interface or pipe to use for live packet capture. +Network interface names should match one of the names listed in "B<netstat -i>" +or "B<ifconfig -a>". +Pipe names should be either the name of a FIFO (named pipe) or ``-'' to read +data from the standard input. Data read from pipes must be in libpcap format. =item -k @@ -532,19 +534,19 @@ The I<Capture Preferences> dialog lets you specify various parameters for capturing live packet data. The I<Interface:> combo box lets you specify the interface from which to -capture packet data. The I<Count:> entry specifies the number of -packets to capture. Entering 0 will capture packets indefinitely. The -I<Filter:> entry lets you specify the capture filter using a -tcpdump-style filter string as described above. The I<File:> entry -specifies the file to save to, as in the I<Printer Options> dialog -above. You can specify the maximum number of bytes to capture per -packet with the I<Capture length> entry, can specify that the display -should be updated as packets are captured with the I<Update list of -packets in real time> check box, can specify whether in such a capture -the packet list pane should scroll to show the most recently captured -packets with the I<Automatic scrolling in live capture> check box, and -can specify whether addresses should be translated to names in the -display with the I<Enable name resolution> check box. +capture packet data, or the name of a FIFO from which to get the packet data. +The I<Count:> entry specifies the number of packets to capture. Entering 0 +will capture packets indefinitely. The I<Filter:> entry lets you specify the +capture filter using a tcpdump-style filter string as described above. The +I<File:> entry specifies the file to save to, as in the I<Printer Options> +dialog above. You can specify the maximum number of bytes to capture per +packet with the I<Capture length> entry, can specify that the display should be +updated as packets are captured with the I<Update list of packets in real time> +check box, can specify whether in such a capture the packet list pane should +scroll to show the most recently captured packets with the I<Automatic +scrolling in live capture> check box, and can specify whether addresses should +be translated to names in the display with the I<Enable name resolution> check +box. =item Display Options diff --git a/wiretap/libpcap.c b/wiretap/libpcap.c index 25ed5466ed..c12a4b34e1 100644 --- a/wiretap/libpcap.c +++ b/wiretap/libpcap.c @@ -1,6 +1,6 @@ /* libpcap.c * - * $Id: libpcap.c,v 1.36 2000/07/26 06:04:32 guy Exp $ + * $Id: libpcap.c,v 1.37 2000/07/30 16:54:11 oabad Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -33,73 +33,11 @@ /* See source to the "libpcap" library for information on the "libpcap" file format. */ -/* Magic numbers in "libpcap" files. - - "libpcap" file records are written in the byte order of the host that - writes them, and the reader is expected to fix this up. - - PCAP_MAGIC is the magic number, in host byte order; PCAP_SWAPPED_MAGIC - is a byte-swapped version of that. - - PCAP_MODIFIED_MAGIC is for Alexey Kuznetsov's modified "libpcap" - format, as generated on Linux systems that have a "libpcap" with - his patches, at - - http://ftp.sunet.se/pub/os/Linux/ip-routing/lbl-tools/ - - applied; PCAP_SWAPPED_MODIFIED_MAGIC is the byte-swapped version. */ -#define PCAP_MAGIC 0xa1b2c3d4 -#define PCAP_SWAPPED_MAGIC 0xd4c3b2a1 -#define PCAP_MODIFIED_MAGIC 0xa1b2cd34 -#define PCAP_SWAPPED_MODIFIED_MAGIC 0x34cdb2a1 - /* On some systems, the FDDI MAC addresses are bit-swapped. */ #if !defined(ultrix) && !defined(__alpha) && !defined(__bsdi__) #define BIT_SWAPPED_MAC_ADDRS #endif -/* "libpcap" file header (minus magic number). */ -struct pcap_hdr { - guint16 version_major; /* major version number */ - guint16 version_minor; /* minor version number */ - gint32 thiszone; /* GMT to local correction */ - guint32 sigfigs; /* accuracy of timestamps */ - guint32 snaplen; /* max length of captured packets, in octets */ - guint32 network; /* data link type */ -}; - -/* "libpcap" record header. */ -struct pcaprec_hdr { - guint32 ts_sec; /* timestamp seconds */ - guint32 ts_usec; /* timestamp microseconds */ - guint32 incl_len; /* number of octets of packet saved in file */ - guint32 orig_len; /* actual length of packet */ -}; - -/* "libpcap" record header for Alexey's patched version. */ -struct pcaprec_modified_hdr { - struct pcaprec_hdr hdr; /* the regular header */ - guint32 ifindex; /* index, in *capturing* machine's list of - interfaces, of the interface on which this - packet came in. */ - guint16 protocol; /* Ethernet packet type */ - guint8 pkt_type; /* broadcast/multicast/etc. indication */ - guint8 pad; /* pad to a 4-byte boundary */ -}; - -/* "libpcap" record header for Alexey's patched version in its ss990915 - incarnation; this version shows up in SuSE Linux 6.3. */ -struct pcaprec_ss990915_hdr { - struct pcaprec_hdr hdr; /* the regular header */ - guint32 ifindex; /* index, in *capturing* machine's list of - interfaces, of the interface on which this - packet came in. */ - guint16 protocol; /* Ethernet packet type */ - guint8 pkt_type; /* broadcast/multicast/etc. indication */ - guint8 cpu1, cpu2; /* SMP debugging gunk? */ - guint8 pad[3]; /* pad to a 4-byte boundary */ -}; - static int libpcap_read(wtap *wth, int *err); static void adjust_header(wtap *wth, struct pcaprec_hdr *hdr); static void libpcap_close(wtap *wth); diff --git a/wiretap/libpcap.h b/wiretap/libpcap.h index e01422fe13..1e4e409ac0 100644 --- a/wiretap/libpcap.h +++ b/wiretap/libpcap.h @@ -1,6 +1,6 @@ /* libpcap.h * - * $Id: libpcap.h,v 1.7 2000/01/22 06:22:39 guy Exp $ + * $Id: libpcap.h,v 1.8 2000/07/30 16:54:12 oabad Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -21,6 +21,68 @@ * */ +/* Magic numbers in "libpcap" files. + + "libpcap" file records are written in the byte order of the host that + writes them, and the reader is expected to fix this up. + + PCAP_MAGIC is the magic number, in host byte order; PCAP_SWAPPED_MAGIC + is a byte-swapped version of that. + + PCAP_MODIFIED_MAGIC is for Alexey Kuznetsov's modified "libpcap" + format, as generated on Linux systems that have a "libpcap" with + his patches, at + + http://ftp.sunet.se/pub/os/Linux/ip-routing/lbl-tools/ + + applied; PCAP_SWAPPED_MODIFIED_MAGIC is the byte-swapped version. */ +#define PCAP_MAGIC 0xa1b2c3d4 +#define PCAP_SWAPPED_MAGIC 0xd4c3b2a1 +#define PCAP_MODIFIED_MAGIC 0xa1b2cd34 +#define PCAP_SWAPPED_MODIFIED_MAGIC 0x34cdb2a1 + +/* "libpcap" file header (minus magic number). */ +struct pcap_hdr { + guint16 version_major; /* major version number */ + guint16 version_minor; /* minor version number */ + gint32 thiszone; /* GMT to local correction */ + guint32 sigfigs; /* accuracy of timestamps */ + guint32 snaplen; /* max length of captured packets, in octets */ + guint32 network; /* data link type */ +}; + +/* "libpcap" record header. */ +struct pcaprec_hdr { + guint32 ts_sec; /* timestamp seconds */ + guint32 ts_usec; /* timestamp microseconds */ + guint32 incl_len; /* number of octets of packet saved in file */ + guint32 orig_len; /* actual length of packet */ +}; + +/* "libpcap" record header for Alexey's patched version. */ +struct pcaprec_modified_hdr { + struct pcaprec_hdr hdr; /* the regular header */ + guint32 ifindex; /* index, in *capturing* machine's list of + interfaces, of the interface on which this + packet came in. */ + guint16 protocol; /* Ethernet packet type */ + guint8 pkt_type; /* broadcast/multicast/etc. indication */ + guint8 pad; /* pad to a 4-byte boundary */ +}; + +/* "libpcap" record header for Alexey's patched version in its ss990915 + incarnation; this version shows up in SuSE Linux 6.3. */ +struct pcaprec_ss990915_hdr { + struct pcaprec_hdr hdr; /* the regular header */ + guint32 ifindex; /* index, in *capturing* machine's list of + interfaces, of the interface on which this + packet came in. */ + guint16 protocol; /* Ethernet packet type */ + guint8 pkt_type; /* broadcast/multicast/etc. indication */ + guint8 cpu1, cpu2; /* SMP debugging gunk? */ + guint8 pad[3]; /* pad to a 4-byte boundary */ +}; + int libpcap_open(wtap *wth, int *err); gboolean libpcap_dump_open(wtap_dumper *wdh, int *err); int libpcap_dump_can_write_encap(int filetype, int encap); |