b.a.t.m.a.n.lists.open-mesh.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] batctl: mcast_flags: update to current state
@ 2023-08-01  2:15 Linus Lüssing
  2023-08-01  2:15 ` [PATCH 2/2] batctl: tcpdump: parse batman-adv mcast packet type Linus Lüssing
  0 siblings, 1 reply; 2+ messages in thread
From: Linus Lüssing @ 2023-08-01  2:15 UTC (permalink / raw)
  To: b.a.t.m.a.n

Add the new "P" flag, which signals support for the new batman-adv
multicast packet type, to the "batctl mcast_flags" and "batctl tcpdump"
outputs.

The examples in the README.rst are updated, too, including a description
for the R4 and R6 flags.

Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
---
 README.rst      | 88 ++++++++++++++++++++++++++++---------------------
 batadv_packet.h | 45 +++++++++++++++++++++----
 genl_json.c     |  2 ++
 mcast_flags.c   |  8 +++--
 tcpdump.c       |  5 +--
 5 files changed, 100 insertions(+), 48 deletions(-)

diff --git a/README.rst b/README.rst
index 606d55721204..3495fba02e0e 100644
--- a/README.rst
+++ b/README.rst
@@ -323,15 +323,15 @@ Usage::
 
 Example::
 
-  Multicast flags (own flags: [U46])
+  Multicast flags (own flags: [U46R4R6.])
   * Bridged [U]                           U
   * No IGMP/MLD Querier [4/6]:            ./.
   * Shadowing IGMP/MLD Querier [4/6]:     4/6
   -------------------------------------------
          Originator Flags
-  02:04:64:a4:39:c1 [U..]
-  02:04:64:a4:39:c2 [U..]
-  02:04:64:a4:39:c3 [...]
+  02:04:64:a4:39:c1 [U... . .]
+  02:04:64:a4:39:c2 [...R4R6.]
+  02:04:64:a4:39:c3 [.... . P]
 
 where
 
@@ -348,6 +348,17 @@ U:
 6:
   wants all IPv6 multicast traffic, meaning other nodes need to always forward
   any IPv6 multicast traffic to it
+R4:
+  wants all routable IPv4 multicast traffic, meaning other nodes need to always
+  forward multicast traffic destined to 224.0.0.0/4 excluding 224.0.0.0/24 to
+  it
+R6:
+  wants all routable IPv6 multicast traffic, meaning other nodes need to always
+  forward multicast traffic destined to ffXY::/16 with Y > 2 (scope greater
+  than link-local) to it
+P:
+  the node either cannot handle batman-adv multicast packets with a multicast
+  tracker TVLV or one of its hard interfaces has an MTU smaller than 1280 bytes
 
 If a node does not have multicast optimizations available (e.g. old batman-adv
 version or optimizations not compiled in), therefore not announcing any
@@ -930,39 +941,42 @@ Example::
 
   $ batctl meshif bat0 mcast_flags_json | json_pp
   [
-      {
-          "mcast_flags": {
-              "all_unsnoopables": true,
-              "raw": 1,
-              "want_all_ipv4": false,
-              "want_all_ipv6": false,
-              "want_no_rtr_ipv4": false,
-              "want_no_rtr_ipv6": false
-          },
-          "orig_address": "9e:58:32:59:54:c3"
-      },
-      {
-          "mcast_flags": {
-              "all_unsnoopables": true,
-              "raw": 1,
-              "want_all_ipv4": false,
-              "want_all_ipv6": false,
-              "want_no_rtr_ipv4": false,
-              "want_no_rtr_ipv6": false
-          },
-          "orig_address": "32:12:17:0a:21:63"
-      },
-      {
-          "mcast_flags": {
-              "all_unsnoopables": true,
-              "raw": 1,
-              "want_all_ipv4": false,
-              "want_all_ipv6": false,
-              "want_no_rtr_ipv4": false,
-              "want_no_rtr_ipv6": false
-          },
-          "orig_address": "1a:34:8c:c4:fe:13"
-      },
+     {
+        "mcast_flags" : {
+           "all_unsnoopables" : true,
+           "have_mc_ptype_capa" : true,
+           "raw" : 57,
+           "want_all_ipv4" : false,
+           "want_all_ipv6" : false,
+           "want_no_rtr_ipv4" : true,
+           "want_no_rtr_ipv6" : true
+        },
+        "orig_address" : "02:04:64:a4:39:c1"
+     },
+     {
+        "mcast_flags" : {
+           "all_unsnoopables" : false,
+           "have_mc_ptype_capa" : true,
+           "raw" : 40,
+           "want_all_ipv4" : false,
+           "want_all_ipv6" : false,
+           "want_no_rtr_ipv4" : true,
+           "want_no_rtr_ipv6" : false
+        },
+        "orig_address" : "02:04:64:a4:39:c2"
+     },
+     {
+        "mcast_flags" : {
+           "all_unsnoopables" : false,
+           "have_mc_ptype_capa" : false,
+           "raw" : 24,
+           "want_all_ipv4" : false,
+           "want_all_ipv6" : false,
+           "want_no_rtr_ipv4" : true,
+           "want_no_rtr_ipv6" : true
+        },
+        "orig_address" : "02:04:64:a4:39:c3"
+     },
   [...]
   ]
 
diff --git a/batadv_packet.h b/batadv_packet.h
index 9204e4494b25..6e25753015df 100644
--- a/batadv_packet.h
+++ b/batadv_packet.h
@@ -116,6 +116,9 @@ enum batadv_icmp_packettype {
  * only need routable IPv4 multicast packets we signed up for explicitly
  * @BATADV_MCAST_WANT_NO_RTR6: we have no IPv6 multicast router and therefore
  * only need routable IPv6 multicast packets we signed up for explicitly
+ * @BATADV_MCAST_HAVE_MC_PTYPE_CAPA: we can parse, receive and forward
+ * batman-adv multicast packets with a multicast tracker TVLV. And all our
+ * hard interfaces have an MTU of at least 1280 bytes.
  */
 enum batadv_mcast_flags {
 	BATADV_MCAST_WANT_ALL_UNSNOOPABLES	= 1UL << 0,
@@ -123,6 +126,7 @@ enum batadv_mcast_flags {
 	BATADV_MCAST_WANT_ALL_IPV6		= 1UL << 2,
 	BATADV_MCAST_WANT_NO_RTR4		= 1UL << 3,
 	BATADV_MCAST_WANT_NO_RTR6		= 1UL << 4,
+	BATADV_MCAST_HAVE_MC_PTYPE_CAPA		= 1UL << 5,
 };
 
 /* tt data subtypes */
@@ -174,14 +178,16 @@ enum batadv_bla_claimframe {
  * @BATADV_TVLV_TT: translation table tvlv
  * @BATADV_TVLV_ROAM: roaming advertisement tvlv
  * @BATADV_TVLV_MCAST: multicast capability tvlv
+ * @BATADV_TVLV_MCAST_TRACKER: multicast tracker tvlv
  */
 enum batadv_tvlv_type {
-	BATADV_TVLV_GW		= 0x01,
-	BATADV_TVLV_DAT		= 0x02,
-	BATADV_TVLV_NC		= 0x03,
-	BATADV_TVLV_TT		= 0x04,
-	BATADV_TVLV_ROAM	= 0x05,
-	BATADV_TVLV_MCAST	= 0x06,
+	BATADV_TVLV_GW			= 0x01,
+	BATADV_TVLV_DAT			= 0x02,
+	BATADV_TVLV_NC			= 0x03,
+	BATADV_TVLV_TT			= 0x04,
+	BATADV_TVLV_ROAM		= 0x05,
+	BATADV_TVLV_MCAST		= 0x06,
+	BATADV_TVLV_MCAST_TRACKER	= 0x07,
 };
 
 #pragma pack(2)
@@ -487,6 +493,25 @@ struct batadv_bcast_packet {
 	 */
 };
 
+/**
+ * struct batadv_mcast_packet - multicast packet for network payload
+ * @packet_type: batman-adv packet type, part of the general header
+ * @version: batman-adv protocol version, part of the general header
+ * @ttl: time to live for this packet, part of the general header
+ * @reserved: reserved byte for alignment
+ * @tvlv_len: length of the appended tvlv buffer (in bytes)
+ */
+struct batadv_mcast_packet {
+	__u8 packet_type;
+	__u8 version;
+	__u8 ttl;
+	__u8 reserved;
+	__be16 tvlv_len;
+	/* "4 bytes boundary + 2 bytes" long to make the payload after the
+	 * following ethernet header again 4 bytes boundary aligned
+	 */
+};
+
 /**
  * struct batadv_coded_packet - network coded packet
  * @packet_type: batman-adv packet type, part of the general header
@@ -628,6 +653,14 @@ struct batadv_tvlv_mcast_data {
 	__u8 reserved[3];
 };
 
+/**
+ * struct batadv_tvlv_mcast_tracker - payload of a multicast tracker tvlv
+ * @num_dests: number of subsequent destination originator MAC addresses
+ */
+struct batadv_tvlv_mcast_tracker {
+	__be16	num_dests;
+};
+
 #pragma pack()
 
 #endif /* _UAPI_LINUX_BATADV_PACKET_H_ */
diff --git a/genl_json.c b/genl_json.c
index 2be533d064e0..4cb1bafca8ef 100644
--- a/genl_json.c
+++ b/genl_json.c
@@ -157,6 +157,8 @@ static void nljson_print_mcastflags(struct nlattr *attrs[], int idx)
 	       val & BATADV_MCAST_WANT_NO_RTR4 ? "true" : "false");
 	printf("\"want_no_rtr_ipv6\": %s,",
 	       val & BATADV_MCAST_WANT_NO_RTR6 ? "true" : "false");
+	printf("\"have_mc_ptype_capa\": %s,",
+	       val & BATADV_MCAST_HAVE_MC_PTYPE_CAPA ? "true" : "false");
 	printf("\"raw\": %"PRIu32, val);
 	putchar('}');
 }
diff --git a/mcast_flags.c b/mcast_flags.c
index 44344e0c1f61..7d4c1d69adfb 100644
--- a/mcast_flags.c
+++ b/mcast_flags.c
@@ -80,12 +80,13 @@ static int mcast_flags_callback(struct nl_msg *msg, void *arg)
 	if (attrs[BATADV_ATTR_MCAST_FLAGS]) {
 		flags = nla_get_u32(attrs[BATADV_ATTR_MCAST_FLAGS]);
 
-		printf("[%c%c%c%s%s]\n",
+		printf("[%c%c%c%s%s%c]\n",
 		       flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES ? 'U' : '.',
 		       flags & BATADV_MCAST_WANT_ALL_IPV4 ? '4' : '.',
 		       flags & BATADV_MCAST_WANT_ALL_IPV6 ? '6' : '.',
 		       !(flags & BATADV_MCAST_WANT_NO_RTR4) ? "R4" : ". ",
-		       !(flags & BATADV_MCAST_WANT_NO_RTR6) ? "R6" : ". ");
+		       !(flags & BATADV_MCAST_WANT_NO_RTR6) ? "R6" : ". ",
+		       !(flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA) ? 'P' : '.');
 	} else {
 		printf("-\n");
 	}
@@ -125,7 +126,7 @@ static int netlink_print_mcast_flags(struct state *state, char *orig_iface,
         }
 
 	ret = asprintf(&header,
-		"Multicast flags (own flags: [%c%c%c%s%s])\n"
+		"Multicast flags (own flags: [%c%c%c%s%s%c])\n"
 		 "* Bridged [U]\t\t\t\t%c\n"
 		 "* No IGMP/MLD Querier [4/6]:\t\t%c/%c\n"
 		 "* Shadowing IGMP/MLD Querier [4/6]:\t%c/%c\n"
@@ -136,6 +137,7 @@ static int netlink_print_mcast_flags(struct state *state, char *orig_iface,
 		 (mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.',
 	         !(mcast_flags & BATADV_MCAST_WANT_NO_RTR4) ? "R4" : ". ",
 	         !(mcast_flags & BATADV_MCAST_WANT_NO_RTR6) ? "R6" : ". ",
+	         !(mcast_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA) ? 'P' : '.',
 		 bridged ? 'U' : '.',
 		 querier4, querier6, shadowing4, shadowing6,
 		 "Originator", "Flags");
diff --git a/tcpdump.c b/tcpdump.c
index 9a830b2ba8b2..debcb0ae517a 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -231,12 +231,13 @@ static void batctl_tvlv_parse_mcast_v2(void *buff, ssize_t buff_len)
 
 	flags = tvlv->flags;
 
-	printf("\tTVLV MCASTv2: [%c%c%c%s%s]\n",
+	printf("\tTVLV MCASTv2: [%c%c%c%s%s%c]\n",
 	       flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES ? 'U' : '.',
 	       flags & BATADV_MCAST_WANT_ALL_IPV4 ? '4' : '.',
 	       flags & BATADV_MCAST_WANT_ALL_IPV6 ? '6' : '.',
 	       !(flags & BATADV_MCAST_WANT_NO_RTR4) ? "R4" : ". ",
-	       !(flags & BATADV_MCAST_WANT_NO_RTR6) ? "R6" : ". ");
+	       !(flags & BATADV_MCAST_WANT_NO_RTR6) ? "R6" : ". ",
+	       !(flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA) ? 'P' : '.');
 }
 
 typedef void (*batctl_tvlv_parser_t)(void *buff, ssize_t buff_len);
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH 2/2] batctl: tcpdump: parse batman-adv mcast packet type
  2023-08-01  2:15 [PATCH 1/2] batctl: mcast_flags: update to current state Linus Lüssing
@ 2023-08-01  2:15 ` Linus Lüssing
  0 siblings, 0 replies; 2+ messages in thread
