diff options
author | Peter Wu <peter@lekensteyn.nl> | 2017-04-17 00:54:32 +0200 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2017-04-17 02:06:56 +0000 |
commit | 61c5e8e76d215cd0f1ea2139ecafbada1f933973 (patch) | |
tree | a9961f61e8e6a91278252df9c65f38111b6347f8 | |
parent | 407a2b07e55a262905881c7d1e225d618e9824fb (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.c | 58 | ||||
-rw-r--r-- | epan/dissectors/packet-netlink.c | 4 | ||||
-rw-r--r-- | epan/dissectors/packet-netlink.h | 6 |
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__ */ |