Skip to content

Commit

Permalink
netsniff-ng: Add netlink dissector
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Tobias Klauser <[email protected]>
  • Loading branch information
tklauser committed May 28, 2014
1 parent 98e21eb commit 5f4152b
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 0 deletions.
8 changes: 8 additions & 0 deletions dissector.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}
33 changes: 33 additions & 0 deletions dissector_netlink.c
Original file line number Diff line number Diff line change
@@ -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)
{
}
37 changes: 37 additions & 0 deletions dissector_netlink.h
Original file line number Diff line number Diff line change
@@ -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 */
2 changes: 2 additions & 0 deletions netsniff-ng/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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 \
Expand Down
52 changes: 52 additions & 0 deletions proto_nlmsg.c
Original file line number Diff line number Diff line change
@@ -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,
};
1 change: 1 addition & 0 deletions protos.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

0 comments on commit 5f4152b

Please sign in to comment.