From: Linus Lüssing @ 2023-08-01  2:15 UTC (permalink / raw)
  To: b.a.t.m.a.n

Implement a batctl tcpdump parsing of the new batman-adv multicast
packet type, including its multicast tracker TVLV and encapsulated
payload data.

Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
---
 tcpdump.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++-------
 tcpdump.h |   1 +
 2 files changed, 119 insertions(+), 16 deletions(-)

diff --git a/tcpdump.c b/tcpdump.c
index debcb0ae517a..5e7c76c69bd1 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -57,7 +57,8 @@ static unsigned short dump_level_all = DUMP_TYPE_BATOGM | DUMP_TYPE_BATOGM2 |
 				       DUMP_TYPE_BATELP | DUMP_TYPE_BATICMP |
 				       DUMP_TYPE_BATUCAST | DUMP_TYPE_BATBCAST |
 				       DUMP_TYPE_BATUTVLV | DUMP_TYPE_BATFRAG |
-				       DUMP_TYPE_NONBAT | DUMP_TYPE_BATCODED;
+				       DUMP_TYPE_NONBAT | DUMP_TYPE_BATCODED |
+				       DUMP_TYPE_BATMCAST;
 static unsigned short dump_level;
 
 static void parse_eth_hdr(unsigned char *packet_buff, ssize_t buff_len, int read_opt, int time_printed);
