b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | From 3d8d268320d2381021a409ff8d03533698dd6242 Mon Sep 17 00:00:00 2001 |
| 2 | From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@c0d3.blue> |
| 3 | Date: Mon, 23 Nov 2020 00:38:22 +0100 |
| 4 | Subject: [PATCH] Add support for B.A.T.M.A.N. Advanced |
| 5 | MIME-Version: 1.0 |
| 6 | Content-Type: text/plain; charset=UTF-8 |
| 7 | Content-Transfer-Encoding: 8bit |
| 8 | |
| 9 | This adds support for the layer 2 mesh routing protocol |
| 10 | B.A.T.M.A.N. Advanced. "batadv" can be used to filter on batman-adv |
| 11 | packets. It also allows later filters to look at frames inside the |
| 12 | tunnel when both "version" and "type" are specified. |
| 13 | |
| 14 | Documentation for the batman-adv protocol can be found at the following |
| 15 | locations: |
| 16 | |
| 17 | https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/batman-adv.rst |
| 18 | https://www.open-mesh.org/ |
| 19 | |
| 20 | Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue> |
| 21 | --- |
| 22 | Makefile.in | 2 + |
| 23 | batadv_legacy_packet.h | 77 +++++++++++++++++++ |
| 24 | batadv_packet.h | 78 ++++++++++++++++++++ |
| 25 | ethertype.h | 3 + |
| 26 | gencode.c | 164 +++++++++++++++++++++++++++++++++++++++++ |
| 27 | gencode.h | 3 + |
| 28 | grammar.y.in | 32 +++++++- |
| 29 | nametoaddr.c | 59 +++++++++++++++ |
| 30 | pcap-filter.manmisc.in | 35 ++++++++- |
| 31 | pcap/namedb.h | 2 + |
| 32 | scanner.l | 1 + |
| 33 | 11 files changed, 453 insertions(+), 3 deletions(-) |
| 34 | create mode 100644 batadv_legacy_packet.h |
| 35 | create mode 100644 batadv_packet.h |
| 36 | |
| 37 | --- a/Makefile.in |
| 38 | +++ b/Makefile.in |
| 39 | @@ -130,6 +130,8 @@ PUBHDR = \ |
| 40 | HDR = $(PUBHDR) \ |
| 41 | arcnet.h \ |
| 42 | atmuni31.h \ |
| 43 | + batadv_legacy_packet.h \ |
| 44 | + batadv_packet.h \ |
| 45 | diag-control.h \ |
| 46 | ethertype.h \ |
| 47 | extract.h \ |
| 48 | --- /dev/null |
| 49 | +++ b/batadv_legacy_packet.h |
| 50 | @@ -0,0 +1,77 @@ |
| 51 | +/* SPDX-License-Identifier: BSD-3 */ |
| 52 | +/* Copyright (C) 2020 Linus Lüssing */ |
| 53 | + |
| 54 | +#ifndef _BATADV_LEGACY_PACKET_H_ |
| 55 | +#define _BATADV_LEGACY_PACKET_H_ |
| 56 | + |
| 57 | +enum batadv_legacy_packettype { |
| 58 | + BATADV_LEGACY_IV_OGM = 0x01, |
| 59 | + BATADV_LEGACY_ICMP = 0x02, |
| 60 | + BATADV_LEGACY_UNICAST = 0x03, |
| 61 | + BATADV_LEGACY_BCAST = 0x04, |
| 62 | + BATADV_LEGACY_VIS = 0x05, |
| 63 | + BATADV_LEGACY_UNICAST_FRAG = 0x06, |
| 64 | + BATADV_LEGACY_TT_QUERY = 0x07, |
| 65 | + BATADV_LEGACY_ROAM_ADV = 0x08, |
| 66 | + BATADV_LEGACY_UNICAST_4ADDR = 0x09, |
| 67 | + BATADV_LEGACY_CODED = 0x0a, |
| 68 | +}; |
| 69 | + |
| 70 | +#define ETH_ALEN 6 |
| 71 | + |
| 72 | +struct batadv_legacy_unicast_packet { |
| 73 | + uint8_t packet_type; |
| 74 | + uint8_t version; |
| 75 | + uint8_t ttl; |
| 76 | + uint8_t ttvn; |
| 77 | + uint8_t dest[ETH_ALEN]; |
| 78 | +}; |
| 79 | + |
| 80 | +struct batadv_legacy_unicast_4addr_packet { |
| 81 | + uint8_t packet_type; |
| 82 | + uint8_t version; |
| 83 | + uint8_t ttl; |
| 84 | + uint8_t src[ETH_ALEN]; |
| 85 | + uint8_t subtype; |
| 86 | + uint8_t reserved; |
| 87 | +}; |
| 88 | + |
| 89 | +struct batadv_legacy_unicast_frag_packet { |
| 90 | + uint8_t packet_type; |
| 91 | + uint8_t version; |
| 92 | + uint8_t ttl; |
| 93 | + uint8_t ttvn; |
| 94 | + uint8_t dest[ETH_ALEN]; |
| 95 | + uint8_t flags; |
| 96 | + uint8_t align; |
| 97 | + uint8_t orig[ETH_ALEN]; |
| 98 | + uint8_t seqno[2]; /* 2-byte integral value */ |
| 99 | +}; |
| 100 | + |
| 101 | +struct batadv_legacy_bcast_packet { |
| 102 | + uint8_t packet_type; |
| 103 | + uint8_t version; |
| 104 | + uint8_t ttl; |
| 105 | + uint8_t reserved; |
| 106 | + uint8_t seqno[4]; /* 4-byte integral value */ |
| 107 | + uint8_t orig[ETH_ALEN]; |
| 108 | +}; |
| 109 | + |
| 110 | +struct batadv_legacy_coded_packet { |
| 111 | + uint8_t packet_type; |
| 112 | + uint8_t version; |
| 113 | + uint8_t ttl; |
| 114 | + uint8_t first_ttvn; |
| 115 | + uint8_t first_source[ETH_ALEN]; |
| 116 | + uint8_t first_orig_dest[ETH_ALEN]; |
| 117 | + uint8_t first_crc[4]; /* 4-byte integral value */ |
| 118 | + uint8_t second_ttl; |
| 119 | + uint8_t second_ttvn; |
| 120 | + uint8_t second_dest[ETH_ALEN]; |
| 121 | + uint8_t second_source[ETH_ALEN]; |
| 122 | + uint8_t second_orig_dest[ETH_ALEN]; |
| 123 | + uint8_t second_crc[4]; /* 4-byte integral value */ |
| 124 | + uint8_t coded_len[2]; /* 2-byte integral value */ |
| 125 | +}; |
| 126 | + |
| 127 | +#endif /* _BATADV_LEGACY_PACKET_H_ */ |
| 128 | --- /dev/null |
| 129 | +++ b/batadv_packet.h |
| 130 | @@ -0,0 +1,78 @@ |
| 131 | +/* SPDX-License-Identifier: BSD-3 */ |
| 132 | +/* Copyright (C) 2020 Linus Lüssing */ |
| 133 | + |
| 134 | +#ifndef _BATADV_PACKET_H_ |
| 135 | +#define _BATADV_PACKET_H_ |
| 136 | + |
| 137 | +/* For the definitive and most recent packet format definition, |
| 138 | + * see the batadv_packet.h in the Linux kernel. |
| 139 | + */ |
| 140 | + |
| 141 | +enum batadv_packettype { |
| 142 | + BATADV_IV_OGM = 0x00, |
| 143 | + BATADV_BCAST = 0x01, |
| 144 | + BATADV_CODED = 0x02, |
| 145 | + BATADV_ELP = 0x03, |
| 146 | + BATADV_OGM2 = 0x04, |
| 147 | + BATADV_UNICAST = 0x40, |
| 148 | + BATADV_UNICAST_FRAG = 0x41, |
| 149 | + BATADV_UNICAST_4ADDR = 0x42, |
| 150 | + BATADV_ICMP = 0x43, |
| 151 | + BATADV_UNICAST_TVLV = 0x44, |
| 152 | +}; |
| 153 | + |
| 154 | +#define ETH_ALEN 6 |
| 155 | + |
| 156 | +struct batadv_unicast_packet { |
| 157 | + uint8_t packet_type; |
| 158 | + uint8_t version; |
| 159 | + uint8_t ttl; |
| 160 | + uint8_t ttvn; |
| 161 | + uint8_t dest[ETH_ALEN]; |
| 162 | +}; |
| 163 | + |
| 164 | +struct batadv_unicast_4addr_packet { |
| 165 | + struct batadv_unicast_packet u; |
| 166 | + uint8_t src[ETH_ALEN]; |
| 167 | + uint8_t subtype; |
| 168 | + uint8_t reserved; |
| 169 | +}; |
| 170 | + |
| 171 | +struct batadv_frag_packet { |
| 172 | + uint8_t packet_type; |
| 173 | + uint8_t version; |
| 174 | + uint8_t ttl; |
| 175 | + uint8_t num_pri; /* number and priority */ |
| 176 | + uint8_t dest[ETH_ALEN]; |
| 177 | + uint8_t orig[ETH_ALEN]; |
| 178 | + uint8_t seqno[2]; /* 2-byte integral value */ |
| 179 | + uint8_t total_size[2]; /* 2-byte integral value */ |
| 180 | +}; |
| 181 | + |
| 182 | +struct batadv_bcast_packet { |
| 183 | + uint8_t packet_type; |
| 184 | + uint8_t version; |
| 185 | + uint8_t ttl; |
| 186 | + uint8_t reserved; |
| 187 | + uint8_t seqno[4]; /* 4-byte integral value */ |
| 188 | + uint8_t orig[ETH_ALEN]; |
| 189 | +}; |
| 190 | + |
| 191 | +struct batadv_coded_packet { |
| 192 | + uint8_t packet_type; |
| 193 | + uint8_t version; |
| 194 | + uint8_t ttl; |
| 195 | + uint8_t first_ttvn; |
| 196 | + uint8_t first_source[ETH_ALEN]; |
| 197 | + uint8_t first_orig_dest[ETH_ALEN]; |
| 198 | + uint8_t first_crc[4]; /* 4-byte integral value */ |
| 199 | + uint8_t second_ttl; |
| 200 | + uint8_t second_ttvn; |
| 201 | + uint8_t second_dest[ETH_ALEN]; |
| 202 | + uint8_t second_source[ETH_ALEN]; |
| 203 | + uint8_t second_orig_dest[ETH_ALEN]; |
| 204 | + uint8_t second_crc[4]; /* 4-byte integral value */ |
| 205 | + uint8_t coded_len[2]; /* 2-byte integral value */ |
| 206 | +}; |
| 207 | + |
| 208 | +#endif /* _BATADV_PACKET_H_ */ |
| 209 | --- a/ethertype.h |
| 210 | +++ b/ethertype.h |
| 211 | @@ -49,6 +49,9 @@ |
| 212 | #ifndef ETHERTYPE_TRAIL |
| 213 | #define ETHERTYPE_TRAIL 0x1000 |
| 214 | #endif |
| 215 | +#ifndef ETHERTYPE_BATMAN |
| 216 | +#define ETHERTYPE_BATMAN 0x4305 /* B.A.T.M.A.N. Advanced */ |
| 217 | +#endif |
| 218 | #ifndef ETHERTYPE_MOPDL |
| 219 | #define ETHERTYPE_MOPDL 0x6001 |
| 220 | #endif |
| 221 | --- a/gencode.c |
| 222 | +++ b/gencode.c |
| 223 | @@ -58,6 +58,8 @@ |
| 224 | #include "sunatmpos.h" |
| 225 | #include "pflog.h" |
| 226 | #include "ppp.h" |
| 227 | +#include "batadv_packet.h" |
| 228 | +#include "batadv_legacy_packet.h" |
| 229 | #include "pcap/sll.h" |
| 230 | #include "pcap/ipnet.h" |
| 231 | #include "arcnet.h" |
| 232 | @@ -9704,6 +9706,168 @@ gen_geneve(compiler_state_t *cstate, bpf |
| 233 | return b1; |
| 234 | } |
| 235 | |
| 236 | +static struct block * |
| 237 | +gen_batadv_check_version(compiler_state_t *cstate, struct block *b0, bpf_u_int32 version) |
| 238 | +{ |
| 239 | + struct block *b1; |
| 240 | + |
| 241 | + if (version > UINT8_MAX) |
| 242 | + bpf_error(cstate, |
| 243 | + "batman-adv compatibility version number %u unsupported", |
| 244 | + version); |
| 245 | + |
| 246 | + b1 = gen_cmp(cstate, OR_LINKPL, 1, BPF_B, version); |
| 247 | + gen_and(b0, b1); |
| 248 | + |
| 249 | + return b1; |
| 250 | +} |
| 251 | + |
| 252 | +static struct block * |
| 253 | +gen_batadv_check_type(compiler_state_t *cstate, struct block *b0, |
| 254 | + bpf_u_int32 version, bpf_u_int32 type) |
| 255 | +{ |
| 256 | + struct block *b1; |
| 257 | + |
| 258 | + switch (version) { |
| 259 | + case 14: |
| 260 | + case 15: |
| 261 | + if (type > UINT8_MAX) |
| 262 | + bpf_error(cstate, |
| 263 | + "batman-adv packet type %u unsupported for compatibility version %u", |
| 264 | + type, version); |
| 265 | + |
| 266 | + b1 = gen_cmp(cstate, OR_LINKPL, 0, BPF_B, type); |
| 267 | + gen_and(b0, b1); |
| 268 | + b0 = b1; |
| 269 | + |
| 270 | + break; |
| 271 | + default: |
| 272 | + bpf_error(cstate, |
| 273 | + "batman-adv compatibility version number %u unsupported", |
| 274 | + version); |
| 275 | + } |
| 276 | + |
| 277 | + return b0; |
| 278 | +} |
| 279 | + |
| 280 | + |
| 281 | +static void gen_batadv_push_offset(compiler_state_t *cstate, u_int offset) |
| 282 | +{ |
| 283 | + PUSH_LINKHDR(cstate, DLT_EN10MB, cstate->off_linkpl.is_variable, |
| 284 | + cstate->off_linkpl.constant_part + cstate->off_nl + offset, |
| 285 | + cstate->off_linkpl.reg); |
| 286 | + |
| 287 | + cstate->off_linktype.constant_part += cstate->off_linkhdr.constant_part; |
| 288 | + cstate->off_linkpl.constant_part += cstate->off_linkhdr.constant_part; |
| 289 | + |
| 290 | + cstate->off_nl = 0; |
| 291 | + cstate->off_nl_nosnap = 0; /* no 802.2 LLC */ |
| 292 | +} |
| 293 | + |
| 294 | +static void |
| 295 | +gen_batadv_offsets_v14(compiler_state_t *cstate, bpf_u_int32 type) |
| 296 | +{ |
| 297 | + size_t offset; |
| 298 | + |
| 299 | + switch (type) { |
| 300 | + case BATADV_LEGACY_UNICAST: /* 0x03 */ |
| 301 | + offset = sizeof(struct batadv_legacy_unicast_packet); |
| 302 | + break; |
| 303 | + case BATADV_LEGACY_BCAST: /* 0x04 */ |
| 304 | + offset = sizeof(struct batadv_legacy_bcast_packet); |
| 305 | + break; |
| 306 | + case BATADV_LEGACY_UNICAST_FRAG: /* 0x06 */ |
| 307 | + offset = sizeof(struct batadv_legacy_unicast_frag_packet); |
| 308 | + break; |
| 309 | + case BATADV_LEGACY_UNICAST_4ADDR: /* 0x09 */ |
| 310 | + offset = sizeof(struct batadv_legacy_unicast_4addr_packet); |
| 311 | + break; |
| 312 | + case BATADV_LEGACY_CODED: /* 0x0a */ |
| 313 | + offset = sizeof(struct batadv_legacy_coded_packet); |
| 314 | + break; |
| 315 | + default: |
| 316 | + offset = 0; |
| 317 | + } |
| 318 | + |
| 319 | + if (offset) |
| 320 | + gen_batadv_push_offset(cstate, (u_int)offset); |
| 321 | +} |
| 322 | + |
| 323 | +static void |
| 324 | +gen_batadv_offsets_v15(compiler_state_t *cstate, bpf_u_int32 type) |
| 325 | +{ |
| 326 | + size_t offset; |
| 327 | + |
| 328 | + switch (type) { |
| 329 | + case BATADV_BCAST: /* 0x01 */ |
| 330 | + offset = sizeof(struct batadv_bcast_packet); |
| 331 | + break; |
| 332 | + case BATADV_CODED: /* 0x02 */ |
| 333 | + offset = sizeof(struct batadv_coded_packet); |
| 334 | + break; |
| 335 | + case BATADV_UNICAST: /* 0x40 */ |
| 336 | + offset = sizeof(struct batadv_unicast_packet); |
| 337 | + break; |
| 338 | + case BATADV_UNICAST_FRAG: /* 0x41 */ |
| 339 | + offset = sizeof(struct batadv_frag_packet); |
| 340 | + break; |
| 341 | + case BATADV_UNICAST_4ADDR: /* 0x42 */ |
| 342 | + offset = sizeof(struct batadv_unicast_4addr_packet); |
| 343 | + break; |
| 344 | + case BATADV_UNICAST_TVLV: |
| 345 | + /* unsupported for now, needs variable offset to |
| 346 | + * take tvlv_len into account |
| 347 | + */ |
| 348 | + /* fall through */ |
| 349 | + default: |
| 350 | + offset = 0; |
| 351 | + } |
| 352 | + |
| 353 | + if (offset) |
| 354 | + gen_batadv_push_offset(cstate, (u_int)offset); |
| 355 | +} |
| 356 | + |
| 357 | +static void |
| 358 | +gen_batadv_offsets(compiler_state_t *cstate, bpf_u_int32 version, bpf_u_int32 type) |
| 359 | +{ |
| 360 | + switch (version) { |
| 361 | + case 14: |
| 362 | + gen_batadv_offsets_v14(cstate, type); |
| 363 | + break; |
| 364 | + case 15: |
| 365 | + gen_batadv_offsets_v15(cstate, type); |
| 366 | + break; |
| 367 | + default: |
| 368 | + break; |
| 369 | + } |
| 370 | +} |
| 371 | + |
| 372 | +struct block * |
| 373 | +gen_batadv(compiler_state_t *cstate, bpf_u_int32 version, int has_version, |
| 374 | + bpf_u_int32 type, int has_type) |
| 375 | +{ |
| 376 | + struct block *b0; |
| 377 | + |
| 378 | + /* |
| 379 | + * Catch errors reported by us and routines below us, and return NULL |
| 380 | + * on an error. |
| 381 | + */ |
| 382 | + if (setjmp(cstate->top_ctx)) |
| 383 | + return (NULL); |
| 384 | + |
| 385 | + b0 = gen_linktype(cstate, ETHERTYPE_BATMAN); |
| 386 | + |
| 387 | + if (has_version) |
| 388 | + b0 = gen_batadv_check_version(cstate, b0, version); |
| 389 | + |
| 390 | + if (has_type) { |
| 391 | + b0 = gen_batadv_check_type(cstate, b0, version, type); |
| 392 | + gen_batadv_offsets(cstate, version, type); |
| 393 | + } |
| 394 | + |
| 395 | + return b0; |
| 396 | +} |
| 397 | + |
| 398 | /* Check that the encapsulated frame has a link layer header |
| 399 | * for Ethernet filters. */ |
| 400 | static struct block * |
| 401 | --- a/gencode.h |
| 402 | +++ b/gencode.h |
| 403 | @@ -358,6 +358,9 @@ struct block *gen_pppoes(compiler_state_ |
| 404 | |
| 405 | struct block *gen_geneve(compiler_state_t *, bpf_u_int32, int); |
| 406 | |
| 407 | +struct block *gen_batadv(compiler_state_t *, bpf_u_int32, int, |
| 408 | + bpf_u_int32, int); |
| 409 | + |
| 410 | struct block *gen_atmfield_code(compiler_state_t *, int, bpf_u_int32, |
| 411 | int, int); |
| 412 | struct block *gen_atmtype_abbrev(compiler_state_t *, int); |
| 413 | --- a/grammar.y.in |
| 414 | +++ b/grammar.y.in |
| 415 | @@ -383,6 +383,7 @@ DIAG_OFF_BISON_BYACC |
| 416 | %type <i> mtp2type |
| 417 | %type <blk> mtp3field |
| 418 | %type <blk> mtp3fieldvalue mtp3value mtp3listvalue |
| 419 | +%type <rblk> pbatadv |
| 420 | |
| 421 | |
| 422 | %token DST SRC HOST GATEWAY |
| 423 | @@ -401,7 +402,7 @@ DIAG_OFF_BISON_BYACC |
| 424 | %token LEN |
| 425 | %token IPV6 ICMPV6 AH ESP |
| 426 | %token VLAN MPLS |
| 427 | -%token PPPOED PPPOES GENEVE |
| 428 | +%token PPPOED PPPOES GENEVE BATADV |
| 429 | %token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP |
| 430 | %token STP |
| 431 | %token IPX |
| 432 | @@ -698,11 +699,40 @@ other: pqual TK_BROADCAST { CHECK_PTR_ |
| 433 | | PPPOES { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, 0, 0))); } |
| 434 | | GENEVE pnum { CHECK_PTR_VAL(($$ = gen_geneve(cstate, $2, 1))); } |
| 435 | | GENEVE { CHECK_PTR_VAL(($$ = gen_geneve(cstate, 0, 0))); } |
| 436 | + | BATADV pbatadv { $$ = $2; } |
| 437 | | pfvar { $$ = $1; } |
| 438 | | pqual p80211 { $$ = $2; } |
| 439 | | pllc { $$ = $1; } |
| 440 | ; |
| 441 | |
| 442 | +pbatadv: { CHECK_PTR_VAL(($$ = gen_batadv(cstate, 0, 0, 0, 0))); } |
| 443 | + | pnum { CHECK_PTR_VAL(($$ = gen_batadv(cstate, $1, 1, 0, 0))); } |
| 444 | + | pnum pnum { CHECK_PTR_VAL(($$ = gen_batadv(cstate, $1, 1, $2, 1))); } |
| 445 | + | pnum ID |
| 446 | + { |
| 447 | + int type; |
| 448 | + |
| 449 | + switch ($1) { |
| 450 | + case 14: |
| 451 | + type = pcap_nametobatadvtype_v14($2); |
| 452 | + break; |
| 453 | + case 15: |
| 454 | + type = pcap_nametobatadvtype_v15($2); |
| 455 | + break; |
| 456 | + default: |
| 457 | + bpf_set_error(cstate, "batman-adv compatibility version number %u unsupported", $1); |
| 458 | + YYABORT; |
| 459 | + } |
| 460 | + |
| 461 | + if (type == PROTO_UNDEF) { |
| 462 | + bpf_set_error(cstate, "invalid batman-adv packet type value \"%s\"", $2); |
| 463 | + YYABORT; |
| 464 | + } |
| 465 | + |
| 466 | + CHECK_PTR_VAL(($$ = gen_batadv(cstate, $1, 1, type, 1))); |
| 467 | + } |
| 468 | + ; |
| 469 | + |
| 470 | pfvar: PF_IFNAME ID { CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ifname(cstate, $2))); } |
| 471 | | PF_RSET ID { CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ruleset(cstate, $2))); } |
| 472 | | PF_RNR NUM { CHECK_PTR_VAL(($$ = gen_pf_rnr(cstate, $2))); } |
| 473 | --- a/nametoaddr.c |
| 474 | +++ b/nametoaddr.c |
| 475 | @@ -134,8 +134,12 @@ |
| 476 | |
| 477 | #include "diag-control.h" |
| 478 | |
| 479 | +#include "batadv_packet.h" |
| 480 | +#include "batadv_legacy_packet.h" |
| 481 | + |
| 482 | #include "gencode.h" |
| 483 | #include <pcap/namedb.h> |
| 484 | + |
| 485 | #include "nametoaddr.h" |
| 486 | |
| 487 | #include "thread-local.h" |
| 488 | @@ -597,6 +601,7 @@ PCAP_API_DEF struct eproto eproto_db[] = |
| 489 | { "moprc", ETHERTYPE_MOPRC }, |
| 490 | { "rarp", ETHERTYPE_REVARP }, |
| 491 | { "sca", ETHERTYPE_SCA }, |
| 492 | + { "batadv", ETHERTYPE_BATMAN }, |
| 493 | { (char *)0, 0 } |
| 494 | }; |
| 495 | |
| 496 | @@ -631,6 +636,60 @@ pcap_nametollc(const char *s) |
| 497 | |
| 498 | while (p->s != 0) { |
| 499 | if (strcmp(p->s, s) == 0) |
| 500 | + return p->p; |
| 501 | + p += 1; |
| 502 | + } |
| 503 | + return PROTO_UNDEF; |
| 504 | +} |
| 505 | + |
| 506 | +/* Static data base of batman-adv v14 packet type values. */ |
| 507 | +static struct eproto batadv_type_db_v14[] = { |
| 508 | + { "iv_ogm", BATADV_LEGACY_IV_OGM }, |
| 509 | + { "icmp", BATADV_LEGACY_ICMP }, |
| 510 | + { "unicast", BATADV_LEGACY_UNICAST }, |
| 511 | + { "bcast", BATADV_LEGACY_BCAST }, |
| 512 | + { "vis", BATADV_LEGACY_VIS }, |
| 513 | + { "unicast_frag", BATADV_LEGACY_UNICAST_FRAG }, |
| 514 | + { "tt_query", BATADV_LEGACY_TT_QUERY }, |
| 515 | + { "roam_adv", BATADV_LEGACY_ROAM_ADV }, |
| 516 | + { "unicast_4addr", BATADV_LEGACY_UNICAST_4ADDR }, |
| 517 | + { "coded", BATADV_LEGACY_CODED }, |
| 518 | + { (char *)0, 0 } |
| 519 | +}; |
| 520 | + |
| 521 | +int pcap_nametobatadvtype_v14(const char *s) |
| 522 | +{ |
| 523 | + struct eproto *p = batadv_type_db_v14; |
| 524 | + |
| 525 | + while (p->s != 0) { |
| 526 | + if (strcmp(p->s, s) == 0) |
| 527 | + return p->p; |
| 528 | + p += 1; |
| 529 | + } |
| 530 | + return PROTO_UNDEF; |
| 531 | +} |
| 532 | + |
| 533 | +/* Static data base of batman-adv v15 packet type values. */ |
| 534 | +static struct eproto batadv_type_db_v15[] = { |
| 535 | + { "iv_ogm", BATADV_IV_OGM }, |
| 536 | + { "bcast", BATADV_BCAST }, |
| 537 | + { "coded", BATADV_CODED }, |
| 538 | + { "elp", BATADV_ELP }, |
| 539 | + { "ogm2", BATADV_OGM2 }, |
| 540 | + { "unicast", BATADV_UNICAST }, |
| 541 | + { "unicast_frag", BATADV_UNICAST_FRAG }, |
| 542 | + { "unicast_4addr", BATADV_UNICAST_4ADDR }, |
| 543 | + { "icmp", BATADV_ICMP }, |
| 544 | + { "unicast_tvlv", BATADV_UNICAST_TVLV }, |
| 545 | + { (char *)0, 0 } |
| 546 | +}; |
| 547 | + |
| 548 | +int pcap_nametobatadvtype_v15(const char *s) |
| 549 | +{ |
| 550 | + struct eproto *p = batadv_type_db_v15; |
| 551 | + |
| 552 | + while (p->s != 0) { |
| 553 | + if (strcmp(p->s, s) == 0) |
| 554 | return p->p; |
| 555 | p += 1; |
| 556 | } |
| 557 | --- a/pcap-filter.manmisc.in |
| 558 | +++ b/pcap-filter.manmisc.in |
| 559 | @@ -98,6 +98,7 @@ protocols are: |
| 560 | .BR arp , |
| 561 | .BR rarp , |
| 562 | .BR decnet , |
| 563 | +.BR batadv , |
| 564 | .BR sctp , |
| 565 | .B tcp |
| 566 | and |
| 567 | @@ -400,7 +401,7 @@ True if the packet is an IPv6 multicast |
| 568 | .IP "\fBether proto \fIprotocol\fR" |
| 569 | True if the packet is of ether type \fIprotocol\fR. |
| 570 | \fIProtocol\fP can be a number or one of the names |
| 571 | -\fBaarp\fP, \fBarp\fP, \fBatalk\fP, \fBdecnet\fP, \fBip\fP, \fBip6\fP, |
| 572 | +\fBaarp\fP, \fBarp\fP, \fBatalk\fP, \fBbatadv\fP, \fBdecnet\fP, \fBip\fP, \fBip6\fP, |
| 573 | \fBipx\fP, \fBiso\fP, \fBlat\fP, \fBloopback\fP, \fBmopdl\fP, \fBmoprc\fP, \fBnetbeui\fP, |
| 574 | \fBrarp\fP, \fBsca\fP or \fBstp\fP. |
| 575 | Note these identifiers (except \fBloopback\fP) are also keywords |
| 576 | @@ -454,7 +455,7 @@ the filter checks for the IPX etype in a |
| 577 | DSAP in the LLC header, the 802.3-with-no-LLC-header encapsulation of |
| 578 | IPX, and the IPX etype in a SNAP frame. |
| 579 | .RE |
| 580 | -.IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBatalk\fR, \fBaarp\fR, \fBdecnet\fR, \fBiso\fR, \fBstp\fR, \fBipx\fR, \fBnetbeui\fP" |
| 581 | +.IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBatalk\fR, \fBaarp\fR, \fBdecnet\fR, \fBiso\fR, \fBstp\fR, \fBipx\fR, \fBnetbeui\fP, \fBbatadv\fP" |
| 582 | Abbreviations for: |
| 583 | .in +.5i |
| 584 | .nf |
| 585 | @@ -795,6 +796,36 @@ For example: |
| 586 | filters IPv4 protocol encapsulated in Geneve with VNI 0xb. This will |
| 587 | match both IPv4 directly encapsulated in Geneve as well as IPv4 contained |
| 588 | inside an Ethernet frame. |
| 589 | +.IP "\fBbatadv \fI[version] \fI[type]\fR" |
| 590 | +True if the packet is a B.A.T.M.A.N. Advanced packet (Ethernet type 0x4305). |
| 591 | +If the optional \fIversion\fR is specified, only true if the packet has the |
| 592 | +specified batman-adv compatibility \fIversion\fR. If the optional \fIversion\fR |
| 593 | +and \fItype\fR are specified, only true if the packet has both the specified |
| 594 | +batman-adv compatibility \fIversion\fR and batman-adv packet \fItype\fR. |
| 595 | +.IP |
| 596 | +\fIversion\fR may be a number from 0 to 255, though only compatibility version |
| 597 | +14 and 15 were actually deployed in the wild. Version 15 is the current version, |
| 598 | +14 is considered deprecated. |
| 599 | +.IP |
| 600 | +\fItype\fR is currently only defined for compatibility \fIversion\fR 14 and 15. |
| 601 | +\fItype\fR may be a number from 0 to 255 for compatibility \fIversion\fR 14 and 15. |
| 602 | +.IP |
| 603 | +The following packet \fItype\fR aliases are available for compat \fIversion\fR 14: |
| 604 | +\fBiv_ogm\fP, \fBicmp\fP, \fBunicast\fP, \fBbcast\fP, \fBvis\fP, \fBunicast-frag\fP, |
| 605 | +\fBtt_query\fP, \fBroam_adv\fP, \fBunicast_4addr\fP, \fPcoded\fP. |
| 606 | +.IP |
| 607 | +The following packet \fItype\fR aliases are available for compat \fIversion\fR 15: |
| 608 | +\fBiv_ogm\fP, \fBbcast\fP, \fBcoded\fP, \fBelp\fP, \fBogm2\fP, \fBunicast\fP, |
| 609 | +\fBunicast_frag\fP, \fBunicast_4addr\fP, \fBicmp\fP, \fPunicast_tvlv\fP. |
| 610 | +.IP |
| 611 | +Note that when the \fBbatadv\fR keyword is encountered in an expression and |
| 612 | +a batman-adv packet \fItype\fR is provided which specifies an encapsulating |
| 613 | +packet type then it changes the decoding offsets for the remainder of the |
| 614 | +expression on the assumption that the packet is a batman-adv packet. For compat |
| 615 | +\fIversion\fR 14 these are packet \fItype\fRs \fBunicast\fP, \fBbcast\fP, |
| 616 | +\fBunicast_frag\fP, \fBunicast_4addr\fP and \fBcoded\fP. For compat \fIversion\fR |
| 617 | +15 these are currently packet \fItype\fRs \fBbcast\fP, \fBcoded\fP, \fBunicast\fP, |
| 618 | +\fBunicast_frag\fP and \fBunicast_4addr\fP. |
| 619 | .IP "\fBiso proto \fIprotocol\fR" |
| 620 | True if the packet is an OSI packet of protocol type \fIprotocol\fP. |
| 621 | \fIProtocol\fP can be a number or one of the names |
| 622 | --- a/pcap/namedb.h |
| 623 | +++ b/pcap/namedb.h |
| 624 | @@ -94,6 +94,8 @@ PCAP_API int pcap_nametoeproto(const cha |
| 625 | |
| 626 | PCAP_AVAILABLE_0_9 |
| 627 | PCAP_API int pcap_nametollc(const char *); |
| 628 | +PCAP_API int pcap_nametobatadvtype_v14(const char *); |
| 629 | +PCAP_API int pcap_nametobatadvtype_v15(const char *); |
| 630 | |
| 631 | /* |
| 632 | * If a protocol is unknown, PROTO_UNDEF is returned. |
| 633 | --- a/scanner.l |
| 634 | +++ b/scanner.l |
| 635 | @@ -365,6 +365,7 @@ mpls return MPLS; |
| 636 | pppoed return PPPOED; |
| 637 | pppoes return PPPOES; |
| 638 | geneve return GENEVE; |
| 639 | +batadv return BATADV; |
| 640 | |
| 641 | lane return LANE; |
| 642 | llc return LLC; |