aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorJakub Zawadzki <darkjames-ws@darkjames.pl>2013-12-08 19:30:33 +0000
committerJakub Zawadzki <darkjames-ws@darkjames.pl>2013-12-08 19:30:33 +0000
commit64456261b9214f7b8bd520f74cbaee26d95b5f3e (patch)
treef1451d7171551cf4ae7c6a5aa4dfccbdc6237d67 /epan
parentfab9e520551ed2b92d85a7676ed67caf64f41f6b (diff)
Improve netlink dissection:
- add standard message types - add dissection for WS_RTM_*NEIGH - add BASE_CUSTOM functions to print bitfields svn path=/trunk/; revision=53864
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-netlink-route.c251
-rw-r--r--epan/dissectors/packet-netlink.c13
-rw-r--r--epan/dissectors/packet-netlink.h7
3 files changed, 219 insertions, 52 deletions
diff --git a/epan/dissectors/packet-netlink-route.c b/epan/dissectors/packet-netlink-route.c
index d073809ce2..7d2ac45d21 100644
--- a/epan/dissectors/packet-netlink-route.c
+++ b/epan/dissectors/packet-netlink-route.c
@@ -188,10 +188,10 @@ enum {
/* values for rtmsg.rtm_scope from <linux/rtnetlink.h> */
enum {
WS_RT_SCOPE_UNIVERSE = 0,
-/* user defined */
- WS_RT_SCOPE_SITE = 200,
- WS_RT_SCOPE_LINK = 253,
- WS_RT_SCOPE_HOST = 254,
+/* ... user defined (/etc/iproute2/rt_scopes) ... */
+ WS_RT_SCOPE_SITE = 200,
+ WS_RT_SCOPE_LINK = 253,
+ WS_RT_SCOPE_HOST = 254,
WS_RT_SCOPE_NOWHERE = 255
};
@@ -234,6 +234,31 @@ enum {
WS_IFF_ECHO = 0x40000,
};
+/* values for ifaddrmsg.ifa_flags <linux/if_addr.h> */
+enum {
+ WS_IFA_F_SECONDARY = 0x01,
+ WS_IFA_F_NODAD = 0x02,
+ WS_IFA_F_OPTIMISTIC = 0x04,
+ WS_IFA_F_DADFAILED = 0x08,
+ WS_IFA_F_HOMEADDRESS = 0x10,
+ WS_IFA_F_DEPRECATED = 0x20,
+ WS_IFA_F_TENTATIVE = 0x40,
+ WS_IFA_F_PERMANENT = 0x80
+};
+
+/* values for ndmsg.ndm_state <linux/neighbour.h> */
+enum {
+ WS_NUD_INCOMPLETE = 0x01,
+ WS_NUD_REACHABLE = 0x02,
+ WS_NUD_STALE = 0x04,
+ WS_NUD_DELAY = 0x08,
+ WS_NUD_PROBE = 0x10,
+ WS_NUD_FAILED = 0x20,
+/* Dummy states */
+ WS_NUD_NOARP = 0x40,
+ WS_NUD_PERMANENT = 0x80
+};
+
static dissector_handle_t netlink_route_handle;
static header_field_info *hfi_netlink_route = NULL;
@@ -287,6 +312,33 @@ static gint ett_netlink_route_if_flags = -1;
typedef int netlink_route_attributes_cb_t(tvbuff_t *, struct netlink_route_info *, proto_tree *, int rta_type, int offset, int len);
+static void
+_fill_label_value_string_bitmask(char *label, guint32 value, const value_string *vals)
+{
+ char tmp[16];
+
+ label[0] = '\0';
+
+ while (vals->strptr) {
+ if (value & vals->value) {
+ value &= ~(vals->value);
+ if (label[0])
+ g_strlcat(label, ", ", ITEM_LABEL_LENGTH);
+
+ g_strlcat(label, vals->strptr, ITEM_LABEL_LENGTH);
+ }
+
+ vals++;
+ }
+
+ if (value) {
+ if (label[0])
+ g_strlcat(label, ", ", ITEM_LABEL_LENGTH);
+ g_snprintf(tmp, sizeof(tmp), "0x%x", value);
+ g_strlcat(label, tmp, ITEM_LABEL_LENGTH);
+ }
+}
+
static int
dissect_netlink_route_attributes(tvbuff_t *tvb, header_field_info *hfi_type, struct netlink_route_info *info, proto_tree *tree, int offset, netlink_route_attributes_cb_t cb)
{
@@ -348,9 +400,43 @@ static header_field_info hfi_netlink_route_ifi_index NETLINK_ROUTE_HFI_INIT =
{ "Interface index", "netlink-route.ifi_index", FT_INT32, BASE_DEC,
NULL, 0x00, NULL, HFILL };
+static void
+hfi_netlink_route_ifi_flags_label(char *label, guint32 value)
+{
+ static const value_string iff_vals[] = {
+ { WS_IFF_UP, "UP" },
+ { WS_IFF_BROADCAST, "BROADCAST" },
+ { WS_IFF_DEBUG, "DEBUG" },
+ { WS_IFF_LOOPBACK, "LOOPBACK" },
+ { WS_IFF_POINTOPOINT, "POINTOPOINT" },
+ { WS_IFF_NOTRAILERS, "NOTRAILERS" },
+ { WS_IFF_RUNNING, "RUNNING" },
+ { WS_IFF_NOARP, "NOARP" },
+ { WS_IFF_PROMISC, "PROMISC" },
+ { WS_IFF_ALLMULTI, "ALLMULTI" },
+ { WS_IFF_MASTER, "MASTER" },
+ { WS_IFF_SLAVE, "SLAVE" },
+ { WS_IFF_MULTICAST, "MULTICAST" },
+ { WS_IFF_PORTSEL, "PORTSEL" },
+ { WS_IFF_AUTOMEDIA, "AUTOMEDIA" },
+ { WS_IFF_DYNAMIC, "DYNAMIC" },
+ { WS_IFF_LOWER_UP, "LOWER_UP" },
+ { WS_IFF_DORMANT, "DORMANT" },
+ { WS_IFF_ECHO, "ECHO" },
+ { 0x00, NULL }
+ };
+
+ char tmp[16];
+
+ _fill_label_value_string_bitmask(label, value, iff_vals);
+
+ g_snprintf(tmp, sizeof(tmp), " (0x%.8x)", value);
+ g_strlcat(label, tmp, ITEM_LABEL_LENGTH);
+}
+
static header_field_info hfi_netlink_route_ifi_flags NETLINK_ROUTE_HFI_INIT =
- { "Device flags", "netlink-route.ifi_flags", FT_UINT32, BASE_HEX,
- NULL, 0x00, NULL, HFILL };
+ { "Device flags", "netlink-route.ifi_flags", FT_UINT32, BASE_CUSTOM,
+ &hfi_netlink_route_ifi_flags_label, 0x00, NULL, HFILL };
static const true_false_string hfi_netlink_route_ifi_flags_iff_up_tfs = { "Up", "Down" };
@@ -388,47 +474,6 @@ dissect_netlink_route_ifinfomsg(tvbuff_t *tvb, struct netlink_route_info *info,
if_flags_tree = proto_item_add_subtree(ti, ett_netlink_route_if_flags);
if (if_flags_tree) {
- guint32 if_flags = tvb_get_letohl(tvb, offset);
-
- if (if_flags & WS_IFF_UP)
- proto_item_append_text(ti, " UP");
- if (if_flags & WS_IFF_BROADCAST)
- proto_item_append_text(ti, " BROADCAST");
- if (if_flags & WS_IFF_DEBUG)
- proto_item_append_text(ti, " DEBUG");
- if (if_flags & WS_IFF_LOOPBACK)
- proto_item_append_text(ti, " LOOPBACK");
- if (if_flags & WS_IFF_POINTOPOINT)
- proto_item_append_text(ti, " POINTOPOINT");
- if (if_flags & WS_IFF_NOTRAILERS)
- proto_item_append_text(ti, " NOTRAILERS");
- if (if_flags & WS_IFF_RUNNING)
- proto_item_append_text(ti, " RUNNING");
- if (if_flags & WS_IFF_NOARP)
- proto_item_append_text(ti, " NOARP");
- if (if_flags & WS_IFF_PROMISC)
- proto_item_append_text(ti, " PROMISC");
- if (if_flags & WS_IFF_ALLMULTI)
- proto_item_append_text(ti, " ALLMULTI");
- if (if_flags & WS_IFF_MASTER)
- proto_item_append_text(ti, " MASTER");
- if (if_flags & WS_IFF_SLAVE)
- proto_item_append_text(ti, " SLAVE");
- if (if_flags & WS_IFF_MULTICAST)
- proto_item_append_text(ti, " MULTICAST");
- if (if_flags & WS_IFF_PORTSEL)
- proto_item_append_text(ti, " PORTSEL");
- if (if_flags & WS_IFF_AUTOMEDIA)
- proto_item_append_text(ti, " AUTOMEDIA");
- if (if_flags & WS_IFF_DYNAMIC)
- proto_item_append_text(ti, " DYNAMIC");
- if (if_flags & WS_IFF_LOWER_UP)
- proto_item_append_text(ti, " LOWER_UP");
- if (if_flags & WS_IFF_DORMANT)
- proto_item_append_text(ti, " DORMANT");
- if (if_flags & WS_IFF_ECHO)
- proto_item_append_text(ti, " ECHO");
-
proto_tree_add_item(if_flags_tree, &hfi_netlink_route_ifi_flags_iff_up, tvb, offset, 4, info->encoding);
proto_tree_add_item(if_flags_tree, &hfi_netlink_route_ifi_flags_iff_broadcast, tvb, offset, 4, info->encoding);
/* XXX */
@@ -477,11 +522,13 @@ dissect_netlink_route_ifla_attrs(tvbuff_t *tvb, struct netlink_route_info *info,
switch (type) {
case WS_IFLA_IFNAME:
+ proto_item_append_text(tree, ": %s", tvb_get_string_enc(wmem_packet_scope(), tvb, offset, len, ENC_ASCII | ENC_NA));
proto_tree_add_item(tree, &hfi_netlink_route_ifla_ifname, tvb, offset, len, ENC_ASCII | ENC_NA);
return 1;
case WS_IFLA_MTU:
if (len == 4) {
+ proto_item_append_text(tree, ": %u", tvb_get_letohl(tvb, offset));
proto_tree_add_item(tree, &hfi_netlink_route_ifla_mtu, tvb, offset, len, info->encoding);
return 1;
}
@@ -501,9 +548,32 @@ static header_field_info hfi_netlink_route_ifa_prefixlen NETLINK_ROUTE_HFI_INIT
{ "Address prefixlength", "netlink-route.ifa_prefixlen", FT_UINT8, BASE_DEC,
NULL, 0x00, NULL, HFILL };
+static void
+hfi_netlink_route_ifa_flags_label(char *label, guint32 value)
+{
+ static const value_string iff_vals[] = {
+ { WS_IFA_F_SECONDARY, "secondary/temporary" },
+ { WS_IFA_F_NODAD, "nodad" },
+ { WS_IFA_F_OPTIMISTIC, "optimistic" },
+ { WS_IFA_F_DADFAILED, "dadfailed" },
+ { WS_IFA_F_HOMEADDRESS, "homeaddress" },
+ { WS_IFA_F_DEPRECATED, "deprecated" },
+ { WS_IFA_F_TENTATIVE, "tentative" },
+ { WS_IFA_F_PERMANENT, "permanent" },
+ { 0x00, NULL }
+ };
+
+ char tmp[16];
+
+ _fill_label_value_string_bitmask(label, value, iff_vals);
+
+ g_snprintf(tmp, sizeof(tmp), " (0x%.8x)", value);
+ g_strlcat(label, tmp, ITEM_LABEL_LENGTH);
+}
+
static header_field_info hfi_netlink_route_ifa_flags NETLINK_ROUTE_HFI_INIT =
- { "Address flags", "netlink-route.ifa_flags", FT_UINT8, BASE_HEX,
- NULL, 0x00, NULL, HFILL };
+ { "Address flags", "netlink-route.ifa_flags", FT_UINT8, BASE_CUSTOM,
+ &hfi_netlink_route_ifa_flags_label, 0x00, NULL, HFILL };
static header_field_info hfi_netlink_route_ifa_scope NETLINK_ROUTE_HFI_INIT =
{ "Address scope", "netlink-route.ifa_scope", FT_UINT8, BASE_DEC,
@@ -563,6 +633,7 @@ dissect_netlink_route_ifa_attrs(tvbuff_t *tvb, struct netlink_route_info *info _
switch (type) {
case WS_IFA_LABEL:
+ proto_item_append_text(tree, ": %s", tvb_get_string_enc(wmem_packet_scope(), tvb, offset, len, ENC_ASCII | ENC_NA));
proto_tree_add_item(tree, &hfi_netlink_route_ifa_label, tvb, offset, len, ENC_ASCII | ENC_NA);
return 1;
@@ -718,6 +789,7 @@ dissect_netlink_route_route_attrs(tvbuff_t *tvb, struct netlink_route_info *info
switch (type) {
case WS_RTA_IIF:
if (len == 4) {
+ proto_item_append_text(tree, ": %u", tvb_get_letohl(tvb, offset));
proto_tree_add_item(tree, &hfi_netlink_route_rta_iif, tvb, offset, 4, info->encoding);
return 1;
}
@@ -725,6 +797,7 @@ dissect_netlink_route_route_attrs(tvbuff_t *tvb, struct netlink_route_info *info
case WS_RTA_OIF:
if (len == 4) {
+ proto_item_append_text(tree, ": %u", tvb_get_letohl(tvb, offset));
proto_tree_add_item(tree, &hfi_netlink_route_rta_oif, tvb, offset, 4, info->encoding);
return 1;
}
@@ -735,6 +808,73 @@ dissect_netlink_route_route_attrs(tvbuff_t *tvb, struct netlink_route_info *info
}
}
+static header_field_info hfi_netlink_route_nd_family NETLINK_ROUTE_HFI_INIT =
+ { "Family", "netlink-route.nd_family", FT_UINT8, BASE_DEC | BASE_EXT_STRING,
+ &linux_af_vals_ext, 0x00, NULL, HFILL };
+
+static header_field_info hfi_netlink_route_nd_index NETLINK_ROUTE_HFI_INIT =
+ { "Interface index", "netlink-route.nd_index", FT_INT32, BASE_DEC,
+ NULL, 0x00, NULL, HFILL };
+
+static void
+hfi_netlink_route_nd_states_label(char *label, guint32 value)
+{
+ static const value_string flags_vals[] = {
+ { WS_NUD_INCOMPLETE, "INCOMPLETE" },
+ { WS_NUD_REACHABLE, "REACHABLE" },
+ { WS_NUD_STALE, "STALE" },
+ { WS_NUD_DELAY, "DELAY" },
+ { WS_NUD_PROBE, "PROBE" },
+ { WS_NUD_FAILED, "FAILED" },
+ { WS_NUD_NOARP, "NOARP" },
+ { WS_NUD_PERMANENT, "PERMAMENT" },
+ { 0x00, NULL }
+ };
+
+ char tmp[16];
+
+ _fill_label_value_string_bitmask(label, value, flags_vals);
+
+ g_snprintf(tmp, sizeof(tmp), " (0x%.4x)", value);
+ g_strlcat(label, tmp, ITEM_LABEL_LENGTH);
+}
+
+static header_field_info hfi_netlink_route_nd_state NETLINK_ROUTE_HFI_INIT =
+ { "State", "netlink-route.nd_state", FT_UINT16, BASE_CUSTOM,
+ &hfi_netlink_route_nd_states_label, 0x00, NULL, HFILL };
+
+static header_field_info hfi_netlink_route_nd_flags NETLINK_ROUTE_HFI_INIT =
+ { "Flags", "netlink-route.nd_flags", FT_UINT8, BASE_HEX,
+ NULL, 0x00, NULL, HFILL };
+
+static header_field_info hfi_netlink_route_nd_type NETLINK_ROUTE_HFI_INIT =
+ { "Type", "netlink-route.nd_type", FT_UINT8, BASE_HEX,
+ NULL, 0x00, NULL, HFILL };
+
+static int
+dissect_netlink_route_ndmsg(tvbuff_t *tvb, struct netlink_route_info *info, proto_tree *tree, int offset)
+{
+ proto_tree_add_item(tree, &hfi_netlink_route_nd_family, tvb, offset, 1, ENC_NA);
+ offset += 1;
+
+ /* XXX, 3B padding */
+ offset += 3;
+
+ proto_tree_add_item(tree, &hfi_netlink_route_nd_index, tvb, offset, 4, info->encoding);
+ offset += 4;
+
+ proto_tree_add_item(tree, &hfi_netlink_route_nd_state, tvb, offset, 2, info->encoding);
+ offset += 2;
+
+ proto_tree_add_item(tree, &hfi_netlink_route_nd_flags, tvb, offset, 1, ENC_NA);
+ offset += 1;
+
+ proto_tree_add_item(tree, &hfi_netlink_route_nd_type, tvb, offset, 1, ENC_NA);
+ offset += 1;
+
+ return offset;
+}
+
static int
dissect_netlink_route(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *_data)
{
@@ -791,6 +931,12 @@ dissect_netlink_route(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
/* Optional attributes */
offset = dissect_netlink_route_attributes(tvb, &hfi_netlink_route_rta_attr_type, &info, tree, offset, dissect_netlink_route_route_attrs);
break;
+
+ case WS_RTM_NEWNEIGH:
+ case WS_RTM_DELNEIGH:
+ case WS_RTM_GETNEIGH:
+ offset = dissect_netlink_route_ndmsg(tvb, &info, tree, offset);
+ break;
}
return offset;
@@ -840,6 +986,13 @@ proto_register_netlink_route(void)
&hfi_netlink_route_rta_attr_type,
&hfi_netlink_route_rta_iif,
&hfi_netlink_route_rta_oif,
+
+ /* Neighbor */
+ &hfi_netlink_route_nd_family,
+ &hfi_netlink_route_nd_index,
+ &hfi_netlink_route_nd_state,
+ &hfi_netlink_route_nd_flags,
+ &hfi_netlink_route_nd_type,
};
#endif
diff --git a/epan/dissectors/packet-netlink.c b/epan/dissectors/packet-netlink.c
index 51fe73cf67..5b11b4110c 100644
--- a/epan/dissectors/packet-netlink.c
+++ b/epan/dissectors/packet-netlink.c
@@ -40,7 +40,7 @@
*/
#define SLL_HEADER_SIZE 16 /* total header length */
-static const value_string ltype_vals[] = {
+static const value_string family_vals[] = {
{ WS_NETLINK_ROUTE, "Route" },
{ WS_NETLINK_UNUSED, "Unused" },
{ WS_NETLINK_USERSOCK, "user-mode" },
@@ -65,6 +65,13 @@ static const value_string ltype_vals[] = {
{ 0, NULL }
};
+static const value_string type_vals[] = {
+ { WS_NLMSG_NOOP, "nothing" },
+ { WS_NLMSG_ERROR, "error" },
+ { WS_NLMSG_DONE, "end of a dump" },
+ { WS_NLMSG_OVERRUN, "data lost" },
+ { 0, NULL }
+};
static dissector_handle_t netlink_handle;
@@ -79,7 +86,7 @@ static header_field_info hfi_netlink_hatype NETLINK_HFI_INIT =
/* Linux netlink protocol type */
static header_field_info hfi_netlink_family NETLINK_HFI_INIT =
{ "Family", "netlink.family", FT_UINT16, BASE_HEX,
- VALS(ltype_vals), 0x00, NULL, HFILL };
+ VALS(family_vals), 0x00, NULL, HFILL };
static header_field_info hfi_netlink_hdr_len NETLINK_HFI_INIT =
@@ -88,7 +95,7 @@ static header_field_info hfi_netlink_hdr_len NETLINK_HFI_INIT =
static header_field_info hfi_netlink_hdr_type NETLINK_HFI_INIT =
{ "Type", "netlink.hdr_type", FT_UINT16, BASE_HEX,
- NULL, 0x00, NULL, HFILL };
+ VALS(type_vals), 0x00, NULL, HFILL };
static header_field_info hfi_netlink_hdr_flags NETLINK_HFI_INIT =
{ "Flags", "netlink.hdr_flags", FT_UINT16, BASE_HEX,
diff --git a/epan/dissectors/packet-netlink.h b/epan/dissectors/packet-netlink.h
index 2708462413..fbe858db05 100644
--- a/epan/dissectors/packet-netlink.h
+++ b/epan/dissectors/packet-netlink.h
@@ -50,6 +50,13 @@ enum {
WS_NETLINK_CRYPTO = 21
};
+enum {
+ WS_NLMSG_NOOP = 0x01,
+ WS_NLMSG_ERROR = 0x02,
+ WS_NLMSG_DONE = 0x03,
+ WS_NLMSG_OVERRUN = 0x04
+};
+
#define PACKET_NETLINK_MAGIC 0x4A5ACCCE
struct packet_netlink_data {