forked from osmocom/wireshark
tshark: Add new long option --hexdump <hexoption>
parent
fdc5166234
commit
b5f89dbe2d
|
@ -1025,6 +1025,76 @@ Cause *TShark* to print a hex and ASCII dump of the packet data
|
|||
after printing the summary and/or details, if either are also being displayed.
|
||||
--
|
||||
|
||||
--hexdump <hexoption>::
|
||||
+
|
||||
--
|
||||
Cause *TShark* to print a hex and ASCII dump of the packet data
|
||||
with the ability to select which data sources to dump and how to
|
||||
format or exclude the ASCII dump text.
|
||||
|
||||
This option can be used multiple times where the data source *<hexoption>*
|
||||
is *all* or *frames* and the ASCII dump text *<hexoption>* is *ascii*,
|
||||
*delimit*, *noascii*.
|
||||
|
||||
Example: tshark ... --hexdump frames --hexdump delimit ...
|
||||
|
||||
*all*::
|
||||
|
||||
Enable hexdump, generate hexdump blocks for all data sources associated
|
||||
with each frame. Used to negate earlier use of `--hexdump frames`.
|
||||
The *-x* option displays all data sources by default.
|
||||
|
||||
*frames*::
|
||||
|
||||
Enable hexdump, generate hexdump blocks only for the frame data. Use
|
||||
this option to exclude, from hexdump output, any hexdump blocks for
|
||||
secondary data sources such as 'Bitstring tvb', 'Reassembled TCP',
|
||||
'De-chunked entity body', etc.
|
||||
|
||||
*ascii*::
|
||||
|
||||
Enable hexdump, with undelimited ASCII dump text. Used to negate earlier
|
||||
use of `--hexdump delimit` or `--hexdump noascii`. The *-x* option
|
||||
displays undelimited ASCII dump text by default.
|
||||
|
||||
*delimit*::
|
||||
|
||||
Enable hexdump with the ASCII dump text delimited with '|' characters.
|
||||
This is useful to unambigiously determine the last of the hex byte text
|
||||
and start of the ASCII dump text.
|
||||
|
||||
*noascii*::
|
||||
|
||||
Enable hexdump without printing any ASCII dump text.
|
||||
|
||||
*help*::
|
||||
|
||||
Display --hexdump specific help then exit.
|
||||
|
||||
The use of *--hexdump <hexoption>* is particularly useful to generate output
|
||||
that can be used to create a pcap or pcapng file from a capture file type such
|
||||
as Microsoft NetMon 2.x which *TShark* and *Wireshark* can read but can not
|
||||
directly do a "Save as" nor export packets from.
|
||||
|
||||
Examples:
|
||||
|
||||
Generate hexdump output, with only the frame data source, with delimited ASCII
|
||||
dump text, with each frame hex block preceeded by a human readable timestamp that
|
||||
is directly usable by the *text2pcap* utility:
|
||||
|
||||
tshark ... --hexdump frames --hexdump delimit \
|
||||
-P -t ad -o gui.column.format:"Time","%t" \
|
||||
| text2pcap -n -t '%F %T.%f' - MYNEWPCAPNG
|
||||
|
||||
Generate hexdump output, with only the frame data source, with no ASCII dump text,
|
||||
with each frame hex block preceeded by an epoch timestamp that is directly
|
||||
usable by the *text2pcap* utility:
|
||||
|
||||
tshark ... --hexdump frames --hexdump noascii \
|
||||
-P -t e -o gui.column.format:"Time","%t" \
|
||||
| text2pcap -n -t %s.%f - MYNEWPCAPNG
|
||||
--
|
||||
|
||||
-X <eXtension options>::
|
||||
+
|
||||
--
|
||||
|
|
32
epan/print.c
32
epan/print.c
|
@ -91,7 +91,8 @@ static const guint8 *get_field_data(GSList *src_list, field_info *fi);
|
|||
static void pdml_write_field_hex_value(write_pdml_data *pdata, field_info *fi);
|
||||
static void json_write_field_hex_value(write_json_data *pdata, field_info *fi);
|
||||
static gboolean print_hex_data_buffer(print_stream_t *stream, const guchar *cp,
|
||||
guint length, packet_char_enc encoding);
|
||||
guint length, packet_char_enc encoding,
|
||||
guint hexdump_options);
|
||||
static void write_specified_fields(fields_format format,
|
||||
output_fields_t *fields,
|
||||
epan_dissect_t *edt, column_info *cinfo,
|
||||
|
@ -223,7 +224,7 @@ proto_tree_print_node(proto_node *node, gpointer data)
|
|||
return;
|
||||
}
|
||||
if (!print_hex_data_buffer(pdata->stream, pd,
|
||||
fi->length, pdata->encoding)) {
|
||||
fi->length, pdata->encoding, HEXDUMP_ASCII_INCLUDE)) {
|
||||
pdata->success = FALSE;
|
||||
return;
|
||||
}
|
||||
|
@ -1961,7 +1962,7 @@ json_write_field_hex_value(write_json_data *pdata, field_info *fi)
|
|||
}
|
||||
|
||||
gboolean
|
||||
print_hex_data(print_stream_t *stream, epan_dissect_t *edt)
|
||||
print_hex_data(print_stream_t *stream, epan_dissect_t *edt, guint hexdump_options)
|
||||
{
|
||||
gboolean multiple_sources;
|
||||
GSList *src_le;
|
||||
|
@ -1983,7 +1984,7 @@ print_hex_data(print_stream_t *stream, epan_dissect_t *edt)
|
|||
src_le = src_le->next) {
|
||||
src = (struct data_source *)src_le->data;
|
||||
tvb = get_data_source_tvb(src);
|
||||
if (multiple_sources) {
|
||||
if (multiple_sources && (HEXDUMP_SOURCE_OPTION(hexdump_options) == HEXDUMP_SOURCE_MULTI)) {
|
||||
name = get_data_source_name(src);
|
||||
line = ws_strdup_printf("%s:", name);
|
||||
wmem_free(NULL, name);
|
||||
|
@ -1995,8 +1996,12 @@ print_hex_data(print_stream_t *stream, epan_dissect_t *edt)
|
|||
return TRUE;
|
||||
cp = tvb_get_ptr(tvb, 0, length);
|
||||
if (!print_hex_data_buffer(stream, cp, length,
|
||||
(packet_char_enc)edt->pi.fd->encoding))
|
||||
(packet_char_enc)edt->pi.fd->encoding,
|
||||
HEXDUMP_ASCII_OPTION(hexdump_options)))
|
||||
return FALSE;
|
||||
if (HEXDUMP_SOURCE_OPTION(hexdump_options) == HEXDUMP_SOURCE_PRIMARY) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -2013,10 +2018,11 @@ print_hex_data(print_stream_t *stream, epan_dissect_t *edt)
|
|||
#define HEX_DUMP_LEN (BYTES_PER_LINE*3)
|
||||
/* max number of characters hex dump takes -
|
||||
2 digits plus trailing blank */
|
||||
#define DATA_DUMP_LEN (HEX_DUMP_LEN + 2 + BYTES_PER_LINE)
|
||||
#define DATA_DUMP_LEN (HEX_DUMP_LEN + 2 + 2 + BYTES_PER_LINE)
|
||||
/* number of characters those bytes take;
|
||||
3 characters per byte of hex dump,
|
||||
2 blanks separating hex from ASCII,
|
||||
2 optional ASCII dump delimiters,
|
||||
1 character per byte of ASCII dump */
|
||||
#define MAX_LINE_LEN (MAX_OFFSET_LEN + 2 + DATA_DUMP_LEN)
|
||||
/* number of characters per line;
|
||||
|
@ -2025,7 +2031,7 @@ print_hex_data(print_stream_t *stream, epan_dissect_t *edt)
|
|||
|
||||
static gboolean
|
||||
print_hex_data_buffer(print_stream_t *stream, const guchar *cp,
|
||||
guint length, packet_char_enc encoding)
|
||||
guint length, packet_char_enc encoding, guint ascii_option)
|
||||
{
|
||||
register unsigned int ad, i, j, k, l;
|
||||
guchar c;
|
||||
|
@ -2076,15 +2082,19 @@ print_hex_data_buffer(print_stream_t *stream, const guchar *cp,
|
|||
* Offset in line of ASCII dump.
|
||||
*/
|
||||
k = j + HEX_DUMP_LEN + 2;
|
||||
if (ascii_option == HEXDUMP_ASCII_DELIMIT)
|
||||
line[k++] = '|';
|
||||
}
|
||||
c = *cp++;
|
||||
line[j++] = binhex[c>>4];
|
||||
line[j++] = binhex[c&0xf];
|
||||
j++;
|
||||
if (encoding == PACKET_CHAR_ENC_CHAR_EBCDIC) {
|
||||
c = EBCDIC_to_ASCII1(c);
|
||||
if (ascii_option != HEXDUMP_ASCII_EXCLUDE ) {
|
||||
if (encoding == PACKET_CHAR_ENC_CHAR_EBCDIC) {
|
||||
c = EBCDIC_to_ASCII1(c);
|
||||
}
|
||||
line[k++] = ((c >= ' ') && (c < 0x7f)) ? c : '.';
|
||||
}
|
||||
line[k++] = ((c >= ' ') && (c < 0x7f)) ? c : '.';
|
||||
i++;
|
||||
if (((i & 15) == 0) || (i == length)) {
|
||||
/*
|
||||
|
@ -2093,6 +2103,8 @@ print_hex_data_buffer(print_stream_t *stream, const guchar *cp,
|
|||
* dump out the line we've constructed,
|
||||
* and advance the offset.
|
||||
*/
|
||||
if (ascii_option == HEXDUMP_ASCII_DELIMIT)
|
||||
line[k++] = '|';
|
||||
line[k] = '\0';
|
||||
if (!print_line(stream, 0, line))
|
||||
return FALSE;
|
||||
|
|
24
epan/print.h
24
epan/print.h
|
@ -80,7 +80,29 @@ WS_DLL_PUBLIC gboolean proto_tree_print(print_dissections_e print_dissections,
|
|||
epan_dissect_t *edt,
|
||||
GHashTable *output_only_tables,
|
||||
print_stream_t *stream);
|
||||
WS_DLL_PUBLIC gboolean print_hex_data(print_stream_t *stream, epan_dissect_t *edt);
|
||||
|
||||
/*
|
||||
* Hexdump options for ASCII:
|
||||
*/
|
||||
|
||||
#define HEXDUMP_ASCII_MASK (0x0003U)
|
||||
#define HEXDUMP_ASCII_OPTION(option) ((option) & HEXDUMP_ASCII_MASK)
|
||||
|
||||
#define HEXDUMP_ASCII_INCLUDE (0x0000U) /* include ASCII section no delimiters (legacy tshark behavior) */
|
||||
#define HEXDUMP_ASCII_DELIMIT (0x0001U) /* include ASCII section with delimiters, useful for reliable detection of last hexdata */
|
||||
#define HEXDUMP_ASCII_EXCLUDE (0x0002U) /* exclude ASCII section from hexdump reports, if we really don't want or need it */
|
||||
|
||||
/*
|
||||
* Hexdump option for displaying data sources:
|
||||
*/
|
||||
|
||||
#define HEXDUMP_SOURCE_MASK (0x0004U)
|
||||
#define HEXDUMP_SOURCE_OPTION(option) ((option) & HEXDUMP_SOURCE_MASK)
|
||||
|
||||
#define HEXDUMP_SOURCE_MULTI (0x0000U) /* create hexdumps for all data sources assigned to a frame (legacy tshark behavor) */
|
||||
#define HEXDUMP_SOURCE_PRIMARY (0x0004U) /* create hexdumps for only the frame data */
|
||||
|
||||
WS_DLL_PUBLIC gboolean print_hex_data(print_stream_t *stream, epan_dissect_t *edt, guint hexdump_options);
|
||||
|
||||
WS_DLL_PUBLIC void write_pdml_preamble(FILE *fh, const gchar* filename);
|
||||
WS_DLL_PUBLIC void write_pdml_proto_tree(output_fields_t* fields, gchar **protocolfilter, pf_flags protocolfilter_flags, epan_dissect_t *edt, column_info *cinfo, FILE *fh, gboolean use_color);
|
||||
|
|
2
file.c
2
file.c
|
@ -2467,7 +2467,7 @@ print_packet(capture_file *cf, frame_data *fdata, wtap_rec *rec, Buffer *buf,
|
|||
goto fail;
|
||||
}
|
||||
/* Print the full packet data as hex. */
|
||||
if (!print_hex_data(args->print_args->stream, &args->edt))
|
||||
if (!print_hex_data(args->print_args->stream, &args->edt, HEXDUMP_SOURCE_MULTI | HEXDUMP_ASCII_INCLUDE))
|
||||
goto fail;
|
||||
|
||||
/* Print a blank line if we print anything after this (aka more than one packet). */
|
||||
|
|
|
@ -1962,7 +1962,7 @@ print_packet(capture_file *cf, epan_dissect_t *edt)
|
|||
if (!print_line(print_stream, 0, ""))
|
||||
return FALSE;
|
||||
}
|
||||
if (!print_hex_data(print_stream, edt))
|
||||
if (!print_hex_data(print_stream, edt, HEXDUMP_SOURCE_MULTI | HEXDUMP_ASCII_INCLUDE))
|
||||
return FALSE;
|
||||
if (!print_line(print_stream, 0, separator))
|
||||
return FALSE;
|
||||
|
|
62
tshark.c
62
tshark.c
|
@ -134,6 +134,7 @@
|
|||
#define LONGOPT_ELASTIC_MAPPING_FILTER LONGOPT_BASE_APPLICATION+4
|
||||
#define LONGOPT_EXPORT_TLS_SESSION_KEYS LONGOPT_BASE_APPLICATION+5
|
||||
#define LONGOPT_CAPTURE_COMMENT LONGOPT_BASE_APPLICATION+6
|
||||
#define LONGOPT_HEXDUMP LONGOPT_BASE_APPLICATION+7
|
||||
|
||||
capture_file cfile;
|
||||
|
||||
|
@ -171,6 +172,8 @@ static gboolean quiet = FALSE;
|
|||
static gboolean really_quiet = FALSE;
|
||||
static gchar* delimiter_char = " ";
|
||||
static gboolean dissect_color = FALSE;
|
||||
static guint hexdump_source_option = HEXDUMP_SOURCE_MULTI; /* Default - Enable legacy multi-source mode */
|
||||
static guint hexdump_ascii_option = HEXDUMP_ASCII_INCLUDE; /* Default - Enable legacy undelimited ASCII dump */
|
||||
|
||||
static print_format_e print_format = PR_FMT_TEXT;
|
||||
static print_stream_t *print_stream = NULL;
|
||||
|
@ -428,6 +431,13 @@ print_usage(FILE *output)
|
|||
fprintf(output, " -P, --print print packet summary even when writing to a file\n");
|
||||
fprintf(output, " -S <separator> the line separator to print between packets\n");
|
||||
fprintf(output, " -x add output of hex and ASCII dump (Packet Bytes)\n");
|
||||
fprintf(output, " --hexdump <hexoption> add hexdump, set options for data source and ASCII dump\n");
|
||||
fprintf(output, " all dump all data sources (-x default)\n");
|
||||
fprintf(output, " frames dump only frame data source\n");
|
||||
fprintf(output, " ascii include ASCII dump text (-x default)\n");
|
||||
fprintf(output, " delimit delimit ASCII dump text with '|' characters\n");
|
||||
fprintf(output, " noascii exclude ASCII dump text\n");
|
||||
fprintf(output, " help display help for --hexdump and exit\n");
|
||||
fprintf(output, " -T pdml|ps|psml|json|jsonraw|ek|tabs|text|fields|?\n");
|
||||
fprintf(output, " format of text output (def: text)\n");
|
||||
fprintf(output, " -j <protocolfilter> protocols layers filter if -T ek|pdml|json selected\n");
|
||||
|
@ -527,6 +537,31 @@ glossary_option_help(void)
|
|||
fprintf(output, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
hexdump_option_help(FILE *output)
|
||||
{
|
||||
fprintf(output, "%s\n", get_appname_and_version());
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "tshark: Valid --hexdump <hexoption> values include:\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Data source options:\n");
|
||||
fprintf(output, " all add hexdump, dump all data sources (-x default)\n");
|
||||
fprintf(output, " frames add hexdump, dump only frame data source\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "ASCII options:\n");
|
||||
fprintf(output, " ascii add hexdump, include ASCII dump text (-x default)\n");
|
||||
fprintf(output, " delimit add hexdump, delimit ASCII dump text with '|' characters\n");
|
||||
fprintf(output, " noascii add hexdump, exclude ASCII dump text\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Miscellaneous:\n");
|
||||
fprintf(output, " help display this help and exit\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Example:\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, " $ tshark ... --hexdump frames --hexdump delimit ...\n");
|
||||
fprintf(output, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
print_current_user(void) {
|
||||
gchar *cur_user, *cur_group;
|
||||
|
@ -701,6 +736,7 @@ main(int argc, char *argv[])
|
|||
{"no-duplicate-keys", ws_no_argument, NULL, LONGOPT_NO_DUPLICATE_KEYS},
|
||||
{"elastic-mapping-filter", ws_required_argument, NULL, LONGOPT_ELASTIC_MAPPING_FILTER},
|
||||
{"capture-comment", ws_required_argument, NULL, LONGOPT_CAPTURE_COMMENT},
|
||||
{"hexdump", ws_required_argument, NULL, LONGOPT_HEXDUMP},
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
gboolean arg_error = FALSE;
|
||||
|
@ -1476,6 +1512,30 @@ main(int argc, char *argv[])
|
|||
}
|
||||
g_ptr_array_add(capture_comments, g_strdup(ws_optarg));
|
||||
break;
|
||||
case LONGOPT_HEXDUMP:
|
||||
print_hex = TRUE;
|
||||
print_packet_info = TRUE;
|
||||
if (strcmp(ws_optarg, "all") == 0)
|
||||
hexdump_source_option = HEXDUMP_SOURCE_MULTI;
|
||||
else if (strcmp(ws_optarg, "frames") == 0)
|
||||
hexdump_source_option = HEXDUMP_SOURCE_PRIMARY;
|
||||
else if (strcmp(ws_optarg, "ascii") == 0)
|
||||
hexdump_ascii_option = HEXDUMP_ASCII_INCLUDE;
|
||||
else if (strcmp(ws_optarg, "delimit") == 0)
|
||||
hexdump_ascii_option = HEXDUMP_ASCII_DELIMIT;
|
||||
else if (strcmp(ws_optarg, "noascii") == 0)
|
||||
hexdump_ascii_option = HEXDUMP_ASCII_EXCLUDE;
|
||||
else if (strcmp("help", ws_optarg) == 0) {
|
||||
hexdump_option_help(stdout);
|
||||
exit_status = EXIT_SUCCESS;
|
||||
goto clean_exit;
|
||||
} else {
|
||||
fprintf(stderr, "tshark: \"%s\" is an invalid value for --hexdump <hexoption>\n", ws_optarg);
|
||||
fprintf(stderr, "For valid <hexoption> values enter: tshark --hexdump help\n");
|
||||
exit_status = INVALID_OPTION;
|
||||
goto clean_exit;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
case '?': /* Bad flag - print usage message */
|
||||
switch(ws_optopt) {
|
||||
|
@ -4315,7 +4375,7 @@ print_packet(capture_file *cf, epan_dissect_t *edt)
|
|||
if (!print_line(print_stream, 0, ""))
|
||||
return FALSE;
|
||||
}
|
||||
if (!print_hex_data(print_stream, edt))
|
||||
if (!print_hex_data(print_stream, edt, hexdump_source_option | hexdump_ascii_option))
|
||||
return FALSE;
|
||||
if (!print_line(print_stream, 0, separator))
|
||||
return FALSE;
|
||||
|
|
Loading…
Reference in New Issue