summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--capture.c102
-rw-r--r--ethereal.c19
-rw-r--r--file.h8
-rw-r--r--wiretap/file.c106
-rw-r--r--wiretap/libpcap.c154
-rw-r--r--wiretap/libpcap.h4
-rw-r--r--wiretap/netmon.c7
-rw-r--r--wiretap/netxray.c8
-rw-r--r--wiretap/wtap.c26
-rw-r--r--wiretap/wtap.h69
10 files changed, 410 insertions, 93 deletions
diff --git a/capture.c b/capture.c
index 7fef47e3e9..bbfd0c99c7 100644
--- a/capture.c
+++ b/capture.c
@@ -1,7 +1,7 @@
/* capture.c
* Routines for packet capture windows
*
- * $Id: capture.c,v 1.52 1999/08/15 22:31:22 guy Exp $
+ * $Id: capture.c,v 1.53 1999/08/18 04:17:26 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -309,8 +309,8 @@ capture_prep_cb(GtkWidget *w, gpointer d) {
static void
capture_prep_ok_cb(GtkWidget *ok_bt, gpointer parent_w) {
GtkWidget *if_cb, *filter_te, *count_cb, *snap_sb;
-
gchar *filter_text;
+ char tmpname[128+1];
if_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_IFACE_KEY);
filter_te = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILT_KEY);
@@ -341,23 +341,27 @@ capture_prep_ok_cb(GtkWidget *ok_bt, gpointer parent_w) {
unlink(cf.save_file); /* silently ignore error */
g_free(cf.save_file);
}
- cf.save_file = tempnam(NULL, "ether");
+ cf.save_file_fd = create_tempfile(tmpname, sizeof tmpname, "ether");
+ cf.save_file = strdup(tmpname);
cf.user_saved = 0;
if( fork_mode ){ /* use fork() for capture */
int fork_child;
char ssnap[24];
char scount[24]; /* need a constant for len of numbers */
+ char save_file_fd[24];
int err;
- sprintf(ssnap,"%d",cf.snap); /* in liu of itoa */
+ sprintf(ssnap,"%d",cf.snap); /* in lieu of itoa */
sprintf(scount,"%d",cf.count);
+ sprintf(save_file_fd,"%d",cf.save_file_fd);
signal(SIGCHLD, SIG_IGN);
if (sync_mode) pipe(sync_pipe);
if((fork_child = fork()) == 0){
/* args: -k -- capture
* -i interface specification
* -w file to write
+ * -W file descriptor to write
* -c count to capture
* -Q quit after capture (forces -k)
* -s snaplen
@@ -369,18 +373,22 @@ capture_prep_ok_cb(GtkWidget *ok_bt, gpointer parent_w) {
close(1);
dup(sync_pipe[1]);
close(sync_pipe[0]);
- execlp(ethereal_path,"ethereal","-k","-Q","-i",cf.iface,"-w",cf.save_file,
+ execlp(ethereal_path, "ethereal", "-k", "-Q", "-i", cf.iface,
+ "-w", cf.save_file, "-W", save_file_fd,
"-c", scount, "-s", ssnap, "-S",
"-m", medium_font, "-b", bold_font,
- (cf.cfilter == NULL)? 0 : "-f", (cf.cfilter == NULL)? 0 : cf.cfilter,
- 0);
+ (cf.cfilter == NULL)? 0 : "-f",
+ (cf.cfilter == NULL)? 0 : cf.cfilter,
+ (const char *)NULL);
}
else {
- execlp(ethereal_path,"ethereal","-k","-Q","-i",cf.iface,"-w",cf.save_file,
+ execlp(ethereal_path, "ethereal", "-k", "-Q", "-i", cf.iface,
+ "-w", cf.save_file, "-W", save_file_fd,
"-c", scount, "-s", ssnap,
"-m", medium_font, "-b", bold_font,
- (cf.cfilter == NULL)? 0 : "-f", (cf.cfilter == NULL)? 0 : cf.cfilter,
- 0);
+ (cf.cfilter == NULL)? 0 : "-f",
+ (cf.cfilter == NULL)? 0 : cf.cfilter,
+ (const char *)NULL);
}
}
else {
@@ -419,9 +427,10 @@ typedef struct _loop_data {
gint go;
gint max;
gint linktype;
+ gint wtap_linktype;
gint sync_packets;
packet_counts counts;
- pcap_dumper_t *pdh;
+ wtap_dumper *pdh;
} loop_data;
void
@@ -434,6 +443,8 @@ capture(void) {
bpf_u_int32 netnum, netmask;
time_t upd_time, cur_time;
int err, inpkts;
+ char *errmsg;
+ char errmsg_errno[1024+1];
ld.go = TRUE;
ld.counts.total = 0;
@@ -454,42 +465,60 @@ capture(void) {
pch = pcap_open_live(cf.iface, cf.snap, 1, 250, err_str);
if (pch) {
- /* save the old new umask and set the new one to readable only by the user */
- mode_t old_umask = umask(0066);
-
- /* Have libpcap create the empty dumpfile */
- ld.pdh = pcap_dump_open(pch, cf.save_file);
-
- /* reset the umask to the original value */
- (void) umask(old_umask);
+ ld.linktype = pcap_datalink(pch);
+ ld.wtap_linktype = wtap_pcap_encap_to_wtap_encap(ld.linktype);
+ ld.pdh = wtap_dump_fdopen(cf.save_file_fd, WTAP_FILE_PCAP,
+ ld.wtap_linktype, pcap_snapshot(pch), &err);
if (ld.pdh == NULL) { /* We have an error */
- snprintf(err_str, PCAP_ERRBUF_SIZE, "Error trying to save capture to "
- "file:\n%s", pcap_geterr(pch));
+ switch (err) {
+
+ case WTAP_ERR_CANT_OPEN:
+ errmsg = "The file to which the capture would be saved"
+ " couldn't be created for some unknown reason.";
+ break;
+
+ case WTAP_ERR_SHORT_WRITE:
+ errmsg = "A full header couldn't be written to the file"
+ " to which the capture would be saved.";
+ break;
+
+ default:
+ if (err < 0) {
+ sprintf(errmsg_errno, "The file to which the capture would be"
+ " saved (\"%%s\") could not be opened: Error %d.",
+ err);
+ } else {
+ sprintf(errmsg_errno, "The file to which the capture would be"
+ " saved (\"%%s\") could not be opened: %s.",
+ strerror(err));
+ }
+ errmsg = errmsg_errno;
+ break;
+ }
+ snprintf(err_str, PCAP_ERRBUF_SIZE, errmsg, cf.save_file);
simple_dialog(ESD_TYPE_WARN, NULL, err_str);
pcap_close(pch);
return;
}
- ld.linktype = pcap_datalink(pch);
-
if (cf.cfilter) {
if (pcap_lookupnet (cf.iface, &netnum, &netmask, err_str) < 0) {
simple_dialog(ESD_TYPE_WARN, NULL,
"Can't use filter: Couldn't obtain netmask info.");
- pcap_dump_close(ld.pdh);
+ wtap_dump_close(ld.pdh);
unlink(cf.save_file); /* silently ignore error */
pcap_close(pch);
return;
} else if (pcap_compile(pch, &cf.fcode, cf.cfilter, 1, netmask) < 0) {
simple_dialog(ESD_TYPE_WARN, NULL, "Unable to parse filter string.");
- pcap_dump_close(ld.pdh);
+ wtap_dump_close(ld.pdh);
unlink(cf.save_file); /* silently ignore error */
pcap_close(pch);
return;
} else if (pcap_setfilter(pch, &cf.fcode) < 0) {
simple_dialog(ESD_TYPE_WARN, NULL, "Can't install filter.");
- pcap_dump_close(ld.pdh);
+ wtap_dump_close(ld.pdh);
unlink(cf.save_file); /* silently ignore error */
pcap_close(pch);
return;
@@ -501,7 +530,7 @@ capture(void) {
system, and signal our parent so that they'll open the capture
file and update its windows to indicate that we have a live
capture in progress. */
- fflush((FILE *)ld.pdh);
+ fflush(wtap_dump_file(ld.pdh));
kill(getppid(), SIGUSR2);
}
@@ -603,7 +632,7 @@ capture(void) {
gtk_label_set(GTK_LABEL(other_lb), label_str);
/* do sync here, too */
- fflush((FILE *)ld.pdh);
+ fflush(wtap_dump_file(ld.pdh));
if (sync_mode && ld.sync_packets) {
char tmp[20];
sprintf(tmp, "%d*", ld.sync_packets);
@@ -613,7 +642,7 @@ capture(void) {
}
}
- if (ld.pdh) pcap_dump_close(ld.pdh);
+ if (ld.pdh) wtap_dump_close(ld.pdh);
pcap_close(pch);
gtk_grab_remove(GTK_WIDGET(cap_w));
@@ -664,15 +693,22 @@ capture_stop_cb(GtkWidget *w, gpointer data) {
static void
capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
const u_char *pd) {
-
+ struct wtap_pkthdr whdr;
loop_data *ld = (loop_data *) user;
-
+
if ((++ld->counts.total >= ld->max) && (ld->max > 0))
{
ld->go = FALSE;
}
- /* Currently, pcap_dumper_t is a FILE *. Let's hope that doesn't change. */
- if (ld->pdh) pcap_dump((u_char *) ld->pdh, phdr, pd);
+ if (ld->pdh) {
+ whdr.ts = phdr->ts;
+ whdr.caplen = phdr->caplen;
+ whdr.len = phdr->len;
+ whdr.pkt_encap = ld->wtap_linktype;
+
+ /* XXX - check for errors */
+ wtap_dump(ld->pdh, &whdr, pd);
+ }
switch (ld->linktype) {
case DLT_EN10MB :
diff --git a/ethereal.c b/ethereal.c
index cc168fe4e4..82414c2991 100644
--- a/ethereal.c
+++ b/ethereal.c
@@ -1,6 +1,6 @@
/* ethereal.c
*
- * $Id: ethereal.c,v 1.94 1999/08/18 02:59:04 guy Exp $
+ * $Id: ethereal.c,v 1.95 1999/08/18 04:17:27 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -536,7 +536,7 @@ file_save_cmd_cb(GtkWidget *w, gpointer data) {
void
file_save_as_cmd_cb(GtkWidget *w, gpointer data) {
- file_sel = gtk_file_selection_new ("Ethereal: Save Capture File as");
+ file_sel = gtk_file_selection_new ("Ethereal: Save Capture File As");
/* Connect the ok_button to file_save_as_ok_cb function and pass along a
pointer to the file selection box widget */
@@ -1122,6 +1122,7 @@ main(int argc, char *argv[])
#endif
cf.iface = NULL;
cf.save_file = NULL;
+ cf.save_file_fd = -1;
cf.user_saved = 0;
cf.snap = MAX_PACKET_SIZE;
cf.count = 0;
@@ -1149,7 +1150,7 @@ main(int argc, char *argv[])
#ifndef WIN32
/* Now get our args */
- while ((opt = getopt(argc, argv, "b:B:c:f:Fhi:km:nP:Qr:R:Ss:t:T:w:v")) != EOF) {
+ while ((opt = getopt(argc, argv, "b:B:c:f:Fhi:km:nP:Qr:R:Ss:t:T:w:W:v")) != EOF) {
switch (opt) {
case 'b': /* Bold font */
bold_font = g_strdup(optarg);
@@ -1233,9 +1234,12 @@ main(int argc, char *argv[])
exit(0);
break;
#ifdef HAVE_LIBPCAP
- case 'w': /* Write capture file xxx */
+ case 'w': /* Write to capture file xxx */
cf.save_file = g_strdup(optarg);
break;
+ case 'W': /* Write to capture file FD xxx */
+ cf.save_file_fd = atoi(optarg);
+ break;
#endif
}
}
@@ -1250,6 +1254,13 @@ main(int argc, char *argv[])
fprintf(stderr, "ethereal: \"-k\" flag was specified without \"-w\" flag\n");
exit(1);
}
+ if (fork_mode) {
+ if (cf.save_file_fd == -1) {
+ fprintf(stderr, "ethereal: \"-k\" flag was specified with \"-%c\" flag but without \"-W\" flag\n",
+ (sync_mode ? 'S' : 'F'));
+ exit(1);
+ }
+ }
}
#ifdef HAVE_LIBPCAP
diff --git a/file.h b/file.h
index 8326c3f2a2..03dcf5d2d7 100644
--- a/file.h
+++ b/file.h
@@ -1,7 +1,7 @@
/* file.h
* Definitions for file structures and routines
*
- * $Id: file.h,v 1.36 1999/08/15 19:18:46 guy Exp $
+ * $Id: file.h,v 1.37 1999/08/18 04:17:28 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -55,7 +55,7 @@ typedef struct _capture_file {
gchar *filename; /* filename */
long f_len; /* File length */
guint16 cd_t; /* Capture data type */
- const gchar *cd_t_desc;/* Description of that data type */
+ const gchar *cd_t_desc; /* Description of that data type */
guint32 vers; /* Version. For tcpdump minor is appended to major */
guint32 count; /* Packet count */
gfloat unfiltered_count; /* used for dfilter progress bar */
@@ -65,6 +65,7 @@ typedef struct _capture_file {
guint32 snap; /* Captured packet length */
gchar *iface; /* Interface */
gchar *save_file; /* File that user saved capture to */
+ int save_file_fd; /* File descriptor for saved file */
gint user_saved;/* Was capture file saved by user yet? */
wtap *wth; /* Wiretap session */
dfilter *rfcode; /* Compiled read filter program */
@@ -114,6 +115,3 @@ char *file_read_error_message(int);
char *file_write_error_message(int);
#endif /* file.h */
-
-
-
diff --git a/wiretap/file.c b/wiretap/file.c
index 1e08ffb821..0d10aa62b4 100644
--- a/wiretap/file.c
+++ b/wiretap/file.c
@@ -1,6 +1,6 @@
/* file.c
*
- * $Id: file.c,v 1.13 1999/08/15 06:59:13 guy Exp $
+ * $Id: file.c,v 1.14 1999/08/18 04:17:37 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@@ -100,16 +100,15 @@ wtap* wtap_open_offline(const char *filename, int *err)
if ((wth->file_type = iptrace_open(wth)) != WTAP_FILE_UNKNOWN) {
goto success;
}
- /* WTAP_FILE_NETMON */
+ /* WTAP_FILE_NETMON_xxx */
if ((wth->file_type = netmon_open(wth)) != WTAP_FILE_UNKNOWN) {
goto success;
}
- /* WTAP_FILE_NETXRAY */
+ /* WTAP_FILE_NETXRAY_xxx */
if ((wth->file_type = netxray_open(wth)) != WTAP_FILE_UNKNOWN) {
goto success;
}
-
/* failure: */
fclose(wth->fh);
free(wth);
@@ -121,3 +120,102 @@ success:
buffer_init(wth->frame_buffer, 1500);
return wth;
}
+
+
+static wtap_dumper* wtap_dump_open_common(FILE *fh, int filetype,
+ int encap, int snaplen, int *err);
+
+wtap_dumper* wtap_dump_open(const char *filename, int filetype, int encap,
+ int snaplen, int *err)
+{
+ FILE *fh;
+
+ /* In case "fopen()" fails but doesn't set "errno", set "errno"
+ to a generic "the open failed" error. */
+ errno = WTAP_ERR_CANT_OPEN;
+ fh = fopen(filename, "w");
+ if (fh == NULL) {
+ *err = errno;
+ return NULL; /* can't create file */
+ }
+ return wtap_dump_open_common(fh, filetype, encap, snaplen, err);
+}
+
+wtap_dumper* wtap_dump_fdopen(int fd, int filetype, int encap, int snaplen,
+ int *err)
+{
+ FILE *fh;
+
+ /* In case "fopen()" fails but doesn't set "errno", set "errno"
+ to a generic "the open failed" error. */
+ errno = WTAP_ERR_CANT_OPEN;
+ fh = fdopen(fd, "w");
+ if (fh == NULL) {
+ *err = errno;
+ return NULL; /* can't create standard I/O stream */
+ }
+ return wtap_dump_open_common(fh, filetype, encap, snaplen, err);
+}
+
+static wtap_dumper* wtap_dump_open_common(FILE *fh, int filetype, int encap,
+ int snaplen, int *err)
+{
+ wtap_dumper *wdh;
+
+ wdh = malloc(sizeof (wtap_dumper));
+ if (wdh == NULL) {
+ *err = errno;
+ /* NOTE: this means the FD handed to "wtap_dump_fdopen()"
+ will be closed if the malloc fails. */
+ fclose(fh);
+ return NULL;
+ }
+ wdh->fh = fh;
+ wdh->file_type = filetype;
+ wdh->snaplen = snaplen;
+ wdh->encap = encap;
+
+ switch (filetype) {
+
+ case WTAP_FILE_PCAP:
+ if (!libpcap_dump_open(wdh, err))
+ goto fail;
+ break;
+
+ default:
+ /* We currently only support dumping "libpcap" files */
+ *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
+ goto fail;
+ }
+ return wdh;
+
+fail:
+ free(wdh);
+ fclose(fh);
+ return NULL; /* XXX - provide a reason why we failed */
+}
+
+FILE* wtap_dump_file(wtap_dumper *wdh)
+{
+ return wdh->fh;
+}
+
+int wtap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
+ const u_char *pd)
+{
+ return (wdh->subtype_write)(wdh, phdr, pd);
+}
+
+int wtap_dump_close(wtap_dumper *wdh)
+{
+ int ret = 1;
+
+ if (!(wdh->subtype_close)(wdh))
+ ret = 0;
+ ret = fclose(wdh->fh);
+ if (ret == EOF)
+ ret = 0;
+ free(wdh);
+ return ret;
+}
+
diff --git a/wiretap/libpcap.c b/wiretap/libpcap.c
index 34232712de..c44eeee62e 100644
--- a/wiretap/libpcap.c
+++ b/wiretap/libpcap.c
@@ -1,6 +1,6 @@
/* libpcap.c
*
- * $Id: libpcap.c,v 1.6 1999/07/28 23:16:42 guy Exp $
+ * $Id: libpcap.c,v 1.7 1999/08/18 04:17:35 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@@ -23,6 +23,8 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#include <stdlib.h>
+#include <errno.h>
#include "wtap.h"
#include "buffer.h"
#include "libpcap.h"
@@ -64,39 +66,45 @@ struct pcap_hdr {
struct pcaprec_hdr {
guint32 ts_sec; /* timestamp seconds */
guint32 ts_usec; /* timestamp microseconds */
- guint32 incl_len; /* number of octets captured in file */
+ guint32 incl_len; /* number of octets of packet saved in file */
guint32 orig_len; /* actual length of packet */
};
+static int libpcap_read(wtap *wth);
+static int libpcap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
+ const u_char *pd);
+static int libpcap_dump_close(wtap_dumper *wdh);
+
+static const int pcap_encap[] = {
+ WTAP_ENCAP_NONE, /* no encapsulation */
+ WTAP_ENCAP_ETHERNET,
+ WTAP_ENCAP_NONE, /* 3Mb experimental Ethernet */
+ WTAP_ENCAP_NONE, /* Amateur Radio AX.25 */
+ WTAP_ENCAP_NONE, /* Proteon ProNET Token Ring */
+ WTAP_ENCAP_NONE, /* Chaos */
+ WTAP_ENCAP_TR, /* IEEE 802 Networks - assume token ring */
+ WTAP_ENCAP_ARCNET,
+ WTAP_ENCAP_SLIP,
+ WTAP_ENCAP_PPP,
+ WTAP_ENCAP_FDDI,
+ WTAP_ENCAP_ATM_RFC1483,
+ WTAP_ENCAP_RAW_IP,
+ WTAP_ENCAP_NONE,
+ WTAP_ENCAP_NONE,
+ WTAP_ENCAP_NONE,
+ WTAP_ENCAP_NONE,
+ WTAP_ENCAP_NONE,
+ WTAP_ENCAP_NONE,
+ WTAP_ENCAP_LINUX_ATM_CLIP
+};
+#define NUM_PCAP_ENCAPS (sizeof pcap_encap / sizeof pcap_encap[0])
+
/* Returns WTAP_FILE_PCAP on success, WTAP_FILE_UNKNOWN on failure */
int libpcap_open(wtap *wth)
{
int bytes_read;
guint32 magic;
struct pcap_hdr hdr;
- static const int pcap_encap[] = {
- WTAP_ENCAP_NONE, /* no encapsulation */
- WTAP_ENCAP_ETHERNET,
- WTAP_ENCAP_NONE, /* 3Mb experimental Ethernet */
- WTAP_ENCAP_NONE, /* Amateur Radio AX.25 */
- WTAP_ENCAP_NONE, /* Proteon ProNET Token Ring */
- WTAP_ENCAP_NONE, /* Chaos */
- WTAP_ENCAP_TR, /* IEEE 802 Networks - assume token ring */
- WTAP_ENCAP_ARCNET,
- WTAP_ENCAP_SLIP,
- WTAP_ENCAP_PPP,
- WTAP_ENCAP_FDDI,
- WTAP_ENCAP_ATM_RFC1483,
- WTAP_ENCAP_RAW_IP,
- WTAP_ENCAP_NONE,
- WTAP_ENCAP_NONE,
- WTAP_ENCAP_NONE,
- WTAP_ENCAP_NONE,
- WTAP_ENCAP_NONE,
- WTAP_ENCAP_NONE,
- WTAP_ENCAP_LINUX_ATM_CLIP
- };
- #define NUM_PCAP_ENCAPS (sizeof pcap_encap / sizeof pcap_encap[0])
int byte_swapped = 0;
/* Read in the number that should be at the start of a "libpcap" file */
@@ -151,7 +159,7 @@ int libpcap_open(wtap *wth)
}
/* Read the next packet */
-int libpcap_read(wtap *wth)
+static int libpcap_read(wtap *wth)
{
int packet_size;
int bytes_read;
@@ -220,3 +228,97 @@ int libpcap_read(wtap *wth)
return data_offset;
}
+
+int wtap_pcap_encap_to_wtap_encap(int encap)
+{
+ if (encap < 0 || encap >= NUM_PCAP_ENCAPS)
+ return WTAP_FILE_UNKNOWN;
+ return pcap_encap[encap];
+}
+
+/* Returns 1 on success, 0 on failure; sets "*err" to an error code on
+ failure */
+int libpcap_dump_open(wtap_dumper *wdh, int *err)
+{
+ static const guint32 pcap_magic = PCAP_MAGIC;
+ struct pcap_hdr file_hdr;
+ static const int wtap_encap[] = {
+ 0, /* WTAP_ENCAP_NONE */
+ 1, /* WTAP_ENCAP_ETHERNET */
+ 6, /* WTAP_ENCAP_TR */
+ 8, /* WTAP_ENCAP_SLIP */
+ 9, /* WTAP_ENCAP_PPP */
+ 10, /* WTAP_ENCAP_FDDI */
+ 12, /* WTAP_ENCAP_RAW_IP */
+ 7, /* WTAP_ENCAP_ARCNET */
+ 11, /* WTAP_ENCAP_ATM_RFC1483 */
+ 19 /* WTAP_ENCAP_LINUX_ATM_CLIP */
+ };
+ int nwritten;
+
+ /* Per-packet encapsulations aren't supported. */
+ if (wdh->encap == WTAP_ENCAP_PER_PACKET) {
+ *err = WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
+ return 0;
+ }
+
+ /* This is a libpcap file */
+ wdh->subtype_write = libpcap_dump;
+ wdh->subtype_close = libpcap_dump_close;
+
+ /* Write the file header. */
+ nwritten = fwrite(&pcap_magic, 1, sizeof pcap_magic, wdh->fh);
+ if (nwritten != sizeof pcap_magic) {
+ if (nwritten < 0)
+ *err = errno;
+ else
+ *err = WTAP_ERR_SHORT_WRITE;
+ return 0;
+ }
+
+ /* current "libpcap" format is 2.4 */
+ file_hdr.version_major = 2;
+ file_hdr.version_minor = 4;
+ file_hdr.thiszone = 0; /* XXX - current offset? */
+ file_hdr.sigfigs = 0; /* unknown, but also apparently unused */
+ file_hdr.snaplen = wdh->snaplen;
+ file_hdr.network = wtap_encap[wdh->encap];
+ nwritten = fwrite(&file_hdr, 1, sizeof file_hdr, wdh->fh);
+ if (nwritten != sizeof file_hdr) {
+ if (nwritten < 0)
+ *err = errno;
+ else
+ *err = WTAP_ERR_SHORT_WRITE;
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Write a record for a packet to a dump file.
+ Returns 1 on success, 0 on failure. */
+static int libpcap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
+ const u_char *pd)
+{
+ struct pcaprec_hdr rec_hdr;
+ int nwritten;
+
+ rec_hdr.ts_sec = phdr->ts.tv_sec;
+ rec_hdr.ts_usec = phdr->ts.tv_usec;
+ rec_hdr.incl_len = phdr->caplen;
+ rec_hdr.orig_len = phdr->len;
+ nwritten = fwrite(&rec_hdr, 1, sizeof rec_hdr, wdh->fh);
+ if (nwritten != sizeof rec_hdr)
+ return 0; /* failed (XXX - save reason why) */
+ nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
+ if (nwritten != phdr->caplen)
+ return 0; /* failed (XXX - save reason why) */
+ return 1;
+}
+
+/* Close a dump file.
+ Returns 1 on success, 0 on failure. */
+static int libpcap_dump_close(wtap_dumper *wdh)
+{
+ return 1;
+}
diff --git a/wiretap/libpcap.h b/wiretap/libpcap.h
index 5de0a34e71..2bd1449996 100644
--- a/wiretap/libpcap.h
+++ b/wiretap/libpcap.h
@@ -1,6 +1,6 @@
/* libpcap.h
*
- * $Id: libpcap.h,v 1.1 1998/11/15 05:29:12 guy Exp $
+ * $Id: libpcap.h,v 1.2 1999/08/18 04:17:36 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@@ -22,4 +22,4 @@
*/
int libpcap_open(wtap *wth);
-int libpcap_read(wtap *wth);
+int libpcap_dump_open(wtap_dumper *wdh, int *err);
diff --git a/wiretap/netmon.c b/wiretap/netmon.c
index dba0cf5784..32ce63e1b1 100644
--- a/wiretap/netmon.c
+++ b/wiretap/netmon.c
@@ -1,6 +1,6 @@
/* netmon.c
*
- * $Id: netmon.c,v 1.8 1999/07/13 02:53:24 gram Exp $
+ * $Id: netmon.c,v 1.9 1999/08/18 04:17:38 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@@ -95,6 +95,7 @@ int netmon_open(wtap *wth)
int bytes_read;
char magic[sizeof netmon_1_x_magic];
struct netmon_hdr hdr;
+ int file_type;
static const int netmon_encap[] = {
WTAP_ENCAP_NONE,
WTAP_ENCAP_ETHERNET,
@@ -135,9 +136,11 @@ int netmon_open(wtap *wth)
switch (hdr.ver_major) {
case 1:
+ file_type = WTAP_FILE_NETMON_1_x;
break;
case 2:
+ file_type = WTAP_FILE_NETMON_2_x;
break;
default:
@@ -195,7 +198,7 @@ int netmon_open(wtap *wth)
/* Seek to the beginning of the data records. */
fseek(wth->fh, CAPTUREFILE_HEADER_SIZE, SEEK_SET);
- return WTAP_FILE_NETMON;
+ return file_type;
}
/* Read the next packet */
diff --git a/wiretap/netxray.c b/wiretap/netxray.c
index 92fe34a398..17ce354b43 100644
--- a/wiretap/netxray.c
+++ b/wiretap/netxray.c
@@ -1,6 +1,6 @@
/* netxray.c
*
- * $Id: netxray.c,v 1.8 1999/07/13 02:53:25 gram Exp $
+ * $Id: netxray.c,v 1.9 1999/08/18 04:17:37 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@@ -94,6 +94,7 @@ int netxray_open(wtap *wth)
struct netxray_hdr hdr;
double timeunit;
int version_major;
+ int file_type;
double t;
static const int netxray_encap[] = {
WTAP_ENCAP_ETHERNET,
@@ -139,12 +140,15 @@ int netxray_open(wtap *wth)
if (memcmp(hdr.version, vers_1_0, sizeof vers_1_0) == 0) {
timeunit = 1000.0;
version_major = 1;
+ file_type = WTAP_FILE_NETXRAY_1_0;
} else if (memcmp(hdr.version, vers_1_1, sizeof vers_1_1) == 0) {
timeunit = 1000000.0;
version_major = 1;
+ file_type = WTAP_FILE_NETXRAY_1_1;
} else if (memcmp(hdr.version, vers_2_001, sizeof vers_2_001) == 0) {
timeunit = 1000000.0;
version_major = 2;
+ file_type = WTAP_FILE_NETXRAY_2_001;
} else {
return WTAP_FILE_UNKNOWN;
}
@@ -179,7 +183,7 @@ int netxray_open(wtap *wth)
/* Seek to the beginning of the data records. */
fseek(wth->fh, pletohl(&hdr.start_offset), SEEK_SET);
- return WTAP_FILE_NETXRAY;
+ return file_type;
}
/* Read the next packet */
diff --git a/wiretap/wtap.c b/wiretap/wtap.c
index aae8794639..49f9312f42 100644
--- a/wiretap/wtap.c
+++ b/wiretap/wtap.c
@@ -1,6 +1,6 @@
/* wtap.c
*
- * $Id: wtap.c,v 1.13 1999/08/02 02:35:57 guy Exp $
+ * $Id: wtap.c,v 1.14 1999/08/18 04:17:37 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@@ -62,11 +62,20 @@ const char *wtap_file_type_string(wtap *wth)
case WTAP_FILE_IPTRACE:
return "iptrace";
- case WTAP_FILE_NETMON:
- return "Microsoft Network Monitor";
+ case WTAP_FILE_NETMON_1_x:
+ return "Microsoft Network Monitor 1.x";
- case WTAP_FILE_NETXRAY:
- return "Cinco Networks NetXRay/Network Associates Sniffer (Windows-based)";
+ case WTAP_FILE_NETMON_2_x:
+ return "Microsoft Network Monitor 2.x";
+
+ case WTAP_FILE_NETXRAY_1_0:
+ return "Cinco Networks NetXRay";
+
+ case WTAP_FILE_NETXRAY_1_1:
+ return "Network Associates Sniffer (Windows-based) 1.1";
+
+ case WTAP_FILE_NETXRAY_2_001:
+ return "Network Associates Sniffer (Windows-based) 2.001";
case WTAP_FILE_RADCOM:
return "RADCOM WAN/LAN analyzer";
@@ -100,11 +109,14 @@ void wtap_close(wtap *wth)
g_free(wth->capture.radcom);
break;
- case WTAP_FILE_NETMON:
+ case WTAP_FILE_NETMON_1_x:
+ case WTAP_FILE_NETMON_2_x:
g_free(wth->capture.netmon);
break;
- case WTAP_FILE_NETXRAY:
+ case WTAP_FILE_NETXRAY_1_0:
+ case WTAP_FILE_NETXRAY_1_1:
+ case WTAP_FILE_NETXRAY_2_001:
g_free(wth->capture.netxray);
break;
diff --git a/wiretap/wtap.h b/wiretap/wtap.h
index 9664d2a427..e1a7465460 100644
--- a/wiretap/wtap.h
+++ b/wiretap/wtap.h
@@ -1,6 +1,6 @@
/* wtap.h
*
- * $Id: wtap.h,v 1.23 1999/08/15 06:59:13 guy Exp $
+ * $Id: wtap.h,v 1.24 1999/08/18 04:17:36 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@@ -32,7 +32,13 @@
* that code adds a DLT_ATM_CLIP DLT_ code of 19, and that
* encapsulation isn't the same as the DLT_ATM_RFC1483 encapsulation
* presumably used on some BSD systems, which we turn into
- * WTAP_ENCAP_ATM_RFC1483. */
+ * WTAP_ENCAP_ATM_RFC1483.
+ *
+ * WTAP_ENCAP_PER_PACKET is a value passed to "wtap_dump_open()" or
+ * "wtap_dump_fdopen()" to indicate that there is no single encapsulation
+ * type for all packets in the file; this may cause those routines to
+ * fail if the capture file format being written can't support that. */
+#define WTAP_ENCAP_PER_PACKET -1
#define WTAP_ENCAP_NONE 0
#define WTAP_ENCAP_ETHERNET 1
#define WTAP_ENCAP_TR 2
@@ -48,7 +54,9 @@
/* last WTAP_ENCAP_ value + 1 */
#define WTAP_NUM_ENCAP_TYPES 11
-/* File types that can be read by wiretap */
+/* File types that can be read by wiretap.
+ We may eventually support writing some or all of these file types,
+ too, so we distinguish between different versions of them. */
#define WTAP_FILE_UNKNOWN 0
#define WTAP_FILE_WTAP 1
#define WTAP_FILE_PCAP 2
@@ -56,9 +64,12 @@
#define WTAP_FILE_NGSNIFFER 4
#define WTAP_FILE_SNOOP 6
#define WTAP_FILE_IPTRACE 7
-#define WTAP_FILE_NETMON 8
-#define WTAP_FILE_NETXRAY 9
-#define WTAP_FILE_RADCOM 10
+#define WTAP_FILE_NETMON_1_x 8
+#define WTAP_FILE_NETMON_2_x 9
+#define WTAP_FILE_NETXRAY_1_0 10
+#define WTAP_FILE_NETXRAY_1_1 11
+#define WTAP_FILE_NETXRAY_2_001 12
+#define WTAP_FILE_RADCOM 13
/* Filter types that wiretap can create. An 'offline' filter is really
* a BPF filter, but it is treated specially because wiretap might not know
@@ -162,12 +173,25 @@ typedef struct wtap {
types */
} wtap;
+struct wtap_dumper;
+
+typedef int (*subtype_write_func)(struct wtap_dumper*,
+ const struct wtap_pkthdr*, const u_char*);
+typedef int (*subtype_close_func)(struct wtap_dumper *);
+typedef struct wtap_dumper {
+ FILE* fh;
+ int file_type;
+ int snaplen;
+ int encap;
+
+ subtype_write_func subtype_write;
+ subtype_close_func subtype_close;
+} wtap_dumper;
+
/*
* On failure, "wtap_open_offline()" returns NULL, and puts into the
* "int" pointed to by its second argument:
*
- * 0 on success;
- *
* a positive "errno" value if the capture file can't be opened;
*
* a negative number, indicating the type of error, on other failures.
@@ -184,6 +208,35 @@ int wtap_file_type(wtap *wth);
const char *wtap_file_type_string(wtap *wth);
void wtap_close(wtap *wth);
+/*
+ * On failure, "wtap_dump_open()" and "wtap_dump_fdopen()" return NULL,
+ * and put into the "int" pointed to by its second argument:
+ *
+ * a positive "errno" value if the capture file can't be created, or
+ * some other failure that sets "errno" occurs;
+ *
+ * a negative number, indicating the type of error, on other failures.
+ */
+#define WTAP_ERR_CANT_OPEN -1
+ /* couldn't open, reason unknown */
+#define WTAP_ERR_UNSUPPORTED_FILE_TYPE -2
+ /* can't save files in that format */
+#define WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED -3
+ /* that format doesn't support per-packet encapsulations */
+#define WTAP_ERR_SHORT_WRITE -4
+ /* write wrote less data than it should have */
+
+wtap_dumper* wtap_dump_open(const char *filename, int filetype, int encap,
+ int snaplen, int *err);
+wtap_dumper* wtap_dump_fdopen(int fd, int filetype, int encap, int snaplen,
+ int *err);
+int wtap_dump(wtap_dumper *, const struct wtap_pkthdr *, const u_char *);
+FILE* wtap_dump_file(wtap_dumper *);
+int wtap_dump_close(wtap_dumper *);
+
+/* XXX - needed until "wiretap" can do live packet captures */
+int wtap_pcap_encap_to_wtap_encap(int encap);
+
/* Pointer versions of ntohs and ntohl. Given a pointer to a member of a
* byte array, returns the value of the two or four bytes at the pointer.
* The pletoh[sl] versions return the little-endian representation.