aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2017-04-17 00:54:32 +0200
committerMichael Mann <mmann78@netscape.net>2017-04-17 02:06:56 +0000
commit61c5e8e76d215cd0f1ea2139ecafbada1f933973 (patch)
treea9961f61e8e6a91278252df9c65f38111b6347f8
parent407a2b07e55a262905881c7d1e225d618e9824fb (diff)
genl: make subdissectors responsible for header
Allow subdissectors to specify the command field for the Generic Netlink message header, similar to how Netlink subdissectors handle the Netlink message header (for its type field). Pass the root tree instead of the genl tree to subdissectors (so subdissectors can add their own layer). Change-Id: I3e56f538661b7e8a51d2411da14d181ead820c4b Reviewed-on: https://code.wireshark.org/review/21150 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Reviewed-by: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
-rw-r--r--epan/dissectors/packet-netlink-generic.c58
-rw-r--r--epan/dissectors/packet-netlink.c4
-rw-r--r--epan/dissectors/packet-netlink.h6
3 files changed, 47 insertions, 21 deletions
diff --git a/epan/dissectors/packet-netlink-generic.c b/epan/dissectors/packet-netlink-generic.c
index 8caa8b18a7..64ae0f1127 100644
--- a/epan/dissectors/packet-netlink-generic.c
+++ b/epan/dissectors/packet-netlink-generic.c
@@ -351,15 +351,20 @@ dissect_genl_ctrl_attrs(tvbuff_t *tvb, void *data, proto_tree *tree, int nla_typ
return offset;
}
+static header_field_info hfi_genl_ctrl_cmd NETLINK_GENERIC_HFI_INIT =
+ { "Command", "genl.ctrl.cmd", FT_UINT8, BASE_DEC,
+ VALS(genl_ctrl_cmds), 0x00, "Generic Netlink command", HFILL };
+
static header_field_info hfi_genl_ctrl_attr NETLINK_GENERIC_HFI_INIT =
{ "Type", "genl.ctrl_attr", FT_UINT16, BASE_DEC,
VALS(genl_ctrl_attr_vals), NLA_TYPE_MASK, NULL, HFILL };
static int
-dissect_genl_ctrl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data)
+dissect_genl_ctrl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_, void *data)
{
genl_info_t *genl_info = (genl_info_t *) data;
genl_ctrl_info_t info;
+ int offset;
if (!genl_info) {
return 0;
@@ -370,9 +375,9 @@ dissect_genl_ctrl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void
info.family_id = 0;
info.family_name = NULL;
- proto_item_append_text(genl_info->cmd_pi, " (%s)",
- val_to_str_const(genl_info->cmd, genl_ctrl_cmds, "Unknown"));
- dissect_netlink_attributes(tvb, &hfi_genl_ctrl_attr, ett_genl_ctrl_attr, &info, info.data, tree, 0, -1, dissect_genl_ctrl_attrs);
+ offset = dissect_genl_header(tvb, genl_info, &hfi_genl_ctrl_cmd);
+
+ dissect_netlink_attributes(tvb, &hfi_genl_ctrl_attr, ett_genl_ctrl_attr, &info, info.data, genl_info->genl_tree, offset, -1, dissect_genl_ctrl_attrs);
/*
* Remember association of dynamic ID with the family name such that
@@ -403,6 +408,22 @@ static header_field_info hfi_genl_reserved NETLINK_GENERIC_HFI_INIT =
{ "Reserved", "genl.reserved", FT_NONE, BASE_NONE,
NULL, 0x00, NULL, HFILL };
+int dissect_genl_header(tvbuff_t *tvb, genl_info_t *genl_info, header_field_info *hfi_cmd)
+{
+ int offset = 0;
+
+ if (!hfi_cmd) {
+ hfi_cmd = &hfi_genl_cmd;
+ }
+ proto_tree_add_item(genl_info->genl_tree, hfi_cmd, tvb, offset, 1, ENC_NA);
+ offset++;
+ proto_tree_add_item(genl_info->genl_tree, &hfi_genl_version, tvb, offset, 1, ENC_NA);
+ offset++;
+ proto_tree_add_item(genl_info->genl_tree, &hfi_genl_reserved, tvb, offset, 2, genl_info->encoding);
+ offset += 2;
+ return offset;
+}
+
static int
dissect_netlink_generic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *_data)
{
@@ -410,8 +431,8 @@ dissect_netlink_generic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi
genl_info_t info;
proto_tree *nlmsg_tree;
proto_item *pi, *pi_type;
- guint32 cmd;
const char *family_name;
+ tvbuff_t *next_tvb;
int offset = 0;
DISSECTOR_ASSERT(data && data->magic == PACKET_NETLINK_MAGIC);
@@ -427,30 +448,30 @@ dissect_netlink_generic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi
family_name = (const char *)wmem_map_lookup(genl_family_map, GUINT_TO_POINTER(data->type));
proto_item_append_text(pi_type, " (%s)", family_name ? family_name : "Unknown");
- /* Generic Netlink message header (genlmsghdr) */
+ /* Populate info from Generic Netlink message header (genlmsghdr) */
info.data = data;
info.encoding = data->encoding;
- info.cmd_pi = proto_tree_add_item_ret_uint(nlmsg_tree, hfi_genl_cmd.id, tvb, offset, 1, ENC_NA, &cmd);
- info.cmd = cmd;
- offset++;
- proto_tree_add_item(nlmsg_tree, &hfi_genl_version, tvb, offset, 1, ENC_NA);
- offset++;
- proto_tree_add_item(nlmsg_tree, &hfi_genl_reserved, tvb, offset, 2, ENC_NA);
- offset += 2;
+ info.genl_tree = nlmsg_tree;
+ info.cmd = tvb_get_guint8(tvb, offset);
/* Optional user-specific message header and optional message payload. */
- if (tvb_reported_length_remaining(tvb, offset)) {
- tvbuff_t *next_tvb = tvb_new_subset_remaining(tvb, offset);
+ next_tvb = tvb_new_subset_remaining(tvb, offset);
+ /* Try subdissector if there is a payload. */
+ if (tvb_reported_length_remaining(tvb, offset + 4)) {
if (family_name) {
int ret;
- /* XXX should subdissectors add to the top-level tree? */
- ret = dissector_try_string(genl_dissector_table, family_name, next_tvb, pinfo, nlmsg_tree, &info);
+ /* Invoke subdissector with genlmsghdr present. */
+ ret = dissector_try_string(genl_dissector_table, family_name, next_tvb, pinfo, tree, &info);
if (ret) {
return ret;
}
}
+ }
- /* fallback if no subdissector was found. */
+ /* No subdissector added the genl header, do it now. */
+ offset = dissect_genl_header(next_tvb, &info, NULL);
+ if (tvb_reported_length_remaining(tvb, offset)) {
+ next_tvb = tvb_new_subset_remaining(tvb, offset);
call_data_dissector(next_tvb, pinfo, tree);
}
@@ -475,6 +496,7 @@ proto_register_netlink_generic(void)
&hfi_genl_reserved,
&hfi_genl_ctrl_attr,
/* Controller */
+ &hfi_genl_ctrl_cmd,
&hfi_genl_ctrl_family_id,
&hfi_genl_ctrl_family_name,
&hfi_genl_ctrl_version,
diff --git a/epan/dissectors/packet-netlink.c b/epan/dissectors/packet-netlink.c
index 3d73982eea..22cedaa68d 100644
--- a/epan/dissectors/packet-netlink.c
+++ b/epan/dissectors/packet-netlink.c
@@ -348,7 +348,7 @@ dissect_netlink_header(tvbuff_t *tvb, proto_tree *tree, int offset, int encoding
proto_tree *fh_hdr;
proto_item *pi;
- fh_hdr = proto_tree_add_subtree(tree, tvb, offset, 16, ett_netlink_msghdr, NULL, "Header");
+ fh_hdr = proto_tree_add_subtree(tree, tvb, offset, 16, ett_netlink_msghdr, NULL, "Netlink message header");
proto_tree_add_item(fh_hdr, &hfi_netlink_hdr_len, tvb, offset, 4, encoding);
offset += 4;
@@ -497,7 +497,7 @@ dissect_netlink(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *_data
*/
proto_tree *fh_hdr;
- fh_hdr = proto_tree_add_subtree(tree, tvb, offset, 4, ett_netlink_msghdr, NULL, "Header");
+ fh_hdr = proto_tree_add_subtree(tree, tvb, offset, 4, ett_netlink_msghdr, NULL, "Netlink message header");
proto_tree_add_item(fh_hdr, &hfi_netlink_hdr_len, tvb, offset, 4, encoding);
/* XXX invalid expert */
diff --git a/epan/dissectors/packet-netlink.h b/epan/dissectors/packet-netlink.h
index 12b872e2e7..07e52e9523 100644
--- a/epan/dissectors/packet-netlink.h
+++ b/epan/dissectors/packet-netlink.h
@@ -135,9 +135,13 @@ typedef struct {
struct packet_netlink_data *data;
int encoding; /* copy of data->encoding */
+ /* For internal use by genl. */
+ proto_tree *genl_tree;
+
/* fields from genlmsghdr */
guint8 cmd; /* Command number */
- proto_item *cmd_pi; /* Field for command, for appending protocol-specific name. */
} genl_info_t;
+int dissect_genl_header(tvbuff_t *tvb, genl_info_t *genl_info, header_field_info *hfi_cmd);
+
#endif /* __PACKET_NETLINK_H__ */