diff --git a/tools/pkt-from-core.py b/tools/pkt-from-core.py index b6cf491594..efc252d369 100755 --- a/tools/pkt-from-core.py +++ b/tools/pkt-from-core.py @@ -77,6 +77,7 @@ class BackTrace: # Some values from wiretap; wiretap should be a shared # libray and a Python module should be created for it so # this program could just write a libpcap file directly. +WTAP_ENCAP_NONE = -2 WTAP_ENCAP_PER_PACKET = -1 WTAP_ENCAP_UNKNOWN = 0 WTAP_ENCAP_ETHERNET = 1 @@ -133,6 +134,7 @@ wtap_to_pcap_map = { wtap_name = { + WTAP_ENCAP_NONE : "None", WTAP_ENCAP_UNKNOWN : "Unknown", WTAP_ENCAP_ETHERNET : "Ethernet", WTAP_ENCAP_TOKEN_RING : "Token-Ring", diff --git a/tshark.c b/tshark.c index 93b9029011..b24942e04b 100644 --- a/tshark.c +++ b/tshark.c @@ -3623,24 +3623,11 @@ process_cap_file(capture_file *cf, char *save_file, int out_file_type, wtap_dump_params params = WTAP_DUMP_PARAMS_INIT; char *shb_user_appl; pass_status_t first_pass_status, second_pass_status; - gboolean pcapng_pcapng_workaround = false; - wtapng_iface_descriptions_t if_tmp; if (save_file != NULL) { /* Set up to write to the capture file. */ wtap_dump_params_init_no_idbs(¶ms, cf->provider.wth); - /* workaround for pcapng -> pcapng (e.g., when pcapng starts with a custom block) */ - if (out_file_type == wtap_pcapng_file_type_subtype() && params.encap == WTAP_ENCAP_UNKNOWN) { - pcapng_pcapng_workaround = true; - params.encap = WTAP_ENCAP_PER_PACKET; - params.dont_copy_idbs = true; /* make sure this stay true */ - if (params.idb_inf->interface_data != NULL) { - /* lets fake an interface, which is not copied anyway */ - g_array_insert_val(params.idb_inf->interface_data, 0, if_tmp); - } - } - /* If we don't have an application name add TShark */ if (wtap_block_get_string_option_value(g_array_index(params.shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, &shb_user_appl) != WTAP_OPTTYPE_SUCCESS) { /* this is free'd by wtap_block_unref() later */ @@ -3664,11 +3651,6 @@ process_cap_file(capture_file *cf, char *save_file, int out_file_type, &err, &err_info); } - if (pcapng_pcapng_workaround) { - /* remove the fake interface before it will be used */ - g_array_remove_index((params.idb_inf->interface_data), 0); - } - g_free(params.idb_inf); params.idb_inf = NULL; diff --git a/wiretap/file_access.c b/wiretap/file_access.c index 54adc1e5d3..795a1ba77e 100644 --- a/wiretap/file_access.c +++ b/wiretap/file_access.c @@ -2291,10 +2291,19 @@ wtap_dump_init_dumper(int file_type_subtype, wtap_compression_type compression_t g_array_append_val(wdh->interface_data, descr); } } - } else { + } else if (params->encap != WTAP_ENCAP_NONE) { int snaplen; - // XXX IDBs should be optional. + // Generate a fake IDB if we don't have one, unless the + // file encapsulation is none. (WTAP_ENCAP_NONE either + // means that there are no interfaces, or they will be + // provided later when reading the file in single-pass mode.) + // + // XXX File types should provide their own IDBs (possibly + // fake ones generated by wtap_add_generated_idb()), in + // order to support being used as inputs for mergecap where + // pcapng is the output. This doesn't work for files with + // WTAP_ENCAP_PER_PACKET. descr = wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO); descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(descr); descr_mand->wtap_encap = params->encap; diff --git a/wiretap/introspection-enums.c b/wiretap/introspection-enums.c index f030f7738b..6fe474605a 100644 --- a/wiretap/introspection-enums.c +++ b/wiretap/introspection-enums.c @@ -269,6 +269,7 @@ static ws_enum_t all_enums[] = { ENUM(WTAP_ENCAP_ATM_PDUS), ENUM(WTAP_ENCAP_ATM_PDUS_UNTRUNCATED), ENUM(WTAP_ENCAP_ATM_RFC1483), + ENUM(WTAP_ENCAP_ATSC_ALP), ENUM(WTAP_ENCAP_AUERSWALD_LOG), ENUM(WTAP_ENCAP_AUTOSAR_DLT), ENUM(WTAP_ENCAP_AX25), @@ -408,6 +409,7 @@ static ws_enum_t all_enums[] = { ENUM(WTAP_ENCAP_NETTL_X25), ENUM(WTAP_ENCAP_NFC_LLCP), ENUM(WTAP_ENCAP_NFLOG), + ENUM(WTAP_ENCAP_NONE), ENUM(WTAP_ENCAP_NORDIC_BLE), ENUM(WTAP_ENCAP_NSTRACE_1_0), ENUM(WTAP_ENCAP_NSTRACE_2_0), diff --git a/wiretap/pcapng.c b/wiretap/pcapng.c index 6cd40f2564..4ed6c5a23c 100644 --- a/wiretap/pcapng.c +++ b/wiretap/pcapng.c @@ -1621,7 +1621,7 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh, * so it probably doesn't have a single encapsulation for all * packets in the file. */ - if (wth->file_encap == WTAP_ENCAP_UNKNOWN) { + if (wth->file_encap == WTAP_ENCAP_NONE) { wth->file_encap = if_descr_mand->wtap_encap; } else { if (wth->file_encap != if_descr_mand->wtap_encap) { @@ -3097,7 +3097,7 @@ pcapng_read_systemd_journal_export_block(wtap *wth, FILE_T fh, pcapng_block_head */ wblock->internal = FALSE; - if (wth->file_encap == WTAP_ENCAP_UNKNOWN) { + if (wth->file_encap == WTAP_ENCAP_NONE) { /* * Nothing (most notably an IDB) has set a file encap at this point. * Do so here. @@ -3666,7 +3666,7 @@ pcapng_open(wtap *wth, int *err, gchar **err_info) wtap_block_unref(wblock.block); wblock.block = NULL; - wth->file_encap = WTAP_ENCAP_UNKNOWN; + wth->file_encap = WTAP_ENCAP_NONE; wth->snapshot_length = 0; wth->file_tsprec = WTAP_TSPREC_UNKNOWN; pcapng = g_new(pcapng_t, 1); @@ -6323,6 +6323,10 @@ static int pcapng_dump_can_write_encap(int wtap_encap) if (wtap_encap == WTAP_ENCAP_PER_PACKET) return 0; + /* No encapsulation type (yet) is supported. */ + if (wtap_encap == WTAP_ENCAP_NONE) + return 0; + /* Is it a filetype-specific encapsulation that we support? */ if (pcapng_encap_is_ft_specific(wtap_encap)) { return 0; diff --git a/wiretap/wtap.c b/wiretap/wtap.c index d18ff3dcad..7e485cc4a5 100644 --- a/wiretap/wtap.c +++ b/wiretap/wtap.c @@ -212,7 +212,8 @@ wtap_add_generated_idb(wtap *wth) int snaplen; ws_assert(wth->file_encap != WTAP_ENCAP_UNKNOWN && - wth->file_encap != WTAP_ENCAP_PER_PACKET); + wth->file_encap != WTAP_ENCAP_PER_PACKET && + wth->file_encap != WTAP_ENCAP_NONE); ws_assert(wth->file_tsprec != WTAP_TSPREC_UNKNOWN && wth->file_tsprec != WTAP_TSPREC_PER_PACKET); @@ -1249,8 +1250,10 @@ wtap_register_encap_type(const char *description, const char *name) const char * wtap_encap_name(int encap) { - if (encap < WTAP_ENCAP_PER_PACKET || encap >= WTAP_NUM_ENCAP_TYPES) + if (encap < WTAP_ENCAP_NONE || encap >= WTAP_NUM_ENCAP_TYPES) return "illegal"; + else if (encap == WTAP_ENCAP_NONE) + return "none"; else if (encap == WTAP_ENCAP_PER_PACKET) return "per-packet"; else @@ -1261,8 +1264,10 @@ wtap_encap_name(int encap) const char * wtap_encap_description(int encap) { - if (encap < WTAP_ENCAP_PER_PACKET || encap >= WTAP_NUM_ENCAP_TYPES) + if (encap < WTAP_ENCAP_NONE || encap >= WTAP_NUM_ENCAP_TYPES) return "Illegal"; + else if (encap == WTAP_ENCAP_NONE) + return "None"; else if (encap == WTAP_ENCAP_PER_PACKET) return "Per packet"; else @@ -1665,6 +1670,7 @@ wtap_read(wtap *wth, wtap_rec *rec, Buffer *buf, int *err, * encapsulation type. */ ws_assert(rec->rec_header.packet_header.pkt_encap != WTAP_ENCAP_PER_PACKET); + ws_assert(rec->rec_header.packet_header.pkt_encap != WTAP_ENCAP_NONE); } return TRUE; /* success */ @@ -1821,6 +1827,7 @@ wtap_seek_read(wtap *wth, gint64 seek_off, wtap_rec *rec, Buffer *buf, * encapsulation type. */ ws_assert(rec->rec_header.packet_header.pkt_encap != WTAP_ENCAP_PER_PACKET); + ws_assert(rec->rec_header.packet_header.pkt_encap != WTAP_ENCAP_NONE); } return TRUE; diff --git a/wiretap/wtap.h b/wiretap/wtap.h index d2e911e60b..6fa47a5cd0 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -31,7 +31,17 @@ extern "C" { * don't have a single encapsulation type for all packets in the file. * * WTAP_ENCAP_UNKNOWN is returned by "wtap_pcap_encap_to_wtap_encap()" - * if it's handed an unknown encapsulation. + * if it's handed an unknown encapsulation. It is also used by file + * types for encapsulations which are unsupported by libwiretap. + * + * WTAP_ENCAP_NONE is an initial value used by file types like pcapng + * that do not have a single file level encapsulation type. If and when + * something that indicate encapsulation is read, the encapsulation will + * change (possibly to WTAP_ENCAP_PER_PACKET) and appropriate IDBs will + * be generated. If a file type uses this value, it MUST provide IDBs + * (possibly fake) when the encapsulation changes; otherwise, it should + * return WTAP_ENCAP_UNKNOWN so that attempts to write an output file + * without reading the entire input file first fail gracefully. * * WTAP_ENCAP_FDDI_BITSWAPPED is for FDDI captures on systems where the * MAC addresses you get from the hardware are bit-swapped. Ideally, @@ -74,6 +84,7 @@ extern "C" { * what older versions of "libpcap" on Linux turn the Ethernet * header for loopback interfaces into (0.6.0 and later versions * leave the Ethernet header alone and make it DLT_EN10MB). */ +#define WTAP_ENCAP_NONE -2 #define WTAP_ENCAP_PER_PACKET -1 #define WTAP_ENCAP_UNKNOWN 0 #define WTAP_ENCAP_ETHERNET 1