summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Klauser <tklauser@distanz.ch>2014-05-28 14:32:10 +0200
committerTobias Klauser <tklauser@distanz.ch>2014-05-28 17:50:29 +0200
commit5f4152b01e17433b29e3f9cc1407b60800b1e0b9 (patch)
tree55eb213e301ede01578bae46683a4a72861f0d9c
parent98e21eb8633b31b006671735602df08d3f073261 (diff)
netsniff-ng: Add netlink dissector
Add an initial implementation of a dissector to work on netlink messages as received from an nlmon device. Use can use it as follows to monitor netlink traffic to/from the kernel: modprobe nlmon ip link add type nlmon ip link set nlmon0 up netsniff-ng -i nlmon0 ip link set nlmon 0 down ip link del dev nlmon0 rmmod nlmon Fixes: #89 Suggested-by: Daniel Borkmann <dborkman@redhat.com> Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
-rw-r--r--dissector.c8
-rw-r--r--dissector_netlink.c33
-rw-r--r--dissector_netlink.h37
-rw-r--r--netsniff-ng/Makefile2
-rw-r--r--proto_nlmsg.c52
-rw-r--r--protos.h1
6 files changed, 133 insertions, 0 deletions
diff --git a/dissector.c b/dissector.c
index a412999..ccc9b3c 100644
--- a/dissector.c
+++ b/dissector.c
@@ -15,6 +15,7 @@
#include "dissector.h"
#include "dissector_eth.h"
#include "dissector_80211.h"
+#include "dissector_netlink.h"
#include "linktype.h"
int dissector_set_print_type(void *ptr, int type)
@@ -80,6 +81,11 @@ void dissector_entry_point(uint8_t *packet, size_t len, int linktype, int mode)
proto_start = dissector_get_ieee80211_entry_point();
proto_end = dissector_get_ieee80211_exit_point();
break;
+ case LINKTYPE_NETLINK:
+ case ___constant_swab32(LINKTYPE_NETLINK):
+ proto_start = dissector_get_netlink_entry_point();
+ proto_end = dissector_get_netlink_exit_point();
+ break;
default:
proto_start = &none_ops;
proto_end = NULL;
@@ -108,10 +114,12 @@ void dissector_init_all(int fnttype)
{
dissector_init_ethernet(fnttype);
dissector_init_ieee80211(fnttype);
+ dissector_init_netlink(fnttype);
}
void dissector_cleanup_all(void)
{
dissector_cleanup_ethernet();
dissector_cleanup_ieee80211();
+ dissector_cleanup_netlink();
}
diff --git a/dissector_netlink.c b/dissector_netlink.c
new file mode 100644
index 0000000..387f198
--- /dev/null
+++ b/dissector_netlink.c
@@ -0,0 +1,33 @@
+/*
+ * netsniff-ng - the packet sniffing beast
+ * Copyright 2014 Tobias Klauser.
+ * Subject to the GPL, version 2.
+ */
+
+#include "dissector.h"
+#include "dissector_netlink.h"
+
+#ifdef HAVE_DISSECTOR_PROTOS
+static inline void dissector_init_entry(int type)
+{
+ dissector_set_print_type(&nlmsg_ops, type);
+}
+
+static inline void dissector_init_exit(int type)
+{
+ dissector_set_print_type(&none_ops, type);
+}
+#else
+static inline void dissector_init_entry(int type __maybe_unused) {}
+static inline void dissector_init_exit(int type __maybe_unused) {}
+#endif
+
+void dissector_init_netlink(int fnttype)
+{
+ dissector_init_entry(fnttype);
+ dissector_init_exit(fnttype);
+}
+
+void dissector_cleanup_netlink(void)
+{
+}
diff --git a/dissector_netlink.h b/dissector_netlink.h
new file mode 100644
index 0000000..185881c
--- /dev/null
+++ b/dissector_netlink.h
@@ -0,0 +1,37 @@
+/*
+ * netsniff-ng - the packet sniffing beast
+ * Copyright 2014 Tobias Klauser.
+ * Subject to the GPL, version 2.
+ */
+
+#ifndef DISSECTOR_NETLINK_H
+#define DISSECTOR_NETLINK_H
+
+#include "protos.h"
+
+extern void dissector_init_netlink(int fnttype);
+extern void dissector_cleanup_netlink(void);
+
+#ifdef HAVE_DISSECTOR_PROTOS
+static inline struct protocol *dissector_get_netlink_entry_point(void)
+{
+ return &nlmsg_ops;
+}
+
+static inline struct protocol *dissector_get_netlink_exit_point(void)
+{
+ return &none_ops;
+}
+#else
+static inline struct protocol *dissector_get_netlink_entry_point(void)
+{
+ return NULL;
+}
+
+static inline struct protocol *dissector_get_netlink_exit_point(void)
+{
+ return NULL;
+}
+#endif /* HAVE_DISSECTOR_PROTOS */
+
+#endif /* DISSECTOR_NETLINK_H */
diff --git a/netsniff-ng/Makefile b/netsniff-ng/Makefile
index 2ddddfd..745bb1d 100644
--- a/netsniff-ng/Makefile
+++ b/netsniff-ng/Makefile
@@ -13,6 +13,7 @@ endif
netsniff-ng-objs = dissector.o \
dissector_eth.o \
dissector_80211.o \
+ dissector_netlink.o \
proto_arp.o \
proto_ethernet.o \
proto_icmpv4.o \
@@ -30,6 +31,7 @@ netsniff-ng-objs = dissector.o \
proto_ipv6_no_nxt_hdr.o \
proto_ipv6_routing.o \
proto_lldp.o \
+ proto_nlmsg.o \
proto_none.o \
proto_tcp.o \
proto_udp.o \
diff --git a/proto_nlmsg.c b/proto_nlmsg.c
new file mode 100644
index 0000000..f5abf57
--- /dev/null
+++ b/proto_nlmsg.c
@@ -0,0 +1,52 @@
+/*
+ * netsniff-ng - the packet sniffing beast
+ * Copyright 2014 Tobias Klauser.
+ * Subject to the GPL, version 2.
+ */
+
+#include <libnl3/netlink/msg.h>
+
+#include "pkt_buff.h"
+#include "proto.h"
+
+static void nlmsg(struct pkt_buff *pkt)
+{
+ struct nlmsghdr *hdr = (struct nlmsghdr *) pkt_pull(pkt, sizeof(*hdr));
+ char type[32];
+ char flags[128];
+
+ if (hdr == NULL)
+ return;
+
+ tprintf(" [ NLMSG ");
+ tprintf("Len %u, ", hdr->nlmsg_len);
+ tprintf("Type 0x%.4x (%s%s%s), ", hdr->nlmsg_type,
+ colorize_start(bold),
+ nl_nlmsgtype2str(hdr->nlmsg_type, type, sizeof(type)),
+ colorize_end());
+ tprintf("Flags 0x%.4x (%s%s%s), ", hdr->nlmsg_flags,
+ colorize_start(bold),
+ nl_nlmsg_flags2str(hdr->nlmsg_flags, flags, sizeof(flags)),
+ colorize_end());
+ tprintf("Seq-Nr %u, ", hdr->nlmsg_seq);
+ tprintf("PID %u", hdr->nlmsg_pid);
+ tprintf(" ]\n");
+}
+
+static void nlmsg_less(struct pkt_buff *pkt)
+{
+ struct nlmsghdr *hdr = (struct nlmsghdr *) pkt_pull(pkt, sizeof(*hdr));
+ char type[32];
+
+ if (hdr == NULL)
+ return;
+
+ tprintf(" NLMSG %u (%s%s%s)", hdr->nlmsg_type, colorize_start(bold),
+ nl_nlmsgtype2str(hdr->nlmsg_type, type, sizeof(type)),
+ colorize_end());
+}
+
+struct protocol nlmsg_ops = {
+ .print_full = nlmsg,
+ .print_less = nlmsg_less,
+};
diff --git a/protos.h b/protos.h
index 23bf744..201439a 100644
--- a/protos.h
+++ b/protos.h
@@ -27,5 +27,6 @@ extern struct protocol vlan_ops;
extern struct protocol ieee80211_ops;
extern struct protocol QinQ_ops;
extern struct protocol mpls_uc_ops;
+extern struct protocol nlmsg_ops;
#endif /* PROTOS_H */