Make "wtap_dump()" and "wtap_dump_close()" return error codes, and check

for errors when closing a file to which we've written packets (we don't
bother checking if we're giving up on a capture).

Add some more error checks in Wiretap.

Make a single list of all Wiretap error codes, giving them all different
values (some can be returned by more than one routine, so they shouldn't
be per-routine).

svn path=/trunk/; revision=510
This commit is contained in:
Guy Harris 1999-08-18 04:41:20 +00:00
parent df490a7085
commit 28809e2002
4 changed files with 105 additions and 50 deletions

View File

@ -1,7 +1,7 @@
/* capture.c
* Routines for packet capture windows
*
* $Id: capture.c,v 1.53 1999/08/18 04:17:26 guy Exp $
* $Id: capture.c,v 1.54 1999/08/18 04:41:12 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -506,19 +506,19 @@ capture(void) {
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.");
wtap_dump_close(ld.pdh);
wtap_dump_close(ld.pdh, NULL);
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.");
wtap_dump_close(ld.pdh);
wtap_dump_close(ld.pdh, NULL);
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.");
wtap_dump_close(ld.pdh);
wtap_dump_close(ld.pdh, NULL);
unlink(cf.save_file); /* silently ignore error */
pcap_close(pch);
return;
@ -642,7 +642,37 @@ capture(void) {
}
}
if (ld.pdh) wtap_dump_close(ld.pdh);
if (ld.pdh) {
if (!wtap_dump_close(ld.pdh, &err)) {
switch (err) {
case WTAP_ERR_CANT_CLOSE:
errmsg = "The file to which the capture was being saved"
" couldn't be closed for some unknown reason.";
break;
case WTAP_ERR_SHORT_WRITE:
errmsg = "Not all the data could be written to the file"
" to which the capture was being saved.";
break;
default:
if (err < 0) {
sprintf(errmsg_errno, "The file to which the capture was being"
" saved (\"%%s\") could not be closed: Error %d.",
err);
} else {
sprintf(errmsg_errno, "The file to which the capture was being"
" saved (\"%%s\") could not be closed: %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);
gtk_grab_remove(GTK_WIDGET(cap_w));
@ -695,6 +725,7 @@ 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;
int err;
if ((++ld->counts.total >= ld->max) && (ld->max > 0))
{
@ -706,8 +737,8 @@ capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
whdr.len = phdr->len;
whdr.pkt_encap = ld->wtap_linktype;
/* XXX - check for errors */
wtap_dump(ld->pdh, &whdr, pd);
/* XXX - do something if this fails */
wtap_dump(ld->pdh, &whdr, pd, &err);
}
switch (ld->linktype) {

View File

@ -1,6 +1,6 @@
/* file.c
*
* $Id: file.c,v 1.14 1999/08/18 04:17:37 guy Exp $
* $Id: file.c,v 1.15 1999/08/18 04:41:19 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@ -51,7 +51,7 @@ wtap* wtap_open_offline(const char *filename, int *err)
wtap *wth;
/* First, make sure the file is valid */
if (stat(filename, &statb)) {
if (stat(filename, &statb) < 0) {
*err = errno;
return NULL;
}
@ -62,9 +62,15 @@ wtap* wtap_open_offline(const char *filename, int *err)
}
#endif
errno = ENOMEM;
wth = (wtap*)malloc(sizeof(wtap));
if (wth == NULL) {
*err = errno;
return NULL;
}
/* Open the file */
errno = WTAP_ERR_CANT_OPEN;
if (!(wth->fh = fopen(filename, "rb"))) {
*err = errno;
free(wth);
@ -201,20 +207,29 @@ FILE* wtap_dump_file(wtap_dumper *wdh)
}
int wtap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
const u_char *pd)
const u_char *pd, int *err)
{
return (wdh->subtype_write)(wdh, phdr, pd);
return (wdh->subtype_write)(wdh, phdr, pd, err);
}
int wtap_dump_close(wtap_dumper *wdh)
int wtap_dump_close(wtap_dumper *wdh, int *err)
{
int ret = 1;
if (!(wdh->subtype_close)(wdh))
if (!(wdh->subtype_close)(wdh, err))
ret = 0;
errno = WTAP_ERR_CANT_CLOSE;
ret = fclose(wdh->fh);
if (ret == EOF)
if (ret == EOF) {
if (ret) {
/* The per-format close function succeeded,
but the fclose didn't. Save the reason
why, if our caller asked for it. */
if (err != NULL)
*err = errno;
}
ret = 0;
}
free(wdh);
return ret;
}

View File

@ -1,6 +1,6 @@
/* libpcap.c
*
* $Id: libpcap.c,v 1.7 1999/08/18 04:17:35 guy Exp $
* $Id: libpcap.c,v 1.8 1999/08/18 04:41:19 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@ -72,8 +72,8 @@ struct pcaprec_hdr {
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);
const u_char *pd, int *err);
static int libpcap_dump_close(wtap_dumper *wdh, int *err);
static const int pcap_encap[] = {
WTAP_ENCAP_NONE, /* no encapsulation */
@ -298,7 +298,7 @@ int libpcap_dump_open(wtap_dumper *wdh, int *err)
/* 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)
const u_char *pd, int *err)
{
struct pcaprec_hdr rec_hdr;
int nwritten;
@ -308,17 +308,28 @@ static int libpcap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
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) */
if (nwritten != sizeof rec_hdr) {
if (nwritten < 0)
*err = errno;
else
*err = WTAP_ERR_SHORT_WRITE;
return 0;
}
nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
if (nwritten != phdr->caplen)
return 0; /* failed (XXX - save reason why) */
if (nwritten != phdr->caplen) {
if (nwritten < 0)
*err = errno;
else
*err = WTAP_ERR_SHORT_WRITE;
return 0;
}
return 1;
}
/* Close a dump file.
/* Finish writing to a dump file.
Returns 1 on success, 0 on failure. */
static int libpcap_dump_close(wtap_dumper *wdh)
static int libpcap_dump_close(wtap_dumper *wdh, int *err)
{
/* Nothing to do here. */
return 1;
}

View File

@ -1,6 +1,6 @@
/* wtap.h
*
* $Id: wtap.h,v 1.24 1999/08/18 04:17:36 guy Exp $
* $Id: wtap.h,v 1.25 1999/08/18 04:41:20 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@ -176,8 +176,8 @@ typedef struct 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 *);
const struct wtap_pkthdr*, const u_char*, int*);
typedef int (*subtype_close_func)(struct wtap_dumper*, int*);
typedef struct wtap_dumper {
FILE* fh;
int file_type;
@ -196,9 +196,6 @@ typedef struct wtap_dumper {
*
* a negative number, indicating the type of error, on other failures.
*/
#define WTAP_ERR_NOT_REGULAR_FILE -1 /* not a plain file */
#define WTAP_ERR_FILE_UNKNOWN_FORMAT -2 /* not a capture file in a known format */
wtap* wtap_open_offline(const char *filename, int *err);
void wtap_loop(wtap *wth, int, wtap_handler, u_char*);
@ -208,35 +205,36 @@ 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 *);
int wtap_dump(wtap_dumper *, const struct wtap_pkthdr *, const u_char *,
int *err);
FILE* wtap_dump_file(wtap_dumper *);
int wtap_dump_close(wtap_dumper *);
int wtap_dump_close(wtap_dumper *, int *);
/* XXX - needed until "wiretap" can do live packet captures */
int wtap_pcap_encap_to_wtap_encap(int encap);
/*
* Wiretap error codes.
*/
#define WTAP_ERR_NOT_REGULAR_FILE -1
/* The file being opened for reading isn't a plain file */
#define WTAP_ERR_FILE_UNKNOWN_FORMAT -2
/* The file being opened is not a capture file in a known format */
#define WTAP_ERR_CANT_OPEN -3
/* The file couldn't be opened, reason unknown */
#define WTAP_ERR_UNSUPPORTED_FILE_TYPE -4
/* Wiretap can't save files in the specified format */
#define WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED -5
/* The specified format doesn't support per-packet encapsulations */
#define WTAP_ERR_CANT_CLOSE -6
/* The file couldn't be closed, reason unknown */
#define WTAP_ERR_SHORT_WRITE -7
/* An attempt to write wrote less data than it should have */
/* 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.