forked from osmocom/wireshark
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:
parent
bc3c8c0641
commit
df490a7085
102
capture.c
102
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 :
|
||||
|
|
19
ethereal.c
19
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
|
||||
|
|
8
file.h
8
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 */
|
||||
|
||||
|
||||
|
||||
|
|
106
wiretap/file.c
106
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue