summaryrefslogtreecommitdiff
path: root/proto_nlmsg.c
diff options
context:
space:
mode:
authorVadim Kochan <vadim4j@gmail.com>2015-06-17 00:38:31 +0300
committerDaniel Borkmann <daniel@iogearbox.net>2015-06-17 23:02:12 +0200
commit1c8226e7b4a452c576f5e891895faadd5065be0a (patch)
tree40fa88c8e3bfcc555f14a446f204a7186ad58dbc /proto_nlmsg.c
parentb780681c3c9b42d6e60d369c499eaf4b94088c1d (diff)
netsniff-ng: nlmsg: Print rtnl neigh info
Dissect basic rtnl neighbour info. Signed-off-by: Vadim Kochan <vadim4j@gmail.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'proto_nlmsg.c')
-rw-r--r--proto_nlmsg.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/proto_nlmsg.c b/proto_nlmsg.c
index 9dc9f6b..5018adf 100644
--- a/proto_nlmsg.c
+++ b/proto_nlmsg.c
@@ -30,6 +30,15 @@
#define RTA_UINT32(attr) (*(uint32_t *)RTA_DATA(attr))
#define RTA_STR(attr) ((char *)RTA_DATA(attr))
+#ifndef NDA_RTA
+#define NDA_RTA(r) \
+ ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
+#endif
+
+#ifndef NDA_PAYLOAD
+#define NDA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndmsg))
+#endif
+
#define attr_fmt(attr, fmt, ...) \
tprintf("\tA: "fmt, ##__VA_ARGS__); \
tprintf(", Len %lu\n", RTA_LEN(attr));
@@ -562,6 +571,93 @@ static void rtnl_print_route(struct nlmsghdr *hdr)
}
}
+static struct flag_name neigh_states[] = {
+ { "incomplete", NUD_INCOMPLETE },
+ { "reachable", NUD_REACHABLE },
+ { "stale", NUD_STALE },
+ { "delay", NUD_DELAY },
+ { "probe", NUD_PROBE },
+ { "failed", NUD_FAILED },
+ { "noarp", NUD_NOARP },
+ { "permanent", NUD_PERMANENT },
+ { "none", NUD_NONE },
+ { NULL, 0 },
+};
+
+static struct flag_name neigh_flags[] = {
+ { "use", NTF_USE },
+ { "self", NTF_SELF },
+ { "master", NTF_MASTER },
+ { "proxy", NTF_PROXY },
+#ifdef NTF_EXT_LEARNED
+ { "ext learned", NTF_EXT_LEARNED },
+#endif
+ { "router", NTF_ROUTER },
+ { NULL, 0 },
+};
+
+static void rtnl_print_neigh(struct nlmsghdr *hdr)
+{
+ struct ndmsg *ndm = NLMSG_DATA(hdr);
+ uint32_t attrs_len = NDA_PAYLOAD(hdr);
+ struct rtattr *attr = NDA_RTA(ndm);
+ struct nda_cacheinfo *ci;
+ int hz = get_user_hz();
+ char addr_str[256];
+ char hw_addr[30];
+ char states[256];
+ char flags[256];
+
+ tprintf(" [ Neigh Family %d (%s%s%s)", ndm->ndm_family,
+ colorize_start(bold),
+ addr_family2str(ndm->ndm_family),
+ colorize_end());
+ tprintf(", Link Index %d", ndm->ndm_ifindex);
+ tprintf(", State %d (%s%s%s)", ndm->ndm_state,
+ colorize_start(bold),
+ flags2str(neigh_states, ndm->ndm_state, states,
+ sizeof(states)),
+ colorize_end());
+ tprintf(", Flags %d (%s%s%s)", ndm->ndm_flags,
+ colorize_start(bold),
+ flags2str(neigh_flags, ndm->ndm_flags, flags,
+ sizeof(flags)),
+ colorize_end());
+ tprintf(", Type %d (%s%s%s)", ndm->ndm_type,
+ colorize_start(bold),
+ route_type2str(ndm->ndm_type),
+ colorize_end());
+ tprintf(" ]\n");
+
+ for (; RTA_OK(attr, attrs_len); attr = RTA_NEXT(attr, attrs_len)) {
+ switch (attr->rta_type) {
+ case NDA_DST:
+ attr_fmt(attr, "Address %s", addr2str(ndm->ndm_family,
+ RTA_DATA(attr), addr_str,
+ sizeof(addr_str)));
+ break;
+ case NDA_LLADDR:
+ attr_fmt(attr, "HW Address %s",
+ device_addr2str(RTA_DATA(attr),
+ RTA_LEN(attr), 0, hw_addr,
+ sizeof(hw_addr)));
+ break;
+ case NDA_PROBES:
+ attr_fmt(attr, "Probes %d", RTA_UINT32(attr));
+ break;
+ case NDA_CACHEINFO:
+ ci = RTA_DATA(attr);
+ tprintf("\tA: Cache (");
+ tprintf("confirmed(%ds)", ci->ndm_confirmed / hz);
+ tprintf(", used(%ds)", ci->ndm_used / hz);
+ tprintf(", updated(%ds)", ci->ndm_updated / hz);
+ tprintf(", refcnt(%d))", ci->ndm_refcnt);
+ tprintf(", Len %lu\n", RTA_LEN(attr));
+ break;
+ }
+ }
+}
+
static void rtnl_msg_print(struct nlmsghdr *hdr)
{
switch (hdr->nlmsg_type) {
@@ -581,6 +677,11 @@ static void rtnl_msg_print(struct nlmsghdr *hdr)
case RTM_GETROUTE:
rtnl_print_route(hdr);
break;
+ case RTM_NEWNEIGH:
+ case RTM_DELNEIGH:
+ case RTM_GETNEIGH:
+ rtnl_print_neigh(hdr);
+ break;
}
}