Add to Wiretap the ability to write capture files; for now, it can only

write them in "libpcap" format, but the mechanism can have other formats
added.

When creating the temporary file for a capture, use "create_tempfile()",
to close a security hole opened by the fact that "tempnam()" creates a
temporary file, but doesn't open it, and we open the file with the name
it gives us - somebody could remove the file and plant a link to some
file, and, if as may well be the case when Ethereal is capturing
packets, it's running as "root", that means we write a capture on top of
that file....  (The aforementioned changes to Wiretap let you open a
capture file for writing given an file descriptor, "fdopen()"-style,
which this change requires.)

svn path=/trunk/; revision=509
This commit is contained in:
Guy Harris 1999-08-18 04:17:38 +00:00
parent bc3c8c0641
commit df490a7085
10 changed files with 410 additions and 93 deletions

102
capture.c
View File

@ -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 :

View File

@ -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

8
file.h
View File

@ -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 */

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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;

View File

@ -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.