@@ -82,6 +83,7 @@ static void tcpdump_usage(void)
 	fprintf(stderr, " \t\t%3d - batman unicast tvlv packets\n", DUMP_TYPE_BATUTVLV);
 	fprintf(stderr, " \t\t%3d - non batman packets\n", DUMP_TYPE_NONBAT);
 	fprintf(stderr, " \t\t%3d - batman coded packets\n", DUMP_TYPE_BATCODED);
+	fprintf(stderr, " \t\t%3d - batman multicast packets\n", DUMP_TYPE_BATMCAST);
 	fprintf(stderr, " \t\t%3d - batman ogm & non batman packets\n", DUMP_TYPE_BATOGM | DUMP_TYPE_NONBAT);
 }
 
@@ -101,7 +103,8 @@ static int print_time(void)
 	return 1;
 }
 
-static void batctl_tvlv_parse_gw_v1(void *buff, ssize_t buff_len)
+static void batctl_tvlv_parse_gw_v1(void *buff, ssize_t buff_len,
+				    int read_opt __maybe_unused)
 {
 	struct batadv_tvlv_gateway_data *tvlv = buff;
 	uint32_t down, up;
@@ -119,8 +122,9 @@ static void batctl_tvlv_parse_gw_v1(void *buff, ssize_t buff_len)
 	       down / 10, down % 10, up / 10, up % 10);
 }
 
-static void batctl_tvlv_parse_dat_v1(void (*buff)__attribute__((unused)),
-				     ssize_t buff_len)
+static void batctl_tvlv_parse_dat_v1(void *buff __maybe_unused,
+				     ssize_t buff_len,
+				     int read_opt __maybe_unused)
 {
 	if (buff_len != 0) {
 		fprintf(stderr, "Warning - dropping received %s packet as it is not the correct size (0): %zu\n",
@@ -131,8 +135,9 @@ static void batctl_tvlv_parse_dat_v1(void (*buff)__attribute__((unused)),
 	printf("\tTVLV DATv1: enabled\n");
 }
 
-static void batctl_tvlv_parse_nc_v1(void (*buff)__attribute__((unused)),
-				    ssize_t buff_len)
+static void batctl_tvlv_parse_nc_v1(void *buff __maybe_unused,
+				    ssize_t buff_len,
+				    int read_opt __maybe_unused)
 {
 	if (buff_len != 0) {
 		fprintf(stderr, "Warning - dropping received %s packet as it is not the correct size (0): %zu\n",
@@ -143,7 +148,8 @@ static void batctl_tvlv_parse_nc_v1(void (*buff)__attribute__((unused)),
 	printf("\tTVLV NCv1: enabled\n");
 }
 
-static void batctl_tvlv_parse_tt_v1(void *buff, ssize_t buff_len)
+static void batctl_tvlv_parse_tt_v1(void *buff, ssize_t buff_len,
+				    int read_opt __maybe_unused)
 {
 	struct batadv_tvlv_tt_data *tvlv = buff;
 	struct batadv_tvlv_tt_vlan_data *vlan;
@@ -183,7 +189,8 @@ static void batctl_tvlv_parse_tt_v1(void *buff, ssize_t buff_len)
 	}
 }
 
-static void batctl_tvlv_parse_roam_v1(void *buff, ssize_t buff_len)
+static void batctl_tvlv_parse_roam_v1(void *buff, ssize_t buff_len,
+				      int read_opt __maybe_unused)
 {
 	struct batadv_tvlv_roam_adv *tvlv = buff;
 
@@ -199,7 +206,8 @@ static void batctl_tvlv_parse_roam_v1(void *buff, ssize_t buff_len)
 }
 
 static void batctl_tvlv_parse_mcast_v1(void *buff __maybe_unused,
-				       ssize_t buff_len)
+				       ssize_t buff_len,
+				       int read_opt __maybe_unused)
 {
 	struct batadv_tvlv_mcast_data *tvlv = buff;
 	uint8_t flags;
@@ -218,7 +226,8 @@ static void batctl_tvlv_parse_mcast_v1(void *buff __maybe_unused,
 	       flags & BATADV_MCAST_WANT_ALL_IPV6 ? '6' : '.');
 }
 
-static void batctl_tvlv_parse_mcast_v2(void *buff, ssize_t buff_len)
+static void batctl_tvlv_parse_mcast_v2(void *buff, ssize_t buff_len,
+				       int read_opt __maybe_unused)
 {
 	struct batadv_tvlv_mcast_data *tvlv = buff;
 	uint8_t flags;
@@ -240,7 +249,37 @@ static void batctl_tvlv_parse_mcast_v2(void *buff, ssize_t buff_len)
 	       !(flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA) ? 'P' : '.');
 }
 
-typedef void (*batctl_tvlv_parser_t)(void *buff, ssize_t buff_len);
+static void
+batctl_tvlv_parse_mcast_tracker_v1(void *buff, ssize_t buff_len, int read_opt)
+{
+	struct batadv_tvlv_mcast_tracker *tvlv = buff;
+	size_t tvlv_len = sizeof(*tvlv);
+	struct ether_addr *dst;
+	uint16_t num_dests;
+
+	if (buff_len < (ssize_t)tvlv_len) {
+		fprintf(stderr, "Warning - dropping received %s packet as it is not the correct size (%zu): %zu\n",
+			"TVLV MCAST TRACKER v1", tvlv_len, buff_len);
+		return;
+	}
+
+	num_dests = ntohs(tvlv->num_dests);
+	tvlv_len += num_dests * ETH_ALEN;
+	dst = (struct ether_addr *)(tvlv + 1);
+
+	if (buff_len < (ssize_t)tvlv_len) {
+		fprintf(stderr, "Warning - dropping received %s packet as it is not the correct size (%zu): %zu\n",
+			"TVLV MCAST TRACKER v1 (with destinations)", tvlv_len, buff_len);
+		return;
+	}
+
+	printf("\tTVLV MCAST TRACKER v1, destinations (%hu):\n", num_dests);
+
+	for (int i = 0; i < num_dests; i++)
+		printf("\t\t%s\n", get_name_by_macaddr(dst++, read_opt));
+}
+
+typedef void (*batctl_tvlv_parser_t)(void *buff, ssize_t buff_len, int read_opt);
 
 static batctl_tvlv_parser_t tvlv_parser_get(uint8_t type, uint8_t version)
 {
@@ -295,12 +334,20 @@ static batctl_tvlv_parser_t tvlv_parser_get(uint8_t type, uint8_t version)
 			return NULL;
 		}
 
+	case BATADV_TVLV_MCAST_TRACKER:
+		switch (version) {
+		case 1:
+			return batctl_tvlv_parse_mcast_tracker_v1;
+		default:
+			return NULL;
+		}
+
 	default:
 		return NULL;
 	}
 }
 
-static void dump_tvlv(unsigned char *ptr, ssize_t tvlv_len)
+static void dump_tvlv(unsigned char *ptr, ssize_t tvlv_len, int read_opt)
 {
 	struct batadv_tvlv_hdr *tvlv_hdr;
 	batctl_tvlv_parser_t parser;
@@ -318,7 +365,7 @@ static void dump_tvlv(unsigned char *ptr, ssize_t tvlv_len)
 
 		parser = tvlv_parser_get(tvlv_hdr->type, tvlv_hdr->version);
 		if (parser)
-			parser(ptr, len);
+			parser(ptr, len, read_opt);
 
 		/* go to the next container */
 		ptr += len;
@@ -358,7 +405,7 @@ static void dump_batman_ucast_tvlv(unsigned char *packet_buff, ssize_t buff_len,
 	       buff_len - sizeof(struct ether_header), tvlv_len,
 	       tvlv_packet->ttl);
 
-	dump_tvlv((uint8_t *)(tvlv_packet + 1), tvlv_len);
+	dump_tvlv((uint8_t *)(tvlv_packet + 1), tvlv_len, read_opt);
 }
 
 static int dump_bla2_claim(struct ether_header *eth_hdr,
@@ -779,7 +826,7 @@ static void dump_batman_iv_ogm(unsigned char *packet_buff, ssize_t buff_len, int
 	check_len -= sizeof(struct batadv_ogm_packet);
 	LEN_CHECK(check_len, (size_t)tvlv_len, "BAT OGM TVLV (containers)");
 
-	dump_tvlv((uint8_t *)(batman_ogm_packet + 1), tvlv_len);
+	dump_tvlv((uint8_t *)(batman_ogm_packet + 1), tvlv_len, read_opt);
 }
 
 static void dump_batman_ogm2(unsigned char *packet_buff, ssize_t buff_len,
@@ -823,7 +870,7 @@ static void dump_batman_ogm2(unsigned char *packet_buff, ssize_t buff_len,
 	check_len -= BATADV_OGM2_HLEN;
 	LEN_CHECK(check_len, (size_t)tvlv_len, "BAT OGM2 TVLV (containers)");
 
-	dump_tvlv((uint8_t *)(batman_ogm2 + 1), tvlv_len);
+	dump_tvlv((uint8_t *)(batman_ogm2 + 1), tvlv_len, read_opt);
 }
 
 static void dump_batman_elp(unsigned char *packet_buff, ssize_t buff_len,
@@ -988,6 +1035,57 @@ static void dump_batman_bcast(unsigned char *packet_buff, ssize_t buff_len, int
 		      read_opt, time_printed);
 }
 
+static void dump_batman_mcast(unsigned char *packet_buff, ssize_t buff_len,
+			      int read_opt, int time_printed)
+{
+	struct batadv_mcast_packet *mcast_packet;
+	struct ether_header *ether_header;
+	uint8_t *tvlv_hdr;
+	ssize_t check_len;
+	size_t tvlv_len;
+
+	check_len = (size_t)buff_len - sizeof(struct ether_header);
+
+	LEN_CHECK(check_len, sizeof(*mcast_packet), "BAT MCAST");
+	check_len -= sizeof(*mcast_packet);
+
+	ether_header = (struct ether_header *)packet_buff;
+	mcast_packet = (struct batadv_mcast_packet *)(ether_header + 1);
+	tvlv_len = ntohs(mcast_packet->tvlv_len);
+
+	LEN_CHECK(check_len, tvlv_len, "BAT MCAST TVLV (containers)");
+	check_len -= tvlv_len;
+
+	tvlv_hdr = (uint8_t *)(mcast_packet + 1);
+
+	if (!time_printed)
+		time_printed = print_time();
+
+	printf("BAT %s > ",
+	       get_name_by_macaddr((struct ether_addr *)ether_header->ether_shost, read_opt));
+
+	printf("%s: MCAST, ttl %hhu, ",
+	       get_name_by_macaddr((struct ether_addr *)ether_header->ether_dhost, read_opt),
+	       mcast_packet->ttl);
+
+	/* batman-adv mcast packet's data payload is optional */
+	if (check_len >= ETH_HLEN) {
+		ether_header = (struct ether_header *)(tvlv_hdr + tvlv_len);
+
+		printf("%s > ",
+		       get_name_by_macaddr((struct ether_addr *)ether_header->ether_shost, read_opt));
+		printf("%s, ",
+		       get_name_by_macaddr((struct ether_addr *)ether_header->ether_dhost, read_opt));
+
+		parse_eth_hdr((unsigned char *)ether_header, check_len,
+			      read_opt, time_printed);
+	} else {
+		printf("\n");
+	}
+
+	dump_tvlv(tvlv_hdr, tvlv_len, read_opt);
+}
+
 static void dump_batman_coded(unsigned char *packet_buff, ssize_t buff_len, int read_opt, int time_printed)
 {
 	struct batadv_coded_packet *coded_packet;
@@ -1106,6 +1204,10 @@ static void parse_eth_hdr(unsigned char *packet_buff, ssize_t buff_len, int read
 			if (dump_level & DUMP_TYPE_BATBCAST)
 				dump_batman_bcast(packet_buff, buff_len, read_opt, time_printed);
 			break;
+		case BATADV_MCAST:
+			if (dump_level & DUMP_TYPE_BATMCAST)
+				dump_batman_mcast(packet_buff, buff_len, read_opt, time_printed);
+			break;
 		case BATADV_CODED:
 			if (dump_level & DUMP_TYPE_BATCODED)
 				dump_batman_coded(packet_buff, buff_len, read_opt, time_printed);
diff --git a/tcpdump.h b/tcpdump.h
index 527fb7f0891d..be64aeb810c6 100644
--- a/tcpdump.h
+++ b/tcpdump.h
@@ -34,6 +34,7 @@
 #define DUMP_TYPE_BATFRAG 128
 #define DUMP_TYPE_NONBAT 256
 #define DUMP_TYPE_BATCODED 512
+#define DUMP_TYPE_BATMCAST 1024
 
 #define IEEE80211_FCTL_FTYPE 0x0c00
 #define IEEE80211_FCTL_TODS 0x0001
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-08-01  2:17 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-01  2:15 [PATCH 1/2] batctl: mcast_flags: update to current state Linus Lüssing
2023-08-01  2:15 ` [PATCH 2/2] batctl: tcpdump: parse batman-adv mcast packet type Linus Lüssing

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).