]> The Tcpdump Group git mirrors - tcpdump/commitdiff
bgp: Parse rfc9072 (Extended Optional Parameters Length for BGP OPEN Message)
authorDonatas Abraitis <[email protected]>
Wed, 2 Feb 2022 09:32:51 +0000 (11:32 +0200)
committerfxlb <[email protected]>
Wed, 2 Feb 2022 10:21:58 +0000 (10:21 +0000)
Signed-off-by: Donatas Abraitis <[email protected]>
print-bgp.c
tests/TESTLIST
tests/bgp-extended-optional-parameters-length.out [new file with mode: 0644]
tests/bgp-extended-optional-parameters-length.pcap [new file with mode: 0644]

index 6d24011ffff86457e3f58c9205443170692c4d29..6a2923984e271b5432e5cc80a9381e857c0974b0 100644 (file)
@@ -80,13 +80,15 @@ struct bgp_open {
     nd_uint16_t bgpo_holdtime;
     nd_uint32_t bgpo_id;
     nd_uint8_t  bgpo_optlen;
+    nd_uint8_t  bgpo_opttype;         /* RFC9072 */
+    nd_uint16_t bgpo_optlen_extended; /* RFC9072 */
     /* options should follow */
 };
 #define BGP_OPEN_SIZE        29    /* unaligned */
 
 struct bgp_opt {
-    nd_uint8_t bgpopt_type;
-    nd_uint8_t bgpopt_len;
+    nd_uint8_t  bgpopt_type;
+    nd_uint16_t bgpopt_len; /* Can be one or two bytes, depending on RFC9072 */
     /* variable length */
 };
 #define BGP_OPT_SIZE           2    /* some compilers may pad to 4 bytes */
@@ -461,6 +463,9 @@ static const struct tok bgp_safi_values[] = {
 #define BGP_EXT_COM_EIGRP_EXT_REMAS_REMID        0x8804
 #define BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC 0x8805
 
+/* Optional Parameters */
+#define BGP_OPEN_NON_EXT_OPT_TYPE_EXTENDED_LENGTH 255 /* Non-Ext OP Type */
+
 static const struct tok bgp_extd_comm_flag_values[] = {
     { 0x8000,                  "vendor-specific"},
     { 0x4000,                  "non-transitive"},
@@ -2662,9 +2667,13 @@ bgp_open_print(netdissect_options *ndo,
     char astostr[AS_STR_SIZE];
     const struct bgp_open *bgp_open_header;
     u_int optslen;
+    uint8_t opsttype;
     const struct bgp_opt *bgpopt;
     const u_char *opt;
     u_int i;
+    uint8_t extended_opt_params = 0;
+    u_int open_size = BGP_OPEN_SIZE;
+    u_int opt_size = BGP_OPT_SIZE;
 
     ND_TCHECK_LEN(dat, BGP_OPEN_SIZE);
     if (length < BGP_OPEN_SIZE)
@@ -2680,22 +2689,32 @@ bgp_open_print(netdissect_options *ndo,
         GET_BE_U_2(bgp_open_header->bgpo_holdtime));
     ND_PRINT("ID %s", GET_IPADDR_STRING(bgp_open_header->bgpo_id));
     optslen = GET_U_1(bgp_open_header->bgpo_optlen);
-    ND_PRINT("\n\t  Optional parameters, length: %u", optslen);
+    opsttype = GET_U_1(bgp_open_header->bgpo_opttype);
+    if (opsttype == BGP_OPEN_NON_EXT_OPT_TYPE_EXTENDED_LENGTH) {
+        optslen = GET_BE_U_2(bgp_open_header->bgpo_optlen_extended);
+        extended_opt_params = 1;
+        open_size += 3;
+        opt_size += 1;
+    }
+    ND_PRINT("\n\t  Optional parameters%s, length: %u",
+             extended_opt_params ? " (Extended)" : "", optslen);
 
-    opt = dat + BGP_OPEN_SIZE;
-    length -= BGP_OPEN_SIZE;
+    opt = dat + open_size;
+    length -= open_size;
 
     i = 0;
     while (i < optslen) {
-        uint8_t opt_type, opt_len;
+        uint8_t opt_type;
+        uint16_t opt_len;
 
-        ND_TCHECK_LEN(opt + i, BGP_OPT_SIZE);
-        if (length < BGP_OPT_SIZE + i)
+        ND_TCHECK_LEN(opt + i, opt_size);
+        if (length < opt_size + i)
             goto trunc;
         bgpopt = (const struct bgp_opt *)(opt + i);
         opt_type = GET_U_1(bgpopt->bgpopt_type);
-        opt_len = GET_U_1(bgpopt->bgpopt_len);
-        if (BGP_OPT_SIZE + i + opt_len > optslen) {
+        opt_len = extended_opt_params ? GET_BE_U_2(bgpopt->bgpopt_len)
+                                      : GET_U_1(bgpopt->bgpopt_len);
+        if (opt_size + i + opt_len > optslen) {
             ND_PRINT("\n\t     Option %u, length: %u, goes past the end of the options",
                       opt_type, opt_len);
             break;
@@ -2710,7 +2729,7 @@ bgp_open_print(netdissect_options *ndo,
         switch(opt_type) {
 
         case BGP_OPT_CAP:
-            bgp_capabilities_print(ndo, opt + BGP_OPT_SIZE + i,
+            bgp_capabilities_print(ndo, opt + opt_size + i,
                                    opt_len);
             break;
 
@@ -2720,7 +2739,7 @@ bgp_open_print(netdissect_options *ndo,
                opt_type);
                break;
         }
-        i += BGP_OPT_SIZE + opt_len;
+        i += opt_size + opt_len;
     }
     return;
 trunc:
index c70fb77540548ca6e47be2ac2d4379193fff247a..6fb9b9ae1329ad088e5fae8dbd6241d26ec12f4c 100644 (file)
@@ -62,6 +62,7 @@ bgp-link-bw-extcommunity      bgp-link-bw-extcommunity.pcapng bgp-link-bw-extcommunit
 bgp-extended-msg       bgp-extended-msg.pcapng bgp-extended-msg.out    -v
 bgp-enhanced-route-refresh     bgp-enhanced-route-refresh.pcapng       bgp-enhanced-route-refresh.out  -v
 bgp-enhanced-route-refresh-subtype     bgp-enhanced-route-refresh-subtype.pcapng       bgp-enhanced-route-refresh-subtype.out  -v
+bgp-extended-optional-parameters-length        bgp-extended-optional-parameters-length.pcap    bgp-extended-optional-parameters-length.out     -v
 
 # Broadcom tag tests
 brcmtag                brcm-tag.pcap           brcm-tag.out
diff --git a/tests/bgp-extended-optional-parameters-length.out b/tests/bgp-extended-optional-parameters-length.out
new file mode 100644 (file)
index 0000000..3d45b84
--- /dev/null
@@ -0,0 +1,35 @@
+    1  21:07:21.568564 IP6 (class 0xc0, flowlabel 0x67c6e, hlim 1, next-header TCP (6) payload length: 172) 2a02:abc::123.45566 > 2a02:abc::17.179: Flags [P.], cksum 0xdfd3 (correct), seq 83043996:83044136, ack 2441923920, win 127, options [nop,nop,TS val 4087797327 ecr 29756155], length 140: BGP
+       Open Message (1), length: 140
+         Version 4, my AS 174, Holdtime 180s, ID 6.6.6.6
+         Optional parameters (Extended), length: 108
+           Option Capabilities Advertisement (2), length: 6
+             Multiprotocol Extensions (1), length: 4
+               AFI IPv4 (1), SAFI Unicast (1)
+           Option Capabilities Advertisement (2), length: 6
+             Multiprotocol Extensions (1), length: 4
+               AFI IPv6 (2), SAFI Unicast (1)
+           Option Capabilities Advertisement (2), length: 2
+             Route Refresh (Cisco) (128), length: 0
+           Option Capabilities Advertisement (2), length: 2
+             Route Refresh (2), length: 0
+           Option Capabilities Advertisement (2), length: 2
+             Enhanced Route Refresh (70), length: 0
+           Option Capabilities Advertisement (2), length: 6
+             32-Bit AS Number (65), length: 4
+                4 Byte AS 174
+           Option Capabilities Advertisement (2), length: 2
+             BGP Extended Message (6), length: 0
+           Option Capabilities Advertisement (2), length: 10
+             Multiple Paths (69), length: 8
+               AFI IPv4 (1), SAFI Unicast (1), Send/Receive: Receive
+               AFI IPv6 (2), SAFI Unicast (1), Send/Receive: Receive
+           Option Capabilities Advertisement (2), length: 19
+             Unknown (73), length: 17
+               no decoder for Capability 73
+               0x0000:  0f65 7869 7431 2d64 6562 6961 6e2d 3131
+               0x0010:  00
+           Option Capabilities Advertisement (2), length: 4
+             Graceful Restart (64), length: 2
+               Restart Flags: [none], Restart Time 120s
+           Option Capabilities Advertisement (2), length: 16
+             Long-lived Graceful Restart (71), length: 14
diff --git a/tests/bgp-extended-optional-parameters-length.pcap b/tests/bgp-extended-optional-parameters-length.pcap
new file mode 100644 (file)
index 0000000..8061e36
Binary files /dev/null and b/tests/bgp-extended-optional-parameters-length.pcap differ