2014-01-20 05:51:10 +00:00
|
|
|
/* tap_export_pdu.c
|
2014-07-15 20:15:27 +00:00
|
|
|
* Routines for exporting PDUs to file
|
2014-01-20 05:51:10 +00:00
|
|
|
*
|
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
2018-04-30 07:47:58 +00:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
2014-01-20 05:51:10 +00:00
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2016-02-18 12:06:13 +00:00
|
|
|
#include "wiretap/pcap-encap.h"
|
2014-06-21 18:01:19 +00:00
|
|
|
#include "wsutil/os_version_info.h"
|
2017-09-26 14:04:56 +00:00
|
|
|
#include "version_info.h"
|
2014-01-20 05:51:10 +00:00
|
|
|
|
|
|
|
#include <epan/tap.h>
|
|
|
|
#include <epan/exported_pdu.h>
|
2014-12-19 13:08:38 +00:00
|
|
|
#include <epan/epan_dissect.h>
|
2016-04-29 13:23:28 +00:00
|
|
|
#include <wiretap/wtap.h>
|
2016-01-26 01:17:21 +00:00
|
|
|
#include <wiretap/wtap_opttypes.h>
|
|
|
|
#include <wiretap/pcapng.h>
|
2014-01-20 05:51:10 +00:00
|
|
|
|
|
|
|
#include "tap_export_pdu.h"
|
|
|
|
|
|
|
|
/* Main entry point to the tap */
|
2019-01-01 03:36:12 +00:00
|
|
|
static tap_packet_status
|
2014-12-19 13:08:38 +00:00
|
|
|
export_pdu_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, const void *data)
|
2014-01-20 05:51:10 +00:00
|
|
|
{
|
|
|
|
const exp_pdu_data_t *exp_pdu_data = (const exp_pdu_data_t *)data;
|
|
|
|
exp_pdu_t *exp_pdu_tap_data = (exp_pdu_t *)tapdata;
|
2018-02-09 00:19:12 +00:00
|
|
|
wtap_rec rec;
|
2014-01-20 05:51:10 +00:00
|
|
|
int err;
|
2014-12-18 00:02:50 +00:00
|
|
|
gchar *err_info;
|
2014-01-20 05:51:10 +00:00
|
|
|
int buffer_len;
|
|
|
|
guint8 *packet_buf;
|
|
|
|
|
2018-02-09 00:19:12 +00:00
|
|
|
memset(&rec, 0, sizeof rec);
|
2014-03-18 22:01:22 +00:00
|
|
|
buffer_len = exp_pdu_data->tvb_captured_length + exp_pdu_data->tlv_buffer_len;
|
2014-01-20 05:51:10 +00:00
|
|
|
packet_buf = (guint8 *)g_malloc(buffer_len);
|
|
|
|
|
|
|
|
if(exp_pdu_data->tlv_buffer_len > 0){
|
|
|
|
memcpy(packet_buf, exp_pdu_data->tlv_buffer, exp_pdu_data->tlv_buffer_len);
|
|
|
|
}
|
2015-06-24 04:35:46 +00:00
|
|
|
if(exp_pdu_data->tvb_captured_length > 0){
|
|
|
|
tvb_memcpy(exp_pdu_data->pdu_tvb, packet_buf+exp_pdu_data->tlv_buffer_len, 0, exp_pdu_data->tvb_captured_length);
|
2014-01-20 05:51:10 +00:00
|
|
|
}
|
2018-02-09 00:19:12 +00:00
|
|
|
rec.rec_type = REC_TYPE_PACKET;
|
|
|
|
rec.presence_flags = WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID|WTAP_HAS_TS|WTAP_HAS_PACK_FLAGS;
|
|
|
|
rec.ts.secs = pinfo->abs_ts.secs;
|
|
|
|
rec.ts.nsecs = pinfo->abs_ts.nsecs;
|
|
|
|
rec.rec_header.packet_header.caplen = buffer_len;
|
|
|
|
rec.rec_header.packet_header.len = exp_pdu_data->tvb_reported_length + exp_pdu_data->tlv_buffer_len;
|
2014-01-20 05:51:10 +00:00
|
|
|
|
2018-02-09 00:19:12 +00:00
|
|
|
rec.rec_header.packet_header.pkt_encap = exp_pdu_tap_data->pkt_encap;
|
2014-12-19 13:08:38 +00:00
|
|
|
|
2019-01-24 11:08:57 +00:00
|
|
|
/* rec.opt_comment is not modified by wtap_dump, but if for some reason the
|
|
|
|
* epan_get_user_comment() or pinfo->rec->opt_comment are invalidated,
|
|
|
|
* copying it here does not hurt. (Can invalidation really happen?) */
|
2018-12-27 02:26:24 +00:00
|
|
|
if (pinfo->fd->has_user_comment) {
|
2018-02-09 00:19:12 +00:00
|
|
|
rec.opt_comment = g_strdup(epan_get_user_comment(edt->session, pinfo->fd));
|
|
|
|
rec.has_comment_changed = TRUE;
|
2018-12-27 02:26:24 +00:00
|
|
|
} else if (pinfo->fd->has_phdr_comment) {
|
2018-02-09 00:19:12 +00:00
|
|
|
rec.opt_comment = g_strdup(pinfo->rec->opt_comment);
|
2017-06-01 08:34:25 +00:00
|
|
|
}
|
2014-12-19 13:08:38 +00:00
|
|
|
|
2018-02-09 00:19:12 +00:00
|
|
|
/* XXX: should the rec.rec_header.packet_header.pseudo_header be set to the pinfo's pseudo-header? */
|
2019-01-01 03:36:12 +00:00
|
|
|
/* XXX: report errors and return TAP_PACKET_FAILED! */
|
2018-02-09 00:19:12 +00:00
|
|
|
if (!wtap_dump(exp_pdu_tap_data->wdh, &rec, packet_buf, &err, &err_info)) {
|
2014-12-18 00:02:50 +00:00
|
|
|
switch (err) {
|
2014-03-27 21:24:20 +00:00
|
|
|
|
2014-12-18 00:02:50 +00:00
|
|
|
case WTAP_ERR_UNWRITABLE_REC_DATA:
|
|
|
|
g_free(err_info);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2014-01-20 05:51:10 +00:00
|
|
|
|
|
|
|
g_free(packet_buf);
|
2018-02-09 00:19:12 +00:00
|
|
|
g_free(rec.opt_comment);
|
2014-01-20 05:51:10 +00:00
|
|
|
|
2019-01-01 03:36:12 +00:00
|
|
|
return TAP_PACKET_DONT_REDRAW; /* Do not redraw */
|
2014-01-20 05:51:10 +00:00
|
|
|
}
|
|
|
|
|
2020-10-14 01:48:46 +00:00
|
|
|
gboolean
|
|
|
|
exp_pdu_open(exp_pdu_t *exp_pdu_tap_data, int fd, const char *comment, int *err,
|
|
|
|
gchar **err_info)
|
2014-01-20 05:51:10 +00:00
|
|
|
{
|
|
|
|
/* pcapng defs */
|
2016-07-14 23:01:57 +00:00
|
|
|
wtap_block_t shb_hdr;
|
|
|
|
wtap_block_t int_data;
|
2016-01-26 01:17:21 +00:00
|
|
|
wtapng_if_descr_mandatory_t *int_data_mand;
|
2014-01-20 05:51:10 +00:00
|
|
|
GString *os_info_str;
|
2016-05-20 02:28:43 +00:00
|
|
|
gsize opt_len;
|
2016-07-26 11:58:55 +00:00
|
|
|
gchar *opt_str;
|
2014-01-20 05:51:10 +00:00
|
|
|
|
|
|
|
/* Create data for SHB */
|
|
|
|
os_info_str = g_string_new("");
|
|
|
|
get_os_version_info(os_info_str);
|
|
|
|
|
2021-02-09 21:40:59 +00:00
|
|
|
shb_hdr = wtap_block_create(WTAP_BLOCK_SECTION);
|
2016-01-26 01:17:21 +00:00
|
|
|
|
2014-01-20 05:51:10 +00:00
|
|
|
/* options */
|
2016-07-14 23:01:57 +00:00
|
|
|
wtap_block_add_string_option(shb_hdr, OPT_COMMENT, comment, strlen(comment));
|
2016-01-26 01:17:21 +00:00
|
|
|
|
2015-01-13 23:13:40 +00:00
|
|
|
/*
|
|
|
|
* UTF-8 string containing the name of the operating system used to create
|
|
|
|
* this section.
|
|
|
|
*/
|
2016-05-20 02:28:43 +00:00
|
|
|
opt_len = os_info_str->len;
|
2016-07-26 11:58:55 +00:00
|
|
|
opt_str = g_string_free(os_info_str, FALSE);
|
|
|
|
if (opt_str) {
|
|
|
|
wtap_block_add_string_option(shb_hdr, OPT_SHB_OS, opt_str, opt_len);
|
|
|
|
g_free(opt_str);
|
|
|
|
}
|
2015-01-13 23:13:40 +00:00
|
|
|
/*
|
|
|
|
* UTF-8 string containing the name of the application used to create
|
|
|
|
* this section.
|
|
|
|
*/
|
2018-12-13 02:16:15 +00:00
|
|
|
wtap_block_add_string_option_format(shb_hdr, OPT_SHB_USERAPPL, "%s", get_appname_and_version());
|
2014-01-20 05:51:10 +00:00
|
|
|
|
|
|
|
/* Create fake IDB info */
|
2018-08-02 23:17:07 +00:00
|
|
|
exp_pdu_tap_data->idb_inf = g_new(wtapng_iface_descriptions_t,1);
|
|
|
|
exp_pdu_tap_data->idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
|
2014-01-20 05:51:10 +00:00
|
|
|
|
|
|
|
/* create the fake interface data */
|
wiretap: have file handlers advertise blocks and options supported.
Instead of a "supports name resolution" Boolean and bitflags for types of
comments supported, provide a list of block types that the file
type/subtype supports, with each block type having a list of options
supported. Indicate whether "supported" means "one instance" or
"multiple instances".
"Supports" doesn't just mean "can be written", it also means "could be
read".
Rename WTAP_BLOCK_IF_DESCRIPTION to WTAP_BLOCK_IF_ID_AND_INFO, to
indicate that it provides, in addition to information about the
interface, an ID (implicitly, in pcapng files, by its ordinal number)
that is associated with every packet in the file. Emphasize that in
comments - just because your capture file format can list the interfaces
on which a capture was done, that doesn't mean it supports this; it
doesn't do so if the file doesn't indicate, for every packet, on which
of those interfaces it was captured (I'm looking at *you*, Microsoft
Network Monitor...).
Use APIs to query that information to do what the "does this file
type/subtype support name resolution information", "does this file
type/subtype support all of these comment types", and "does this file
type/subtype support - and require - interface IDs" APIs did.
Provide backwards compatibility for Lua.
This allows us to eliminate the WTAP_FILE_TYPE_SUBTYPE_ values for IBM's
iptrace; do so.
2021-02-21 22:18:04 +00:00
|
|
|
int_data = wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO);
|
2016-07-14 23:01:57 +00:00
|
|
|
int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
|
2016-01-26 01:17:21 +00:00
|
|
|
int_data_mand->wtap_encap = WTAP_ENCAP_WIRESHARK_UPPER_PDU;
|
|
|
|
int_data_mand->time_units_per_second = 1000000000; /* default nanosecond resolution */
|
Allow bigger snapshot lengths for D-Bus captures.
Use WTAP_MAX_PACKET_SIZE_STANDARD, set to 256KB, for everything except
for D-Bus captures. Use WTAP_MAX_PACKET_SIZE_DBUS, set to 128MB, for
them, because that's the largest possible D-Bus message size. See
https://bugs.freedesktop.org/show_bug.cgi?id=100220
for an example of the problems caused by limiting the snapshot length to
256KB for D-Bus.
Have a snapshot length of 0 in a capture_file structure mean "there is
no snapshot length for the file"; we don't need the has_snap field in
that case, a value of 0 mean "no, we don't have a snapshot length".
In dumpcap, start out with a pipe buffer size of 2KB, and grow it as
necessary. When checking for a too-big packet from a pipe, check
against the appropriate maximum - 128MB for DLT_DBUS, 256KB for
everything else.
Change-Id: Ib2ce7a0cf37b971fbc0318024fd011e18add8b20
Reviewed-on: https://code.wireshark.org/review/21952
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2017-06-05 01:58:40 +00:00
|
|
|
int_data_mand->snap_len = WTAP_MAX_PACKET_SIZE_STANDARD;
|
2016-01-26 01:17:21 +00:00
|
|
|
|
2016-07-14 23:01:57 +00:00
|
|
|
wtap_block_add_string_option(int_data, OPT_IDB_NAME, "Fake IF, PDU->Export", strlen("Fake IF, PDU->Export"));
|
|
|
|
wtap_block_add_uint8_option(int_data, OPT_IDB_TSRESOL, 9);
|
2014-01-20 05:51:10 +00:00
|
|
|
|
2018-08-02 23:17:07 +00:00
|
|
|
g_array_append_val(exp_pdu_tap_data->idb_inf->interface_data, int_data);
|
2014-01-20 05:51:10 +00:00
|
|
|
|
2018-08-02 23:17:07 +00:00
|
|
|
exp_pdu_tap_data->shb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
|
|
|
|
g_array_append_val(exp_pdu_tap_data->shb_hdrs, shb_hdr);
|
2016-05-31 03:42:41 +00:00
|
|
|
|
2018-11-14 00:10:53 +00:00
|
|
|
const wtap_dump_params params = {
|
|
|
|
.encap = WTAP_ENCAP_WIRESHARK_UPPER_PDU,
|
|
|
|
.snaplen = WTAP_MAX_PACKET_SIZE_STANDARD,
|
2018-11-11 14:49:12 +00:00
|
|
|
.shb_hdrs = exp_pdu_tap_data->shb_hdrs,
|
|
|
|
.idb_inf = exp_pdu_tap_data->idb_inf,
|
|
|
|
};
|
2018-08-01 08:05:05 +00:00
|
|
|
if (fd == 1) {
|
2018-11-12 23:43:10 +00:00
|
|
|
exp_pdu_tap_data->wdh = wtap_dump_open_stdout(WTAP_FILE_TYPE_SUBTYPE_PCAPNG,
|
2020-10-14 01:48:46 +00:00
|
|
|
WTAP_UNCOMPRESSED, ¶ms, err, err_info);
|
2018-08-01 08:05:05 +00:00
|
|
|
} else {
|
2018-11-12 23:43:10 +00:00
|
|
|
exp_pdu_tap_data->wdh = wtap_dump_fdopen(fd, WTAP_FILE_TYPE_SUBTYPE_PCAPNG,
|
2020-10-14 01:48:46 +00:00
|
|
|
WTAP_UNCOMPRESSED, ¶ms, err, err_info);
|
2014-01-20 05:51:10 +00:00
|
|
|
}
|
2020-10-14 01:48:46 +00:00
|
|
|
if (exp_pdu_tap_data->wdh == NULL)
|
|
|
|
return FALSE;
|
2014-01-20 05:51:10 +00:00
|
|
|
|
2020-10-14 01:48:46 +00:00
|
|
|
return TRUE;
|
2016-04-29 13:23:28 +00:00
|
|
|
}
|
2014-01-20 05:51:10 +00:00
|
|
|
|
2020-10-14 01:48:46 +00:00
|
|
|
gboolean
|
|
|
|
exp_pdu_close(exp_pdu_t *exp_pdu_tap_data, int *err, gchar **err_info)
|
2016-04-29 13:23:28 +00:00
|
|
|
{
|
2020-10-14 01:48:46 +00:00
|
|
|
gboolean status;
|
|
|
|
|
|
|
|
status = wtap_dump_close(exp_pdu_tap_data->wdh, err, err_info);
|
2014-01-20 05:51:10 +00:00
|
|
|
|
2018-08-02 23:17:07 +00:00
|
|
|
wtap_block_array_free(exp_pdu_tap_data->shb_hdrs);
|
|
|
|
wtap_free_idb_info(exp_pdu_tap_data->idb_inf);
|
|
|
|
|
2014-01-20 05:51:10 +00:00
|
|
|
remove_tap_listener(exp_pdu_tap_data);
|
2020-10-14 01:48:46 +00:00
|
|
|
return status;
|
2014-01-20 05:51:10 +00:00
|
|
|
}
|
|
|
|
|
2016-04-29 13:23:28 +00:00
|
|
|
|
|
|
|
char *
|
|
|
|
exp_pdu_pre_open(const char *tap_name, const char *filter, exp_pdu_t *exp_pdu_tap_data)
|
2014-01-20 05:51:10 +00:00
|
|
|
{
|
2016-06-19 09:01:56 +00:00
|
|
|
GString *error_string;
|
|
|
|
|
2016-04-29 13:23:28 +00:00
|
|
|
/* XXX: can we always assume WTAP_ENCAP_WIRESHARK_UPPER_PDU? */
|
|
|
|
exp_pdu_tap_data->pkt_encap = wtap_wtap_encap_to_pcap_encap(WTAP_ENCAP_WIRESHARK_UPPER_PDU);
|
|
|
|
|
2014-01-20 05:51:10 +00:00
|
|
|
/* Register this tap listener now */
|
2016-06-19 09:01:56 +00:00
|
|
|
error_string = register_tap_listener(tap_name, /* The name of the tap we want to listen to */
|
2014-01-20 05:51:10 +00:00
|
|
|
exp_pdu_tap_data, /* instance identifier/pointer to a struct holding
|
|
|
|
* all state variables */
|
|
|
|
filter, /* pointer to a filter string */
|
2016-04-29 13:23:28 +00:00
|
|
|
TL_REQUIRES_PROTO_TREE, /* flags for the tap listener */
|
2014-01-20 05:51:10 +00:00
|
|
|
NULL,
|
|
|
|
export_pdu_packet,
|
2018-07-21 00:07:19 +00:00
|
|
|
NULL,
|
2014-01-20 05:51:10 +00:00
|
|
|
NULL);
|
2016-06-19 09:01:56 +00:00
|
|
|
if (error_string != NULL)
|
|
|
|
return g_string_free(error_string, FALSE);
|
|
|
|
|
|
|
|
return NULL;
|
2014-01-20 05:51:10 +00:00
|
|
|
}
|
2014-01-20 09:42:52 +00:00
|
|
|
|
2016-04-29 13:23:28 +00:00
|
|
|
|
2014-01-20 09:42:52 +00:00
|
|
|
/*
|
|
|
|
* Editor modelines
|
|
|
|
*
|
|
|
|
* Local Variables:
|
|
|
|
* c-basic-offset: 4
|
|
|
|
* tab-width: 8
|
|
|
|
* indent-tabs-mode: nil
|
|
|
|
* End:
|
|
|
|
*
|
|
|
|
* ex: set shiftwidth=4 tabstop=8 expandtab:
|
|
|
|
* :indentSize=4:tabSize=8:noTabs=true:
|
|
|
|
*/
|