From 5f4152b01e17433b29e3f9cc1407b60800b1e0b9 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 28 May 2014 14:32:10 +0200 Subject: [PATCH] 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 Signed-off-by: Tobias Klauser --- dissector.c | 8 ++++++++ dissector_netlink.c | 33 +++++++++++++++++++++++++++++++++ dissector_netlink.h | 37 +++++++++++++++++++++++++++++++++++++ netsniff-ng/Makefile | 2 ++ proto_nlmsg.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ protos.h | 1 + 6 files changed, 133 insertions(+) create mode 100644 dissector_netlink.c create mode 100644 dissector_netlink.h create mode 100644 proto_nlmsg.c diff --git a/dissector.c b/dissector.c index a412999a..ccc9b3cf 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 00000000..387f1989 --- /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 00000000..185881c1 --- /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 2ddddfdb..745bb1dd 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 00000000..f5abf573 --- /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 + +#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 23bf7449..201439a2 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 */ -- 2.11.4.GIT