Skip to content

Add support for B.A.T.M.A.N. Advanced #980

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

T-X
Copy link

@T-X T-X commented Nov 23, 2020

This adds support for the layer 2 mesh routing protocol
B.A.T.M.A.N. Advanced. "batadv" can be used to filter on batman-adv
packets. It also allows later filters to look at frames inside the
tunnel when both "version" and "type" are specified.

Documentation for the batman-adv protocol can be found at the following
locations:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/batman-adv.rst
https://www.open-mesh.org/

Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>

@T-X
Copy link
Author

T-X commented Nov 23, 2020

One remark: pcap/batadv_packet.h and pcap/batadv_legacy_packet.h are basically copies from the Linux kernel and are therefore GPLv2 licensed. Let me know if that's okay for you or if I should ask the other maintainers and contributors for a BSD-3-Clause (compatible) dual-license for these two header files.

@infrastation
Copy link
Member

Thank you for preparing this feature. Neither macOS nor FreeBSD like the new Linux-specific headers. As you mentioned, these are GPL, also the amount of filter-specific code seems to be much smaller than the amount of declarations. So it might be worth to consider if the new code could have just the declarations it needs, then it would be simpler to make these portable and have the same licence as the rest of libpcap. Other opinions are welcome.

@guyharris
Copy link
Member

So it might be worth to consider if the new code could have just the declarations it needs, then it would be simpler to make these portable and have the same licence as the rest of libpcap. Other opinions are welcome.

My opinion can be summarized as "+1". :-)

I.e., no GPLed code, please.

#ifndef _UAPI_LINUX_BATADV_PACKET_H_
#define _UAPI_LINUX_BATADV_PACKET_H_

#include <asm/byteorder.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of those three headers are available on all the operating systems on which libpcap operates. (Note that one of those operating systems is Windows.)

Find a way not to use them.

@@ -0,0 +1,631 @@
/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No GPLed code, please.

@guyharris
Copy link
Member

Here's a tarball containing a patch, pcap/batadv_legacy_packet.h, and pcap/batadv_packet.h. The patch is a variant of your change that compiles on macOS Catalina and Xcode 11.7, so it rips out enough Linuxisms to get it to compile there, at least.

It also gets rid of all #pragma pack stuff (not all compilers necessarily support it), instead declaring 2-byte and 4-byte integral values as arrays of uint8_t of the appropriate length.

Do those headers need to be part of the libpcap distribution, rather than being internal to the libpcap source?

tarfile.gz

@T-X
Copy link
Author

T-X commented Nov 23, 2020

Thanks for the great feedback!

Changelog v2:

  • changes to batadv_{legacy_,}packet.h:
    • integrated @guyharris' suggested changes: removal of #pragma packed(2), bitfield endianess #ifdefs, Linux specific includes, unused definitions, conversion to uint8_t only
    • further removed kernel doc comments and instead added a small note to consult the Linux kernel version for a complete definition
    • changed the license to BSD-3 for these new, tiny versions
    • moved these two header files from the pcap directory to the root directory
    • shortened the include guards, the UAPI directory for instance was Linux specific

@T-X T-X force-pushed the batman-adv-support branch from cf95dad to 53f2460 Compare November 23, 2020 21:40
@T-X
Copy link
Author

T-X commented Nov 23, 2020

Changelog v3:

  • removed unused variables "s" and "b1" in gen_batadv() to satisfy the AppVeyor CI / Visual Studio builds

@infrastation
Copy link
Member

Passed FreeBSD build this time, that's better. One other thing that would complement this feature is some tcpdump test(s) to flex the new keywords. Do you have enough batman packets with the right protocol fields?

@T-X T-X force-pushed the batman-adv-support branch 3 times, most recently from ed25b1c to 5a89e57 Compare November 24, 2020 10:54
@T-X
Copy link
Author

T-X commented Nov 24, 2020

Changelog v4:

  • changed offset parameter of gen_batadv_push_offset() from size_t to u_int and added according type cast on callers, to make AppVeyor CI / Visual Studio happy

@T-X
Copy link
Author

T-X commented Nov 24, 2020

@infrastation sure, generating some test packets is no issue, can do that next weekend. According tests need to be added to the tcpdump repository in a separate commit over there, right?

@infrastation
Copy link
Member

Yes, that's correct, and the tests will not pass until this feature has been merged, but eventually it would be consistent.

@T-X
Copy link
Author

T-X commented Dec 2, 2020

Some simple tests for tcpdump for the batman-adv version 15 packet types and their decoding offsets can be found here: the-tcpdump-group/tcpdump#891

@infrastation
Copy link
Member

Thank you. For what it's worth, I have just looked through the proposed changes one more time and could not find any immediate issues to fix (which does not automatically mean everything is good, but still). Other reviewers are welcome.

@T-X
Copy link
Author

T-X commented Feb 13, 2021

I'm a bit hesitant to ask, as I can see with all the frequent commits that everyone is very eagerly working on libpcap/tcpdump. But any chance to get this merged? Would help me adding it to the collaborative projects I would want to use this in. Which are usually reluctant in adding changes that are not upstream yet.

@mcr
Copy link
Member

mcr commented Feb 13, 2021

Hi, @fenner , you've been down the pcap compiler space more than I, do you have any final comments before I merge this?

type = pcap_nametobatadvtype_v15($2);
break;
default:
YYABORT;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably call bpf_set_error() to report that $1 is an unsupported batman-adv version.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I've added an according error message with bpf_set_error().

@T-X T-X force-pushed the batman-adv-support branch from 5a89e57 to 3dcde32 Compare February 14, 2021 20:09
@fxlb fxlb force-pushed the batman-adv-support branch from 3dcde32 to a576d46 Compare July 10, 2021 09:57
@fxlb fxlb force-pushed the batman-adv-support branch from a576d46 to 555ee39 Compare October 10, 2021 13:31
@fxlb
Copy link
Member

fxlb commented Oct 10, 2021

Rebased. "All checks have failed" => There are some errors fo fix.

@T-X T-X force-pushed the batman-adv-support branch from 555ee39 to e3698e7 Compare November 4, 2021 23:01
@fxlb
Copy link
Member

fxlb commented Jul 29, 2023

The current types/sub-types in libpcap filter syntax use "-" and not "_".

Examples:

wlan:   
assoc-req,  assoc-resp, ...

The  following   ICMP   type   field   values   are   available:
icmp-echoreply,  icmp-unreach, ...

The  following  ICMPv6  type   field   values   are   available:
icmp6-destinationunreach, icmp6-packettoobig, ...

The following TCP flags field  values  are  available:  tcp-fin,
tcp-syn, tcp-rst, tcp-push, tcp-ack, tcp-urg, tcp-ece, tcp-cwr.

Thus for batman-adv packet types,

The following packet type aliases are available for compat  ver-
sion  14:  iv_ogm,  unicast-frag (?), tt_query, roam_adv, unicast_4addr.

The following packet type aliases are available for compat  ver-
sion 15: iv_ogm, unicast_frag, unicast_4addr, unicast_tvlv.

it should be better to replace "_" by "-".

@fxlb fxlb force-pushed the batman-adv-support branch from 5f47568 to 512ae9f Compare August 2, 2023 14:41
@T-X T-X force-pushed the batman-adv-support branch from 512ae9f to f8cbaf1 Compare September 11, 2023 06:10
@T-X
Copy link
Author

T-X commented Sep 11, 2023

Changelog v6:

  • rebased to current master (no changes)
  • changed all packet sub-type aliases to use hyphens instead of underscores and updated manpage accordingly

@T-X T-X force-pushed the batman-adv-support branch from f8cbaf1 to bab4324 Compare June 28, 2024 03:42
@T-X
Copy link
Author

T-X commented Jun 28, 2024

Changelog v7:

  • rebased to current master branch
  • added new batman-adv multicast packet type, introduced in batman-adv v2024.0

@T-X
Copy link
Author

T-X commented Jun 28, 2024

I would also like to add the correct offset to the batadv_mcast_packet type, which has a variable payload offset. I would need to add the contents of the two bytes tvlv_len field to the offset:
https://git.open-mesh.org/batman-adv.git/blob/9e1f3974cca1fc0866793076684ea0f5c2649412:/include/uapi/linux/batadv_packet.h#l509

My tries so far were not successful with this, I might need some help/guidance for that.

@T-X T-X force-pushed the batman-adv-support branch from bab4324 to 1fc5b59 Compare June 30, 2024 06:11
@T-X
Copy link
Author

T-X commented Jun 30, 2024

Changelog v8:

  • removed mention of BATADV_UNICAST_TVLV from gen_batadv_offsets_v15(): currently a batman-adv unicast tvlv packets do not carry/support any payload frames, it only contains TVLVs, therefore removing it from offset considerations
  • added a new patch to take variable length offsets, the tvlv length, in a batman-adv mcast packet into account ("batman-adv: Add offset support to batman-adv mcast packet"), allows using offset adjustments with this packet type, too

@T-X T-X force-pushed the batman-adv-support branch from 1fc5b59 to da42b5b Compare June 30, 2024 06:23
@T-X
Copy link
Author

T-X commented Jun 30, 2024

Changelog v9:

  • removed an implicit cast from size_t to bpf_u_int32 for the field_offset variable in gen_batadv_offsets_v15(), which was added in v8 in the newly added patch

@simonwunderlich
Copy link

I would love to see this in tcpdump, too!

@mcr @fenner @infrastation @guyharris any chance you could help getting it merged? It sounded like @mcr was ready to merge it in 2021 already, but it's been stalled since then. Some embedded distributions already took the code as patch in to support their users, but having actually it merged would be great ...

T-X added 2 commits January 5, 2025 20:23
This adds support for the layer 2 mesh routing protocol
B.A.T.M.A.N. Advanced. "batadv" can be used to filter on batman-adv
packets. It also allows later filters to look at frames inside the
tunnel when both "version" and "type" are specified.

Documentation for the batman-adv protocol can be found at the following
locations:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/batman-adv.rst
https://www.open-mesh.org/

Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
The batman-adv multicast packet type has a variable offset for its
encapsulated payload frames. The offset depends not only on the
batman-adv mcast packet header length but also the length of a
potential, variable length TVLV between the batman-adv mcast packet
header and the payload.

This adds according BPF instructions to take the TVLV length into
account for a batman-adv mcast packet and adjusts the payload offset
accordingly.

Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
@infrastation
Copy link
Member

Thank you for waiting. Rebased on the current master branch. I have looked through the changes one more time, there are minor places for improvement, but the most demanding parts are in gencode.c and grammar.y.in, as expected. One way to make it easier to verify could be capturing the new keywords in filter tests in TESTrun, I may be able to do that soon.

@T-X
Copy link
Author

T-X commented Jan 6, 2025

@infrastation thanks once more for the feedback and a happy new year!
Btw. one more limitation I noticed, which I think other protocols in libpcap that use header offsets, like Geneve or PPPoE, would have too: I can't match multiple batman-adv packet types. Something like these won't work:

  • batadv 15 and not batadv 15 bcast
  • batadv 15 bcast or batadv 15 iv-ogm
  • (batadv 15 bcast) or (batadv 15 iv-ogm)
  • batadv 15 (bcast or iv-ogm) -> syntax error

But it seemed to me that this is a limitation of how these offsets work in libpcap right now in general, right? Once the keyword matches then the offset is applied immediately and globally and not within a specific scope? Which in the first three examples above would result in matching batman-adv packets within batman-adv packets, even when using brackets?

@mcr
Copy link
Member

mcr commented Jan 6, 2025 via email

@infrastation
Copy link
Member

Three weeks of bikeshedding is not as bad as setting in stone something that causes pain by design, e.g. the rnr keyword.

@infrastation
Copy link
Member

Thank you for waiting. I had another brief look at the proposed changes and would like to make a few comments, hopefully this will not take long.

{ "roam-adv", BATADV_LEGACY_ROAM_ADV },
{ "unicast-4addr", BATADV_LEGACY_UNICAST_4ADDR },
{ "coded", BATADV_LEGACY_CODED },
{ (char *)0, 0 }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NULL

{ "unicast-4addr", BATADV_UNICAST_4ADDR },
{ "icmp", BATADV_ICMP },
{ "unicast-tvlv", BATADV_UNICAST_TVLV },
{ (char *)0, 0 }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NULL

PCAP_API int pcap_nametobatadvtype_v14(const char *);

PCAP_AVAILABLE_1_11
PCAP_API int pcap_nametobatadvtype_v15(const char *);
Copy link
Member

@infrastation infrastation Aug 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two new functions look out of place in the public API and should not exist even in the private API. The translation of a packet type string to a packet type number should be done in grammar.y.in using the existing str2tok() function the same way it is done for ieee80211_types[].

Comment on lines +10428 to +10431
if (has_type) {
b0 = gen_batadv_check_type(cstate, b0, version, type);
b0 = gen_batadv_offsets(cstate, b0, version, type);
}
Copy link
Member

@infrastation infrastation Aug 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block uses version, is it supposed to be within the block just above then?

size_t offset;

switch (type) {
case BATADV_LEGACY_UNICAST: /* 0x03 */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and elsewhere: if there is no reason to know the exact value of a named constant, it is better not to provide it.

switch (version) {
case 14:
case 15:
if (type > UINT8_MAX)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BATMAN packet types seem to be 8-bit (I could find a few TVLV diagrams, but not a packet diagram with a Type field in it, which does not look right, please see if you could fix that as well). Anyway, the point here is that the valid range check should be done as early in gencode.c as possible (see the call to assert_maxval() in gen_pppoes() and similar examples), then the functions that actually process the packet type should use an uint8_t for the validated value.

@@ -119,6 +119,8 @@ PUBHDR = \
pcap/vlan.h

HDR = $(PUBHDR) \
batadv_legacy_packet.h \
batadv_packet.h \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The contents of these two new header files that is used only in gencode.c should go directly into gencode.c, and the remaining part (message types only, as far as I can see) should be in one header file used by both grammar.y.in and gencode.c (much like ieee80211.h). Also for clarity it may be better to use BATADV14_ and BATADV15_ for the packet types and batadv14_ and batadv15_ for the structures, in case there is yet another version in future.

@infrastation
Copy link
Member

This is one of several proposed non-trivial changes that I did not originally understand, so I took a rather long detour earlier to develop additional tooling and tests and to learn the BPF compiler better. In addition to the comments left on the patch, please note:

  • The new code needs a number of tests: "filter" type (to show the resulting filter program explicitly) for all permutations of the new syntax and "apply" type (to prove that the filter program works as expected) for several keywords and a selection of packets in a pcap savefile.
  • If there is no better specification for the protocol encoding, it would be useful to say somewhere that the encoding is defined by the C structures in this and this file.

Other things I do not understand yet are:

  • whether the new offset code works exactly as it should
  • whether it would be better to separate v14 and v15 syntax explicitly, especially with the batadv [version] [type] syntax in mind when the version is not specified, but the type is

Copy link
Member

@infrastation infrastation left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also please rebase these changes on the current master branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

7 participants