Get in touch:
01524 851 877
07718 896 553

Linux Kernel Module And ndisc_get_neigh()

Posted on Jun 16 2009 by Matthew Jakeman

I am currently looking at a way to get the MAC address of the next hop of a packet within a kernel module. I had previously made the silly assumption that this should be relatively simple. Of course that turns out not to be the case.

After browsing the kernel source I came across the following function in net/ndisc.h:

static inline struct neighbour * ndisc_get_neigh(struct net_device *dev, const struct in6_addr *addr)
This seemed perfect for what I wanted so I used it and got the following link error:

WARNING: "nd_tbl" [/path/to/source/np++.ko] undefined!
After a little digging I discovered that the list of neighbours (nd_tbl) stored by the kernel is not exported and therefore modules have no way to access it.

Since then I have tried a number of different approches (doing a rt6_lookup() and trying to obtain the MAC through that etc) but none of them have proved successful. The only glimmer of hope was that the sk_buff pointer I was being passed by the netfilter hook displayed the correct MAC address every now and again by using the skb->dst=>neighbour->ha variable. However most of the time it displays 33:33:00:00:00:01 for some reason.

I am going to continue digging around and see why it is not always being displayed properly through the sk_buff (I’m guessing this doesn’t always get properly set for some reason but considering it is 33:33:00:00:00:01 every time this is not a coincidence). If this method yields no results soon howver I think I will be left with the last resort option of having to supply a kernel patch with the NP++ code. This is a real pain as all the kernel patch will do is exprot the nd_tbl struct but it may have to be done.

If anyone knows of a workaround for this without patching the kernel I would love to hear it…

Leave a comment