The official llllloooooo blog

Wednesday, November 4, 2020

tcpdump displays oui Unknown when displaying Ethernet headers

When you run the popular lightweight packet sniffer tcpdump and you command it to display link layer or Ethernet headers by specifying the -e option you will most likely see a message saying oui Unknown as per the following example...

tcpdump -e -t -i eth0 udp port chargen
dc:a6:32:11:22:33 (oui Unknown) > 00:1c:58:33:22:11 (oui Unknown), ethertype IPv6 (0x86dd), length 63: fd55:5555:5555:5555:dea6:32ff:fe11:2233.33031 > fd55:5555:5555:5555::1.chargen: UDP, length 1

As I'm sure that anyone who is reading this knows, an Organizationally Unique Identifier (OUI) is a 3 byte code at the start of an Ethernet Address that is meant to identify the manufacturer of the device or Ethernet interface that the Ethernet Address belongs to.

By default tcpdump only recognizes a very, very small list of OUI codes that belong to very old equipment and so the chances are that when you run tcpdump -e you'll see the oui Unknown message displayed.

You can fix that by recompiling tcpdump to include a more up to date list of OUI codes with the help of a python script called make-oui.py which is available at

https://gist.githubusercontent.com/gvanem/1643c946fb2395b6c8a05c3ec8904e13/raw/620085609082829a0f5572ad2359b21df2c1b0f0/make-oui.py

This script downloads the latest version of the OUI codes. By default it also downloads a list of something called Enterprise Numbers which map certain numbers to equipment Manufacturer names. This Enterprise Numbers list only has relevance to tcpdump when you're decoding RADIUS packets or MPLS LSP Ping packets. I can see some people wanting to decode RADIUS packets but MPLS LSP Ping would be extremely rare except for in very sophisticated high end ISP or Enterprise networks.

I really need to stop procrastinating and implement MPLS in
my home network.

The way to get the script to work is to first download it to the directory containing the tcpdump source code. (I've tested this with tcpdump version 4.9.3). Naturally make sure the script is executable

# wget https://gist.githubusercontent.com/gvanem/1643c946fb2395b6c8a05c3ec8904e13/raw/620085609082829a0f5572ad2359b21df2c1b0f0/make-oui.py
# chmod +x make-oui.py

I suggest that you DO perform the next command but it is optional. If you perform the next step the tool will NOT download the Enterprise Numbers that I talked about. Just to reemphasize, you don't need these Enterprise Numbers if you just want to look at Ethernet OUI names. If you do skip the next step so that you can have tcpdump include Enterprise Numbers then the resultant binary executable is about 2M bigger than it would be otherwise!!

# echo "" > enterprise-numbers

Now run the script as follows

./make-oui.py 
Downloading oui-generated.txt from http://standards-oui.ieee.org/oui.txt 
Got 4488 kBytes (100%)
Wrote 28843 OUI records to oui-generated.c
A local enterprise-numbers already exist.
Appended 0 SMI records to oui-generated.c

This script has now generated a file called oui-generated.c which we can now use to replace the original oui.c file included in the tcpdump source code.

cp oui.c oui.c.orig
cp oui-generated.c oui.c

Finally build and install tcpdump as per normal (Remember to make sure libpcap is installed first). 

Note that the new oui.c file will generate some warning messages when it compiles as per the following. For some reason the make-oui.py tool adds some functions to oui.c that aren't actually used but they are harmless.

./oui.c: In function 'oui_val_to_name':
./oui.c:28883:25: warning: implicit declaration of function 'bsearch' [-Wimplicit-function-declaration]
28883 |   const struct tok *t = bsearch (&oui, oui_values, num, sizeof(oui_values[0]),
      |                         ^~~~~~~
./oui.c:28883:25: warning: initialization of 'const struct tok *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
./oui.c: In function 'smi_val_to_name':
./oui.c:28891:25: warning: initialization of 'const struct tok *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
28891 |   const struct tok *t = bsearch (&smi, smi_values, num, sizeof(smi_values[0]),

If you really want to get rid of those warnings then just edit the new oui.c file and remove all the lines at the bottom beginning with the one that says

/* Comparision routine needed by bsearch() routines.

If we re-run the new binary with the same input as the command shown at the top of this post, you'll see that I'm sending a packet from my Raspberry Pi to a Cisco router.

tcpdump -e -t -i eth0 udp port chargen
dc:a6:32:11:22:33 (oui Raspberry Pi Trading Ltd) > 00:1c:58:33:22:11 (oui Cisco Systems, Inc), ethertype IPv6 (0x86dd), length 63: fd55:5555:5555:5555:dea6:32ff:fe11:2233.33031 > fd55:5555:5555:5555::1.chargen: UDP, length 1

Note that the tcpdump binary executable that includes the up to date OUI list will be about 600kbytes larger than the normal tcpdump binary without the OUI list. If you decide that you want to include the Enterprise Numbers then add about another 2Mbytes to that. 

I'd love it if anyone out there has actually decoded a packet with tcpdump (i.e. an MPLS LSP Ping or RADIUS packet). Please let me know in the comments because you are very cool!

No comments: