]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Fix BGP Route Target Membership NLRI prefix decoding 854/head
authorEamon Doyle <[email protected]>
Wed, 1 Apr 2020 14:25:39 +0000 (07:25 -0700)
committerBill Fenner <[email protected]>
Fri, 22 May 2020 15:03:00 +0000 (08:03 -0700)
As described in RFC4684, prefix lengths of 0 and
32-96 are all valid.  Introduce bgp_rt_prefix_print()
to print partial route targets.

print-bgp.c
tests/TESTLIST
tests/bgp-rt-prefix.out [new file with mode: 0644]
tests/bgp-rt-prefix.pcap [new file with mode: 0644]

index 9f6b5f21fe0f0cf56870bcdd976403de0693b23a..5b6922277ac2acbe35e29384d3f8f81668cb340d 100644 (file)
@@ -905,13 +905,101 @@ bgp_extended_community_print(netdissect_options *ndo,
     }
 }
 
+/*
+ * RFC4684 (Section 4)/RFC2858 (Section 4).
+ * RTC membership prefix is structured as follows
+ * [prefix-len] [origin-as] [route-target]
+ * The route-target is encoded as RT ext-comms.
+ * Prefix-len may be 0, 32..96
+ *
+ * Note that pptr is not packet data - it is
+ * a buffer owned by our caller - therefore GET_*
+ * macros can not be used.
+ */
+static char *
+bgp_rt_prefix_print(netdissect_options *ndo,
+                    const u_char *pptr,
+                    u_int plen)
+{
+    /* allocate space for the largest possible string */
+    char rtc_prefix_in_hex[20] = "";
+    u_int rtc_prefix_in_hex_len = 0;
+    static char output[60]; /* max response string */
+    uint16_t ec_type = 0;
+    u_int octet_count;
+    u_int i;
+
+    if (plen == 0) {
+        snprintf(output, sizeof(output), "route-target: 0:0/0");
+        return (output);
+    }
+
+    /* hex representation of the prefix */
+    octet_count = (plen+7)/8;
+    for (i=0; i<octet_count; i++) {
+        rtc_prefix_in_hex_len += snprintf(rtc_prefix_in_hex+rtc_prefix_in_hex_len,
+                                sizeof(rtc_prefix_in_hex)-rtc_prefix_in_hex_len,
+                                "%02x%s", *(pptr+i),
+                                ((i%2 == 1) && (i<octet_count-1)) ? " " : "");
+            }
+
+    if (plen < 16) {
+       /*
+        * The prefix is too short to include the full ext-comm type,
+        * so we have no way to parse it further.
+        */
+        snprintf(output, sizeof(output), "route-target: partial-type: (%s/%d)",
+                 rtc_prefix_in_hex, plen);
+        return (output);
+    }
+
+    /*
+     * get the ext-comm type
+     * Note: pptr references a static 8 octet buffer with unused bits set to 0,
+     * hense EXTRACT_*() macros are safe.
+     */
+    ec_type = EXTRACT_BE_U_2(pptr);
+    switch (ec_type) {
+    case BGP_EXT_COM_RT_0:
+        /* 2-byte-AS:number fmt */
+        snprintf(output, sizeof(output), "route-target: %u:%u/%d (%s)",
+                 EXTRACT_BE_U_2(pptr+2),
+                 EXTRACT_BE_U_4(pptr+4),
+                 plen, rtc_prefix_in_hex);
+        break;
+
+    case BGP_EXT_COM_RT_1:
+        /* IP-address:AS fmt */
+        snprintf(output, sizeof(output), "route-target: %u.%u.%u.%u:%u/%d (%s)",
+                 *(pptr+2), *(pptr+3), *(pptr+4), *(pptr+5),
+                 EXTRACT_BE_U_2(pptr+6), plen, rtc_prefix_in_hex);
+        break;
+
+    case BGP_EXT_COM_RT_2:
+        /* 4-byte-AS:number fmt */
+        snprintf(output, sizeof(output), "route-target: %s:%u/%d (%s)",
+                 as_printf(ndo, astostr, sizeof(astostr), EXTRACT_BE_U_4(pptr+2)),
+                 EXTRACT_BE_U_2(pptr+6), plen, rtc_prefix_in_hex);
+        break;
+
+    default:
+        snprintf(output, sizeof(output), "route target: unknown-type(%04x) (%s/%d)",
+                 ec_type,
+                 rtc_prefix_in_hex, plen);
+        break;
+    }
+    return (output);
+}
+
 /* RFC 4684 */
 static int
 decode_rt_routing_info(netdissect_options *ndo,
                        const u_char *pptr)
 {
+    uint8_t route_target[8];
     u_int plen;
     char asbuf[sizeof(astostr)]; /* bgp_vpn_rd_print() overwrites astostr */
+    u_int num_octets;
 
     /* NLRI "prefix length" from RFC 2858 Section 4. */
     ND_TCHECK_1(pptr);
@@ -938,19 +1026,29 @@ decode_rt_routing_info(netdissect_options *ndo,
 
     plen -= 32; /* adjust prefix length */
 
-    /* An extended community is 8 octets, so the remaining prefix
-     * length must be 64.
-     */
-    if (64 != plen) {
-        ND_PRINT("\n\t    (illegal prefix length)");
+    if (64 < plen) {
+        ND_PRINT("\n\t      (illegal prefix length)");
         return -1;
     }
-    ND_TCHECK_LEN(pptr + 5, 8);
-    ND_PRINT("\n\t      origin AS: %s, route target ", asbuf);
-    bgp_extended_community_print(ndo, pptr + 5);
 
-    return 5 + 8;
+    /* From now on (plen + 7) / 8 evaluates to { 0, 1, 2, ..., 8 }
+     * and gives the number of octets in the variable-length "route
+     * target" field inside this NLRI "prefix". Look for it.
+     */
+    memset(&route_target, 0, sizeof(route_target));
+    num_octets = (plen + 7) / 8;
+    ND_TCHECK_LEN(pptr[5], num_octets);
+    memcpy(&route_target, &pptr[5], num_octets);
+    /* If mask-len is not on octet boundary, ensure all extra bits are 0 */
+    if (plen % 8) {
+        ((u_char *)&route_target)[num_octets - 1] &=
+            ((0xff00 >> (plen % 8)) & 0xff);
+    }
+    ND_PRINT("\n\t      origin AS: %s, %s",
+             asbuf,
+             bgp_rt_prefix_print(ndo, (u_char *)&route_target, plen));
 
+    return 5 + num_octets;
 trunc:
     return -2;
 }
index f9e5981801a18b964a4dace0e69c9ec2961413fa..5af439ae25b86b16430c5bb9ff56e6c4592e4eb3 100644 (file)
@@ -33,6 +33,7 @@ bgp-lu-multiple-labels bgp-lu-multiple-labels.pcap bgp-lu-multiple-labels.out -v
 bgp-evpn       bgp-evpn.pcap           bgp-evpn.out            -v
 bgp-llgr       bgp-evpn.pcap           bgp-llgr.out            -v
 bgp-encap      bgp-encap.pcap          bgp-encap.out           -v
+bgp-rt-prefix  bgp-rt-prefix.pcap      bgp-rt-prefix.out       -v
 
 # Broadcom tag tests
 brcmtag                brcm-tag.pcap           brcm-tag.out
diff --git a/tests/bgp-rt-prefix.out b/tests/bgp-rt-prefix.out
new file mode 100644 (file)
index 0000000..0641a97
--- /dev/null
@@ -0,0 +1,89 @@
+    1  15:01:45.841851 IP (tos 0x0, ttl 64, id 62521, offset 0, flags [DF], proto TCP (6), length 110)
+    1.0.0.2.42195 > 1.0.0.1.179: Flags [P.], cksum 0x6f82 (correct), seq 1362195181:1362195239, ack 648591571, win 58, options [nop,nop,TS val 2630416124 ecr 2630387382], length 58: BGP
+       Update Message (2), length: 58
+         Origin (1), length: 1, Flags [T]: EGP
+         AS Path (2), length: 4, Flags [T]: 200 
+         Next Hop (3), length: 4, Flags [T]: 0.0.0.0
+         Multi-Protocol Reach NLRI (14), length: 14, Flags [O]: 
+           AFI: IPv4 (1), vendor specific SAFI: Route Target Routing Information (132)
+           nexthop: 1.0.0.2, nh-length: 4, no SNPA
+             origin AS: 22, route-target: 0:0/0
+    2  15:01:45.887255 IP (tos 0xc0, ttl 1, id 16100, offset 0, flags [DF], proto TCP (6), length 52)
+    1.0.0.1.179 > 1.0.0.2.42195: Flags [.], cksum 0x0391 (correct), ack 58, win 57, options [nop,nop,TS val 2630416135 ecr 2630416124], length 0
+    3  15:01:45.887452 IP (tos 0x0, ttl 64, id 62522, offset 0, flags [DF], proto TCP (6), length 176)
+    1.0.0.2.42195 > 1.0.0.1.179: Flags [P.], cksum 0xeffc (correct), seq 58:182, ack 1, win 58, options [nop,nop,TS val 2630416136 ecr 2630416135], length 124: BGP
+       Update Message (2), length: 60
+         Origin (1), length: 1, Flags [T]: EGP
+         AS Path (2), length: 4, Flags [T]: 200 
+         Next Hop (3), length: 4, Flags [T]: 0.0.0.0
+         Multi-Protocol Reach NLRI (14), length: 16, Flags [O]: 
+           AFI: IPv4 (1), vendor specific SAFI: Route Target Routing Information (132)
+           nexthop: 1.0.0.2, nh-length: 4, no SNPA
+             origin AS: 22, route-target: 0:0/16 (0002)
+       Update Message (2), length: 64
+         Origin (1), length: 1, Flags [T]: EGP
+         AS Path (2), length: 4, Flags [T]: 200 
+         Next Hop (3), length: 4, Flags [T]: 0.0.0.0
+         Multi-Protocol Reach NLRI (14), length: 20, Flags [O]: 
+           AFI: IPv4 (1), vendor specific SAFI: Route Target Routing Information (132)
+           nexthop: 1.0.0.2, nh-length: 4, no SNPA
+             origin AS: 22, route-target: 65536:0/48 (0202 0001 0000)
+    4  15:01:45.887461 IP (tos 0xc0, ttl 1, id 16101, offset 0, flags [DF], proto TCP (6), length 52)
+    1.0.0.1.179 > 1.0.0.2.42195: Flags [.], cksum 0x0308 (correct), ack 182, win 57, options [nop,nop,TS val 2630416136 ecr 2630416136], length 0
+    5  15:01:45.902997 IP (tos 0x0, ttl 64, id 62523, offset 0, flags [DF], proto TCP (6), length 118)
+    1.0.0.2.42195 > 1.0.0.1.179: Flags [P.], cksum 0xf60d (correct), seq 182:248, ack 1, win 58, options [nop,nop,TS val 2630416139 ecr 2630416136], length 66: BGP
+       Update Message (2), length: 66
+         Origin (1), length: 1, Flags [T]: EGP
+         AS Path (2), length: 4, Flags [T]: 200 
+         Next Hop (3), length: 4, Flags [T]: 0.0.0.0
+         Multi-Protocol Reach NLRI (14), length: 22, Flags [O]: 
+           AFI: IPv4 (1), vendor specific SAFI: Route Target Routing Information (132)
+           nexthop: 1.0.0.2, nh-length: 4, no SNPA
+             origin AS: 22, route-target: 1:65537/64 (0002 0001 0001 0001)
+    6  15:01:45.903022 IP (tos 0xc0, ttl 1, id 16102, offset 0, flags [DF], proto TCP (6), length 52)
+    1.0.0.1.179 > 1.0.0.2.42195: Flags [.], cksum 0x02c0 (correct), ack 248, win 57, options [nop,nop,TS val 2630416139 ecr 2630416139], length 0
+    7  15:01:45.922092 IP (tos 0x0, ttl 64, id 62524, offset 0, flags [DF], proto TCP (6), length 118)
+    1.0.0.2.42195 > 1.0.0.1.179: Flags [P.], cksum 0x6d25 (correct), seq 248:314, ack 1, win 58, options [nop,nop,TS val 2630416144 ecr 2630416139], length 66: BGP
+       Update Message (2), length: 66
+         Origin (1), length: 1, Flags [T]: EGP
+         AS Path (2), length: 4, Flags [T]: 200 
+         Next Hop (3), length: 4, Flags [T]: 0.0.0.0
+         Multi-Protocol Reach NLRI (14), length: 22, Flags [O]: 
+           AFI: IPv4 (1), vendor specific SAFI: Route Target Routing Information (132)
+           nexthop: 1.0.0.2, nh-length: 4, no SNPA
+             origin AS: 22, route-target: 100000:65535/64 (0202 0001 86a0 ffff)
+    8  15:01:45.922106 IP (tos 0xc0, ttl 1, id 16103, offset 0, flags [DF], proto TCP (6), length 52)
+    1.0.0.1.179 > 1.0.0.2.42195: Flags [.], cksum 0x0274 (correct), ack 314, win 57, options [nop,nop,TS val 2630416144 ecr 2630416144], length 0
+    9  15:01:45.945988 IP (tos 0x0, ttl 64, id 62525, offset 0, flags [DF], proto TCP (6), length 106)
+    1.0.0.2.42195 > 1.0.0.1.179: Flags [P.], cksum 0x00d3 (correct), seq 314:368, ack 1, win 58, options [nop,nop,TS val 2630416150 ecr 2630416144], length 54: BGP
+       Update Message (2), length: 54
+         Origin (1), length: 1, Flags [T]: EGP
+         AS Path (2), length: 4, Flags [T]: 200 
+         Next Hop (3), length: 4, Flags [T]: 0.0.0.0
+         Multi-Protocol Unreach NLRI (15), length: 10, Flags [O]: 
+           AFI: IPv4 (1), vendor specific SAFI: Route Target Routing Information (132)
+             origin AS: 23, route-target: 0.0.0.0:0/16 (0102)
+   10  15:01:45.946014 IP (tos 0xc0, ttl 1, id 16104, offset 0, flags [DF], proto TCP (6), length 52)
+    1.0.0.1.179 > 1.0.0.2.42195: Flags [.], cksum 0x0232 (correct), ack 368, win 57, options [nop,nop,TS val 2630416150 ecr 2630416150], length 0
+   11  15:01:45.972778 IP (tos 0x0, ttl 64, id 62526, offset 0, flags [DF], proto TCP (6), length 111)
+    1.0.0.2.42195 > 1.0.0.1.179: Flags [P.], cksum 0x1757 (correct), seq 368:427, ack 1, win 58, options [nop,nop,TS val 2630416157 ecr 2630416150], length 59: BGP
+       Update Message (2), length: 59
+         Origin (1), length: 1, Flags [T]: EGP
+         AS Path (2), length: 4, Flags [T]: 200 
+         Next Hop (3), length: 4, Flags [T]: 0.0.0.0
+         Multi-Protocol Unreach NLRI (15), length: 15, Flags [O]: 
+           AFI: IPv4 (1), vendor specific SAFI: Route Target Routing Information (132)
+             origin AS: 23, route-target: 1.2.3.4:57344/51 (0102 0102 0304 e0)
+   12  15:01:45.972789 IP (tos 0xc0, ttl 1, id 16105, offset 0, flags [DF], proto TCP (6), length 52)
+    1.0.0.1.179 > 1.0.0.2.42195: Flags [.], cksum 0x01e9 (correct), ack 427, win 57, options [nop,nop,TS val 2630416157 ecr 2630416157], length 0
+   13  15:01:45.997647 IP (tos 0x0, ttl 64, id 62527, offset 0, flags [DF], proto TCP (6), length 112)
+    1.0.0.2.42195 > 1.0.0.1.179: Flags [P.], cksum 0xf5ff (correct), seq 427:487, ack 1, win 58, options [nop,nop,TS val 2630416163 ecr 2630416157], length 60: BGP
+       Update Message (2), length: 60
+         Origin (1), length: 1, Flags [T]: EGP
+         AS Path (2), length: 4, Flags [T]: 200 
+         Next Hop (3), length: 4, Flags [T]: 0.0.0.0
+         Multi-Protocol Unreach NLRI (15), length: 16, Flags [O]: 
+           AFI: IPv4 (1), vendor specific SAFI: Route Target Routing Information (132)
+             origin AS: 23, route-target: 1.2.3.4:65535/64 (0102 0102 0304 ffff)
+   14  15:01:45.997673 IP (tos 0xc0, ttl 1, id 16106, offset 0, flags [DF], proto TCP (6), length 52)
+    1.0.0.1.179 > 1.0.0.2.42195: Flags [.], cksum 0x01a1 (correct), ack 487, win 57, options [nop,nop,TS val 2630416163 ecr 2630416163], length 0
diff --git a/tests/bgp-rt-prefix.pcap b/tests/bgp-rt-prefix.pcap
new file mode 100644 (file)
index 0000000..7a1efd2
Binary files /dev/null and b/tests/bgp-rt-prefix.pcap differ