aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-netlink-route.c
diff options
context:
space:
mode:
authorMichal Kubecek <mkubecek@suse.cz>2017-03-10 08:59:02 +0100
committerMichael Mann <mmann78@netscape.net>2017-03-11 22:04:56 +0000
commitc62497066e0e6078b5d5d1ee8e6883f5f78afe26 (patch)
tree1f1d08272879d8ce36890890c9cd06dd711c9601 /epan/dissectors/packet-netlink-route.c
parentbccc2004dfbd179ee05fa2e4d6d336a23df7b150 (diff)
netlink: support legacy dump request messages
Some legacy tools, including iproute2 < 3.9, issue shorter RTM_GETLINK and RTM_GETADDR dump queries which only contain struct rtgenmsg rather than struct ifinfomsg. As noted in kernel comment in rtnl_dump_ifinfo(), these legacy requests will be (even with attributes) always shorter than struct ifinfomsg so that they are easy to detect. Similar problem can be observed with tools using nl_rtgen_request() function from libnl3; this also affects other RTM_GET* types. If such legacy message is detected by length shorter than expected data structure, parse it as this legacy version with (1-byte) struct rtgenmsg so that it's shown as intended rather than as malformed. Change-Id: I53b6bff9e44cd2359d7cd313b6f0724f63f0e74d Reviewed-on: https://code.wireshark.org/review/20461 Petri-Dish: Michael Mann <mmann78@netscape.net> Reviewed-by: Michal Kubeček <mkubecek@suse.cz> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/dissectors/packet-netlink-route.c')
-rw-r--r--epan/dissectors/packet-netlink-route.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/epan/dissectors/packet-netlink-route.c b/epan/dissectors/packet-netlink-route.c
index 8e4c24564f..c00090e0e3 100644
--- a/epan/dissectors/packet-netlink-route.c
+++ b/epan/dissectors/packet-netlink-route.c
@@ -39,6 +39,7 @@ struct netlink_route_info {
struct packet_netlink_data *data;
int encoding; /* copy of data->encoding */
+ gboolean legacy;
};
enum {
@@ -411,6 +412,9 @@ dissect_netlink_route_ifinfomsg(tvbuff_t *tvb, struct netlink_route_info *info,
proto_tree_add_item(tree, &hfi_netlink_route_ifi_family, tvb, offset, 1, info->encoding);
offset += 1;
+ if (info->legacy)
+ return offset;
+
/* XXX padding, check if 0 */
offset += 1;
@@ -578,6 +582,9 @@ dissect_netlink_route_ifaddrmsg(tvbuff_t *tvb, struct netlink_route_info *info,
proto_tree_add_item(tree, &hfi_netlink_route_ifa_family, tvb, offset, 1, ENC_NA);
offset += 1;
+ if (info->legacy)
+ return offset;
+
proto_tree_add_item(tree, &hfi_netlink_route_ifa_prefixlen, tvb, offset, 1, ENC_NA);
offset += 1;
@@ -731,6 +738,9 @@ dissect_netlink_route_rtmsg(tvbuff_t *tvb, struct netlink_route_info *info, prot
proto_tree_add_item(tree, &hfi_netlink_route_rt_family, tvb, offset, 1, ENC_NA);
offset += 1;
+ if (info->legacy)
+ return offset;
+
proto_tree_add_item(tree, &hfi_netlink_route_rt_dst_len, tvb, offset, 1, ENC_NA);
offset += 1;
@@ -877,6 +887,9 @@ dissect_netlink_route_ndmsg(tvbuff_t *tvb, struct netlink_route_info *info, prot
proto_tree_add_item(tree, &hfi_netlink_route_nd_family, tvb, offset, 1, ENC_NA);
offset += 1;
+ if (info->legacy)
+ return offset;
+
/* XXX, 3B padding */
offset += 3;
@@ -990,6 +1003,8 @@ dissect_netlink_route(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
case WS_RTM_NEWLINK:
case WS_RTM_DELLINK:
case WS_RTM_GETLINK:
+ /* backward compatibility with legacy tools; 16 is sizeof(struct ifinfomsg) */
+ info.legacy = (data->type == WS_RTM_GETLINK) && (tvb_reported_length_remaining(tvb, offset) < 16);
offset = dissect_netlink_route_ifinfomsg(tvb, &info, tree, offset);
/* Optional attributes */
offset = dissect_netlink_route_attributes(tvb, &hfi_netlink_route_ifla_attr_type, &info, tree, offset, dissect_netlink_route_ifla_attrs);
@@ -998,6 +1013,8 @@ dissect_netlink_route(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
case WS_RTM_NEWADDR:
case WS_RTM_DELADDR:
case WS_RTM_GETADDR:
+ /* backward compatibility with legacy tools; 8 is sizeof(struct ifaddrmsg) */
+ info.legacy = (data->type == WS_RTM_GETADDR) && (tvb_reported_length_remaining(tvb, offset) < 8);
offset = dissect_netlink_route_ifaddrmsg(tvb, &info, tree, offset);
/* Optional attributes */
offset = dissect_netlink_route_attributes(tvb, &hfi_netlink_route_ifa_attr_type, &info, tree, offset, dissect_netlink_route_ifa_attrs);
@@ -1006,6 +1023,8 @@ dissect_netlink_route(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
case WS_RTM_NEWROUTE:
case WS_RTM_DELROUTE:
case WS_RTM_GETROUTE:
+ /* backward compatibility with legacy tools; 12 is sizeof(struct rtmsg) */
+ info.legacy = (data->type == WS_RTM_GETROUTE) && (tvb_reported_length_remaining(tvb, offset) < 12);
offset = dissect_netlink_route_rtmsg(tvb, &info, tree, offset);
/* Optional attributes */
offset = dissect_netlink_route_attributes(tvb, &hfi_netlink_route_rta_attr_type, &info, tree, offset, dissect_netlink_route_route_attrs);
@@ -1014,6 +1033,8 @@ dissect_netlink_route(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
case WS_RTM_NEWNEIGH:
case WS_RTM_DELNEIGH:
case WS_RTM_GETNEIGH:
+ /* backward compatibility with legacy tools; 12 is sizeof(struct ndmsg) */
+ info.legacy = (data->type == WS_RTM_GETNEIGH) && (tvb_reported_length_remaining(tvb, offset) < 12);
offset = dissect_netlink_route_ndmsg(tvb, &info, tree, offset);
break;
}