Tethereal can write to a file in binary even if not built with libpcap.

svn path=/trunk/; revision=13341
This commit is contained in:
Guy Harris 2005-02-07 19:33:49 +00:00
parent 6e58e3984b
commit da36197902
1 changed files with 41 additions and 40 deletions

View File

@ -148,6 +148,7 @@ typedef struct _loop_data {
gint linktype;
gboolean from_pipe; /* TRUE if we are capturing data from a pipe */
pcap_t *pch;
char *save_file; /* Name of file to which we're writing */
wtap_dumper *pdh;
jmp_buf stopenv;
gboolean output_to_pipe;
@ -168,7 +169,6 @@ static loop_data ld;
#ifdef HAVE_LIBPCAP
typedef struct {
gchar *save_file; /* File that user saved capture to */
gchar *cfilter; /* Capture filter string */
gchar *iface; /* the network interface to capture from */
int snaplen; /* Maximum captured packet length */
@ -189,7 +189,6 @@ typedef struct {
} capture_options;
static capture_options capture_opts = {
NULL, /* We're not writing to a capture file */
"", /* No capture filter string specified */
NULL, /* Default is "pick the first interface" */
WTAP_MAX_PACKET_SIZE, /* snapshot length - default is
@ -219,7 +218,7 @@ static gboolean infoprint; /* if TRUE, print capture info after clearing infodel
#endif /* HAVE_LIBPCAP */
static int capture(int);
static int capture(char *, int);
static void capture_pcap_cb(guchar *, const struct pcap_pkthdr *,
const guchar *);
static void report_counts(void);
@ -233,7 +232,7 @@ static void report_counts_siginfo(int);
#endif /* _WIN32 */
#endif /* HAVE_LIBPCAP */
static int load_cap_file(capture_file *, capture_options *capture_opts, int);
static int load_cap_file(capture_file *, char *, int);
static gboolean process_packet(capture_file *cf, wtap_dumper *pdh, long offset,
const struct wtap_pkthdr *whdr, union wtap_pseudo_header *pseudo_header,
const guchar *pd, int *err);
@ -843,6 +842,7 @@ main(int argc, char *argv[])
#else
gboolean capture_option_specified = FALSE;
#endif
gchar *save_file = NULL;
int out_file_type = WTAP_FILE_PCAP;
gchar *cf_name = NULL, *rfilter = NULL;
#ifdef HAVE_LIBPCAP
@ -1249,7 +1249,7 @@ main(int argc, char *argv[])
exit(0);
break;
case 'w': /* Write to capture file xxx */
capture_opts.save_file = g_strdup(optarg);
save_file = g_strdup(optarg);
break;
case 'V': /* Verbose */
verbose = TRUE;
@ -1328,12 +1328,12 @@ main(int argc, char *argv[])
#ifdef HAVE_LIBPCAP
ld.output_to_pipe = FALSE;
#endif
if (capture_opts.save_file != NULL) {
if (save_file != NULL) {
/* We're writing to a capture file. */
if (strcmp(capture_opts.save_file, "-") == 0) {
if (strcmp(save_file, "-") == 0) {
/* Write to the standard output. */
g_free(capture_opts.save_file);
capture_opts.save_file = g_strdup("");
g_free(save_file);
save_file = g_strdup("");
#ifdef HAVE_LIBPCAP
/* XXX - should we check whether it's a pipe? It's arguably
silly to do "-w - >output_file" rather than "-w output_file",
@ -1344,7 +1344,7 @@ main(int argc, char *argv[])
}
#ifdef HAVE_LIBPCAP
else {
err = test_for_fifo(capture_opts.save_file);
err = test_for_fifo(save_file);
switch (err) {
case ENOENT: /* it doesn't exist, so we'll be creating it,
@ -1417,7 +1417,7 @@ main(int argc, char *argv[])
} else {
/* If they didn't specify a "-w" flag, but specified a maximum capture
file size, tell them that this doesn't work, and exit. */
if (capture_opts.has_autostop_filesize && capture_opts.save_file == NULL) {
if (capture_opts.has_autostop_filesize && save_file == NULL) {
fprintf(stderr, "tethereal: Maximum capture file size specified, but "
"capture isn't being saved to a file.\n");
exit(1);
@ -1431,7 +1431,7 @@ main(int argc, char *argv[])
c) it makes no sense to enable the ring buffer if the maximum
file size is set to "infinite";
d) file must not be a pipe. */
if (capture_opts.save_file == NULL) {
if (save_file == NULL) {
fprintf(stderr, "tethereal: Ring buffer requested, but "
"capture isn't being saved to a file.\n");
exit(1);
@ -1588,7 +1588,7 @@ main(int argc, char *argv[])
epan_cleanup();
exit(2);
}
err = load_cap_file(&cfile, &capture_opts, out_file_type);
err = load_cap_file(&cfile, save_file, out_file_type);
if (err != 0) {
epan_cleanup();
exit(2);
@ -1671,7 +1671,7 @@ main(int argc, char *argv[])
exit(0);
}
capture(out_file_type);
capture(save_file, out_file_type);
if (capture_opts.ringbuffer_on) {
ringbuf_free();
@ -1696,7 +1696,7 @@ main(int argc, char *argv[])
static condition *volatile cnd_ring_timeout = NULL; /* this must be visible in process_packet */
static int
capture(int out_file_type)
capture(char *save_file, int out_file_type)
{
int pcap_encap;
int file_snaplen;
@ -1880,15 +1880,16 @@ capture(int out_file_type)
file_snaplen = pcap_snapshot(ld.pch);
}
ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_encap);
if (capture_opts.save_file != NULL) {
if (save_file != NULL) {
/* Set up to write to the capture file. */
if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
strcpy(errmsg, "The network you're capturing from is of a type"
" that Tethereal doesn't support.");
goto error;
}
ld.save_file = save_file;
if (capture_opts.ringbuffer_on) {
save_file_fd = ringbuf_init(capture_opts.save_file,
save_file_fd = ringbuf_init(save_file,
capture_opts.ringbuffer_num_files);
if (save_file_fd != -1) {
ld.pdh = ringbuf_init_wtap_dump_fdopen(out_file_type, ld.linktype,
@ -1898,14 +1899,14 @@ capture(int out_file_type)
ld.pdh = NULL;
}
} else {
ld.pdh = wtap_dump_open(capture_opts.save_file, out_file_type,
ld.pdh = wtap_dump_open(save_file, out_file_type,
ld.linktype, file_snaplen, &err);
}
if (ld.pdh == NULL) {
snprintf(errmsg, sizeof errmsg,
cf_open_error_message(err, NULL, TRUE, out_file_type),
*capture_opts.save_file == '\0' ? "stdout" : capture_opts.save_file);
*save_file == '\0' ? "stdout" : save_file);
goto error;
}
}
@ -2046,7 +2047,7 @@ capture(int out_file_type)
its maximum size. */
if (capture_opts.ringbuffer_on) {
/* Switch to the next ringbuffer file */
if (ringbuf_switch_file(&ld.pdh, &capture_opts.save_file, &save_file_fd, &loop_err)) {
if (ringbuf_switch_file(&ld.pdh, &save_file, &save_file_fd, &loop_err)) {
/* File switch succeeded: reset the condition */
cnd_reset(cnd_stop_capturesize);
if (cnd_ring_timeout) {
@ -2082,7 +2083,7 @@ capture(int out_file_type)
if (cnd_ring_timeout != NULL)
cnd_delete(cnd_ring_timeout);
if ((capture_opts.save_file != NULL) && !quiet) {
if ((save_file != NULL) && !quiet) {
/* We're saving to a file, which means we're printing packet counts
to stderr if we are not running silent and deep.
Send a newline so that we move to the line after the packet count. */
@ -2108,21 +2109,21 @@ capture(int out_file_type)
if (volatile_err == 0)
write_err = FALSE;
else {
show_capture_file_io_error(capture_opts.save_file, volatile_err, FALSE);
show_capture_file_io_error(save_file, volatile_err, FALSE);
write_err = TRUE;
}
if (capture_opts.save_file != NULL) {
if (save_file != NULL) {
/* We're saving to a file or files; close all files. */
if (capture_opts.ringbuffer_on) {
dump_ok = ringbuf_wtap_dump_close(&capture_opts.save_file, &err);
dump_ok = ringbuf_wtap_dump_close(&save_file, &err);
} else {
dump_ok = wtap_dump_close(ld.pdh, &err);
}
/* If we've displayed a message about a write error, there's no point
in displaying another message about an error on close. */
if (!dump_ok && !write_err)
show_capture_file_io_error(capture_opts.save_file, err, TRUE);
show_capture_file_io_error(save_file, err, TRUE);
}
#ifndef _WIN32
@ -2154,8 +2155,8 @@ error:
if (capture_opts.ringbuffer_on) {
ringbuf_error_cleanup();
}
g_free(capture_opts.save_file);
capture_opts.save_file = NULL;
g_free(save_file);
save_file = NULL;
fprintf(stderr, "tethereal: %s\n", errmsg);
#ifndef _WIN32
if (ld.from_pipe) {
@ -2206,7 +2207,7 @@ capture_pcap_cb(guchar *user, const struct pcap_pkthdr *phdr,
*/
if (cnd_ring_timeout != NULL && cnd_eval(cnd_ring_timeout)) {
/* time elapsed for this ring file, switch to the next */
if (ringbuf_switch_file(&ldat->pdh, &capture_opts.save_file, &save_file_fd, &loop_err)) {
if (ringbuf_switch_file(&ldat->pdh, &ldat->save_file, &save_file_fd, &loop_err)) {
/* File switch succeeded: reset the condition */
cnd_reset(cnd_ring_timeout);
} else {
@ -2223,7 +2224,7 @@ capture_pcap_cb(guchar *user, const struct pcap_pkthdr *phdr,
a count of packets captured; move to the line after the count. */
fprintf(stderr, "\n");
}
show_capture_file_io_error(capture_opts.save_file, err, FALSE);
show_capture_file_io_error(ldat->save_file, err, FALSE);
pcap_close(ldat->pch);
wtap_dump_close(ldat->pdh, &err);
exit(2);
@ -2322,7 +2323,7 @@ report_counts_siginfo(int signum _U_)
#endif /* HAVE_LIBPCAP */
static int
load_cap_file(capture_file *cf, capture_options *capture_opts, int out_file_type)
load_cap_file(capture_file *cf, char *save_file, int out_file_type)
{
gint linktype;
int snapshot_length;
@ -2332,14 +2333,14 @@ load_cap_file(capture_file *cf, capture_options *capture_opts, int out_file_type
long data_offset;
linktype = wtap_file_encap(cf->wth);
if (capture_opts->save_file != NULL) {
if (save_file != NULL) {
/* Set up to write to the capture file. */
snapshot_length = wtap_snapshot_length(cf->wth);
if (snapshot_length == 0) {
/* Snapshot length of input file not known. */
snapshot_length = WTAP_MAX_PACKET_SIZE;
}
pdh = wtap_dump_open(capture_opts->save_file, out_file_type,
pdh = wtap_dump_open(save_file, out_file_type,
linktype, snapshot_length, &err);
if (pdh == NULL) {
@ -2362,19 +2363,19 @@ load_cap_file(capture_file *cf, capture_options *capture_opts, int out_file_type
fprintf(stderr,
"tethereal: The file \"%s\" couldn't be created for some "
"unknown reason.\n",
*capture_opts->save_file == '\0' ? "stdout" : capture_opts->save_file);
*save_file == '\0' ? "stdout" : save_file);
break;
case WTAP_ERR_SHORT_WRITE:
fprintf(stderr,
"tethereal: A full header couldn't be written to the file \"%s\".\n",
*capture_opts->save_file == '\0' ? "stdout" : capture_opts->save_file);
*save_file == '\0' ? "stdout" : save_file);
break;
default:
fprintf(stderr,
"tethereal: The file \"%s\" could not be created: %s\n.",
*capture_opts->save_file == '\0' ? "stdout" : capture_opts->save_file,
*save_file == '\0' ? "stdout" : save_file,
wtap_strerror(err));
break;
}
@ -2395,7 +2396,7 @@ load_cap_file(capture_file *cf, capture_options *capture_opts, int out_file_type
wtap_pseudoheader(cf->wth), wtap_buf_ptr(cf->wth),
&err)) {
/* Error writing to a capture file */
show_capture_file_io_error(capture_opts->save_file, err, FALSE);
show_capture_file_io_error(save_file, err, FALSE);
wtap_dump_close(pdh, &err);
exit(2);
}
@ -2434,16 +2435,16 @@ load_cap_file(capture_file *cf, capture_options *capture_opts, int out_file_type
cf->filename, wtap_strerror(err));
break;
}
if (capture_opts->save_file != NULL) {
if (save_file != NULL) {
/* Now close the capture file. */
if (!wtap_dump_close(pdh, &err))
show_capture_file_io_error(capture_opts->save_file, err, TRUE);
show_capture_file_io_error(save_file, err, TRUE);
}
} else {
if (capture_opts->save_file != NULL) {
if (save_file != NULL) {
/* Now close the capture file. */
if (!wtap_dump_close(pdh, &err))
show_capture_file_io_error(capture_opts->save_file, err, TRUE);
show_capture_file_io_error(save_file, err, TRUE);
} else {
if (print_packet_info) {
if (!write_finale()) {