From 6c3c6de340ff2016b06c0081c6c822c723d40f80 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Mon, 9 Nov 2015 17:21:46 -0800 Subject: [PATCH] Treat "-" as "standard input" in the CLI, not in libwiretap. That's a UI convention, and the GUI shouldn't honor that convention - a user might get confused if they try to save to "-" and end up with nothing (and with a ton of crap in a log file if programs launched from the GUI end up with their standard output and error logged). While we're at it, make randcap report write and close errors. Change-Id: I9c450f0ca0320ce4c36d13d209b56d72edb43012 Reviewed-on: https://code.wireshark.org/review/11666 Reviewed-by: Guy Harris --- editcap.c | 39 +++++++--- randpkt.c | 163 ++++++++++++++++++++++++++++++++---------- reordercap.c | 12 +++- tshark.c | 20 ++++-- wiretap/file_access.c | 36 +++------- 5 files changed, 192 insertions(+), 78 deletions(-) diff --git a/editcap.c b/editcap.c index 8f69671cb1..c2522c59a8 100644 --- a/editcap.c +++ b/editcap.c @@ -888,6 +888,29 @@ get_editcap_runtime_info(GString *str) #endif } +static wtap_dumper * +editcap_dump_open(const char *filename, guint32 snaplen, + wtapng_section_t *shb_hdr, + wtapng_iface_descriptions_t *idb_inf, + wtapng_name_res_t *nrb_hdr, int *write_err) +{ + wtap_dumper *pdh; + + if (strcmp(filename, "-") == 0) { + /* Write to the standard output. */ + pdh = wtap_dump_fdopen_ng(1, out_file_type_subtype, out_frame_type, + snaplen, FALSE /* compressed */, + shb_hdr, idb_inf, nrb_hdr, + write_err); + } else { + pdh = wtap_dump_open_ng(filename, out_file_type_subtype, out_frame_type, + snaplen, FALSE /* compressed */, + shb_hdr, idb_inf, nrb_hdr, + write_err); + } + return pdh; +} + int main(int argc, char *argv[]) { @@ -1334,9 +1357,9 @@ DIAG_ON(cast-qual) shb_hdr->shb_user_appl = g_strdup("Editcap " VERSION); } - pdh = wtap_dump_open_ng(filename, out_file_type_subtype, out_frame_type, + pdh = editcap_dump_open(filename, snaplen ? MIN(snaplen, wtap_snapshot_length(wth)) : wtap_snapshot_length(wth), - FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &write_err); + shb_hdr, idb_inf, nrb_hdr, &write_err); if (pdh == NULL) { fprintf(stderr, "editcap: Can't open or create %s: %s\n", @@ -1376,9 +1399,9 @@ DIAG_ON(cast-qual) if (verbose) fprintf(stderr, "Continuing writing in file %s\n", filename); - pdh = wtap_dump_open_ng(filename, out_file_type_subtype, out_frame_type, + pdh = editcap_dump_open(filename, snaplen ? MIN(snaplen, wtap_snapshot_length(wth)) : wtap_snapshot_length(wth), - FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &write_err); + shb_hdr, idb_inf, nrb_hdr, &write_err); if (pdh == NULL) { fprintf(stderr, "editcap: Can't open or create %s: %s\n", @@ -1405,9 +1428,9 @@ DIAG_ON(cast-qual) if (verbose) fprintf(stderr, "Continuing writing in file %s\n", filename); - pdh = wtap_dump_open_ng(filename, out_file_type_subtype, out_frame_type, + pdh = editcap_dump_open(filename, snaplen ? MIN(snaplen, wtap_snapshot_length(wth)) : wtap_snapshot_length(wth), - FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &write_err); + shb_hdr, idb_inf, nrb_hdr, &write_err); if (pdh == NULL) { fprintf(stderr, "editcap: Can't open or create %s: %s\n", filename, wtap_strerror(write_err)); @@ -1776,9 +1799,9 @@ DIAG_ON(cast-qual) g_free (filename); filename = g_strdup(argv[optind+1]); - pdh = wtap_dump_open_ng(filename, out_file_type_subtype, out_frame_type, + pdh = editcap_dump_open(filename, snaplen ? MIN(snaplen, wtap_snapshot_length(wth)): wtap_snapshot_length(wth), - FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &write_err); + shb_hdr, idb_inf, nrb_hdr, &write_err); if (pdh == NULL) { fprintf(stderr, "editcap: Can't open or create %s: %s\n", filename, wtap_strerror(write_err)); diff --git a/randpkt.c b/randpkt.c index 82d2a9a26d..b5db8407f3 100644 --- a/randpkt.c +++ b/randpkt.c @@ -84,6 +84,7 @@ typedef struct { guint8* pseudo_buffer; guint pseudo_length; wtap_dumper* dump; + const char* filename; guint produce_max_bytes; } randpkt_example; @@ -374,154 +375,176 @@ randpkt_example examples[] = { PKT_ARP, WTAP_ENCAP_ETHERNET, pkt_arp, array_length(pkt_arp), NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "bgp", "Border Gateway Protocol", PKT_BGP, WTAP_ENCAP_ETHERNET, pkt_bgp, array_length(pkt_bgp), NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "bvlc", "BACnet Virtual Link Control", PKT_BVLC, WTAP_ENCAP_ETHERNET, pkt_bvlc, array_length(pkt_bvlc), NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "dns", "Domain Name Service", PKT_DNS, WTAP_ENCAP_ETHERNET, pkt_dns, array_length(pkt_dns), NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "eth", "Ethernet", PKT_ETHERNET, WTAP_ENCAP_ETHERNET, NULL, 0, NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "fddi", "Fiber Distributed Data Interface", PKT_FDDI, WTAP_ENCAP_FDDI, NULL, 0, NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "giop", "General Inter-ORB Protocol", PKT_GIOP, WTAP_ENCAP_ETHERNET, pkt_giop, array_length(pkt_giop), NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "icmp", "Internet Control Message Protocol", PKT_ICMP, WTAP_ENCAP_ETHERNET, pkt_icmp, array_length(pkt_icmp), NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "ip", "Internet Protocol", PKT_IP, WTAP_ENCAP_ETHERNET, pkt_ip, array_length(pkt_ip), NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "llc", "Logical Link Control", PKT_LLC, WTAP_ENCAP_TOKEN_RING, pkt_llc, array_length(pkt_llc), NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "m2m", "WiMAX M2M Encapsulation Protocol", PKT_M2M, WTAP_ENCAP_ETHERNET, pkt_m2m, array_length(pkt_m2m), NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "megaco", "MEGACO", PKT_MEGACO, WTAP_ENCAP_ETHERNET, pkt_megaco, array_length(pkt_megaco), NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "nbns", "NetBIOS-over-TCP Name Service", PKT_NBNS, WTAP_ENCAP_ETHERNET, pkt_nbns, array_length(pkt_nbns), NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "ncp2222", "NetWare Core Protocol", PKT_NCP2222, WTAP_ENCAP_TOKEN_RING, pkt_ncp2222, array_length(pkt_ncp2222), NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "sctp", "Stream Control Transmission Protocol", PKT_SCTP, WTAP_ENCAP_ETHERNET, pkt_sctp, array_length(pkt_sctp), NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "syslog", "Syslog message", PKT_SYSLOG, WTAP_ENCAP_ETHERNET, pkt_syslog, array_length(pkt_syslog), NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "tds", "TDS NetLib", PKT_TDS, WTAP_ENCAP_ETHERNET, pkt_tds, array_length(pkt_tds), NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "tcp", "Transmission Control Protocol", PKT_TCP, WTAP_ENCAP_TOKEN_RING, pkt_tcp, array_length(pkt_tcp), NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "tr", "Token-Ring", PKT_TR, WTAP_ENCAP_TOKEN_RING, NULL, 0, NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "udp", "User Datagram Protocol", PKT_UDP, WTAP_ENCAP_ETHERNET, pkt_udp, array_length(pkt_udp), NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "usb", "Universal Serial Bus", PKT_USB, WTAP_ENCAP_USB, NULL, 0, NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, { "usb-linux", "Universal Serial Bus with Linux specific header", PKT_USB_LINUX, WTAP_ENCAP_USB_LINUX, NULL, 0, NULL, 0, - NULL, 1000, + NULL, NULL, + 1000, }, }; @@ -611,10 +634,18 @@ static void randpkt_example_init(randpkt_example* example, char* produce_filenam { int err; - example->dump = wtap_dump_open(produce_filename, WTAP_FILE_TYPE_SUBTYPE_PCAP, - example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err); + if (strcmp(produce_filename, "-") == 0) { + /* Write to the standard output. */ + example->dump = wtap_dump_fdopen(1, WTAP_FILE_TYPE_SUBTYPE_PCAP, + example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err); + example->filename = "the standard output"; + } else { + example->dump = wtap_dump_open(produce_filename, WTAP_FILE_TYPE_SUBTYPE_PCAP, + example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err); + example->filename = produce_filename; + } if (!example->dump) { - fprintf(stderr, "randpkt: Error writing to %s\n", produce_filename); + fprintf(stderr, "randpkt: Error writing to %s\n", example->filename); exit(2); } @@ -629,10 +660,16 @@ static void randpkt_example_init(randpkt_example* example, char* produce_filenam } } -static void randpkt_example_close(randpkt_example* example) +static gboolean randpkt_example_close(randpkt_example* example) { int err; - wtap_dump_close(example->dump, &err); + + if (!wtap_dump_close(example->dump, &err)) { + fprintf(stderr, "Error writing to %s: %s\n", + example->filename, wtap_strerror(err)); + return FALSE; + } + return TRUE; } static void randpkt_loop(randpkt_example* example, guint64 produce_count) @@ -695,10 +732,64 @@ static void randpkt_loop(randpkt_example* example, guint64 produce_count) } } - /* XXX - report errors! */ if (!wtap_dump(example->dump, pkthdr, buffer, &err, &err_info)) { - if (err_info != NULL) + fprintf(stderr, "randpkt: Error writing to %s: %s\n", + example->filename, wtap_strerror(err)); + switch (err) { + + case WTAP_ERR_UNWRITABLE_ENCAP: + /* + * This is a problem with the particular + * frame we're writing and the file type + * and subtype we're writing; note that, + * and report the file type/subtype. + */ + fprintf(stderr, + "Frame has a network type that can't be saved in a \"%s\" file.\n", + wtap_file_type_subtype_short_string(WTAP_FILE_TYPE_SUBTYPE_PCAP)); + break; + + case WTAP_ERR_PACKET_TOO_LARGE: + /* + * This is a problem with the particular + * frame we're writing and the file type + * and subtype we're writing; note that, + * and report the file type/subtype. + */ + fprintf(stderr, + "Frame is too large for a \"%s\" file.\n", + wtap_file_type_subtype_short_string(WTAP_FILE_TYPE_SUBTYPE_PCAP)); + break; + + case WTAP_ERR_UNWRITABLE_REC_TYPE: + /* + * This is a problem with the particular + * record we're writing and the file type + * and subtype we're writing; note that, + * and report the file type/subtype. + */ + fprintf(stderr, + "Record has a record type that can't be saved in a \"%s\" file.\n", + wtap_file_type_subtype_short_string(WTAP_FILE_TYPE_SUBTYPE_PCAP)); + break; + + case WTAP_ERR_UNWRITABLE_REC_DATA: + /* + * This is a problem with the particular + * record we're writing and the file type + * and subtype we're writing; note that, + * and report the file type/subtype. + */ + fprintf(stderr, + "Record has data that can't be saved in a \"%s\" file.\n(%s)\n", + wtap_file_type_subtype_short_string(WTAP_FILE_TYPE_SUBTYPE_PCAP), + err_info != NULL ? err_info : "no information supplied"); g_free(err_info); + break; + + default: + break; + } } } @@ -708,12 +799,12 @@ static void randpkt_loop(randpkt_example* example, guint64 produce_count) int main(int argc, char **argv) { - int opt; - int produce_type = -1; + int opt; + int produce_type = -1; char *produce_filename = NULL; - int produce_max_bytes = 5000; - int produce_count = 1000; - randpkt_example *example; + int produce_max_bytes = 5000; + int produce_count = 1000; + randpkt_example *example; guint8* type = NULL; int allrandom = FALSE; wtap_dumper *savedump; @@ -781,7 +872,6 @@ DIAG_ON(cast-qual) randpkt_example_init(example, produce_filename, produce_max_bytes); randpkt_loop(example, produce_count); - randpkt_example_close(example); } else { if (type) { fprintf(stderr, "Can't set type in random mode\n"); @@ -805,8 +895,9 @@ DIAG_ON(cast-qual) return 1; example->dump = savedump; } - randpkt_example_close(example); } + if (!randpkt_example_close(example)) + return 2; return 0; } diff --git a/reordercap.c b/reordercap.c index 9939f26987..efbbfdaf36 100644 --- a/reordercap.c +++ b/reordercap.c @@ -204,7 +204,7 @@ DIAG_OFF(cast-qual) DIAG_ON(cast-qual) int file_count; char *infile; - char *outfile; + const char *outfile; /* Get the compile-time version information string */ comp_info_str = get_compiled_version_info(NULL, get_reordercap_compiled_info); @@ -275,8 +275,14 @@ DIAG_ON(cast-qual) nrb_hdr = wtap_file_get_nrb_for_new_file(wth); /* Open outfile (same filetype/encap as input file) */ - pdh = wtap_dump_open_ng(outfile, wtap_file_type_subtype(wth), wtap_file_encap(wth), - 65535, FALSE, shb_hdr, idb_inf, nrb_hdr, &err); + if (strcmp(outfile, "-") == 0) { + pdh = wtap_dump_fdopen_ng(1, wtap_file_type_subtype(wth), wtap_file_encap(wth), + 65535, FALSE, shb_hdr, idb_inf, nrb_hdr, &err); + outfile = "standard output"; + } else { + pdh = wtap_dump_open_ng(outfile, wtap_file_type_subtype(wth), wtap_file_encap(wth), + 65535, FALSE, shb_hdr, idb_inf, nrb_hdr, &err); + } g_free(idb_inf); idb_inf = NULL; diff --git a/tshark.c b/tshark.c index 8d3d3052bf..a43417b63e 100644 --- a/tshark.c +++ b/tshark.c @@ -3199,13 +3199,25 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type, if (linktype != WTAP_ENCAP_PER_PACKET && out_file_type == WTAP_FILE_TYPE_SUBTYPE_PCAP) { tshark_debug("tshark: writing PCAP format to %s", save_file); - pdh = wtap_dump_open(save_file, out_file_type, linktype, - snapshot_length, FALSE /* compressed */, &err); + if (strcmp(save_file, "-")) { + /* Write to the standard output. */ + pdh = wtap_dump_fdopen(1, out_file_type, linktype, + snapshot_length, FALSE /* compressed */, &err); + } else { + pdh = wtap_dump_open(save_file, out_file_type, linktype, + snapshot_length, FALSE /* compressed */, &err); + } } else { tshark_debug("tshark: writing format type %d, to %s", out_file_type, save_file); - pdh = wtap_dump_open_ng(save_file, out_file_type, linktype, - snapshot_length, FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &err); + if (strcmp(save_file, "-")) { + /* Write to the standard output. */ + pdh = wtap_dump_fdopen_ng(1, out_file_type, linktype, + snapshot_length, FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &err); + } else { + pdh = wtap_dump_open_ng(save_file, out_file_type, linktype, + snapshot_length, FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &err); + } } g_free(idb_inf); diff --git a/wiretap/file_access.c b/wiretap/file_access.c index 15e5940ac7..c667118408 100644 --- a/wiretap/file_access.c +++ b/wiretap/file_access.c @@ -2217,34 +2217,16 @@ wtap_dump_open_ng(const char *filename, int file_type_subtype, int encap, if (wdh == NULL) return NULL; - /* "-" means stdout */ - if (strcmp(filename, "-") == 0) { - if (compressed) { - *err = EINVAL; /* XXX - return a Wiretap error code for this */ - g_free(wdh); - return NULL; /* compress won't work on stdout */ - } -#ifdef _WIN32 - if (_setmode(fileno(stdout), O_BINARY) == -1) { - /* "Should not happen" */ - *err = errno; - g_free(wdh); - return NULL; /* couldn't put standard output in binary mode */ - } -#endif - wdh->fh = stdout; - } else { - /* In case "fopen()" fails but doesn't set "errno", set "errno" - to a generic "the open failed" error. */ - errno = WTAP_ERR_CANT_OPEN; - fh = wtap_dump_file_open(wdh, filename); - if (fh == NULL) { - *err = errno; - g_free(wdh); - return NULL; /* can't create file */ - } - wdh->fh = 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 = wtap_dump_file_open(wdh, filename); + if (fh == NULL) { + *err = errno; + g_free(wdh); + return NULL; /* can't create file */ } + wdh->fh = fh; if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) { /* Get rid of the file we created; we couldn't finish