A post-dissector to allow filtering on Protocol and Info columns
Enhancement: filter for info column in Wireshark Issue #13491
Installation - place in plugins directory - see Lua Support in Wireshark
Example - Analyze filter smb2.cmd == 9 && smb2.filename contains "fname" shows no results
Filter filtcols.info contains "file87.txt"
Sample capture from SMB2 page.
Example - Filter TLS 1.3 traffic in Wireshark
Filter filtcols.protocol == "TLSv1.3"
Sample capture from Issue #12779 Add TLS 1.3 support
References
Post-dissector examples
gaddman/wireshark-tcpextend (Also on the Contrib page and LUA dissector: update treeitem in earlier packet )
Creating a Wireshark USB dissector in Lua - part 1 (mouse)
Creating a Wireshark dissector in Lua - part 1 (the basics)
-- filtcols.lua
-- similar to _ws.col.protocol in tshark
local filtcols_info =
{
version = "1.0.2",
author = "Chuck Craft",
description = "Support filtering on Protocol and Info columns",
}
set_plugin_info(filtcols_info)
-- we create a "protocol" for our tree
local filtcols_p = Proto("filtcols","Filterable Protocol/Info columns")
-- we create our fields
local col_protocol_field = ProtoField.string("filtcols.protocol", "Protocol column")
local col_info_field = ProtoField.string("filtcols.info", "Info column")
-- we add our fields to the protocol
filtcols_p.fields = { col_protocol_field, col_info_field }
-- variables to persist across all packets
local pkt_data = {} -- indexed per packet
pkt_data.protocol = {}
pkt_data.info = {}
-- let's do it!
function filtcols_p.dissector(tvb,pinfo,tree)
local cols_protocol = tostring(pinfo.cols.protocol)
if cols_protocol ~= "(protocol)" then
pkt_data.protocol[pinfo.number] = cols_protocol
end
local pkt_proto = pkt_data.protocol[pinfo.number]
if pkt_proto ~= nil then
tree:add(col_protocol_field, pkt_proto)
end
local cols_info = tostring(pinfo.cols.info)
if cols_info ~= "(info)" then
pkt_data.info[pinfo.number] = cols_info
end
local pkt_info = pkt_data.info[pinfo.number]
if pkt_info ~= nil then
tree:add(col_info_field, pkt_info)
end
end
-- then we register filtcols_p as a postdissector
register_postdissector(filtcols_p)
mi·nu·ti·ae
In the SMB2 example there was not a good field(s) to use as a filter but Wireshark had placed enough data in the Info column.
The search for TLSv1.3 was difficult - no version field but could see that Wireshark was decoding by version.
packet-tls-util.c
/* Lookup tables {{{ */
const value_string ssl_version_short_names[] = {
{ SSLV2_VERSION, "SSLv2" },
{ SSLV3_VERSION, "SSLv3" },
{ TLSV1_VERSION, "TLSv1" },
{ TLSV1DOT1_VERSION, "TLSv1.1" },
{ TLSV1DOT2_VERSION, "TLSv1.2" },
{ TLSV1DOT3_VERSION, "TLSv1.3" },
{ DTLSV1DOT0_VERSION, "DTLSv1.0" },
{ DTLSV1DOT2_VERSION, "DTLSv1.2" },
{ DTLSV1DOT0_OPENSSL_VERSION, "DTLS 1.0 (OpenSSL pre 0.9.8f)" },
{ 0x00, NULL }
};
col_set_str(pinfo->cinfo, COL_PROTOCOL,
val_to_str_const(session->version, ssl_version_short_names, "SSL"));
There is session->version
but it's not available to use in a display filter.
Notes
Pinfo and pinfo.cols - where do they come from?
The Wireshark Lua API Reference is auto-generated
from files in epan/wslua and included
in the Wireshark Developer’s Guide.
All the information is there but it's sometimes quicker to look at the source.
As used in filtcols
:
pinfo.number
, pinfo.cols
:
Pinfo source is epan/wslua/wslua_pinfo.c which combines epan/packet_info.h, epan/frame_data.h and maybe others?
pinfo.cols.protocol
, pinfo.cols.info
:
Columns source in epan/wslua/wslua_column.c which aligns with epan/column-utils.h.
Why is pinfo.cols returning an empty value?
tshark has special magical incantations for whether or not it populates the cinfo
that Lua pulls pinfo.cols data from. There is an open merge request (2473: tshark: add --columns option) to add an option to explicitly create the column data.
/* We only need the columns if either 1) some tap needs the columns or 2) we're printing packet info but we're *not* verbose; in verbose mode, we print the protocol tree, not the protocol summary. or 3) there is a column mapped as an individual field */ if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields)) cinfo = &cf->cinfo; else cinfo = NULL;
-T fields
will create the data but at that point you may as well add -e _ws.col.info
and -e _ws.col.protocol
to the command and skip Lua.
Until then try -V
as mentioned in 11.7.1. TreeItem or -P
(tshark man page: DESCRIPTION but be aware -T
options will foobar things.
} else if (strcmp(optarg, "pdml") == 0) { output_action = WRITE_XML; print_details = TRUE; /* Need details */ print_summary = FALSE; /* Don't allow summary */ } else if (strcmp(optarg, "psml") == 0) { output_action = WRITE_XML; print_details = FALSE; /* Don't allow details */ print_summary = TRUE; /* Need summary */ } else if (strcmp(optarg, "fields") == 0) { output_action = WRITE_FIELDS; print_details = TRUE; /* Need full tree info */ print_summary = FALSE; /* Don't allow summary */ } else if (strcmp(optarg, "json") == 0) { output_action = WRITE_JSON; print_details = TRUE; /* Need details */ print_summary = FALSE; /* Don't allow summary */ } else if (strcmp(optarg, "ek") == 0) { output_action = WRITE_EK; if (!print_summary) print_details = TRUE; } else if (strcmp(optarg, "jsonraw") == 0) { output_action = WRITE_JSON_RAW; print_details = TRUE; /* Need details */ print_summary = FALSE; /* Don't allow summary */ }
Nil vs Null
Lua: What's the difference between null and nil?
Lua Reference Manual: "Nil is a type with a single value, nil, whose main property is to be different from any other value."
The 1.0.0 version of filtcols
did comparisons against NULL
(oops) and happened to work in Wireshark but not tshark. @cjmaynard fixed it in this Wireshark Q&A question: Tshark LUA Script
FIXME
- update script here on Wiki page.filtcols.lua