tcpdump icon indicating copy to clipboard operation
tcpdump copied to clipboard

netlink: Implement printer

Open george-hopkins opened this issue 5 years ago • 5 comments

This patch introduces a printer for DLT_NETLINK, Linux netlink packets. Each packet might contain multiple messages. The 16-byte header is the same as in SLL. Usually the packets are captured with the help of the nlmon kernel module ~~and do not cross host boundaries. Since the endianness of the platform is not captured, the printer will assume it is on a host with the same endianness for now~~.

There might be some capture files which use DLT_LINUX_SLL. In these cases, the dissector will call the new printer as well.

george-hopkins avatar Sep 26 '20 10:09 george-hopkins

Usually the packets are captured with the help of the nlmon kernel module and do not cross host boundaries.

A packet crosses a host boundary if you email it to somebody so they can look at it, unless the capture was done on a time-sharing machine into which you both log in.

Since the endianness of the platform is not captured, the printer will assume it is on a host with the same endianness for now.

That's causing the tests to fail.

Wireshark makes an attempt to guess the byte order:

/*
 * We do not know the endianness of the capture host, we have to guess.
 * Compare the size of the message with the reported size of the TVB,
 * take the endianness in which the messsage length is closer to
 * the size of the TVB. Normally we have messages with less
 * than 10KiB here so the sizes are very huge in the wrong endianness.
 */

What it does is:

  • find the remaining length of the packet on the wire (len, not caplen, so that's len - amount parsed before the length of the message);
  • fetch the length of the message, both in big-endian and little-endian byte orders;
  • pick the byte order that minimizes the absolute value of the difference between the length remaining and the length of the message.

guyharris avatar Sep 27 '20 18:09 guyharris

Can you assume that a live capture is host endian, and then use pcap_is_swapped() to decide to swap fields when reading from a capture file? (Obviously some infrastructure would have to be created to propagate the swapped-ness info from pcap into the printer)

fenner avatar Sep 28 '20 14:09 fenner

Can you assume that a live capture is host endian, and then use pcap_is_swapped() to decide to swap fields when reading from a capture file?

That almost works. However, if, for example:

  • you do a capture on a big-endian machine;

  • you read the capture on a little-endian machine, filtering it, and writing the packets that match the filter to a new file, doing tcpdump -r {file} -w {new file} {filter};

you end up with a little-endian version of the file.

That's why libpcap has code to byte-swap fields in some formats where the link-layer header is specified as host-endian (swap_pseudo_headers(), and routines it calls, in pcap-common.c), and Wireshark's pcap/pcapng-reading code does the same. Unfortunately, that's more work to do with netlink.

guyharris avatar Oct 01 '20 18:10 guyharris

Thank you for the review! I added the same heuristic to guess the endianness and added a capture file which was captured on a big-endian system but filtered (and thus rewritten) on a little-endian system.

george-hopkins avatar Oct 02 '20 12:10 george-hopkins

Any reason for some "truncated" messages? Example:

sudo ./tcpdump -#v -i nlmon0
tcpdump: listening on nlmon0, link-type NETLINK (Linux netlink), snapshot length 262144 bytes
    1  09:26:47.203019 Route: length 56
        type 18, length 40, flags 0x0301, sequence 1621322808, pid 0
[...]
    6  09:26:47.203513 Route: length 168
        type 22, length 24, flags 0x0301, sequence 1621322809, pid 0
        type 0, length 0, flags 0x0000, sequence 0, pid 0 [|netlink] <-------------------------------------------

To reproduce (on Debian Bullseye):

sudo modprobe nlmon
sudo ip link add type nlmon
sudo ip link set nlmon0 up
ip a

fxlb avatar May 18 '21 07:05 fxlb