Skip to content

Commit 07ef5f3

Browse files
T-Xinfrastation
authored andcommitted
Add support for B.A.T.M.A.N. Advanced
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>
1 parent 6f3fd41 commit 07ef5f3

File tree

11 files changed

+459
-3
lines changed

11 files changed

+459
-3
lines changed

Makefile.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ PUBHDR = \
119119
pcap/vlan.h
120120

121121
HDR = $(PUBHDR) \
122+
batadv_legacy_packet.h \
123+
batadv_packet.h \
122124
diag-control.h \
123125
ethertype.h \
124126
extract.h \

batadv_legacy_packet.h

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/* SPDX-License-Identifier: BSD-3 */
2+
/* Copyright (C) 2020 Linus Lüssing */
3+
4+
#ifndef _BATADV_LEGACY_PACKET_H_
5+
#define _BATADV_LEGACY_PACKET_H_
6+
7+
enum batadv_legacy_packettype {
8+
BATADV_LEGACY_IV_OGM = 0x01,
9+
BATADV_LEGACY_ICMP = 0x02,
10+
BATADV_LEGACY_UNICAST = 0x03,
11+
BATADV_LEGACY_BCAST = 0x04,
12+
BATADV_LEGACY_VIS = 0x05,
13+
BATADV_LEGACY_UNICAST_FRAG = 0x06,
14+
BATADV_LEGACY_TT_QUERY = 0x07,
15+
BATADV_LEGACY_ROAM_ADV = 0x08,
16+
BATADV_LEGACY_UNICAST_4ADDR = 0x09,
17+
BATADV_LEGACY_CODED = 0x0a,
18+
};
19+
20+
#define ETH_ALEN 6
21+
22+
struct batadv_legacy_unicast_packet {
23+
uint8_t packet_type;
24+
uint8_t version;
25+
uint8_t ttl;
26+
uint8_t ttvn;
27+
uint8_t dest[ETH_ALEN];
28+
};
29+
30+
struct batadv_legacy_unicast_4addr_packet {
31+
uint8_t packet_type;
32+
uint8_t version;
33+
uint8_t ttl;
34+
uint8_t src[ETH_ALEN];
35+
uint8_t subtype;
36+
uint8_t reserved;
37+
};
38+
39+
struct batadv_legacy_unicast_frag_packet {
40+
uint8_t packet_type;
41+
uint8_t version;
42+
uint8_t ttl;
43+
uint8_t ttvn;
44+
uint8_t dest[ETH_ALEN];
45+
uint8_t flags;
46+
uint8_t align;
47+
uint8_t orig[ETH_ALEN];
48+
uint8_t seqno[2]; /* 2-byte integral value */
49+
};
50+
51+
struct batadv_legacy_bcast_packet {
52+
uint8_t packet_type;
53+
uint8_t version;
54+
uint8_t ttl;
55+
uint8_t reserved;
56+
uint8_t seqno[4]; /* 4-byte integral value */
57+
uint8_t orig[ETH_ALEN];
58+
};
59+
60+
struct batadv_legacy_coded_packet {
61+
uint8_t packet_type;
62+
uint8_t version;
63+
uint8_t ttl;
64+
uint8_t first_ttvn;
65+
uint8_t first_source[ETH_ALEN];
66+
uint8_t first_orig_dest[ETH_ALEN];
67+
uint8_t first_crc[4]; /* 4-byte integral value */
68+
uint8_t second_ttl;
69+
uint8_t second_ttvn;
70+
uint8_t second_dest[ETH_ALEN];
71+
uint8_t second_source[ETH_ALEN];
72+
uint8_t second_orig_dest[ETH_ALEN];
73+
uint8_t second_crc[4]; /* 4-byte integral value */
74+
uint8_t coded_len[2]; /* 2-byte integral value */
75+
};
76+
77+
#endif /* _BATADV_LEGACY_PACKET_H_ */

batadv_packet.h

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/* SPDX-License-Identifier: BSD-3 */
2+
/* Copyright (C) 2024 Linus Lüssing */
3+
4+
#ifndef _BATADV_PACKET_H_
5+
#define _BATADV_PACKET_H_
6+
7+
/* For the definitive and most recent packet format definition,
8+
* see the batadv_packet.h in the Linux kernel.
9+
*/
10+
11+
enum batadv_packettype {
12+
BATADV_IV_OGM = 0x00,
13+
BATADV_BCAST = 0x01,
14+
BATADV_CODED = 0x02,
15+
BATADV_ELP = 0x03,
16+
BATADV_OGM2 = 0x04,
17+
BATADV_MCAST = 0x05,
18+
BATADV_UNICAST = 0x40,
19+
BATADV_UNICAST_FRAG = 0x41,
20+
BATADV_UNICAST_4ADDR = 0x42,
21+
BATADV_ICMP = 0x43,
22+
BATADV_UNICAST_TVLV = 0x44,
23+
};
24+
25+
#define ETH_ALEN 6
26+
27+
struct batadv_unicast_packet {
28+
uint8_t packet_type;
29+
uint8_t version;
30+
uint8_t ttl;
31+
uint8_t ttvn;
32+
uint8_t dest[ETH_ALEN];
33+
};
34+
35+
struct batadv_unicast_4addr_packet {
36+
struct batadv_unicast_packet u;
37+
uint8_t src[ETH_ALEN];
38+
uint8_t subtype;
39+
uint8_t reserved;
40+
};
41+
42+
struct batadv_frag_packet {
43+
uint8_t packet_type;
44+
uint8_t version;
45+
uint8_t ttl;
46+
uint8_t num_pri; /* number and priority */
47+
uint8_t dest[ETH_ALEN];
48+
uint8_t orig[ETH_ALEN];
49+
uint8_t seqno[2]; /* 2-byte integral value */
50+
uint8_t total_size[2]; /* 2-byte integral value */
51+
};
52+
53+
struct batadv_bcast_packet {
54+
uint8_t packet_type;
55+
uint8_t version;
56+
uint8_t ttl;
57+
uint8_t reserved;
58+
uint8_t seqno[4]; /* 4-byte integral value */
59+
uint8_t orig[ETH_ALEN];
60+
};
61+
62+
struct batadv_coded_packet {
63+
uint8_t packet_type;
64+
uint8_t version;
65+
uint8_t ttl;
66+
uint8_t first_ttvn;
67+
uint8_t first_source[ETH_ALEN];
68+
uint8_t first_orig_dest[ETH_ALEN];
69+
uint8_t first_crc[4]; /* 4-byte integral value */
70+
uint8_t second_ttl;
71+
uint8_t second_ttvn;
72+
uint8_t second_dest[ETH_ALEN];
73+
uint8_t second_source[ETH_ALEN];
74+
uint8_t second_orig_dest[ETH_ALEN];
75+
uint8_t second_crc[4]; /* 4-byte integral value */
76+
uint8_t coded_len[2]; /* 2-byte integral value */
77+
};
78+
79+
#endif /* _BATADV_PACKET_H_ */

ethertype.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
#ifndef ETHERTYPE_TRAIL
5050
#define ETHERTYPE_TRAIL 0x1000
5151
#endif
52+
#ifndef ETHERTYPE_BATMAN
53+
#define ETHERTYPE_BATMAN 0x4305 /* B.A.T.M.A.N. Advanced */
54+
#endif
5255
#ifndef ETHERTYPE_MOPDL
5356
#define ETHERTYPE_MOPDL 0x6001
5457
#endif

gencode.c

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
#include "ieee80211.h"
4646
#include "pflog.h"
4747
#include "ppp.h"
48+
#include "batadv_packet.h"
49+
#include "batadv_legacy_packet.h"
4850
#include "pcap/sll.h"
4951
#include "pcap/ipnet.h"
5052
#include "diag-control.h"
@@ -10107,6 +10109,168 @@ gen_vxlan(compiler_state_t *cstate, bpf_u_int32 vni, int has_vni)
1010710109
return b1;
1010810110
}
1010910111

10112+
static struct block *
10113+
gen_batadv_check_version(compiler_state_t *cstate, struct block *b0, bpf_u_int32 version)
10114+
{
10115+
struct block *b1;
10116+
10117+
if (version > UINT8_MAX)
10118+
bpf_error(cstate,
10119+
"batman-adv compatibility version number %u unsupported",
10120+
version);
10121+
10122+
b1 = gen_cmp(cstate, OR_LINKPL, 1, BPF_B, version);
10123+
gen_and(b0, b1);
10124+
10125+
return b1;
10126+
}
10127+
10128+
static struct block *
10129+
gen_batadv_check_type(compiler_state_t *cstate, struct block *b0,
10130+
bpf_u_int32 version, bpf_u_int32 type)
10131+
{
10132+
struct block *b1;
10133+
10134+
switch (version) {
10135+
case 14:
10136+
case 15:
10137+
if (type > UINT8_MAX)
10138+
bpf_error(cstate,
10139+
"batman-adv packet type %u unsupported for compatibility version %u",
10140+
type, version);
10141+
10142+
b1 = gen_cmp(cstate, OR_LINKPL, 0, BPF_B, type);
10143+
gen_and(b0, b1);
10144+
b0 = b1;
10145+
10146+
break;
10147+
default:
10148+
bpf_error(cstate,
10149+
"batman-adv compatibility version number %u unsupported",
10150+
version);
10151+
}
10152+
10153+
return b0;
10154+
}
10155+
10156+
10157+
static void gen_batadv_push_offset(compiler_state_t *cstate, u_int offset)
10158+
{
10159+
PUSH_LINKHDR(cstate, DLT_EN10MB, cstate->off_linkpl.is_variable,
10160+
cstate->off_linkpl.constant_part + cstate->off_nl + offset,
10161+
cstate->off_linkpl.reg);
10162+
10163+
cstate->off_linktype.constant_part += cstate->off_linkhdr.constant_part;
10164+
cstate->off_linkpl.constant_part += cstate->off_linkhdr.constant_part;
10165+
10166+
cstate->off_nl = 0;
10167+
cstate->off_nl_nosnap = 0; /* no 802.2 LLC */
10168+
}
10169+
10170+
static void
10171+
gen_batadv_offsets_v14(compiler_state_t *cstate, bpf_u_int32 type)
10172+
{
10173+
size_t offset;
10174+
10175+
switch (type) {
10176+
case BATADV_LEGACY_UNICAST: /* 0x03 */
10177+
offset = sizeof(struct batadv_legacy_unicast_packet);
10178+
break;
10179+
case BATADV_LEGACY_BCAST: /* 0x04 */
10180+
offset = sizeof(struct batadv_legacy_bcast_packet);
10181+
break;
10182+
case BATADV_LEGACY_UNICAST_FRAG: /* 0x06 */
10183+
offset = sizeof(struct batadv_legacy_unicast_frag_packet);
10184+
break;
10185+
case BATADV_LEGACY_UNICAST_4ADDR: /* 0x09 */
10186+
offset = sizeof(struct batadv_legacy_unicast_4addr_packet);
10187+
break;
10188+
case BATADV_LEGACY_CODED: /* 0x0a */
10189+
offset = sizeof(struct batadv_legacy_coded_packet);
10190+
break;
10191+
default:
10192+
offset = 0;
10193+
}
10194+
10195+
if (offset)
10196+
gen_batadv_push_offset(cstate, (u_int)offset);
10197+
}
10198+
10199+
static void
10200+
gen_batadv_offsets_v15(compiler_state_t *cstate, bpf_u_int32 type)
10201+
{
10202+
size_t offset;
10203+
10204+
switch (type) {
10205+
case BATADV_BCAST: /* 0x01 */
10206+
offset = sizeof(struct batadv_bcast_packet);
10207+
break;
10208+
case BATADV_CODED: /* 0x02 */
10209+
offset = sizeof(struct batadv_coded_packet);
10210+
break;
10211+
case BATADV_UNICAST: /* 0x40 */
10212+
offset = sizeof(struct batadv_unicast_packet);
10213+
break;
10214+
case BATADV_UNICAST_FRAG: /* 0x41 */
10215+
offset = sizeof(struct batadv_frag_packet);
10216+
break;
10217+
case BATADV_UNICAST_4ADDR: /* 0x42 */
10218+
offset = sizeof(struct batadv_unicast_4addr_packet);
10219+
break;
10220+
case BATADV_MCAST: /* 0x05 */
10221+
/* unsupported for now, needs variable offset to
10222+
* take tvlv_len into account
10223+
*/
10224+
/* fall through */
10225+
default:
10226+
offset = 0;
10227+
}
10228+
10229+
if (offset)
10230+
gen_batadv_push_offset(cstate, (u_int)offset);
10231+
}
10232+
10233+
static void
10234+
gen_batadv_offsets(compiler_state_t *cstate, bpf_u_int32 version, bpf_u_int32 type)
10235+
{
10236+
switch (version) {
10237+
case 14:
10238+
gen_batadv_offsets_v14(cstate, type);
10239+
break;
10240+
case 15:
10241+
gen_batadv_offsets_v15(cstate, type);
10242+
break;
10243+
default:
10244+
break;
10245+
}
10246+
}
10247+
10248+
struct block *
10249+
gen_batadv(compiler_state_t *cstate, bpf_u_int32 version, int has_version,
10250+
bpf_u_int32 type, int has_type)
10251+
{
10252+
struct block *b0;
10253+
10254+
/*
10255+
* Catch errors reported by us and routines below us, and return NULL
10256+
* on an error.
10257+
*/
10258+
if (setjmp(cstate->top_ctx))
10259+
return (NULL);
10260+
10261+
b0 = gen_linktype(cstate, ETHERTYPE_BATMAN);
10262+
10263+
if (has_version)
10264+
b0 = gen_batadv_check_version(cstate, b0, version);
10265+
10266+
if (has_type) {
10267+
b0 = gen_batadv_check_type(cstate, b0, version, type);
10268+
gen_batadv_offsets(cstate, version, type);
10269+
}
10270+
10271+
return b0;
10272+
}
10273+
1011010274
/* Check that the encapsulated frame has a link layer header
1011110275
* for Ethernet filters. */
1011210276
static struct block *

gencode.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,9 @@ struct block *gen_pppoes(compiler_state_t *, bpf_u_int32, int);
359359
struct block *gen_geneve(compiler_state_t *, bpf_u_int32, int);
360360
struct block *gen_vxlan(compiler_state_t *, bpf_u_int32, int);
361361

362+
struct block *gen_batadv(compiler_state_t *, bpf_u_int32, int,
363+
bpf_u_int32, int);
364+
362365
struct block *gen_atmfield_code(compiler_state_t *, int, bpf_u_int32,
363366
int, int);
364367
struct block *gen_atmtype_abbrev(compiler_state_t *, int);

0 commit comments

Comments
 (0)