return 4;
}
+/*
+ * The only way to know that a BGP UPDATE message is using add path is
+ * by checking if the capability is in the OPEN message which we may have missed.
+ * So this function checks if it is possible that the update could contain add path
+ * and if so it checks that standard BGP doesn't make sense.
+ */
+
+static int
+check_add_path(const u_char *pptr, u_int length, u_int max_prefix_length) {
+
+ u_int offset, prefix_length;
+ if (length < 5) {
+ return 0;
+ }
+
+ /* check if it could be add path */
+ for(offset = 0; offset < length;) {
+ offset += 4;
+ prefix_length = pptr[offset];
+ /*
+ * Add 4 to cover the path id
+ * and check the prefix length isn't greater than 32/128.
+ */
+ if (prefix_length > max_prefix_length) {
+ return 0;
+ }
+ /* Add 1 for the prefix_length byte and prefix_length to cover the address */
+ offset += 1 + ((prefix_length + 7) / 8);
+ }
+ /* check we haven't gone past the end of the section */
+ if (offset > length) {
+ return 0;
+ }
+
+ /* check it's not standard BGP */
+ for(offset = 0; offset < length; ) {
+ prefix_length = pptr[offset];
+ /*
+ * If the prefix_length is zero (0.0.0.0/0)
+ * and since it's not the only address (length >= 5)
+ * then it is add-path
+ */
+ if (prefix_length < 1 || prefix_length > max_prefix_length) {
+ return 1;
+ }
+ offset += 1 + ((prefix_length + 7) / 8);
+ }
+ if (offset > length) {
+ return 1;
+ }
+
+ /* assume not add-path by default */
+ return 0;
+}
+
+
static int
bgp_attr_print(netdissect_options *ndo,
u_int atype, const u_char *pptr, u_int len)
const u_char *tptr;
char buf[MAXHOSTNAMELEN + 100];
int as_size;
+ int add_path4, add_path6, path_id;
tptr = pptr;
tlen=len;
ND_PRINT((ndo, ", no SNPA"));
}
+ add_path4 = check_add_path(tptr, (len-(tptr - pptr)), 32);
+ add_path6 = check_add_path(tptr, (len-(tptr - pptr)), 128);
+
while (tptr < pptr + len) {
switch (af<<8 | safi) {
case (AFNUM_INET<<8 | SAFNUM_UNICAST):
case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
+ if (add_path4) {
+ path_id = EXTRACT_32BITS(tptr);
+ tptr += 4;
+ }
advance = decode_prefix4(ndo, tptr, len, buf, sizeof(buf));
if (advance == -1)
ND_PRINT((ndo, "\n\t (illegal prefix length)"));
break; /* bytes left, but not enough */
else
ND_PRINT((ndo, "\n\t %s", buf));
+ if (add_path4) {
+ ND_PRINT((ndo, " Path Id: %d", path_id));
+ }
break;
case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
advance = decode_labeled_prefix4(ndo, tptr, len, buf, sizeof(buf));
case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
+ if (add_path6) {
+ path_id = EXTRACT_32BITS(tptr);
+ tptr += 4;
+ }
advance = decode_prefix6(ndo, tptr, len, buf, sizeof(buf));
if (advance == -1)
ND_PRINT((ndo, "\n\t (illegal prefix length)"));
break; /* bytes left, but not enough */
else
ND_PRINT((ndo, "\n\t %s", buf));
+ if (add_path6) {
+ ND_PRINT((ndo, " Path Id: %d", path_id));
+ }
break;
case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
advance = decode_labeled_prefix6(ndo, tptr, len, buf, sizeof(buf));
tptr += 3;
+ add_path4 = check_add_path(tptr, (len-(tptr - pptr)), 32);
+ add_path6 = check_add_path(tptr, (len-(tptr - pptr)), 128);
+
while (tptr < pptr + len) {
switch (af<<8 | safi) {
case (AFNUM_INET<<8 | SAFNUM_UNICAST):
case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
+ if (add_path4) {
+ path_id = EXTRACT_32BITS(tptr);
+ tptr += 4;
+ }
advance = decode_prefix4(ndo, tptr, len, buf, sizeof(buf));
if (advance == -1)
ND_PRINT((ndo, "\n\t (illegal prefix length)"));
break; /* bytes left, but not enough */
else
ND_PRINT((ndo, "\n\t %s", buf));
+ if (add_path4) {
+ ND_PRINT((ndo, " Path Id: %d", path_id));
+ }
break;
case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
advance = decode_labeled_prefix4(ndo, tptr, len, buf, sizeof(buf));
case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
+ if (add_path6) {
+ path_id = EXTRACT_32BITS(tptr);
+ tptr += 4;
+ }
advance = decode_prefix6(ndo, tptr, len, buf, sizeof(buf));
if (advance == -1)
ND_PRINT((ndo, "\n\t (illegal prefix length)"));
break; /* bytes left, but not enough */
else
ND_PRINT((ndo, "\n\t %s", buf));
+ if (add_path6) {
+ ND_PRINT((ndo, " Path Id: %d", path_id));
+ }
break;
case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
advance = decode_labeled_prefix6(ndo, tptr, len, buf, sizeof(buf));
const struct bgp *bgp_header;
const u_char *p;
int withdrawn_routes_len;
+ char buf[MAXHOSTNAMELEN + 100];
+ int wpfx;
int len;
int i;
+ int add_path;
+ int path_id;
ND_TCHECK_LEN(dat, BGP_SIZE);
if (length < BGP_SIZE)
withdrawn_routes_len = EXTRACT_BE_U_2(p);
p += 2;
length -= 2;
- if (withdrawn_routes_len) {
+ if (withdrawn_routes_len > 1) {
/*
* Without keeping state from the original NLRI message,
* it's not possible to tell if this a v4 or v6 route,
* so only try to decode it if we're not v6 enabled.
- */
+ */
ND_TCHECK_LEN(p, withdrawn_routes_len);
if (length < withdrawn_routes_len)
goto trunc;
- ND_PRINT((ndo, "\n\t Withdrawn routes: %d bytes", withdrawn_routes_len));
- p += withdrawn_routes_len;
- length -= withdrawn_routes_len;
- }
+
+ ND_PRINT((ndo, "\n\t Withdrawn routes:"));
+ add_path = check_add_path(p, withdrawn_routes_len, 32);
+ while(withdrawn_routes_len > 0) {
+ if (add_path) {
+ path_id = EXTRACT_32BITS(p);
+ p += 4;
+ length -= 4;
+ withdrawn_routes_len -= 4;
+ }
+ wpfx = decode_prefix4(ndo, p, withdrawn_routes_len, buf, sizeof(buf));
+ if (wpfx == -1) {
+ ND_PRINT((ndo, "\n\t (illegal prefix length)"));
+ break;
+ } else if (wpfx == -2)
+ goto trunc;
+ else if (wpfx == -3)
+ goto trunc; /* bytes left, but not enough */
+ else {
+ ND_PRINT((ndo, "\n\t %s", buf));
+ if (add_path) {
+ ND_PRINT((ndo, " Path Id: %d", path_id));
+ }
+ p += wpfx;
+ length -= wpfx;
+ withdrawn_routes_len -= wpfx;
+ }
+ }
+ } else {
+ p += withdrawn_routes_len;
+ length -= withdrawn_routes_len;
+ }
ND_TCHECK_2(p);
if (length < 2)
}
if (length) {
- /*
- * XXX - what if they're using the "Advertisement of
- * Multiple Paths in BGP" feature:
- *
- * https://datatracker.ietf.org/doc/draft-ietf-idr-add-paths/
- *
- * http://tools.ietf.org/html/draft-ietf-idr-add-paths-06
- */
+ add_path = check_add_path(p, length, 32);
ND_PRINT((ndo, "\n\t Updated routes:"));
- while (length) {
- char buf[MAXHOSTNAMELEN + 100];
+ while (length > 0) {
+ if (add_path) {
+ path_id = EXTRACT_32BITS(p);
+ p += 4;
+ length -= 4;
+ }
i = decode_prefix4(ndo, p, length, buf, sizeof(buf));
if (i == -1) {
ND_PRINT((ndo, "\n\t (illegal prefix length)"));
else if (i == -3)
goto trunc; /* bytes left, but not enough */
else {
- ND_PRINT((ndo, "\n\t %s", buf));
- p += i;
- length -= i;
+ ND_PRINT((ndo, "\n\t %s", buf));
+ if (add_path) {
+ ND_PRINT((ndo, " Path Id: %d", path_id));
+ }
+ p += i;
+ length -= i;
}
}
}
bgp-aigp bgp-aigp.pcap bgp-aigp.out -v
bgp-large-community bgp-large-community.pcap bgp-large-community.out -v
bgp-shutdown-communication bgp-shutdown-communication.pcap bgp-shutdown-communication.out -v
+bgp-addpath bgp-addpath.pcap bgp-addpath.out -v
# EAP tests
eapon1 eapon1.pcap eapon1.out
--- /dev/null
+IP truncated-ip - 38 bytes missing! (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto TCP (6), length 309)
+ 127.0.0.1.179 > 127.0.0.1.80: Flags [S], seq 0:269, win 8192, length 269: BGP
+ Update Message (2), length: 231
+ Withdrawn routes:
+ 8.2.0.0/24 Path Id: 20
+ 8.2.1.0/24 Path Id: 21
+ Origin (1), length: 1, Flags [T]: EGP
+ Next Hop (3), length: 0, Flags [T]: invalid len
+ AS Path (2), length: 6, Flags [T]: 100 200
+ Multi-Protocol Reach NLRI (14), length: 25, Flags [T]:
+ AFI: IPv4 (1), SAFI: Unicast (1)
+ nexthop: 1.2.3.4, nh-length: 4, no SNPA
+ 120.4.0.0/24 Path Id: 40
+ 120.4.1.0/24 Path Id: 41
+ Multi-Protocol Unreach NLRI (15), length: 19, Flags [T]:
+ AFI: IPv4 (1), SAFI: Unicast (1)
+ 32.45.0.0/24 Path Id: 700
+ 32.45.1.0/24 Path Id: 701
+ Multi-Protocol Reach NLRI (14), length: 61, Flags [T]:
+ AFI: IPv6 (2), SAFI: Unicast (1)
+ nexthop: 2000:0:0:40::1, nh-length: 16, no SNPA
+ 2002::1400:0/120 Path Id: 1
+ 2002::1400:100/120 Path Id: 2
+ Multi-Protocol Unreach NLRI (15), length: 43, Flags [T]:
+ AFI: IPv6 (2), SAFI: Unicast (1)
+ 2002::2800:0/120 Path Id: 100
+ 2002::2800:100/120 Path Id: 101
+ Updated routes:
+ 6.2.0.0/24 Path Id: 10
+ 6.2.1.0/24 Path Id: 11
0x0040: 0074 0040 4100 0049 8a00 0002 2500 1122
0x0050: 10
Update Message (2), length: 202
- Withdrawn routes: 16 bytes
- Unknown Attribute (0), length: 0, Flags [+4]:
- no Attribute 0 decoder
- Unknown Attribute (100), length: 192[|BGP]
+ Withdrawn routes:
+ 0.0.0.0/0
+ (illegal prefix length)
+ Origin (1), length: 2, Flags [+1]: invalid len
+ 0x0000: 4002
+ Attribute Set (128), length: 4
+ Origin AS: 67108864
+ Unknown Attribute (64), length: 5
+ no Attribute 64 decoder
+ 0x0000: 0400 0000 64
+ Extended Community (16), length: 8, Flags [OT]:
+ target (0x0002), Flags [none]: 19338:650 (= 0.0.2.138)
+ 0x0000: 0002 4b8a 0000 028a
+ Cluster List (10), length: 4, Flags [O]: 172.17.0.0
+ 0x0000: ac11 0000
+ Originator ID (9), length: 4, Flags [O]: 172.17.0.5
+ 0x0000: ac11 0005
+ Multi-Protocol Reach NLRI (14), length: 129, Flags [OE]:
+ AFI: IPv4 (1), SAFI: labeled VPN Unicast (128)
+ nexthop: RD: 0:0 (= 0.0.0.0), 172.17.0.5, nh-length: 12, no SNPA
+ RD: 18826:650 (= 0.0.2.138), 172.17.33.0/27, label:1029 (bottom)
+ RD: 18826:650 (= 0.0.2.138), 172.17.105.0/28, label:1029 (bottom)
+ RD: 18826:650 (= 0.0.2.138), 172.17.105.32/28, label:1029 (bottom)
+ RD: 18826:650 (= 0.0.2.138), 172.17.105.48/28, label:1029 (bottom)
+ RD: 18826:650 (= 0.0.2.138), 172.17.192.128/28, label:1029 (bottom)
+ RD: 18826:650 (= 0.0.2.138), 172.17.192.144/28, label:1029 (bottom)
+ RD: 18826:650 (= 0.0.2.138), 172.17.30.64/26, label:1034 (bottom)
+ 0x0000: 0001 800c 0000 0000 0000 0000 ac11 0005
+ 0x0010: 0073 0040 5100 0049 8a00 0002 8aac 1121
+ 0x0020: 0074 0040 5100 0049 8a00 0002 8aac 1169
+ 0x0030: 0074 0040 5100 0049 8a00 0002 8aac 1169
+ 0x0040: 2074 0040 5100 0049 8a00 0002 8aac 1169
+ 0x0050: 3074 0040 5100 0049 8a00 0002 8aac 11c0
+ 0x0060: 8074 0040 5100 0049 8a00 0002 8aac 11c0
+ 0x0070: 9072 0040 a100 0049 8a00 0002 8aac 111e
+ 0x0080: 40[|BGP]
Update Message (2), length: 106
Origin (1), length: 1, Flags [T]: Incomplete
0x0000: 02
0x0040: 0074 0040 4100 0049 8a00 0002 2500 1122
0x0050: 10
Update Message (2), length: 202
- Withdrawn routes: 16 bytes
- Unknown Attribute (0), length: 0, Flags [+4]:
- no Attribute 0 decoder
- Unknown Attribute (100), length: 192[|BGP]
+ Withdrawn routes:
+ 0.0.0.0/0
+ (illegal prefix length)
+ Origin (1), length: 2, Flags [+1]: invalid len
+ 0x0000: 4002
+ Attribute Set (128), length: 4
+ Origin AS: 67108864
+ Unknown Attribute (64), length: 5
+ no Attribute 64 decoder
+ 0x0000: 0400 0000 64
+ Extended Community (16), length: 8, Flags [OT]:
+ target (0x0002), Flags [none]: 19338:650 (= 0.0.2.138)
+ 0x0000: 0002 4b8a 0000 028a
+ Cluster List (10), length: 4, Flags [O]: 172.17.0.0
+ 0x0000: ac11 0000
+ Originator ID (9), length: 4, Flags [O]: 172.17.0.5
+ 0x0000: ac11 0005
+ Multi-Protocol Reach NLRI (14), length: 129, Flags [OE]:
+ AFI: IPv4 (1), SAFI: labeled VPN Unicast (128)
+ nexthop: RD: 0:0 (= 0.0.0.0), 172.17.0.5, nh-length: 12, no SNPA
+ RD: 18826:650 (= 0.0.2.138), 172.17.33.0/27, label:1029 (bottom)
+ RD: 18826:650 (= 0.0.2.138), 172.17.105.0/28, label:1029 (bottom)
+ RD: 18826:650 (= 0.0.2.138), 172.17.105.32/28, label:1029 (bottom)
+ RD: 18826:650 (= 0.0.2.138), 172.17.105.48/28, label:1029 (bottom)
+ RD: 18826:650 (= 0.0.2.138), 172.17.192.128/28, label:1029 (bottom)
+ RD: 18826:650 (= 0.0.2.138), 172.17.192.144/28, label:1029 (bottom)
+ RD: 18826:650 (= 0.0.2.138), 172.17.30.64/26, label:1034 (bottom)
+ 0x0000: 0001 800c 0000 0000 0000 0000 ac11 0005
+ 0x0010: 0073 0040 5100 0049 8a00 0002 8aac 1121
+ 0x0020: 0074 0040 5100 0049 8a00 0002 8aac 1169
+ 0x0030: 0074 0040 5100 0049 8a00 0002 8aac 1169
+ 0x0040: 2074 0040 5100 0049 8a00 0002 8aac 1169
+ 0x0050: 3074 0040 5100 0049 8a00 0002 8aac 11c0
+ 0x0060: 8074 0040 5100 0049 8a00 0002 8aac 11c0
+ 0x0070: 9072 0040 a100 0049 8a00 0002 8aac 111e
+ 0x0080: 40[|BGP]
Update Message (2), length: 106
Origin (1), length: 1, Flags [T]: Incomplete
0x0000: 02
IP (tos 0xc, ttl 254, id 21263, offset 0, flags [rsvd], proto TCP (6), length 517, bad cksum 8e15 (->99c9)!)
241.0.93.20.179 > 255.247.0.1.200: Flags [none], seq 2146691977:2146692450, win 56026, options [unknown-161,eol], length 473: BGP
Update Message (2), length: 45
- Withdrawn routes: 3 bytes
+ Withdrawn routes:
+ 255.123.0.0/16
Attribute Set (128), length: 7, Flags [OTPE+f]:
Origin AS: 148
Multi-Protocol Reach NLRI (14), length: 71, Flags [T+6]:
IP (tos 0x0, ttl 254, id 40207, offset 0, flags [+, DF, rsvd], proto TCP (6), length 296, bad cksum 8e15 (->3eaa)!)
241.0.32.19.179 > 239.0.0.1.0: Flags [none], seq 2146695561:2146695813, win 56026, options [unknown-161,eol], length 252: BGP
Update Message (2), length: 45
- Withdrawn routes: 3 bytes
+ Withdrawn routes:
+ 24.13.0.0/16
Attribute Set (128), length: 7, Flags [OTPE+f]:
Origin AS: 4067
Origin (1), length: 1EGP
IP (tos 0xc, ttl 254, id 21263, offset 0, flags [rsvd], proto TCP (6), length 60165, bad cksum 8e15 (->9eb8)!)
241.0.128.19.179 > 239.8.0.1.0: Flags [none], seq 2146695561:2146755682, win 56026, options [unknown-161,eol], length 60121: BGP
Update Message (2), length: 45
- Withdrawn routes: 3 bytes
+ Withdrawn routes:
+ 255.144.0.0/12
Attribute Set (128), length: 7, Flags [OTPE+f]:
Origin AS: 0
Multi-Protocol Unreach NLRI (15), length: 227, Flags [T+6]:
Route-Type: Unknown (0), length: 0[|BGP] [|BGP]
Update Message (2), length: 45[|BGP] [|BGP]
Update Message (2), length: 45
- Withdrawn routes: 3 bytes
+ Withdrawn routes:
+ 255.112.0.0/12
Attribute Set (128), length: 7, Flags [OTPE+f]:
Origin AS: 0
Multi-Protocol Reach NLRI (14), length: 227, Flags [T+6]:
End-of-Rib Marker (empty NLRI)
0x0000: 0001 80
Update Message (2), length: 30
- Withdrawn routes: 1 bytes
Unknown Attribute (0), length: 3, Flags [+f]:
no Attribute 0 decoder
0x0000: 0001 05[|BGP]