]> The Tcpdump Group git mirrors - tcpdump/blob - print-bgp.c
EIGRP: Modernize packet parsing style.
[tcpdump] / print-bgp.c
1 /*
2 * Copyright (C) 1999 WIDE Project.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the project nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * Extensively modified by Hannes Gredler (hannes@gredler.at) for more
30 * complete BGP support.
31 */
32
33 /* \summary: Border Gateway Protocol (BGP) printer */
34
35 /* specification: RFC 4271 */
36
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40
41 #include "netdissect-stdinc.h"
42
43 #include <stdio.h>
44 #include <string.h>
45
46 #include "netdissect.h"
47 #include "addrtoname.h"
48 #include "extract.h"
49 #include "af.h"
50 #include "l2vpn.h"
51
52 struct bgp {
53 nd_byte bgp_marker[16];
54 nd_uint16_t bgp_len;
55 nd_uint8_t bgp_type;
56 };
57 #define BGP_SIZE 19 /* unaligned */
58
59 #define BGP_OPEN 1
60 #define BGP_UPDATE 2
61 #define BGP_NOTIFICATION 3
62 #define BGP_KEEPALIVE 4
63 #define BGP_ROUTE_REFRESH 5
64
65 static const struct tok bgp_msg_values[] = {
66 { BGP_OPEN, "Open"},
67 { BGP_UPDATE, "Update"},
68 { BGP_NOTIFICATION, "Notification"},
69 { BGP_KEEPALIVE, "Keepalive"},
70 { BGP_ROUTE_REFRESH, "Route Refresh"},
71 { 0, NULL}
72 };
73
74 struct bgp_open {
75 nd_byte bgpo_marker[16];
76 nd_uint16_t bgpo_len;
77 nd_uint8_t bgpo_type;
78 nd_uint8_t bgpo_version;
79 nd_uint16_t bgpo_myas;
80 nd_uint16_t bgpo_holdtime;
81 nd_uint32_t bgpo_id;
82 nd_uint8_t bgpo_optlen;
83 /* options should follow */
84 };
85 #define BGP_OPEN_SIZE 29 /* unaligned */
86
87 struct bgp_opt {
88 nd_uint8_t bgpopt_type;
89 nd_uint8_t bgpopt_len;
90 /* variable length */
91 };
92 #define BGP_OPT_SIZE 2 /* some compilers may pad to 4 bytes */
93 #define BGP_CAP_HEADER_SIZE 2 /* some compilers may pad to 4 bytes */
94
95 struct bgp_notification {
96 nd_byte bgpn_marker[16];
97 nd_uint16_t bgpn_len;
98 nd_uint8_t bgpn_type;
99 nd_uint8_t bgpn_major;
100 nd_uint8_t bgpn_minor;
101 };
102 #define BGP_NOTIFICATION_SIZE 21 /* unaligned */
103
104 struct bgp_route_refresh {
105 nd_byte bgp_marker[16];
106 nd_uint16_t len;
107 nd_uint8_t type; /* No padding after this; afi is, in fact, not aligned */
108 nd_uint16_t afi;
109 nd_uint8_t res;
110 nd_uint8_t safi;
111 };
112 #define BGP_ROUTE_REFRESH_SIZE 23
113
114 #define bgp_attr_lenlen(flags, p) \
115 (((flags) & 0x10) ? 2U : 1U)
116 #define bgp_attr_len(flags, p) \
117 (((flags) & 0x10) ? GET_BE_U_2(p) : GET_U_1(p))
118
119 #define BGPTYPE_ORIGIN 1
120 #define BGPTYPE_AS_PATH 2
121 #define BGPTYPE_NEXT_HOP 3
122 #define BGPTYPE_MULTI_EXIT_DISC 4
123 #define BGPTYPE_LOCAL_PREF 5
124 #define BGPTYPE_ATOMIC_AGGREGATE 6
125 #define BGPTYPE_AGGREGATOR 7
126 #define BGPTYPE_COMMUNITIES 8 /* RFC1997 */
127 #define BGPTYPE_ORIGINATOR_ID 9 /* RFC4456 */
128 #define BGPTYPE_CLUSTER_LIST 10 /* RFC4456 */
129 #define BGPTYPE_DPA 11 /* deprecated, draft-ietf-idr-bgp-dpa */
130 #define BGPTYPE_ADVERTISERS 12 /* deprecated RFC1863 */
131 #define BGPTYPE_RCID_PATH 13 /* deprecated RFC1863 */
132 #define BGPTYPE_MP_REACH_NLRI 14 /* RFC4760 */
133 #define BGPTYPE_MP_UNREACH_NLRI 15 /* RFC4760 */
134 #define BGPTYPE_EXTD_COMMUNITIES 16 /* RFC4360 */
135 #define BGPTYPE_AS4_PATH 17 /* RFC6793 */
136 #define BGPTYPE_AGGREGATOR4 18 /* RFC6793 */
137 #define BGPTYPE_PMSI_TUNNEL 22 /* RFC6514 */
138 #define BGPTYPE_TUNNEL_ENCAP 23 /* RFC5512 */
139 #define BGPTYPE_TRAFFIC_ENG 24 /* RFC5543 */
140 #define BGPTYPE_IPV6_EXTD_COMMUNITIES 25 /* RFC5701 */
141 #define BGPTYPE_AIGP 26 /* RFC7311 */
142 #define BGPTYPE_PE_DISTINGUISHER_LABEL 27 /* RFC6514 */
143 #define BGPTYPE_ENTROPY_LABEL 28 /* RFC6790 */
144 #define BGPTYPE_LARGE_COMMUNITY 32 /* draft-ietf-idr-large-community-05 */
145 #define BGPTYPE_ATTR_SET 128 /* RFC6368 */
146
147 #define BGP_MP_NLRI_MINSIZE 3 /* End of RIB Marker detection */
148
149 static const struct tok bgp_attr_values[] = {
150 { BGPTYPE_ORIGIN, "Origin"},
151 { BGPTYPE_AS_PATH, "AS Path"},
152 { BGPTYPE_AS4_PATH, "AS4 Path"},
153 { BGPTYPE_NEXT_HOP, "Next Hop"},
154 { BGPTYPE_MULTI_EXIT_DISC, "Multi Exit Discriminator"},
155 { BGPTYPE_LOCAL_PREF, "Local Preference"},
156 { BGPTYPE_ATOMIC_AGGREGATE, "Atomic Aggregate"},
157 { BGPTYPE_AGGREGATOR, "Aggregator"},
158 { BGPTYPE_AGGREGATOR4, "Aggregator4"},
159 { BGPTYPE_COMMUNITIES, "Community"},
160 { BGPTYPE_ORIGINATOR_ID, "Originator ID"},
161 { BGPTYPE_CLUSTER_LIST, "Cluster List"},
162 { BGPTYPE_DPA, "DPA"},
163 { BGPTYPE_ADVERTISERS, "Advertisers"},
164 { BGPTYPE_RCID_PATH, "RCID Path / Cluster ID"},
165 { BGPTYPE_MP_REACH_NLRI, "Multi-Protocol Reach NLRI"},
166 { BGPTYPE_MP_UNREACH_NLRI, "Multi-Protocol Unreach NLRI"},
167 { BGPTYPE_EXTD_COMMUNITIES, "Extended Community"},
168 { BGPTYPE_PMSI_TUNNEL, "PMSI Tunnel"},
169 { BGPTYPE_TUNNEL_ENCAP, "Tunnel Encapsulation"},
170 { BGPTYPE_TRAFFIC_ENG, "Traffic Engineering"},
171 { BGPTYPE_IPV6_EXTD_COMMUNITIES, "IPv6 Extended Community"},
172 { BGPTYPE_AIGP, "Accumulated IGP Metric"},
173 { BGPTYPE_PE_DISTINGUISHER_LABEL, "PE Distinguisher Label"},
174 { BGPTYPE_ENTROPY_LABEL, "Entropy Label"},
175 { BGPTYPE_LARGE_COMMUNITY, "Large Community"},
176 { BGPTYPE_ATTR_SET, "Attribute Set"},
177 { 255, "Reserved for development"},
178 { 0, NULL}
179 };
180
181 #define BGP_AS_SET 1
182 #define BGP_AS_SEQUENCE 2
183 #define BGP_CONFED_AS_SEQUENCE 3 /* draft-ietf-idr-rfc3065bis-01 */
184 #define BGP_CONFED_AS_SET 4 /* draft-ietf-idr-rfc3065bis-01 */
185
186 #define BGP_AS_SEG_TYPE_MIN BGP_AS_SET
187 #define BGP_AS_SEG_TYPE_MAX BGP_CONFED_AS_SET
188
189 static const struct tok bgp_as_path_segment_open_values[] = {
190 { BGP_AS_SEQUENCE, ""},
191 { BGP_AS_SET, "{ "},
192 { BGP_CONFED_AS_SEQUENCE, "( "},
193 { BGP_CONFED_AS_SET, "({ "},
194 { 0, NULL}
195 };
196
197 static const struct tok bgp_as_path_segment_close_values[] = {
198 { BGP_AS_SEQUENCE, ""},
199 { BGP_AS_SET, "}"},
200 { BGP_CONFED_AS_SEQUENCE, ")"},
201 { BGP_CONFED_AS_SET, "})"},
202 { 0, NULL}
203 };
204
205 #define BGP_OPT_AUTH 1
206 #define BGP_OPT_CAP 2
207
208 static const struct tok bgp_opt_values[] = {
209 { BGP_OPT_AUTH, "Authentication Information"},
210 { BGP_OPT_CAP, "Capabilities Advertisement"},
211 { 0, NULL}
212 };
213
214 #define BGP_CAPCODE_MP 1 /* RFC2858 */
215 #define BGP_CAPCODE_RR 2 /* RFC2918 */
216 #define BGP_CAPCODE_ORF 3 /* RFC5291 */
217 #define BGP_CAPCODE_MR 4 /* RFC3107 */
218 #define BGP_CAPCODE_EXT_NH 5 /* RFC5549 */
219 #define BGP_CAPCODE_ML 8 /* RFC8277 */
220 #define BGP_CAPCODE_RESTART 64 /* RFC4724 */
221 #define BGP_CAPCODE_AS_NEW 65 /* RFC6793 */
222 #define BGP_CAPCODE_DYN_CAP 67 /* draft-ietf-idr-dynamic-cap */
223 #define BGP_CAPCODE_MULTISESS 68 /* draft-ietf-idr-bgp-multisession */
224 #define BGP_CAPCODE_ADD_PATH 69 /* RFC7911 */
225 #define BGP_CAPCODE_ENH_RR 70 /* draft-keyur-bgp-enhanced-route-refresh */
226 #define BGP_CAPCODE_LLGR 71 /* draft-uttaro-idr-bgp-persistence-05 */
227 #define BGP_CAPCODE_RR_CISCO 128
228
229 static const struct tok bgp_capcode_values[] = {
230 { BGP_CAPCODE_MP, "Multiprotocol Extensions"},
231 { BGP_CAPCODE_RR, "Route Refresh"},
232 { BGP_CAPCODE_ORF, "Cooperative Route Filtering"},
233 { BGP_CAPCODE_MR, "Multiple Routes to a Destination"},
234 { BGP_CAPCODE_EXT_NH, "Extended Next Hop Encoding"},
235 { BGP_CAPCODE_ML, "Multiple Labels"},
236 { BGP_CAPCODE_RESTART, "Graceful Restart"},
237 { BGP_CAPCODE_AS_NEW, "32-Bit AS Number"},
238 { BGP_CAPCODE_DYN_CAP, "Dynamic Capability"},
239 { BGP_CAPCODE_MULTISESS, "Multisession BGP"},
240 { BGP_CAPCODE_ADD_PATH, "Multiple Paths"},
241 { BGP_CAPCODE_ENH_RR, "Enhanced Route Refresh"},
242 { BGP_CAPCODE_LLGR, "Long-lived Graceful Restart"},
243 { BGP_CAPCODE_RR_CISCO, "Route Refresh (Cisco)"},
244 { 0, NULL}
245 };
246
247 #define BGP_NOTIFY_MAJOR_MSG 1
248 #define BGP_NOTIFY_MAJOR_OPEN 2
249 #define BGP_NOTIFY_MAJOR_UPDATE 3
250 #define BGP_NOTIFY_MAJOR_HOLDTIME 4
251 #define BGP_NOTIFY_MAJOR_FSM 5
252 #define BGP_NOTIFY_MAJOR_CEASE 6
253 #define BGP_NOTIFY_MAJOR_CAP 7
254
255 static const struct tok bgp_notify_major_values[] = {
256 { BGP_NOTIFY_MAJOR_MSG, "Message Header Error"},
257 { BGP_NOTIFY_MAJOR_OPEN, "OPEN Message Error"},
258 { BGP_NOTIFY_MAJOR_UPDATE, "UPDATE Message Error"},
259 { BGP_NOTIFY_MAJOR_HOLDTIME,"Hold Timer Expired"},
260 { BGP_NOTIFY_MAJOR_FSM, "Finite State Machine Error"},
261 { BGP_NOTIFY_MAJOR_CEASE, "Cease"},
262 { BGP_NOTIFY_MAJOR_CAP, "Capability Message Error"},
263 { 0, NULL}
264 };
265
266 /* draft-ietf-idr-cease-subcode-02 */
267 #define BGP_NOTIFY_MINOR_CEASE_MAXPRFX 1
268 /* draft-ietf-idr-shutdown-07 */
269 #define BGP_NOTIFY_MINOR_CEASE_SHUT 2
270 #define BGP_NOTIFY_MINOR_CEASE_RESET 4
271 #define BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN 128
272 static const struct tok bgp_notify_minor_cease_values[] = {
273 { BGP_NOTIFY_MINOR_CEASE_MAXPRFX, "Maximum Number of Prefixes Reached"},
274 { BGP_NOTIFY_MINOR_CEASE_SHUT, "Administrative Shutdown"},
275 { 3, "Peer Unconfigured"},
276 { BGP_NOTIFY_MINOR_CEASE_RESET, "Administrative Reset"},
277 { 5, "Connection Rejected"},
278 { 6, "Other Configuration Change"},
279 { 7, "Connection Collision Resolution"},
280 { 0, NULL}
281 };
282
283 static const struct tok bgp_notify_minor_msg_values[] = {
284 { 1, "Connection Not Synchronized"},
285 { 2, "Bad Message Length"},
286 { 3, "Bad Message Type"},
287 { 0, NULL}
288 };
289
290 static const struct tok bgp_notify_minor_open_values[] = {
291 { 1, "Unsupported Version Number"},
292 { 2, "Bad Peer AS"},
293 { 3, "Bad BGP Identifier"},
294 { 4, "Unsupported Optional Parameter"},
295 { 5, "Authentication Failure"},
296 { 6, "Unacceptable Hold Time"},
297 { 7, "Capability Message Error"},
298 { 0, NULL}
299 };
300
301 static const struct tok bgp_notify_minor_update_values[] = {
302 { 1, "Malformed Attribute List"},
303 { 2, "Unrecognized Well-known Attribute"},
304 { 3, "Missing Well-known Attribute"},
305 { 4, "Attribute Flags Error"},
306 { 5, "Attribute Length Error"},
307 { 6, "Invalid ORIGIN Attribute"},
308 { 7, "AS Routing Loop"},
309 { 8, "Invalid NEXT_HOP Attribute"},
310 { 9, "Optional Attribute Error"},
311 { 10, "Invalid Network Field"},
312 { 11, "Malformed AS_PATH"},
313 { 0, NULL}
314 };
315
316 static const struct tok bgp_notify_minor_fsm_values[] = {
317 { 0, "Unspecified Error"},
318 { 1, "In OpenSent State"},
319 { 2, "In OpenConfirm State"},
320 { 3, "In Established State"},
321 { 0, NULL }
322 };
323
324 static const struct tok bgp_notify_minor_cap_values[] = {
325 { 1, "Invalid Action Value" },
326 { 2, "Invalid Capability Length" },
327 { 3, "Malformed Capability Value" },
328 { 4, "Unsupported Capability Code" },
329 { 0, NULL }
330 };
331
332 static const struct tok bgp_origin_values[] = {
333 { 0, "IGP"},
334 { 1, "EGP"},
335 { 2, "Incomplete"},
336 { 0, NULL}
337 };
338
339 #define BGP_PMSI_TUNNEL_RSVP_P2MP 1
340 #define BGP_PMSI_TUNNEL_LDP_P2MP 2
341 #define BGP_PMSI_TUNNEL_PIM_SSM 3
342 #define BGP_PMSI_TUNNEL_PIM_SM 4
343 #define BGP_PMSI_TUNNEL_PIM_BIDIR 5
344 #define BGP_PMSI_TUNNEL_INGRESS 6
345 #define BGP_PMSI_TUNNEL_LDP_MP2MP 7
346
347 static const struct tok bgp_pmsi_tunnel_values[] = {
348 { BGP_PMSI_TUNNEL_RSVP_P2MP, "RSVP-TE P2MP LSP"},
349 { BGP_PMSI_TUNNEL_LDP_P2MP, "LDP P2MP LSP"},
350 { BGP_PMSI_TUNNEL_PIM_SSM, "PIM-SSM Tree"},
351 { BGP_PMSI_TUNNEL_PIM_SM, "PIM-SM Tree"},
352 { BGP_PMSI_TUNNEL_PIM_BIDIR, "PIM-Bidir Tree"},
353 { BGP_PMSI_TUNNEL_INGRESS, "Ingress Replication"},
354 { BGP_PMSI_TUNNEL_LDP_MP2MP, "LDP MP2MP LSP"},
355 { 0, NULL}
356 };
357
358 static const struct tok bgp_pmsi_flag_values[] = {
359 { 0x01, "Leaf Information required"},
360 { 0, NULL}
361 };
362
363 #define BGP_AIGP_TLV 1
364
365 static const struct tok bgp_aigp_values[] = {
366 { BGP_AIGP_TLV, "AIGP"},
367 { 0, NULL}
368 };
369
370 /* Subsequent address family identifier, RFC2283 section 7 */
371 #define SAFNUM_RES 0
372 #define SAFNUM_UNICAST 1
373 #define SAFNUM_MULTICAST 2
374 #define SAFNUM_UNIMULTICAST 3 /* deprecated now */
375 /* labeled BGP RFC3107 */
376 #define SAFNUM_LABUNICAST 4
377 /* RFC6514 */
378 #define SAFNUM_MULTICAST_VPN 5
379 /* draft-nalawade-kapoor-tunnel-safi */
380 #define SAFNUM_TUNNEL 64
381 /* RFC4761 */
382 #define SAFNUM_VPLS 65
383 /* RFC6037 */
384 #define SAFNUM_MDT 66
385 /* RFC7432 */
386 #define SAFNUM_EVPN 70
387 /* RFC4364 */
388 #define SAFNUM_VPNUNICAST 128
389 /* RFC6513 */
390 #define SAFNUM_VPNMULTICAST 129
391 #define SAFNUM_VPNUNIMULTICAST 130 /* deprecated now */
392 /* RFC4684 */
393 #define SAFNUM_RT_ROUTING_INFO 132
394
395 #define BGP_VPN_RD_LEN 8
396
397 static const struct tok bgp_safi_values[] = {
398 { SAFNUM_RES, "Reserved"},
399 { SAFNUM_UNICAST, "Unicast"},
400 { SAFNUM_MULTICAST, "Multicast"},
401 { SAFNUM_UNIMULTICAST, "Unicast+Multicast"},
402 { SAFNUM_LABUNICAST, "labeled Unicast"},
403 { SAFNUM_TUNNEL, "Tunnel"},
404 { SAFNUM_VPLS, "VPLS"},
405 { SAFNUM_MDT, "MDT"},
406 { SAFNUM_EVPN, "EVPN"},
407 { SAFNUM_VPNUNICAST, "labeled VPN Unicast"},
408 { SAFNUM_VPNMULTICAST, "labeled VPN Multicast"},
409 { SAFNUM_VPNUNIMULTICAST, "labeled VPN Unicast+Multicast"},
410 { SAFNUM_RT_ROUTING_INFO, "Route Target Routing Information"},
411 { SAFNUM_MULTICAST_VPN, "Multicast VPN"},
412 { 0, NULL }
413 };
414
415 /* well-known community */
416 #define BGP_COMMUNITY_NO_EXPORT 0xffffff01
417 #define BGP_COMMUNITY_NO_ADVERT 0xffffff02
418 #define BGP_COMMUNITY_NO_EXPORT_SUBCONFED 0xffffff03
419
420 /* Extended community type - RFC 4360 */
421 #define BGP_EXT_COM_RT_0 0x0002 /* Route Target,Format AS(2bytes):AN(4bytes) */
422 #define BGP_EXT_COM_RT_1 0x0102 /* Route Target,Format IP address:AN(2bytes) */
423 #define BGP_EXT_COM_RT_2 0x0202 /* Route Target,Format AN(4bytes):local(2bytes) */
424 #define BGP_EXT_COM_RO_0 0x0003 /* Route Origin,Format AS(2bytes):AN(4bytes) */
425 #define BGP_EXT_COM_RO_1 0x0103 /* Route Origin,Format IP address:AN(2bytes) */
426 #define BGP_EXT_COM_RO_2 0x0203 /* Route Origin,Format AN(4bytes):local(2bytes) */
427 #define BGP_EXT_COM_LINKBAND 0x4004 /* Link Bandwidth,Format AS(2B):Bandwidth(4B) */
428 /* rfc2547 bgp-mpls-vpns */
429 #define BGP_EXT_COM_VPN_ORIGIN 0x0005 /* OSPF Domain ID / VPN of Origin - draft-rosen-vpns-ospf-bgp-mpls */
430 #define BGP_EXT_COM_VPN_ORIGIN2 0x0105 /* duplicate - keep for backwards compatibility */
431 #define BGP_EXT_COM_VPN_ORIGIN3 0x0205 /* duplicate - keep for backwards compatibility */
432 #define BGP_EXT_COM_VPN_ORIGIN4 0x8005 /* duplicate - keep for backwards compatibility */
433
434 #define BGP_EXT_COM_OSPF_RTYPE 0x0306 /* OSPF Route Type,Format Area(4B):RouteType(1B):Options(1B) */
435 #define BGP_EXT_COM_OSPF_RTYPE2 0x8000 /* duplicate - keep for backwards compatibility */
436 #define BGP_EXT_COM_ENCAP 0x030c /* rfc5512 */
437
438 #define BGP_EXT_COM_OSPF_RID 0x0107 /* OSPF Router ID,Format RouterID(4B):Unused(2B) */
439 #define BGP_EXT_COM_OSPF_RID2 0x8001 /* duplicate - keep for backwards compatibility */
440
441 #define BGP_EXT_COM_L2INFO 0x800a /* draft-kompella-ppvpn-l2vpn */
442
443 #define BGP_EXT_COM_SOURCE_AS 0x0009 /* RFC-ietf-l3vpn-2547bis-mcast-bgp-08.txt */
444 #define BGP_EXT_COM_VRF_RT_IMP 0x010b /* RFC-ietf-l3vpn-2547bis-mcast-bgp-08.txt */
445 #define BGP_EXT_COM_L2VPN_RT_0 0x000a /* L2VPN Identifier,Format AS(2bytes):AN(4bytes) */
446 #define BGP_EXT_COM_L2VPN_RT_1 0xF10a /* L2VPN Identifier,Format IP address:AN(2bytes) */
447
448 /* https://www.cisco.com/en/US/tech/tk436/tk428/technologies_tech_note09186a00801eb09a.shtml */
449 #define BGP_EXT_COM_EIGRP_GEN 0x8800
450 #define BGP_EXT_COM_EIGRP_METRIC_AS_DELAY 0x8801
451 #define BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW 0x8802
452 #define BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU 0x8803
453 #define BGP_EXT_COM_EIGRP_EXT_REMAS_REMID 0x8804
454 #define BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC 0x8805
455
456 static const struct tok bgp_extd_comm_flag_values[] = {
457 { 0x8000, "vendor-specific"},
458 { 0x4000, "non-transitive"},
459 { 0, NULL},
460 };
461
462 static const struct tok bgp_extd_comm_subtype_values[] = {
463 { BGP_EXT_COM_RT_0, "target"},
464 { BGP_EXT_COM_RT_1, "target"},
465 { BGP_EXT_COM_RT_2, "target"},
466 { BGP_EXT_COM_RO_0, "origin"},
467 { BGP_EXT_COM_RO_1, "origin"},
468 { BGP_EXT_COM_RO_2, "origin"},
469 { BGP_EXT_COM_LINKBAND, "link-BW"},
470 { BGP_EXT_COM_VPN_ORIGIN, "ospf-domain"},
471 { BGP_EXT_COM_VPN_ORIGIN2, "ospf-domain"},
472 { BGP_EXT_COM_VPN_ORIGIN3, "ospf-domain"},
473 { BGP_EXT_COM_VPN_ORIGIN4, "ospf-domain"},
474 { BGP_EXT_COM_OSPF_RTYPE, "ospf-route-type"},
475 { BGP_EXT_COM_OSPF_RTYPE2, "ospf-route-type"},
476 { BGP_EXT_COM_ENCAP, "encapsulation"},
477 { BGP_EXT_COM_OSPF_RID, "ospf-router-id"},
478 { BGP_EXT_COM_OSPF_RID2, "ospf-router-id"},
479 { BGP_EXT_COM_L2INFO, "layer2-info"},
480 { BGP_EXT_COM_EIGRP_GEN, "eigrp-general-route (flag, tag)" },
481 { BGP_EXT_COM_EIGRP_METRIC_AS_DELAY, "eigrp-route-metric (AS, delay)" },
482 { BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW, "eigrp-route-metric (reliability, nexthop, bandwidth)" },
483 { BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU, "eigrp-route-metric (load, MTU)" },
484 { BGP_EXT_COM_EIGRP_EXT_REMAS_REMID, "eigrp-external-route (remote-AS, remote-ID)" },
485 { BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC, "eigrp-external-route (remote-proto, remote-metric)" },
486 { BGP_EXT_COM_SOURCE_AS, "source-AS" },
487 { BGP_EXT_COM_VRF_RT_IMP, "vrf-route-import"},
488 { BGP_EXT_COM_L2VPN_RT_0, "l2vpn-id"},
489 { BGP_EXT_COM_L2VPN_RT_1, "l2vpn-id"},
490 { 0, NULL},
491 };
492
493 /* RFC RFC5512 BGP Tunnel Encapsulation Attribute Tunnel Types */
494 #define BGP_ENCAP_TUNNEL_L2TPV3_IP 1
495 #define BGP_ENCAP_TUNNEL_GRE 2
496 #define BGP_ENCAP_TUNNEL_TRANSMIT 3
497 #define BGP_ENCAP_TUNNEL_IPSEC 4
498 #define BGP_ENCAP_TUNNEL_IP_IPSEC 5
499 #define BGP_ENCAP_TUNNEL_MPLS_IP 6
500 #define BGP_ENCAP_TUNNEL_IP_IP 7
501 #define BGP_ENCAP_TUNNEL_VXLAN 8
502 #define BGP_ENCAP_TUNNEL_NVGRE 9
503 #define BGP_ENCAP_TUNNEL_MPLS 10
504 #define BGP_ENCAP_TUNNEL_MPLS_GRE 11
505 #define BGP_ENCAP_TUNNEL_VXLAN_GPE 12
506 #define BGP_ENCAP_TUNNEL_MPLS_UDP 13
507 #define BGP_ENCAP_TUNNEL_IPV6 14
508 #define BGP_ENCAP_TUNNEL_SR_TE 15
509 #define BGP_ENCAP_TUNNEL_BARE 16
510 #define BGP_ENCAP_TUNNEL_SR 17
511
512 static const struct tok bgp_extd_comm_encap_tunnel_values[] = {
513 { BGP_ENCAP_TUNNEL_L2TPV3_IP, "L2TPv3 over IP"},
514 { BGP_ENCAP_TUNNEL_GRE, "GRE"},
515 { BGP_ENCAP_TUNNEL_TRANSMIT, "Transmit Tunnel"},
516 { BGP_ENCAP_TUNNEL_IPSEC, "IPsec"},
517 { BGP_ENCAP_TUNNEL_IP_IPSEC, "IP in IP with IPsec"},
518 { BGP_ENCAP_TUNNEL_MPLS_IP, "MPLS in IP with IPsec"},
519 { BGP_ENCAP_TUNNEL_IP_IP, "IP in IP"},
520 { BGP_ENCAP_TUNNEL_VXLAN, "VXLAN"},
521 { BGP_ENCAP_TUNNEL_NVGRE, "NVGRE"},
522 { BGP_ENCAP_TUNNEL_MPLS, "MPLS"},
523 { BGP_ENCAP_TUNNEL_MPLS_GRE, "MPLS in GRE"},
524 { BGP_ENCAP_TUNNEL_VXLAN_GPE, "VXLAN GPE"},
525 { BGP_ENCAP_TUNNEL_MPLS_UDP, "MPLS in UDP"},
526 { BGP_ENCAP_TUNNEL_IPV6, "IPv6"},
527 { BGP_ENCAP_TUNNEL_SR_TE, "SR TE"},
528 { BGP_ENCAP_TUNNEL_BARE, "Bare"},
529 { BGP_ENCAP_TUNNEL_SR, "SR"},
530 { 0, NULL},
531 };
532
533 /* OSPF codes for BGP_EXT_COM_OSPF_RTYPE draft-rosen-vpns-ospf-bgp-mpls */
534 #define BGP_OSPF_RTYPE_RTR 1 /* OSPF Router LSA */
535 #define BGP_OSPF_RTYPE_NET 2 /* OSPF Network LSA */
536 #define BGP_OSPF_RTYPE_SUM 3 /* OSPF Summary LSA */
537 #define BGP_OSPF_RTYPE_EXT 5 /* OSPF External LSA, note that ASBR doesn't apply to MPLS-VPN */
538 #define BGP_OSPF_RTYPE_NSSA 7 /* OSPF NSSA External*/
539 #define BGP_OSPF_RTYPE_SHAM 129 /* OSPF-MPLS-VPN Sham link */
540 #define BGP_OSPF_RTYPE_METRIC_TYPE 0x1 /* LSB of RTYPE Options Field */
541
542 static const struct tok bgp_extd_comm_ospf_rtype_values[] = {
543 { BGP_OSPF_RTYPE_RTR, "Router" },
544 { BGP_OSPF_RTYPE_NET, "Network" },
545 { BGP_OSPF_RTYPE_SUM, "Summary" },
546 { BGP_OSPF_RTYPE_EXT, "External" },
547 { BGP_OSPF_RTYPE_NSSA,"NSSA External" },
548 { BGP_OSPF_RTYPE_SHAM,"MPLS-VPN Sham" },
549 { 0, NULL },
550 };
551
552 /* ADD-PATH Send/Receive field values */
553 static const struct tok bgp_add_path_recvsend[] = {
554 { 1, "Receive" },
555 { 2, "Send" },
556 { 3, "Both" },
557 { 0, NULL },
558 };
559
560 /* allocate space for the largest possible string */
561 static char astostr[sizeof("xxxxx.xxxxx")];
562
563 /*
564 * as_printf
565 *
566 * Convert an AS number into a string and return string pointer.
567 *
568 * Depending on bflag is set or not, AS number is converted into ASDOT notation
569 * or plain number notation.
570 *
571 */
572 static char *
573 as_printf(netdissect_options *ndo,
574 char *str, size_t size, u_int asnum)
575 {
576 if (!ndo->ndo_bflag || asnum <= 0xFFFF) {
577 snprintf(str, size, "%u", asnum);
578 } else {
579 snprintf(str, size, "%u.%u", asnum >> 16, asnum & 0xFFFF);
580 }
581 return str;
582 }
583
584 #define ITEMCHECK(minlen) if (itemlen < minlen) goto badtlv;
585
586 int
587 decode_prefix4(netdissect_options *ndo,
588 const u_char *pptr, u_int itemlen, char *buf, size_t buflen)
589 {
590 nd_ipv4 addr;
591 u_int plen, plenbytes;
592
593 ITEMCHECK(1);
594 plen = GET_U_1(pptr);
595 if (32 < plen)
596 return -1;
597 itemlen -= 1;
598
599 memset(&addr, 0, sizeof(addr));
600 plenbytes = (plen + 7) / 8;
601 ITEMCHECK(plenbytes);
602 GET_CPY_BYTES(&addr, pptr + 1, plenbytes);
603 if (plen % 8) {
604 ((u_char *)&addr)[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff);
605 }
606 snprintf(buf, buflen, "%s/%u", ipaddr_string(ndo, (const u_char *)&addr), plen);
607 return 1 + plenbytes;
608
609 badtlv:
610 return -2;
611 }
612
613 static int
614 decode_labeled_prefix4(netdissect_options *ndo,
615 const u_char *pptr, u_int itemlen, char *buf,
616 size_t buflen)
617 {
618 nd_ipv4 addr;
619 u_int plen, plenbytes;
620
621 /* prefix length and label = 4 bytes */
622 ND_TCHECK_4(pptr);
623 ITEMCHECK(4);
624 plen = GET_U_1(pptr); /* get prefix length */
625
626 /* this is one of the weirdnesses of rfc3107
627 the label length (actually the label + COS bits)
628 is added to the prefix length;
629 we also do only read out just one label -
630 there is no real application for advertisement of
631 stacked labels in a single BGP message
632 */
633
634 if (24 > plen)
635 return -1;
636
637 plen-=24; /* adjust prefixlen - labellength */
638
639 if (32 < plen)
640 return -1;
641 itemlen -= 4;
642
643 memset(&addr, 0, sizeof(addr));
644 plenbytes = (plen + 7) / 8;
645 ITEMCHECK(plenbytes);
646 GET_CPY_BYTES(&addr, pptr + 4, plenbytes);
647 if (plen % 8) {
648 ((u_char *)&addr)[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff);
649 }
650 /* the label may get offsetted by 4 bits so lets shift it right */
651 snprintf(buf, buflen, "%s/%u, label:%u %s",
652 ipaddr_string(ndo, (const u_char *)&addr),
653 plen,
654 GET_BE_U_3(pptr + 1)>>4,
655 ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
656
657 return 4 + plenbytes;
658
659 trunc:
660 return -2;
661
662 badtlv:
663 return -3;
664 }
665
666 /*
667 * bgp_vpn_ip_print
668 *
669 * print an ipv4 or ipv6 address into a buffer dependent on address length.
670 */
671 static char *
672 bgp_vpn_ip_print(netdissect_options *ndo,
673 const u_char *pptr, u_int addr_length)
674 {
675
676 /* worst case string is s fully formatted v6 address */
677 static char addr[sizeof("1234:5678:89ab:cdef:1234:5678:89ab:cdef")];
678 char *pos = addr;
679
680 switch(addr_length) {
681 case (sizeof(nd_ipv4) << 3): /* 32 */
682 snprintf(pos, sizeof(addr), "%s", GET_IPADDR_STRING(pptr));
683 break;
684 case (sizeof(nd_ipv6) << 3): /* 128 */
685 snprintf(pos, sizeof(addr), "%s", GET_IP6ADDR_STRING(pptr));
686 break;
687 default:
688 snprintf(pos, sizeof(addr), "bogus address length %u", addr_length);
689 break;
690 }
691 pos += strlen(pos);
692
693 *(pos) = '\0';
694 return (addr);
695 }
696
697 /*
698 * bgp_vpn_sg_print
699 *
700 * print an multicast s,g entry into a buffer.
701 * the s,g entry is encoded like this.
702 *
703 * +-----------------------------------+
704 * | Multicast Source Length (1 octet) |
705 * +-----------------------------------+
706 * | Multicast Source (Variable) |
707 * +-----------------------------------+
708 * | Multicast Group Length (1 octet) |
709 * +-----------------------------------+
710 * | Multicast Group (Variable) |
711 * +-----------------------------------+
712 *
713 * return the number of bytes read from the wire.
714 */
715 static u_int
716 bgp_vpn_sg_print(netdissect_options *ndo,
717 const u_char *pptr, char *buf, size_t buflen)
718 {
719 uint8_t addr_length;
720 u_int total_length, offset;
721
722 total_length = 0;
723
724 /* Source address length, encoded in bits */
725 addr_length = GET_U_1(pptr);
726 pptr++;
727
728 /* Source address */
729 ND_TCHECK_LEN(pptr, (addr_length >> 3));
730 total_length += (addr_length >> 3) + 1;
731 offset = (u_int)strlen(buf);
732 if (addr_length) {
733 snprintf(buf + offset, buflen - offset, ", Source %s",
734 bgp_vpn_ip_print(ndo, pptr, addr_length));
735 pptr += (addr_length >> 3);
736 }
737
738 /* Group address length, encoded in bits */
739 addr_length = GET_U_1(pptr);
740 pptr++;
741
742 /* Group address */
743 ND_TCHECK_LEN(pptr, (addr_length >> 3));
744 total_length += (addr_length >> 3) + 1;
745 offset = (u_int)strlen(buf);
746 if (addr_length) {
747 snprintf(buf + offset, buflen - offset, ", Group %s",
748 bgp_vpn_ip_print(ndo, pptr, addr_length));
749 pptr += (addr_length >> 3);
750 }
751
752 trunc:
753 return (total_length);
754 }
755
756 /* Print an RFC 4364 Route Distinguisher */
757 const char *
758 bgp_vpn_rd_print(netdissect_options *ndo,
759 const u_char *pptr)
760 {
761 /* allocate space for the largest possible string */
762 static char rd[sizeof("xxxxx.xxxxx:xxxxx (xxx.xxx.xxx.xxx:xxxxx)")];
763 char *pos = rd;
764
765 /* ok lets load the RD format */
766 switch (GET_BE_U_2(pptr)) {
767
768 case 0:
769 /* 2-byte-AS:number fmt */
770 snprintf(pos, sizeof(rd) - (pos - rd), "%u:%u (= %u.%u.%u.%u)",
771 GET_BE_U_2(pptr + 2),
772 GET_BE_U_4(pptr + 4),
773 GET_U_1(pptr + 4), GET_U_1(pptr + 5),
774 GET_U_1(pptr + 6), GET_U_1(pptr + 7));
775 break;
776
777 case 1:
778 /* IP-address:AS fmt */
779 snprintf(pos, sizeof(rd) - (pos - rd), "%u.%u.%u.%u:%u",
780 GET_U_1(pptr + 2), GET_U_1(pptr + 3),
781 GET_U_1(pptr + 4), GET_U_1(pptr + 5),
782 GET_BE_U_2(pptr + 6));
783 break;
784
785 case 2:
786 /* 4-byte-AS:number fmt */
787 snprintf(pos, sizeof(rd) - (pos - rd), "%s:%u (%u.%u.%u.%u:%u)",
788 as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_4(pptr + 2)),
789 GET_BE_U_2(pptr + 6), GET_U_1(pptr + 2),
790 GET_U_1(pptr + 3), GET_U_1(pptr + 4),
791 GET_U_1(pptr + 5), GET_BE_U_2(pptr + 6));
792 break;
793 default:
794 snprintf(pos, sizeof(rd) - (pos - rd), "unknown RD format");
795 break;
796 }
797 pos += strlen(pos);
798 *(pos) = '\0';
799 return (rd);
800 }
801
802 /*
803 * Print an RFC 4360 Extended Community.
804 */
805 static void
806 bgp_extended_community_print(netdissect_options *ndo,
807 const u_char *pptr)
808 {
809 union { /* copy buffer for bandwidth values */
810 float f;
811 uint32_t i;
812 } bw;
813
814 switch (GET_BE_U_2(pptr)) {
815
816 case BGP_EXT_COM_RT_0:
817 case BGP_EXT_COM_RO_0:
818 case BGP_EXT_COM_L2VPN_RT_0:
819 ND_PRINT("%u:%u (= %s)",
820 GET_BE_U_2(pptr + 2),
821 GET_BE_U_4(pptr + 4),
822 GET_IPADDR_STRING(pptr+4));
823 break;
824
825 case BGP_EXT_COM_RT_1:
826 case BGP_EXT_COM_RO_1:
827 case BGP_EXT_COM_L2VPN_RT_1:
828 case BGP_EXT_COM_VRF_RT_IMP:
829 ND_PRINT("%s:%u",
830 GET_IPADDR_STRING(pptr+2),
831 GET_BE_U_2(pptr + 6));
832 break;
833
834 case BGP_EXT_COM_RT_2:
835 case BGP_EXT_COM_RO_2:
836 ND_PRINT("%s:%u",
837 as_printf(ndo, astostr, sizeof(astostr),
838 GET_BE_U_4(pptr + 2)), GET_BE_U_2(pptr + 6));
839 break;
840
841 case BGP_EXT_COM_LINKBAND:
842 bw.i = GET_BE_U_4(pptr + 2);
843 ND_PRINT("bandwidth: %.3f Mbps",
844 bw.f*8/1000000);
845 break;
846
847 case BGP_EXT_COM_VPN_ORIGIN:
848 case BGP_EXT_COM_VPN_ORIGIN2:
849 case BGP_EXT_COM_VPN_ORIGIN3:
850 case BGP_EXT_COM_VPN_ORIGIN4:
851 case BGP_EXT_COM_OSPF_RID:
852 case BGP_EXT_COM_OSPF_RID2:
853 ND_PRINT("%s", GET_IPADDR_STRING(pptr+2));
854 break;
855
856 case BGP_EXT_COM_OSPF_RTYPE:
857 case BGP_EXT_COM_OSPF_RTYPE2:
858 ND_PRINT("area:%s, router-type:%s, metric-type:%s%s",
859 GET_IPADDR_STRING(pptr+2),
860 tok2str(bgp_extd_comm_ospf_rtype_values,
861 "unknown (0x%02x)",
862 GET_U_1((pptr + 6))),
863 (GET_U_1(pptr + 7) & BGP_OSPF_RTYPE_METRIC_TYPE) ? "E2" : "",
864 ((GET_U_1(pptr + 6) == BGP_OSPF_RTYPE_EXT) || (GET_U_1(pptr + 6) == BGP_OSPF_RTYPE_NSSA)) ? "E1" : "");
865 break;
866
867 case BGP_EXT_COM_L2INFO:
868 ND_PRINT("%s Control Flags [0x%02x]:MTU %u",
869 tok2str(l2vpn_encaps_values,
870 "unknown encaps",
871 GET_U_1((pptr + 2))),
872 GET_U_1((pptr + 3)),
873 GET_BE_U_2(pptr + 4));
874 break;
875
876 case BGP_EXT_COM_SOURCE_AS:
877 ND_PRINT("AS %u", GET_BE_U_2(pptr + 2));
878 break;
879
880 case BGP_EXT_COM_ENCAP:
881 ND_PRINT("Tunnel type: %s", tok2str(bgp_extd_comm_encap_tunnel_values,
882 "unknown encaps",
883 GET_BE_U_2(pptr + 6)));
884 break;
885
886 default:
887 ND_PRINT("%02x%02x%02x%02x%02x%02x",
888 GET_U_1(pptr + 2),
889 GET_U_1(pptr + 3),
890 GET_U_1(pptr + 4),
891 GET_U_1(pptr + 5),
892 GET_U_1(pptr + 6),
893 GET_U_1(pptr + 7));
894 break;
895 }
896 }
897
898 /*
899 * RFC4684 (Section 4)/RFC2858 (Section 4).
900 * RTC membership prefix is structured as follows
901 * [prefix-len] [origin-as] [route-target]
902 * The route-target is encoded as RT ext-comms.
903 * Prefix-len may be 0, 32..96
904 *
905 * Note that pptr is not packet data - it is
906 * a buffer owned by our caller - therefore GET_*
907 * macros can not be used.
908 */
909 static char *
910 bgp_rt_prefix_print(netdissect_options *ndo,
911 const u_char *pptr,
912 u_int plen)
913 {
914 /* allocate space for the largest possible string */
915 char rtc_prefix_in_hex[20] = "";
916 u_int rtc_prefix_in_hex_len = 0;
917 static char output[61]; /* max response string */
918 uint16_t ec_type = 0;
919 u_int octet_count;
920 u_int i;
921
922 if (plen == 0) {
923 snprintf(output, sizeof(output), "route-target: 0:0/0");
924 return (output);
925 }
926
927 /* hex representation of the prefix */
928 octet_count = (plen+7)/8;
929 for (i=0; i<octet_count; i++) {
930 rtc_prefix_in_hex_len += snprintf(rtc_prefix_in_hex+rtc_prefix_in_hex_len,
931 sizeof(rtc_prefix_in_hex)-rtc_prefix_in_hex_len,
932 "%02x%s", *(pptr+i),
933 ((i%2 == 1) && (i<octet_count-1)) ? " " : "");
934 }
935
936 if (plen < 16) {
937 /*
938 * The prefix is too short to include the full ext-comm type,
939 * so we have no way to parse it further.
940 */
941 snprintf(output, sizeof(output), "route-target: partial-type: (%s/%d)",
942 rtc_prefix_in_hex, plen);
943 return (output);
944 }
945
946 /*
947 * get the ext-comm type
948 * Note: pptr references a static 8 octet buffer with unused bits set to 0,
949 * hense EXTRACT_*() macros are safe.
950 */
951 ec_type = EXTRACT_BE_U_2(pptr);
952 switch (ec_type) {
953 case BGP_EXT_COM_RT_0:
954 /* 2-byte-AS:number fmt */
955 snprintf(output, sizeof(output), "route-target: %u:%u/%d (%s)",
956 EXTRACT_BE_U_2(pptr+2),
957 EXTRACT_BE_U_4(pptr+4),
958 plen, rtc_prefix_in_hex);
959 break;
960
961 case BGP_EXT_COM_RT_1:
962 /* IP-address:AS fmt */
963 snprintf(output, sizeof(output), "route-target: %u.%u.%u.%u:%u/%d (%s)",
964 *(pptr+2), *(pptr+3), *(pptr+4), *(pptr+5),
965 EXTRACT_BE_U_2(pptr+6), plen, rtc_prefix_in_hex);
966 break;
967
968 case BGP_EXT_COM_RT_2:
969 /* 4-byte-AS:number fmt */
970 snprintf(output, sizeof(output), "route-target: %s:%u/%d (%s)",
971 as_printf(ndo, astostr, sizeof(astostr), EXTRACT_BE_U_4(pptr+2)),
972 EXTRACT_BE_U_2(pptr+6), plen, rtc_prefix_in_hex);
973 break;
974
975 default:
976 snprintf(output, sizeof(output), "route target: unknown-type(%04x) (%s/%d)",
977 ec_type,
978 rtc_prefix_in_hex, plen);
979 break;
980 }
981 return (output);
982 }
983
984 /* RFC 4684 */
985 static int
986 decode_rt_routing_info(netdissect_options *ndo,
987 const u_char *pptr)
988 {
989 uint8_t route_target[8];
990 u_int plen;
991 char asbuf[sizeof(astostr)]; /* bgp_vpn_rd_print() overwrites astostr */
992 u_int num_octets;
993
994 /* NLRI "prefix length" from RFC 2858 Section 4. */
995 plen = GET_U_1(pptr); /* get prefix length */
996
997 /* NLRI "prefix" (ibid), valid lengths are { 0, 32, 33, ..., 96 } bits.
998 * RFC 4684 Section 4 defines the layout of "origin AS" and "route
999 * target" fields inside the "prefix" depending on its length.
1000 */
1001 if (0 == plen) {
1002 /* Without "origin AS", without "route target". */
1003 ND_PRINT("\n\t default route target");
1004 return 1;
1005 }
1006
1007 if (32 > plen) {
1008 ND_PRINT("\n\t (illegal prefix length)");
1009 return -1;
1010 }
1011
1012 /* With at least "origin AS", possibly with "route target". */
1013 as_printf(ndo, asbuf, sizeof(asbuf), GET_BE_U_4(pptr + 1));
1014
1015 plen -= 32; /* adjust prefix length */
1016
1017 if (64 < plen) {
1018 ND_PRINT("\n\t (illegal prefix length)");
1019 return -1;
1020 }
1021
1022 /* From now on (plen + 7) / 8 evaluates to { 0, 1, 2, ..., 8 }
1023 * and gives the number of octets in the variable-length "route
1024 * target" field inside this NLRI "prefix". Look for it.
1025 */
1026 memset(&route_target, 0, sizeof(route_target));
1027 num_octets = (plen + 7) / 8;
1028 GET_CPY_BYTES(&route_target, pptr + 5, num_octets);
1029 /* If mask-len is not on octet boundary, ensure all extra bits are 0 */
1030 if (plen % 8) {
1031 ((u_char *)&route_target)[num_octets - 1] &=
1032 ((0xff00 >> (plen % 8)) & 0xff);
1033 }
1034 ND_PRINT("\n\t origin AS: %s, %s",
1035 asbuf,
1036 bgp_rt_prefix_print(ndo, (u_char *)&route_target, plen));
1037
1038 return 5 + num_octets;
1039 }
1040
1041 static int
1042 decode_labeled_vpn_prefix4(netdissect_options *ndo,
1043 const u_char *pptr, char *buf, size_t buflen)
1044 {
1045 nd_ipv4 addr;
1046 u_int plen;
1047
1048 plen = GET_U_1(pptr); /* get prefix length */
1049
1050 if ((24+64) > plen)
1051 return -1;
1052
1053 plen -= (24+64); /* adjust prefixlen - labellength - RD len*/
1054
1055 if (32 < plen)
1056 return -1;
1057
1058 memset(&addr, 0, sizeof(addr));
1059 GET_CPY_BYTES(&addr, pptr + 12, (plen + 7) / 8);
1060 if (plen % 8) {
1061 ((u_char *)&addr)[(plen + 7) / 8 - 1] &=
1062 ((0xff00 >> (plen % 8)) & 0xff);
1063 }
1064 /* the label may get offsetted by 4 bits so lets shift it right */
1065 snprintf(buf, buflen, "RD: %s, %s/%u, label:%u %s",
1066 bgp_vpn_rd_print(ndo, pptr+4),
1067 ipaddr_string(ndo, (const u_char *)&addr),
1068 plen,
1069 GET_BE_U_3(pptr + 1)>>4,
1070 ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
1071
1072 return 12 + (plen + 7) / 8;
1073 }
1074
1075 /*
1076 * +-------------------------------+
1077 * | |
1078 * | RD:IPv4-address (12 octets) |
1079 * | |
1080 * +-------------------------------+
1081 * | MDT Group-address (4 octets) |
1082 * +-------------------------------+
1083 */
1084
1085 #define MDT_VPN_NLRI_LEN 16
1086
1087 static int
1088 decode_mdt_vpn_nlri(netdissect_options *ndo,
1089 const u_char *pptr, char *buf, size_t buflen)
1090 {
1091 const u_char *rd;
1092 const u_char *vpn_ip;
1093
1094 /* if the NLRI is not predefined length, quit.*/
1095 if (GET_U_1(pptr) != MDT_VPN_NLRI_LEN * 8)
1096 return -1;
1097 pptr++;
1098
1099 /* RD */
1100 ND_TCHECK_8(pptr);
1101 rd = pptr;
1102 pptr += 8;
1103
1104 /* IPv4 address */
1105 vpn_ip = pptr;
1106 pptr += sizeof(nd_ipv4);
1107
1108 /* MDT Group Address */
1109 snprintf(buf, buflen, "RD: %s, VPN IP Address: %s, MC Group Address: %s",
1110 bgp_vpn_rd_print(ndo, rd), GET_IPADDR_STRING(vpn_ip), GET_IPADDR_STRING(pptr));
1111
1112 return MDT_VPN_NLRI_LEN + 1;
1113
1114 trunc:
1115 return -2;
1116 }
1117
1118 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI 1
1119 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI 2
1120 #define BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI 3
1121 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF 4
1122 #define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE 5
1123 #define BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN 6
1124 #define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN 7
1125
1126 static const struct tok bgp_multicast_vpn_route_type_values[] = {
1127 { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI, "Intra-AS I-PMSI"},
1128 { BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI, "Inter-AS I-PMSI"},
1129 { BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI, "S-PMSI"},
1130 { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF, "Intra-AS Segment-Leaf"},
1131 { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE, "Source-Active"},
1132 { BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN, "Shared Tree Join"},
1133 { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN, "Source Tree Join"},
1134 { 0, NULL}
1135 };
1136
1137 static int
1138 decode_multicast_vpn(netdissect_options *ndo,
1139 const u_char *pptr, char *buf, size_t buflen)
1140 {
1141 uint8_t route_type, route_length;
1142 u_int addr_length, sg_length;
1143 u_int offset;
1144
1145 route_type = GET_U_1(pptr);
1146 pptr++;
1147 route_length = GET_U_1(pptr);
1148 pptr++;
1149
1150 snprintf(buf, buflen, "Route-Type: %s (%u), length: %u",
1151 tok2str(bgp_multicast_vpn_route_type_values,
1152 "Unknown", route_type),
1153 route_type, route_length);
1154
1155 switch(route_type) {
1156 case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI:
1157 ND_TCHECK_LEN(pptr, BGP_VPN_RD_LEN);
1158 offset = (u_int)strlen(buf);
1159 snprintf(buf + offset, buflen - offset, ", RD: %s, Originator %s",
1160 bgp_vpn_rd_print(ndo, pptr),
1161 bgp_vpn_ip_print(ndo, pptr + BGP_VPN_RD_LEN,
1162 (route_length - BGP_VPN_RD_LEN) << 3));
1163 break;
1164 case BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI:
1165 ND_TCHECK_LEN(pptr, BGP_VPN_RD_LEN + 4);
1166 offset = (u_int)strlen(buf);
1167 snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s",
1168 bgp_vpn_rd_print(ndo, pptr),
1169 as_printf(ndo, astostr, sizeof(astostr),
1170 GET_BE_U_4(pptr + BGP_VPN_RD_LEN)));
1171 break;
1172
1173 case BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI:
1174 ND_TCHECK_LEN(pptr, BGP_VPN_RD_LEN);
1175 offset = (u_int)strlen(buf);
1176 snprintf(buf + offset, buflen - offset, ", RD: %s",
1177 bgp_vpn_rd_print(ndo, pptr));
1178 pptr += BGP_VPN_RD_LEN;
1179
1180 sg_length = bgp_vpn_sg_print(ndo, pptr, buf, buflen);
1181 addr_length = route_length - sg_length;
1182
1183 ND_TCHECK_LEN(pptr, addr_length);
1184 offset = (u_int)strlen(buf);
1185 snprintf(buf + offset, buflen - offset, ", Originator %s",
1186 bgp_vpn_ip_print(ndo, pptr, addr_length << 3));
1187 break;
1188
1189 case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE:
1190 ND_TCHECK_LEN(pptr, BGP_VPN_RD_LEN);
1191 offset = (u_int)strlen(buf);
1192 snprintf(buf + offset, buflen - offset, ", RD: %s",
1193 bgp_vpn_rd_print(ndo, pptr));
1194 pptr += BGP_VPN_RD_LEN;
1195
1196 bgp_vpn_sg_print(ndo, pptr, buf, buflen);
1197 break;
1198
1199 case BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN: /* fall through */
1200 case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN:
1201 ND_TCHECK_LEN(pptr, BGP_VPN_RD_LEN + 4);
1202 offset = (u_int)strlen(buf);
1203 snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s",
1204 bgp_vpn_rd_print(ndo, pptr),
1205 as_printf(ndo, astostr, sizeof(astostr),
1206 GET_BE_U_4(pptr + BGP_VPN_RD_LEN)));
1207 pptr += BGP_VPN_RD_LEN + 4;
1208
1209 bgp_vpn_sg_print(ndo, pptr, buf, buflen);
1210 break;
1211
1212 /*
1213 * no per route-type printing yet.
1214 */
1215 case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF:
1216 default:
1217 break;
1218 }
1219
1220 return route_length + 2;
1221
1222 trunc:
1223 return -2;
1224 }
1225
1226 /*
1227 * As I remember, some versions of systems have an snprintf() that
1228 * returns -1 if the buffer would have overflowed. If the return
1229 * value is negative, set buflen to 0, to indicate that we've filled
1230 * the buffer up.
1231 *
1232 * If the return value is greater than buflen, that means that
1233 * the buffer would have overflowed; again, set buflen to 0 in
1234 * that case.
1235 */
1236 #define UPDATE_BUF_BUFLEN(buf, buflen, stringlen) \
1237 if (stringlen<0) \
1238 buflen=0; \
1239 else if ((u_int)stringlen>buflen) \
1240 buflen=0; \
1241 else { \
1242 buflen-=stringlen; \
1243 buf+=stringlen; \
1244 }
1245
1246 static int
1247 decode_labeled_vpn_l2(netdissect_options *ndo,
1248 const u_char *pptr, char *buf, size_t buflen)
1249 {
1250 u_int plen, tlen, tlv_type, tlv_len, ttlv_len;
1251 int stringlen;
1252
1253 plen = GET_BE_U_2(pptr);
1254 tlen = plen;
1255 pptr += 2;
1256 /* Old and new L2VPN NLRI share AFI/SAFI
1257 * -> Assume a 12 Byte-length NLRI is auto-discovery-only
1258 * and > 17 as old format. Complain for the middle case
1259 */
1260 if (plen == 12) {
1261 /* assume AD-only with RD, BGPNH */
1262 ND_TCHECK_LEN(pptr, 12);
1263 buf[0] = '\0';
1264 stringlen = snprintf(buf, buflen, "RD: %s, BGPNH: %s",
1265 bgp_vpn_rd_print(ndo, pptr),
1266 GET_IPADDR_STRING(pptr+8));
1267 UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
1268 pptr += 12;
1269 tlen -= 12;
1270 return plen + 2;
1271 } else if (plen > 17) {
1272 /* assume old format */
1273 /* RD, ID, LBLKOFF, LBLBASE */
1274
1275 ND_TCHECK_LEN(pptr, 15);
1276 buf[0] = '\0';
1277 stringlen = snprintf(buf, buflen, "RD: %s, CE-ID: %u, Label-Block Offset: %u, Label Base %u",
1278 bgp_vpn_rd_print(ndo, pptr),
1279 GET_BE_U_2(pptr + 8),
1280 GET_BE_U_2(pptr + 10),
1281 GET_BE_U_3(pptr + 12)>>4); /* the label is offsetted by 4 bits so lets shift it right */
1282 UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
1283 pptr += 15;
1284 tlen -= 15;
1285
1286 /* ok now the variable part - lets read out TLVs*/
1287 while (tlen != 0) {
1288 if (tlen < 3) {
1289 if (buflen != 0) {
1290 stringlen=snprintf(buf,buflen, "\n\t\tran past the end");
1291 UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
1292 }
1293 return plen + 2;
1294 }
1295 tlv_type = GET_U_1(pptr);
1296 pptr++;
1297 tlv_len = GET_BE_U_2(pptr); /* length, in *bits* */
1298 ttlv_len = (tlv_len + 7)/8; /* length, in *bytes* */
1299 pptr += 2;
1300
1301 switch(tlv_type) {
1302 case 1:
1303 if (buflen != 0) {
1304 stringlen=snprintf(buf,buflen, "\n\t\tcircuit status vector (%u) length: %u: 0x",
1305 tlv_type,
1306 tlv_len);
1307 UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
1308 }
1309 while (ttlv_len != 0) {
1310 if (tlen < 1) {
1311 if (buflen != 0) {
1312 stringlen=snprintf(buf,buflen, " (ran past the end)");
1313 UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
1314 }
1315 return plen + 2;
1316 }
1317 ND_TCHECK_1(pptr);
1318 if (buflen != 0) {
1319 stringlen=snprintf(buf,buflen, "%02x",
1320 GET_U_1(pptr));
1321 pptr++;
1322 UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
1323 }
1324 ttlv_len--;
1325 tlen--;
1326 }
1327 break;
1328 default:
1329 if (buflen != 0) {
1330 stringlen=snprintf(buf,buflen, "\n\t\tunknown TLV #%u, length: %u",
1331 tlv_type,
1332 tlv_len);
1333 UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
1334 }
1335 if (tlen < ttlv_len) {
1336 if (buflen != 0) {
1337 stringlen=snprintf(buf,buflen, " (ran past the end)");
1338 UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
1339 }
1340 return plen + 2;
1341 }
1342 tlen -= ttlv_len;
1343 break;
1344 }
1345 }
1346 return plen + 2;
1347 } else {
1348 /* complain bitterly ? */
1349 /* fall through */
1350 goto trunc;
1351 }
1352
1353 trunc:
1354 return -2;
1355 }
1356
1357 int
1358 decode_prefix6(netdissect_options *ndo,
1359 const u_char *pd, u_int itemlen, char *buf, size_t buflen)
1360 {
1361 nd_ipv6 addr;
1362 u_int plen, plenbytes;
1363
1364 ITEMCHECK(1);
1365 plen = GET_U_1(pd);
1366 if (128 < plen)
1367 return -1;
1368 itemlen -= 1;
1369
1370 memset(&addr, 0, sizeof(addr));
1371 plenbytes = (plen + 7) / 8;
1372 ITEMCHECK(plenbytes);
1373 GET_CPY_BYTES(&addr, pd + 1, plenbytes);
1374 if (plen % 8) {
1375 addr[plenbytes - 1] &=
1376 ((0xff00 >> (plen % 8)) & 0xff);
1377 }
1378 snprintf(buf, buflen, "%s/%u", ip6addr_string(ndo, (const u_char *)&addr), plen);
1379 return 1 + plenbytes;
1380
1381 badtlv:
1382 return -2;
1383 }
1384
1385 static int
1386 decode_labeled_prefix6(netdissect_options *ndo,
1387 const u_char *pptr, u_int itemlen, char *buf, size_t buflen)
1388 {
1389 nd_ipv6 addr;
1390 u_int plen, plenbytes;
1391
1392 /* prefix length and label = 4 bytes */
1393 ND_TCHECK_4(pptr);
1394 ITEMCHECK(4);
1395 plen = GET_U_1(pptr); /* get prefix length */
1396
1397 if (24 > plen)
1398 return -1;
1399
1400 plen -= 24; /* adjust prefixlen - labellength */
1401
1402 if (128 < plen)
1403 return -1;
1404 itemlen -= 4;
1405
1406 memset(&addr, 0, sizeof(addr));
1407 plenbytes = (plen + 7) / 8;
1408 GET_CPY_BYTES(&addr, pptr + 4, plenbytes);
1409 if (plen % 8) {
1410 addr[plenbytes - 1] &=
1411 ((0xff00 >> (plen % 8)) & 0xff);
1412 }
1413 /* the label may get offsetted by 4 bits so lets shift it right */
1414 snprintf(buf, buflen, "%s/%u, label:%u %s",
1415 ip6addr_string(ndo, (const u_char *)&addr),
1416 plen,
1417 GET_BE_U_3(pptr + 1)>>4,
1418 ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
1419
1420 return 4 + plenbytes;
1421
1422 trunc:
1423 return -2;
1424
1425 badtlv:
1426 return -3;
1427 }
1428
1429 static int
1430 decode_labeled_vpn_prefix6(netdissect_options *ndo,
1431 const u_char *pptr, char *buf, size_t buflen)
1432 {
1433 nd_ipv6 addr;
1434 u_int plen;
1435
1436 plen = GET_U_1(pptr); /* get prefix length */
1437
1438 if ((24+64) > plen)
1439 return -1;
1440
1441 plen -= (24+64); /* adjust prefixlen - labellength - RD len*/
1442
1443 if (128 < plen)
1444 return -1;
1445
1446 memset(&addr, 0, sizeof(addr));
1447 GET_CPY_BYTES(&addr, pptr + 12, (plen + 7) / 8);
1448 if (plen % 8) {
1449 addr[(plen + 7) / 8 - 1] &=
1450 ((0xff00 >> (plen % 8)) & 0xff);
1451 }
1452 /* the label may get offsetted by 4 bits so lets shift it right */
1453 snprintf(buf, buflen, "RD: %s, %s/%u, label:%u %s",
1454 bgp_vpn_rd_print(ndo, pptr+4),
1455 ip6addr_string(ndo, (const u_char *)&addr),
1456 plen,
1457 GET_BE_U_3(pptr + 1)>>4,
1458 ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
1459
1460 return 12 + (plen + 7) / 8;
1461 }
1462
1463 static int
1464 decode_clnp_prefix(netdissect_options *ndo,
1465 const u_char *pptr, char *buf, size_t buflen)
1466 {
1467 uint8_t addr[19];
1468 u_int plen;
1469
1470 plen = GET_U_1(pptr); /* get prefix length */
1471
1472 if (152 < plen)
1473 return -1;
1474
1475 memset(&addr, 0, sizeof(addr));
1476 GET_CPY_BYTES(&addr, pptr + 4, (plen + 7) / 8);
1477 if (plen % 8) {
1478 addr[(plen + 7) / 8 - 1] &=
1479 ((0xff00 >> (plen % 8)) & 0xff);
1480 }
1481 /* Cannot use GET_ISONSAP_STRING (not packet buffer pointer) */
1482 snprintf(buf, buflen, "%s/%u",
1483 isonsap_string(ndo, addr,(plen + 7) / 8),
1484 plen);
1485
1486 return 1 + (plen + 7) / 8;
1487 }
1488
1489 static int
1490 decode_labeled_vpn_clnp_prefix(netdissect_options *ndo,
1491 const u_char *pptr, char *buf, size_t buflen)
1492 {
1493 uint8_t addr[19];
1494 u_int plen;
1495
1496 plen = GET_U_1(pptr); /* get prefix length */
1497
1498 if ((24+64) > plen)
1499 return -1;
1500
1501 plen -= (24+64); /* adjust prefixlen - labellength - RD len*/
1502
1503 if (152 < plen)
1504 return -1;
1505
1506 memset(&addr, 0, sizeof(addr));
1507 GET_CPY_BYTES(&addr, pptr + 12, (plen + 7) / 8);
1508 if (plen % 8) {
1509 addr[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff);
1510 }
1511 /* the label may get offsetted by 4 bits so lets shift it right */
1512 /* Cannot use GET_ISONSAP_STRING (not packet buffer pointer) */
1513 snprintf(buf, buflen, "RD: %s, %s/%u, label:%u %s",
1514 bgp_vpn_rd_print(ndo, pptr+4),
1515 isonsap_string(ndo, addr,(plen + 7) / 8),
1516 plen,
1517 GET_BE_U_3(pptr + 1)>>4,
1518 ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
1519
1520 return 12 + (plen + 7) / 8;
1521 }
1522
1523 /*
1524 * bgp_attr_get_as_size
1525 *
1526 * Try to find the size of the ASs encoded in an as-path. It is not obvious, as
1527 * both Old speakers that do not support 4 byte AS, and the new speakers that do
1528 * support, exchange AS-Path with the same path-attribute type value 0x02.
1529 */
1530 static u_int
1531 bgp_attr_get_as_size(netdissect_options *ndo,
1532 uint8_t bgpa_type, const u_char *pptr, u_int len)
1533 {
1534 const u_char *tptr = pptr;
1535
1536 /*
1537 * If the path attribute is the optional AS4 path type, then we already
1538 * know, that ASs must be encoded in 4 byte format.
1539 */
1540 if (bgpa_type == BGPTYPE_AS4_PATH) {
1541 return 4;
1542 }
1543
1544 /*
1545 * Let us assume that ASs are of 2 bytes in size, and check if the AS-Path
1546 * TLV is good. If not, ask the caller to try with AS encoded as 4 bytes
1547 * each.
1548 */
1549 while (tptr < pptr + len) {
1550 /*
1551 * If we do not find a valid segment type, our guess might be wrong.
1552 */
1553 if (GET_U_1(tptr) < BGP_AS_SEG_TYPE_MIN || GET_U_1(tptr) > BGP_AS_SEG_TYPE_MAX) {
1554 goto trunc;
1555 }
1556 tptr += 2 + GET_U_1(tptr + 1) * 2;
1557 }
1558
1559 /*
1560 * If we correctly reached end of the AS path attribute data content,
1561 * then most likely ASs were indeed encoded as 2 bytes.
1562 */
1563 if (tptr == pptr + len) {
1564 return 2;
1565 }
1566
1567 trunc:
1568
1569 /*
1570 * We can come here, either we did not have enough data, or if we
1571 * try to decode 4 byte ASs in 2 byte format. Either way, return 4,
1572 * so that calller can try to decode each AS as of 4 bytes. If indeed
1573 * there was not enough data, it will crib and end the parse anyways.
1574 */
1575 return 4;
1576 }
1577
1578 /*
1579 * The only way to know that a BGP UPDATE message is using add path is
1580 * by checking if the capability is in the OPEN message which we may have missed.
1581 * So this function checks if it is possible that the update could contain add path
1582 * and if so it checks that standard BGP doesn't make sense.
1583 */
1584 static int
1585 check_add_path(netdissect_options *ndo, const u_char *pptr, u_int length,
1586 u_int max_prefix_length)
1587 {
1588 u_int offset, prefix_length;
1589
1590 if (length < 5) {
1591 return 0;
1592 }
1593
1594 /*
1595 * Scan through the NLRI information under the assumpetion that
1596 * it doesn't have path IDs.
1597 */
1598 for (offset = 0; offset < length;) {
1599 offset += 4;
1600 if (!ND_TTEST_1(pptr + offset)) {
1601 /* We ran out of captured data; quit scanning. */
1602 break;
1603 }
1604 prefix_length = GET_U_1(pptr + offset);
1605 /*
1606 * Add 4 to cover the path id
1607 * and check the prefix length isn't greater than 32/128.
1608 */
1609 if (prefix_length > max_prefix_length) {
1610 return 0;
1611 }
1612 /* Add 1 for the prefix_length byte and prefix_length to cover the address */
1613 offset += 1 + ((prefix_length + 7) / 8);
1614 }
1615 /* check we haven't gone past the end of the section */
1616 if (offset > length) {
1617 return 0;
1618 }
1619
1620 /* check it's not standard BGP */
1621 for (offset = 0; offset < length; ) {
1622 if (!ND_TTEST_1(pptr + offset)) {
1623 /* We ran out of captured data; quit scanning. */
1624 break;
1625 }
1626 prefix_length = GET_U_1(pptr + offset);
1627 /*
1628 * If the prefix_length is zero (0.0.0.0/0)
1629 * and since it's not the only address (length >= 5)
1630 * then it is add-path
1631 */
1632 if (prefix_length < 1 || prefix_length > max_prefix_length) {
1633 return 1;
1634 }
1635 offset += 1 + ((prefix_length + 7) / 8);
1636 }
1637 if (offset > length) {
1638 return 1;
1639 }
1640
1641 /* assume not add-path by default */
1642 return 0;
1643 }
1644
1645 static int
1646 bgp_mp_af_print(netdissect_options *ndo,
1647 const u_char *tptr, u_int tlen,
1648 uint16_t *afp, uint8_t *safip)
1649 {
1650 uint16_t af;
1651 uint8_t safi;
1652
1653 af = GET_BE_U_2(tptr);
1654 *afp = af;
1655 safi = GET_U_1(tptr + 2);
1656 *safip = safi;
1657
1658 ND_PRINT("\n\t AFI: %s (%u), %sSAFI: %s (%u)",
1659 tok2str(af_values, "Unknown AFI", af),
1660 af,
1661 (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */
1662 tok2str(bgp_safi_values, "Unknown SAFI", safi),
1663 safi);
1664
1665 switch(af<<8 | safi) {
1666 case (AFNUM_INET<<8 | SAFNUM_UNICAST):
1667 case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
1668 case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
1669 case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
1670 case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
1671 case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
1672 case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
1673 case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
1674 case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN):
1675 case (AFNUM_INET<<8 | SAFNUM_MDT):
1676 case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
1677 case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
1678 case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
1679 case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
1680 case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
1681 case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
1682 case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
1683 case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
1684 case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
1685 case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
1686 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST):
1687 case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST):
1688 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST):
1689 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
1690 case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
1691 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
1692 case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
1693 break;
1694 default:
1695 ND_TCHECK_LEN(tptr, tlen);
1696 ND_PRINT("\n\t no AFI %u / SAFI %u decoder", af, safi);
1697 if (ndo->ndo_vflag <= 1)
1698 print_unknown_data(ndo, tptr, "\n\t ", tlen);
1699 return -1;
1700 }
1701 return 0;
1702 trunc:
1703 return -2;
1704 }
1705
1706 static int
1707 bgp_nlri_print(netdissect_options *ndo, uint16_t af, uint8_t safi,
1708 const u_char *tptr, u_int len,
1709 char *buf, size_t buflen,
1710 int add_path4, int add_path6)
1711 {
1712 int advance;
1713 u_int path_id = 0;
1714
1715 switch (af<<8 | safi) {
1716 case (AFNUM_INET<<8 | SAFNUM_UNICAST):
1717 case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
1718 case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
1719 if (add_path4) {
1720 path_id = GET_BE_U_4(tptr);
1721 tptr += 4;
1722 }
1723 advance = decode_prefix4(ndo, tptr, len, buf, buflen);
1724 if (advance == -1)
1725 ND_PRINT("\n\t (illegal prefix length)");
1726 else if (advance == -2)
1727 break; /* bytes left, but not enough */
1728 else
1729 ND_PRINT("\n\t %s", buf);
1730 if (add_path4) {
1731 ND_PRINT(" Path Id: %u", path_id);
1732 advance += 4;
1733 }
1734 break;
1735 case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
1736 advance = decode_labeled_prefix4(ndo, tptr, len, buf, buflen);
1737 if (advance == -1)
1738 ND_PRINT("\n\t (illegal prefix length)");
1739 else if (advance == -2)
1740 goto trunc;
1741 else if (advance == -3)
1742 break; /* bytes left, but not enough */
1743 else
1744 ND_PRINT("\n\t %s", buf);
1745 break;
1746 case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
1747 case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
1748 case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
1749 advance = decode_labeled_vpn_prefix4(ndo, tptr, buf, buflen);
1750 if (advance == -1)
1751 ND_PRINT("\n\t (illegal prefix length)");
1752 else
1753 ND_PRINT("\n\t %s", buf);
1754 break;
1755 case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
1756 advance = decode_rt_routing_info(ndo, tptr);
1757 break;
1758 case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */
1759 case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN):
1760 advance = decode_multicast_vpn(ndo, tptr, buf, buflen);
1761 if (advance == -1)
1762 ND_PRINT("\n\t (illegal prefix length)");
1763 else if (advance == -2)
1764 goto trunc;
1765 else
1766 ND_PRINT("\n\t %s", buf);
1767 break;
1768
1769 case (AFNUM_INET<<8 | SAFNUM_MDT):
1770 advance = decode_mdt_vpn_nlri(ndo, tptr, buf, buflen);
1771 if (advance == -1)
1772 ND_PRINT("\n\t (illegal prefix length)");
1773 else if (advance == -2)
1774 goto trunc;
1775 else
1776 ND_PRINT("\n\t %s", buf);
1777 break;
1778 case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
1779 case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
1780 case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
1781 if (add_path6) {
1782 path_id = GET_BE_U_4(tptr);
1783 tptr += 4;
1784 }
1785 advance = decode_prefix6(ndo, tptr, len, buf, buflen);
1786 if (advance == -1)
1787 ND_PRINT("\n\t (illegal prefix length)");
1788 else if (advance == -2)
1789 break; /* bytes left, but not enough */
1790 else
1791 ND_PRINT("\n\t %s", buf);
1792 if (add_path6) {
1793 ND_PRINT(" Path Id: %u", path_id);
1794 advance += 4;
1795 }
1796 break;
1797 case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
1798 advance = decode_labeled_prefix6(ndo, tptr, len, buf, buflen);
1799 if (advance == -1)
1800 ND_PRINT("\n\t (illegal prefix length)");
1801 else if (advance == -2)
1802 goto trunc;
1803 else if (advance == -3)
1804 break; /* bytes left, but not enough */
1805 else
1806 ND_PRINT("\n\t %s", buf);
1807 break;
1808 case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
1809 case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
1810 case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
1811 advance = decode_labeled_vpn_prefix6(ndo, tptr, buf, buflen);
1812 if (advance == -1)
1813 ND_PRINT("\n\t (illegal prefix length)");
1814 else
1815 ND_PRINT("\n\t %s", buf);
1816 break;
1817 case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
1818 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
1819 case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
1820 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
1821 advance = decode_labeled_vpn_l2(ndo, tptr, buf, buflen);
1822 if (advance == -1)
1823 ND_PRINT("\n\t (illegal length)");
1824 else if (advance == -2)
1825 goto trunc;
1826 else
1827 ND_PRINT("\n\t %s", buf);
1828 break;
1829 case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
1830 case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
1831 case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
1832 advance = decode_clnp_prefix(ndo, tptr, buf, buflen);
1833 if (advance == -1)
1834 ND_PRINT("\n\t (illegal prefix length)");
1835 else
1836 ND_PRINT("\n\t %s", buf);
1837 break;
1838 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST):
1839 case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST):
1840 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST):
1841 advance = decode_labeled_vpn_clnp_prefix(ndo, tptr, buf, buflen);
1842 if (advance == -1)
1843 ND_PRINT("\n\t (illegal prefix length)");
1844 else
1845 ND_PRINT("\n\t %s", buf);
1846 break;
1847 default:
1848 /*
1849 * This should not happen, we should have been protected
1850 * by bgp_mp_af_print()'s return value.
1851 */
1852 ND_PRINT("\n\t ERROR: no AFI %u / SAFI %u decoder", af, safi);
1853 advance = -4;
1854 break;
1855 }
1856 return advance;
1857 trunc: /* we rely on the caller to recognize -2 return value */
1858 return -2;
1859 }
1860
1861 static int
1862 bgp_attr_print(netdissect_options *ndo,
1863 uint8_t atype, const u_char *pptr, u_int len,
1864 const unsigned attr_set_level)
1865 {
1866 u_int i;
1867 uint16_t af;
1868 uint8_t safi, snpa, nhlen;
1869 int advance;
1870 u_int tlen;
1871 const u_char *tptr;
1872 char buf[MAXHOSTNAMELEN + 100];
1873 u_int as_size;
1874 int add_path4, add_path6;
1875 int ret;
1876
1877 tptr = pptr;
1878 tlen = len;
1879
1880 switch (atype) {
1881 case BGPTYPE_ORIGIN:
1882 if (len != 1)
1883 ND_PRINT("invalid len");
1884 else {
1885 ND_PRINT("%s", tok2str(bgp_origin_values,
1886 "Unknown Origin Typecode",
1887 GET_U_1(tptr)));
1888 }
1889 break;
1890
1891 /*
1892 * Process AS4 byte path and AS2 byte path attributes here.
1893 */
1894 case BGPTYPE_AS4_PATH:
1895 case BGPTYPE_AS_PATH:
1896 if (len % 2) {
1897 ND_PRINT("invalid len");
1898 break;
1899 }
1900 if (!len) {
1901 ND_PRINT("empty");
1902 break;
1903 }
1904
1905 /*
1906 * BGP updates exchanged between New speakers that support 4
1907 * byte AS, ASs are always encoded in 4 bytes. There is no
1908 * definitive way to find this, just by the packet's
1909 * contents. So, check for packet's TLV's sanity assuming
1910 * 2 bytes first, and it does not pass, assume that ASs are
1911 * encoded in 4 bytes format and move on.
1912 */
1913 as_size = bgp_attr_get_as_size(ndo, atype, pptr, len);
1914
1915 while (tptr < pptr + len) {
1916 ND_PRINT("%s", tok2str(bgp_as_path_segment_open_values,
1917 "?", GET_U_1(tptr)));
1918 for (i = 0; i < GET_U_1(tptr + 1) * as_size; i += as_size) {
1919 ND_TCHECK_LEN(tptr + 2 + i, as_size);
1920 ND_PRINT("%s ",
1921 as_printf(ndo, astostr, sizeof(astostr),
1922 as_size == 2 ?
1923 GET_BE_U_2(tptr + i + 2) :
1924 GET_BE_U_4(tptr + i + 2)));
1925 }
1926 ND_PRINT("%s", tok2str(bgp_as_path_segment_close_values,
1927 "?", GET_U_1(tptr)));
1928 tptr += 2 + GET_U_1(tptr + 1) * as_size;
1929 }
1930 break;
1931 case BGPTYPE_NEXT_HOP:
1932 if (len != 4)
1933 ND_PRINT("invalid len");
1934 else {
1935 ND_PRINT("%s", GET_IPADDR_STRING(tptr));
1936 }
1937 break;
1938 case BGPTYPE_MULTI_EXIT_DISC:
1939 case BGPTYPE_LOCAL_PREF:
1940 if (len != 4)
1941 ND_PRINT("invalid len");
1942 else {
1943 ND_PRINT("%u", GET_BE_U_4(tptr));
1944 }
1945 break;
1946 case BGPTYPE_ATOMIC_AGGREGATE:
1947 if (len != 0)
1948 ND_PRINT("invalid len");
1949 break;
1950 case BGPTYPE_AGGREGATOR:
1951
1952 /*
1953 * Depending on the AS encoded is of 2 bytes or of 4 bytes,
1954 * the length of this PA can be either 6 bytes or 8 bytes.
1955 */
1956 if (len != 6 && len != 8) {
1957 ND_PRINT("invalid len");
1958 break;
1959 }
1960 ND_TCHECK_LEN(tptr, len);
1961 if (len == 6) {
1962 ND_PRINT(" AS #%s, origin %s",
1963 as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_2(tptr)),
1964 GET_IPADDR_STRING(tptr + 2));
1965 } else {
1966 ND_PRINT(" AS #%s, origin %s",
1967 as_printf(ndo, astostr, sizeof(astostr),
1968 GET_BE_U_4(tptr)), GET_IPADDR_STRING(tptr + 4));
1969 }
1970 break;
1971 case BGPTYPE_AGGREGATOR4:
1972 if (len != 8) {
1973 ND_PRINT("invalid len");
1974 break;
1975 }
1976 ND_PRINT(" AS #%s, origin %s",
1977 as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_4(tptr)),
1978 GET_IPADDR_STRING(tptr + 4));
1979 break;
1980 case BGPTYPE_COMMUNITIES:
1981 if (len % 4) {
1982 ND_PRINT("invalid len");
1983 break;
1984 }
1985 while (tlen != 0) {
1986 uint32_t comm;
1987 ND_TCHECK_4(tptr);
1988 if (tlen < 4)
1989 goto trunc;
1990 comm = GET_BE_U_4(tptr);
1991 switch (comm) {
1992 case BGP_COMMUNITY_NO_EXPORT:
1993 ND_PRINT(" NO_EXPORT");
1994 break;
1995 case BGP_COMMUNITY_NO_ADVERT:
1996 ND_PRINT(" NO_ADVERTISE");
1997 break;
1998 case BGP_COMMUNITY_NO_EXPORT_SUBCONFED:
1999 ND_PRINT(" NO_EXPORT_SUBCONFED");
2000 break;
2001 default:
2002 ND_PRINT("%u:%u%s",
2003 (comm >> 16) & 0xffff,
2004 comm & 0xffff,
2005 (tlen>4) ? ", " : "");
2006 break;
2007 }
2008 tlen -=4;
2009 tptr +=4;
2010 }
2011 break;
2012 case BGPTYPE_ORIGINATOR_ID:
2013 if (len != 4) {
2014 ND_PRINT("invalid len");
2015 break;
2016 }
2017 ND_PRINT("%s",GET_IPADDR_STRING(tptr));
2018 break;
2019 case BGPTYPE_CLUSTER_LIST:
2020 if (len % 4) {
2021 ND_PRINT("invalid len");
2022 break;
2023 }
2024 while (tlen != 0) {
2025 if (tlen < 4)
2026 goto trunc;
2027 ND_PRINT("%s%s",
2028 GET_IPADDR_STRING(tptr),
2029 (tlen>4) ? ", " : "");
2030 tlen -=4;
2031 tptr +=4;
2032 }
2033 break;
2034 case BGPTYPE_MP_REACH_NLRI:
2035 ND_TCHECK_3(tptr);
2036 if (tlen < 3)
2037 goto trunc;
2038 ret = bgp_mp_af_print(ndo, tptr, tlen, &af, &safi);
2039 if (ret == -2)
2040 goto trunc;
2041 if (ret < 0)
2042 break;
2043
2044 tptr += 3;
2045 tlen -= 3;
2046
2047 ND_TCHECK_1(tptr);
2048 if (tlen < 1)
2049 goto trunc;
2050 nhlen = GET_U_1(tptr);
2051 tptr++;
2052 tlen--;
2053
2054 if (nhlen) {
2055 u_int nnh = 0;
2056 uint8_t tnhlen = nhlen;
2057 if (tlen < tnhlen)
2058 goto trunc;
2059 ND_PRINT("\n\t nexthop: ");
2060 while (tnhlen != 0) {
2061 if (nnh++ > 0) {
2062 ND_PRINT(", " );
2063 }
2064 switch(af<<8 | safi) {
2065 case (AFNUM_INET<<8 | SAFNUM_UNICAST):
2066 case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
2067 case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
2068 case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
2069 case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
2070 case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN):
2071 case (AFNUM_INET<<8 | SAFNUM_MDT):
2072 if (tnhlen < sizeof(nd_ipv4)) {
2073 ND_PRINT("invalid len");
2074 tptr += tnhlen;
2075 tlen -= tnhlen;
2076 tnhlen = 0;
2077 } else {
2078 ND_PRINT("%s",GET_IPADDR_STRING(tptr));
2079 tptr += sizeof(nd_ipv4);
2080 tnhlen -= sizeof(nd_ipv4);
2081 tlen -= sizeof(nd_ipv4);
2082 }
2083 break;
2084 case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
2085 case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
2086 case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
2087 if (tnhlen < sizeof(nd_ipv4)+BGP_VPN_RD_LEN) {
2088 ND_PRINT("invalid len");
2089 tptr += tnhlen;
2090 tlen -= tnhlen;
2091 tnhlen = 0;
2092 } else {
2093 ND_PRINT("RD: %s, %s",
2094 bgp_vpn_rd_print(ndo, tptr),
2095 GET_IPADDR_STRING(tptr+BGP_VPN_RD_LEN));
2096 tptr += (sizeof(nd_ipv4)+BGP_VPN_RD_LEN);
2097 tlen -= (sizeof(nd_ipv4)+BGP_VPN_RD_LEN);
2098 tnhlen -= (sizeof(nd_ipv4)+BGP_VPN_RD_LEN);
2099 }
2100 break;
2101 case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
2102 case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
2103 case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
2104 case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
2105 if (tnhlen < sizeof(nd_ipv6)) {
2106 ND_PRINT("invalid len");
2107 tptr += tnhlen;
2108 tlen -= tnhlen;
2109 tnhlen = 0;
2110 } else {
2111 ND_PRINT("%s", GET_IP6ADDR_STRING(tptr));
2112 tptr += sizeof(nd_ipv6);
2113 tlen -= sizeof(nd_ipv6);
2114 tnhlen -= sizeof(nd_ipv6);
2115 }
2116 break;
2117 case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
2118 case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
2119 case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
2120 if (tnhlen < sizeof(nd_ipv6)+BGP_VPN_RD_LEN) {
2121 ND_PRINT("invalid len");
2122 tptr += tnhlen;
2123 tlen -= tnhlen;
2124 tnhlen = 0;
2125 } else {
2126 ND_PRINT("RD: %s, %s",
2127 bgp_vpn_rd_print(ndo, tptr),
2128 GET_IP6ADDR_STRING(tptr+BGP_VPN_RD_LEN));
2129 tptr += (sizeof(nd_ipv6)+BGP_VPN_RD_LEN);
2130 tlen -= (sizeof(nd_ipv6)+BGP_VPN_RD_LEN);
2131 tnhlen -= (sizeof(nd_ipv6)+BGP_VPN_RD_LEN);
2132 }
2133 break;
2134 case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
2135 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
2136 case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
2137 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
2138 if (tnhlen < sizeof(nd_ipv4)) {
2139 ND_PRINT("invalid len");
2140 tptr += tnhlen;
2141 tlen -= tnhlen;
2142 tnhlen = 0;
2143 } else {
2144 ND_PRINT("%s", GET_IPADDR_STRING(tptr));
2145 tptr += (sizeof(nd_ipv4));
2146 tlen -= (sizeof(nd_ipv4));
2147 tnhlen -= (sizeof(nd_ipv4));
2148 }
2149 break;
2150 case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
2151 case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
2152 case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
2153 ND_PRINT("%s", GET_ISONSAP_STRING(tptr, tnhlen));
2154 tptr += tnhlen;
2155 tlen -= tnhlen;
2156 tnhlen = 0;
2157 break;
2158
2159 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST):
2160 case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST):
2161 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST):
2162 if (tnhlen < BGP_VPN_RD_LEN+1) {
2163 ND_PRINT("invalid len");
2164 tptr += tnhlen;
2165 tlen -= tnhlen;
2166 tnhlen = 0;
2167 } else {
2168 ND_TCHECK_LEN(tptr, tnhlen);
2169 ND_PRINT("RD: %s, %s",
2170 bgp_vpn_rd_print(ndo, tptr),
2171 GET_ISONSAP_STRING(tptr+BGP_VPN_RD_LEN,tnhlen-BGP_VPN_RD_LEN));
2172 /* rfc986 mapped IPv4 address ? */
2173 if (GET_BE_U_4(tptr + BGP_VPN_RD_LEN) == 0x47000601)
2174 ND_PRINT(" = %s", GET_IPADDR_STRING(tptr+BGP_VPN_RD_LEN+4));
2175 /* rfc1888 mapped IPv6 address ? */
2176 else if (GET_BE_U_3(tptr + BGP_VPN_RD_LEN) == 0x350000)
2177 ND_PRINT(" = %s", GET_IP6ADDR_STRING(tptr+BGP_VPN_RD_LEN+3));
2178 tptr += tnhlen;
2179 tlen -= tnhlen;
2180 tnhlen = 0;
2181 }
2182 break;
2183 default:
2184 /*
2185 * bgp_mp_af_print() should have saved us from
2186 * an unsupported AFI/SAFI.
2187 */
2188 ND_PRINT("ERROR: no AFI %u/SAFI %u nexthop decoder", af, safi);
2189 tptr += tnhlen;
2190 tlen -= tnhlen;
2191 tnhlen = 0;
2192 goto done;
2193 break;
2194 }
2195 }
2196 }
2197 ND_PRINT(", nh-length: %u", nhlen);
2198
2199 /* As per RFC 2858; this is reserved in RFC 4760 */
2200 if (tlen < 1)
2201 goto trunc;
2202 snpa = GET_U_1(tptr);
2203 tptr++;
2204 tlen--;
2205
2206 if (snpa) {
2207 ND_PRINT("\n\t %u SNPA", snpa);
2208 for (/*nothing*/; snpa != 0; snpa--) {
2209 uint8_t snpalen;
2210 if (tlen < 1)
2211 goto trunc;
2212 snpalen = GET_U_1(tptr);
2213 ND_PRINT("\n\t %u bytes", snpalen);
2214 tptr++;
2215 tlen--;
2216 if (tlen < snpalen)
2217 goto trunc;
2218 ND_TCHECK_LEN(tptr, snpalen);
2219 tptr += snpalen;
2220 tlen -= snpalen;
2221 }
2222 } else {
2223 ND_PRINT(", no SNPA");
2224 }
2225
2226 add_path4 = check_add_path(ndo, tptr, (len-ND_BYTES_BETWEEN(tptr, pptr)), 32);
2227 add_path6 = check_add_path(ndo, tptr, (len-ND_BYTES_BETWEEN(tptr, pptr)), 128);
2228
2229 while (tptr < pptr + len) {
2230 advance = bgp_nlri_print(ndo, af, safi, tptr, len, buf, sizeof(buf),
2231 add_path4, add_path6);
2232 if (advance == -2)
2233 goto trunc;
2234 if (advance < 0)
2235 break;
2236 tptr += advance;
2237 }
2238 break;
2239
2240 case BGPTYPE_MP_UNREACH_NLRI:
2241 ND_TCHECK_LEN(tptr, BGP_MP_NLRI_MINSIZE);
2242 ret = bgp_mp_af_print(ndo, tptr, tlen, &af, &safi);
2243 if (ret == -2)
2244 goto trunc;
2245 if (ret < 0)
2246 break;
2247
2248 if (len == BGP_MP_NLRI_MINSIZE)
2249 ND_PRINT("\n\t End-of-Rib Marker (empty NLRI)");
2250
2251 tptr += 3;
2252
2253 add_path4 = check_add_path(ndo, tptr, (len-ND_BYTES_BETWEEN(tptr, pptr)), 32);
2254 add_path6 = check_add_path(ndo, tptr, (len-ND_BYTES_BETWEEN(tptr, pptr)), 128);
2255
2256 while (tptr < pptr + len) {
2257 advance = bgp_nlri_print(ndo, af, safi, tptr, len, buf, sizeof(buf),
2258 add_path4, add_path6);
2259 if (advance == -2)
2260 goto trunc;
2261 if (advance < 0)
2262 break;
2263 tptr += advance;
2264 }
2265 break;
2266 case BGPTYPE_EXTD_COMMUNITIES:
2267 if (len % 8) {
2268 ND_PRINT("invalid len");
2269 break;
2270 }
2271 while (tlen != 0) {
2272 uint16_t extd_comm;
2273
2274 ND_TCHECK_2(tptr);
2275 if (tlen < 2)
2276 goto trunc;
2277 extd_comm=GET_BE_U_2(tptr);
2278
2279 ND_PRINT("\n\t %s (0x%04x), Flags [%s]",
2280 tok2str(bgp_extd_comm_subtype_values,
2281 "unknown extd community typecode",
2282 extd_comm),
2283 extd_comm,
2284 bittok2str(bgp_extd_comm_flag_values, "none", extd_comm));
2285
2286 ND_TCHECK_8(tptr);
2287 if (tlen < 8)
2288 goto trunc;
2289 ND_PRINT(": ");
2290 bgp_extended_community_print(ndo, tptr);
2291 tlen -= 8;
2292 tptr += 8;
2293 }
2294 break;
2295
2296 case BGPTYPE_PMSI_TUNNEL:
2297 {
2298 uint8_t tunnel_type, flags;
2299
2300 ND_TCHECK_5(tptr);
2301 if (tlen < 5)
2302 goto trunc;
2303 flags = GET_U_1(tptr);
2304 tunnel_type = GET_U_1(tptr + 1);
2305
2306 ND_PRINT("\n\t Tunnel-type %s (%u), Flags [%s], MPLS Label %u",
2307 tok2str(bgp_pmsi_tunnel_values, "Unknown", tunnel_type),
2308 tunnel_type,
2309 bittok2str(bgp_pmsi_flag_values, "none", flags),
2310 GET_BE_U_3(tptr + 2)>>4);
2311
2312 tptr +=5;
2313 tlen -= 5;
2314
2315 switch (tunnel_type) {
2316 case BGP_PMSI_TUNNEL_PIM_SM: /* fall through */
2317 case BGP_PMSI_TUNNEL_PIM_BIDIR:
2318 ND_PRINT("\n\t Sender %s, P-Group %s",
2319 GET_IPADDR_STRING(tptr),
2320 GET_IPADDR_STRING(tptr+4));
2321 break;
2322
2323 case BGP_PMSI_TUNNEL_PIM_SSM:
2324 ND_PRINT("\n\t Root-Node %s, P-Group %s",
2325 GET_IPADDR_STRING(tptr),
2326 GET_IPADDR_STRING(tptr+4));
2327 break;
2328 case BGP_PMSI_TUNNEL_INGRESS:
2329 ND_PRINT("\n\t Tunnel-Endpoint %s",
2330 GET_IPADDR_STRING(tptr));
2331 break;
2332 case BGP_PMSI_TUNNEL_LDP_P2MP: /* fall through */
2333 case BGP_PMSI_TUNNEL_LDP_MP2MP:
2334 ND_PRINT("\n\t Root-Node %s, LSP-ID 0x%08x",
2335 GET_IPADDR_STRING(tptr),
2336 GET_BE_U_4(tptr + 4));
2337 break;
2338 case BGP_PMSI_TUNNEL_RSVP_P2MP:
2339 ND_PRINT("\n\t Extended-Tunnel-ID %s, P2MP-ID 0x%08x",
2340 GET_IPADDR_STRING(tptr),
2341 GET_BE_U_4(tptr + 4));
2342 break;
2343 default:
2344 if (ndo->ndo_vflag <= 1) {
2345 print_unknown_data(ndo, tptr, "\n\t ", tlen);
2346 }
2347 }
2348 break;
2349 }
2350 case BGPTYPE_AIGP:
2351 {
2352 uint8_t type;
2353 uint16_t length;
2354
2355 while (tlen >= 3) {
2356 type = GET_U_1(tptr);
2357 length = GET_BE_U_2(tptr + 1);
2358 tptr += 3;
2359 tlen -= 3;
2360
2361 ND_PRINT("\n\t %s TLV (%u), length %u",
2362 tok2str(bgp_aigp_values, "Unknown", type),
2363 type, length);
2364
2365 if (length < 3)
2366 goto trunc;
2367 length -= 3;
2368
2369 /*
2370 * Check if we can read the TLV data.
2371 */
2372 ND_TCHECK_LEN(tptr + 3, length);
2373 if (tlen < length)
2374 goto trunc;
2375
2376 switch (type) {
2377
2378 case BGP_AIGP_TLV:
2379 if (length < 8)
2380 goto trunc;
2381 ND_PRINT(", metric %" PRIu64,
2382 GET_BE_U_8(tptr));
2383 break;
2384
2385 default:
2386 if (ndo->ndo_vflag <= 1) {
2387 print_unknown_data(ndo, tptr,"\n\t ", length);
2388 }
2389 }
2390
2391 tptr += length;
2392 tlen -= length;
2393 }
2394 break;
2395 }
2396 case BGPTYPE_ATTR_SET:
2397 ND_TCHECK_4(tptr);
2398 if (len < 4)
2399 goto trunc;
2400 ND_PRINT("\n\t Origin AS: %s",
2401 as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_4(tptr)));
2402 tptr += 4;
2403 len -= 4;
2404
2405 while (len) {
2406 u_int aflags, alenlen, alen;
2407
2408 ND_TCHECK_2(tptr);
2409 if (len < 2) {
2410 ND_PRINT(" [path attr too short]");
2411 tptr += len;
2412 break;
2413 }
2414 aflags = GET_U_1(tptr);
2415 atype = GET_U_1(tptr + 1);
2416 tptr += 2;
2417 len -= 2;
2418 alenlen = bgp_attr_lenlen(aflags, tptr);
2419 ND_TCHECK_LEN(tptr, alenlen);
2420 if (len < alenlen) {
2421 ND_PRINT(" [path attr too short]");
2422 tptr += len;
2423 break;
2424 }
2425 alen = bgp_attr_len(aflags, tptr);
2426 tptr += alenlen;
2427 len -= alenlen;
2428
2429 ND_PRINT("\n\t %s (%u), length: %u",
2430 tok2str(bgp_attr_values,
2431 "Unknown Attribute", atype),
2432 atype,
2433 alen);
2434
2435 if (aflags) {
2436 ND_PRINT(", Flags [%s%s%s%s",
2437 aflags & 0x80 ? "O" : "",
2438 aflags & 0x40 ? "T" : "",
2439 aflags & 0x20 ? "P" : "",
2440 aflags & 0x10 ? "E" : "");
2441 if (aflags & 0xf)
2442 ND_PRINT("+%x", aflags & 0xf);
2443 ND_PRINT("]");
2444 }
2445 ND_PRINT(": ");
2446 if (len < alen) {
2447 ND_PRINT(" [path attr too short]");
2448 tptr += len;
2449 break;
2450 }
2451 /*
2452 * The protocol encoding per se allows ATTR_SET to be nested
2453 * as many times as the message can accommodate. This printer
2454 * used to be able to recurse into ATTR_SET contents until the
2455 * stack exhaustion, but now there is a limit on that (if live
2456 * protocol exchange goes that many levels deep, something is
2457 * probably wrong anyway). Feel free to refine this value if
2458 * you can find the spec with respective normative text.
2459 */
2460 if (attr_set_level == 10)
2461 ND_PRINT("(too many nested levels, not recursing)");
2462 else if (!bgp_attr_print(ndo, atype, tptr, alen, attr_set_level + 1))
2463 return 0;
2464 tptr += alen;
2465 len -= alen;
2466 }
2467 break;
2468
2469 case BGPTYPE_LARGE_COMMUNITY:
2470 if (len == 0 || len % 12) {
2471 ND_PRINT("invalid len");
2472 break;
2473 }
2474 ND_PRINT("\n\t ");
2475 while (len != 0) {
2476 ND_PRINT("%u:%u:%u%s",
2477 GET_BE_U_4(tptr),
2478 GET_BE_U_4(tptr + 4),
2479 GET_BE_U_4(tptr + 8),
2480 (len > 12) ? ", " : "");
2481 tptr += 12;
2482 /*
2483 * len will always be a multiple of 12, as per the above,
2484 * so this will never underflow.
2485 */
2486 len -= 12;
2487 }
2488 break;
2489 default:
2490 ND_TCHECK_LEN(pptr, len);
2491 ND_PRINT("\n\t no Attribute %u decoder", atype); /* we have no decoder for the attribute */
2492 if (ndo->ndo_vflag <= 1)
2493 print_unknown_data(ndo, pptr, "\n\t ", len);
2494 break;
2495 }
2496 done:
2497 if (ndo->ndo_vflag > 1 && len) { /* omit zero length attributes*/
2498 ND_TCHECK_LEN(pptr, len);
2499 print_unknown_data(ndo, pptr, "\n\t ", len);
2500 }
2501 return 1;
2502
2503 trunc:
2504 return 0;
2505 }
2506
2507 static void
2508 bgp_capabilities_print(netdissect_options *ndo,
2509 const u_char *opt, u_int caps_len)
2510 {
2511 u_int cap_type, cap_len, tcap_len, cap_offset;
2512 u_int i = 0;
2513
2514 while (i < caps_len) {
2515 ND_TCHECK_LEN(opt + i, BGP_CAP_HEADER_SIZE);
2516 cap_type=GET_U_1(opt + i);
2517 cap_len=GET_U_1(opt + i + 1);
2518 ND_PRINT("\n\t %s (%u), length: %u",
2519 tok2str(bgp_capcode_values, "Unknown", cap_type),
2520 cap_type,
2521 cap_len);
2522 ND_TCHECK_LEN(opt + 2 + i, cap_len);
2523 switch (cap_type) {
2524 case BGP_CAPCODE_MP:
2525 /* AFI (16 bits), Reserved (8 bits), SAFI (8 bits) */
2526 if (cap_len < 4) {
2527 ND_PRINT(" (too short, < 4)");
2528 return;
2529 }
2530 ND_PRINT("\n\t\tAFI %s (%u), SAFI %s (%u)",
2531 tok2str(af_values, "Unknown", GET_BE_U_2(opt + i + 2)),
2532 GET_BE_U_2(opt + i + 2),
2533 tok2str(bgp_safi_values, "Unknown", GET_U_1(opt + i + 5)),
2534 GET_U_1(opt + i + 5));
2535 break;
2536 case BGP_CAPCODE_ML:
2537 cap_offset = 2;
2538 tcap_len = cap_len;
2539 while (tcap_len >= 4) {
2540 ND_PRINT( "\n\t\tAFI %s (%u), SAFI %s (%u), Count: %u",
2541 tok2str(af_values, "Unknown",
2542 GET_BE_U_2(opt + i + cap_offset)),
2543 GET_BE_U_2(opt + i + cap_offset),
2544 tok2str(bgp_safi_values, "Unknown",
2545 GET_U_1(opt + i + cap_offset + 2)),
2546 GET_U_1(opt + i + cap_offset + 2),
2547 GET_U_1(opt + i + cap_offset + 3));
2548 tcap_len -= 4;
2549 cap_offset += 4;
2550 }
2551 break;
2552 case BGP_CAPCODE_RESTART:
2553 /* Restart Flags (4 bits), Restart Time in seconds (12 bits) */
2554 if (cap_len < 2) {
2555 ND_PRINT(" (too short, < 2)");
2556 return;
2557 }
2558 tcap_len=cap_len;
2559 ND_PRINT("\n\t\tRestart Flags: [%s], Restart Time %us",
2560 ((GET_U_1(opt + i + 2))&0x80) ? "R" : "none",
2561 GET_BE_U_2(opt + i + 2)&0xfff);
2562 tcap_len-=2;
2563 cap_offset=4;
2564 while(tcap_len>=4) {
2565 ND_PRINT("\n\t\t AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s",
2566 tok2str(af_values,"Unknown",
2567 GET_BE_U_2(opt + i + cap_offset)),
2568 GET_BE_U_2(opt + i + cap_offset),
2569 tok2str(bgp_safi_values,"Unknown",
2570 GET_U_1(opt + i + cap_offset + 2)),
2571 GET_U_1(opt + (i + cap_offset + 2)),
2572 ((GET_U_1(opt + (i + cap_offset + 3)))&0x80) ? "yes" : "no" );
2573 tcap_len -= 4;
2574 cap_offset += 4;
2575 }
2576 break;
2577 case BGP_CAPCODE_RR:
2578 case BGP_CAPCODE_LLGR:
2579 case BGP_CAPCODE_RR_CISCO:
2580 break;
2581 case BGP_CAPCODE_AS_NEW:
2582 /*
2583 * Extract the 4 byte AS number encoded.
2584 */
2585 if (cap_len < 4) {
2586 ND_PRINT(" (too short, < 4)");
2587 return;
2588 }
2589 ND_PRINT("\n\t\t 4 Byte AS %s",
2590 as_printf(ndo, astostr, sizeof(astostr),
2591 GET_BE_U_4(opt + i + 2)));
2592 break;
2593 case BGP_CAPCODE_ADD_PATH:
2594 if (cap_len == 0) {
2595 ND_PRINT(" (bogus)"); /* length */
2596 break;
2597 }
2598 tcap_len=cap_len;
2599 cap_offset=2;
2600 while (tcap_len != 0) {
2601 if (tcap_len < 4) {
2602 nd_print_invalid(ndo);
2603 break;
2604 }
2605 ND_PRINT("\n\t\tAFI %s (%u), SAFI %s (%u), Send/Receive: %s",
2606 tok2str(af_values,"Unknown",GET_BE_U_2(opt + i + cap_offset)),
2607 GET_BE_U_2(opt + i + cap_offset),
2608 tok2str(bgp_safi_values,"Unknown",GET_U_1(opt + i + cap_offset + 2)),
2609 GET_U_1(opt + (i + cap_offset + 2)),
2610 tok2str(bgp_add_path_recvsend,"Bogus (0x%02x)",GET_U_1(opt + i + cap_offset + 3))
2611 );
2612 tcap_len -= 4;
2613 cap_offset += 4;
2614 }
2615 break;
2616 default:
2617 ND_PRINT("\n\t\tno decoder for Capability %u",
2618 cap_type);
2619 if (ndo->ndo_vflag <= 1)
2620 print_unknown_data(ndo, opt + i + 2, "\n\t\t",
2621 cap_len);
2622 break;
2623 }
2624 if (ndo->ndo_vflag > 1 && cap_len != 0) {
2625 print_unknown_data(ndo, opt + i + 2, "\n\t\t", cap_len);
2626 }
2627 i += BGP_CAP_HEADER_SIZE + cap_len;
2628 }
2629 return;
2630
2631 trunc:
2632 nd_print_trunc(ndo);
2633 }
2634
2635 static void
2636 bgp_open_print(netdissect_options *ndo,
2637 const u_char *dat, u_int length)
2638 {
2639 const struct bgp_open *bgp_open_header;
2640 u_int optslen;
2641 const struct bgp_opt *bgpopt;
2642 const u_char *opt;
2643 u_int i;
2644
2645 ND_TCHECK_LEN(dat, BGP_OPEN_SIZE);
2646 if (length < BGP_OPEN_SIZE)
2647 goto trunc;
2648
2649 bgp_open_header = (const struct bgp_open *)dat;
2650
2651 ND_PRINT("\n\t Version %u, ",
2652 GET_U_1(bgp_open_header->bgpo_version));
2653 ND_PRINT("my AS %s, ",
2654 as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_2(bgp_open_header->bgpo_myas)));
2655 ND_PRINT("Holdtime %us, ",
2656 GET_BE_U_2(bgp_open_header->bgpo_holdtime));
2657 ND_PRINT("ID %s", GET_IPADDR_STRING(bgp_open_header->bgpo_id));
2658 optslen = GET_U_1(bgp_open_header->bgpo_optlen);
2659 ND_PRINT("\n\t Optional parameters, length: %u", optslen);
2660
2661 opt = dat + BGP_OPEN_SIZE;
2662 length -= BGP_OPEN_SIZE;
2663
2664 i = 0;
2665 while (i < optslen) {
2666 uint8_t opt_type, opt_len;
2667
2668 ND_TCHECK_LEN(opt + i, BGP_OPT_SIZE);
2669 if (length < BGP_OPT_SIZE + i)
2670 goto trunc;
2671 bgpopt = (const struct bgp_opt *)(opt + i);
2672 opt_type = GET_U_1(bgpopt->bgpopt_type);
2673 opt_len = GET_U_1(bgpopt->bgpopt_len);
2674 if (BGP_OPT_SIZE + i + opt_len > optslen) {
2675 ND_PRINT("\n\t Option %u, length: %u, goes past the end of the options",
2676 opt_type, opt_len);
2677 break;
2678 }
2679
2680 ND_PRINT("\n\t Option %s (%u), length: %u",
2681 tok2str(bgp_opt_values,"Unknown",opt_type),
2682 opt_type,
2683 opt_len);
2684
2685 /* now let's decode the options we know*/
2686 switch(opt_type) {
2687
2688 case BGP_OPT_CAP:
2689 bgp_capabilities_print(ndo, opt + BGP_OPT_SIZE + i,
2690 opt_len);
2691 break;
2692
2693 case BGP_OPT_AUTH:
2694 default:
2695 ND_PRINT("\n\t no decoder for option %u",
2696 opt_type);
2697 break;
2698 }
2699 i += BGP_OPT_SIZE + opt_len;
2700 }
2701 return;
2702 trunc:
2703 nd_print_trunc(ndo);
2704 }
2705
2706 static void
2707 bgp_update_print(netdissect_options *ndo,
2708 const u_char *dat, u_int length)
2709 {
2710 const u_char *p;
2711 u_int withdrawn_routes_len;
2712 char buf[MAXHOSTNAMELEN + 100];
2713 int wpfx;
2714 u_int len;
2715 int i;
2716 int add_path;
2717 u_int path_id = 0;
2718
2719 ND_TCHECK_LEN(dat, BGP_SIZE);
2720 if (length < BGP_SIZE)
2721 goto trunc;
2722 p = dat + BGP_SIZE;
2723 length -= BGP_SIZE;
2724
2725 /* Unfeasible routes */
2726 ND_TCHECK_2(p);
2727 if (length < 2)
2728 goto trunc;
2729 withdrawn_routes_len = GET_BE_U_2(p);
2730 p += 2;
2731 length -= 2;
2732 if (withdrawn_routes_len > 1) {
2733 /*
2734 * Without keeping state from the original NLRI message,
2735 * it's not possible to tell if this a v4 or v6 route,
2736 * so only try to decode it if we're not v6 enabled.
2737 */
2738 ND_TCHECK_LEN(p, withdrawn_routes_len);
2739 if (length < withdrawn_routes_len)
2740 goto trunc;
2741 ND_PRINT("\n\t Withdrawn routes:");
2742 add_path = check_add_path(ndo, p, withdrawn_routes_len, 32);
2743 while (withdrawn_routes_len != 0) {
2744 if (add_path) {
2745 if (withdrawn_routes_len < 4) {
2746 p += withdrawn_routes_len;
2747 length -= withdrawn_routes_len;
2748 break;
2749 }
2750 path_id = GET_BE_U_4(p);
2751 p += 4;
2752 length -= 4;
2753 withdrawn_routes_len -= 4;
2754 }
2755 wpfx = decode_prefix4(ndo, p, withdrawn_routes_len, buf, sizeof(buf));
2756 if (wpfx == -1) {
2757 ND_PRINT("\n\t (illegal prefix length)");
2758 break;
2759 } else if (wpfx == -2)
2760 goto trunc; /* bytes left, but not enough */
2761 else {
2762 ND_PRINT("\n\t %s", buf);
2763 if (add_path) {
2764 ND_PRINT(" Path Id: %u", path_id);
2765 }
2766 p += wpfx;
2767 length -= wpfx;
2768 withdrawn_routes_len -= wpfx;
2769 }
2770 }
2771 } else {
2772 ND_TCHECK_LEN(p, withdrawn_routes_len);
2773 if (length < withdrawn_routes_len)
2774 goto trunc;
2775 p += withdrawn_routes_len;
2776 length -= withdrawn_routes_len;
2777 }
2778
2779 ND_TCHECK_2(p);
2780 if (length < 2)
2781 goto trunc;
2782 len = GET_BE_U_2(p);
2783 p += 2;
2784 length -= 2;
2785
2786 if (withdrawn_routes_len == 0 && len == 0 && length == 0) {
2787 /* No withdrawn routes, no path attributes, no NLRI */
2788 ND_PRINT("\n\t End-of-Rib Marker (empty NLRI)");
2789 return;
2790 }
2791
2792 if (len) {
2793 /* do something more useful!*/
2794 while (len) {
2795 uint8_t aflags, atype, alenlen;
2796 uint16_t alen;
2797
2798 ND_TCHECK_2(p);
2799 if (length < 2)
2800 goto trunc;
2801 if (len < 2) {
2802 ND_PRINT("\n\t [path attrs too short]");
2803 p += len;
2804 length -= len;
2805 break;
2806 }
2807 aflags = GET_U_1(p);
2808 atype = GET_U_1(p + 1);
2809 p += 2;
2810 len -= 2;
2811 length -= 2;
2812 alenlen = bgp_attr_lenlen(aflags, p);
2813 ND_TCHECK_LEN(p, alenlen);
2814 if (length < alenlen)
2815 goto trunc;
2816 if (len < alenlen) {
2817 ND_PRINT("\n\t [path attrs too short]");
2818 p += len;
2819 length -= len;
2820 break;
2821 }
2822 alen = bgp_attr_len(aflags, p);
2823 p += alenlen;
2824 len -= alenlen;
2825 length -= alenlen;
2826
2827 ND_PRINT("\n\t %s (%u), length: %u",
2828 tok2str(bgp_attr_values, "Unknown Attribute", atype),
2829 atype,
2830 alen);
2831
2832 if (aflags) {
2833 ND_PRINT(", Flags [%s%s%s%s",
2834 aflags & 0x80 ? "O" : "",
2835 aflags & 0x40 ? "T" : "",
2836 aflags & 0x20 ? "P" : "",
2837 aflags & 0x10 ? "E" : "");
2838 if (aflags & 0xf)
2839 ND_PRINT("+%x", aflags & 0xf);
2840 ND_PRINT("]: ");
2841 }
2842 if (len < alen) {
2843 ND_PRINT(" [path attrs too short]");
2844 p += len;
2845 length -= len;
2846 break;
2847 }
2848 if (length < alen)
2849 goto trunc;
2850 if (!bgp_attr_print(ndo, atype, p, alen, 0))
2851 goto trunc;
2852 p += alen;
2853 len -= alen;
2854 length -= alen;
2855 }
2856 }
2857
2858 if (length) {
2859 add_path = check_add_path(ndo, p, length, 32);
2860 ND_PRINT("\n\t Updated routes:");
2861 while (length != 0) {
2862 if (add_path) {
2863 ND_TCHECK_4(p);
2864 if (length < 4)
2865 goto trunc;
2866 path_id = GET_BE_U_4(p);
2867 p += 4;
2868 length -= 4;
2869 }
2870 i = decode_prefix4(ndo, p, length, buf, sizeof(buf));
2871 if (i == -1) {
2872 ND_PRINT("\n\t (illegal prefix length)");
2873 break;
2874 } else if (i == -2)
2875 goto trunc; /* bytes left, but not enough */
2876 else {
2877 ND_PRINT("\n\t %s", buf);
2878 if (add_path) {
2879 ND_PRINT(" Path Id: %u", path_id);
2880 }
2881 p += i;
2882 length -= i;
2883 }
2884 }
2885 }
2886 return;
2887 trunc:
2888 nd_print_trunc(ndo);
2889 }
2890
2891 static void
2892 bgp_notification_print(netdissect_options *ndo,
2893 const u_char *dat, u_int length)
2894 {
2895 const struct bgp_notification *bgp_notification_header;
2896 const u_char *tptr;
2897 uint8_t bgpn_major, bgpn_minor;
2898 uint8_t shutdown_comm_length;
2899 uint8_t remainder_offset;
2900
2901 ND_TCHECK_LEN(dat, BGP_NOTIFICATION_SIZE);
2902 if (length<BGP_NOTIFICATION_SIZE)
2903 return;
2904
2905 bgp_notification_header = (const struct bgp_notification *)dat;
2906 bgpn_major = GET_U_1(bgp_notification_header->bgpn_major);
2907 bgpn_minor = GET_U_1(bgp_notification_header->bgpn_minor);
2908
2909 ND_PRINT(", %s (%u)",
2910 tok2str(bgp_notify_major_values, "Unknown Error",
2911 bgpn_major),
2912 bgpn_major);
2913
2914 switch (bgpn_major) {
2915
2916 case BGP_NOTIFY_MAJOR_MSG:
2917 ND_PRINT(", subcode %s (%u)",
2918 tok2str(bgp_notify_minor_msg_values, "Unknown",
2919 bgpn_minor),
2920 bgpn_minor);
2921 break;
2922 case BGP_NOTIFY_MAJOR_OPEN:
2923 ND_PRINT(", subcode %s (%u)",
2924 tok2str(bgp_notify_minor_open_values, "Unknown",
2925 bgpn_minor),
2926 bgpn_minor);
2927 break;
2928 case BGP_NOTIFY_MAJOR_UPDATE:
2929 ND_PRINT(", subcode %s (%u)",
2930 tok2str(bgp_notify_minor_update_values, "Unknown",
2931 bgpn_minor),
2932 bgpn_minor);
2933 break;
2934 case BGP_NOTIFY_MAJOR_FSM:
2935 ND_PRINT(" subcode %s (%u)",
2936 tok2str(bgp_notify_minor_fsm_values, "Unknown",
2937 bgpn_minor),
2938 bgpn_minor);
2939 break;
2940 case BGP_NOTIFY_MAJOR_CAP:
2941 ND_PRINT(" subcode %s (%u)",
2942 tok2str(bgp_notify_minor_cap_values, "Unknown",
2943 bgpn_minor),
2944 bgpn_minor);
2945 break;
2946 case BGP_NOTIFY_MAJOR_CEASE:
2947 ND_PRINT(", subcode %s (%u)",
2948 tok2str(bgp_notify_minor_cease_values, "Unknown",
2949 bgpn_minor),
2950 bgpn_minor);
2951
2952 /* draft-ietf-idr-cease-subcode-02 mentions optionally 7 bytes
2953 * for the maxprefix subtype, which may contain AFI, SAFI and MAXPREFIXES
2954 */
2955 if(bgpn_minor == BGP_NOTIFY_MINOR_CEASE_MAXPRFX && length >= BGP_NOTIFICATION_SIZE + 7) {
2956 tptr = dat + BGP_NOTIFICATION_SIZE;
2957 ND_PRINT(", AFI %s (%u), SAFI %s (%u), Max Prefixes: %u",
2958 tok2str(af_values, "Unknown", GET_BE_U_2(tptr)),
2959 GET_BE_U_2(tptr),
2960 tok2str(bgp_safi_values, "Unknown", GET_U_1((tptr + 2))),
2961 GET_U_1((tptr + 2)),
2962 GET_BE_U_4(tptr + 3));
2963 }
2964 /*
2965 * draft-ietf-idr-shutdown describes a method to send a communication
2966 * intended for human consumption regarding the Administrative Shutdown
2967 */
2968 if ((bgpn_minor == BGP_NOTIFY_MINOR_CEASE_SHUT ||
2969 bgpn_minor == BGP_NOTIFY_MINOR_CEASE_RESET) &&
2970 length >= BGP_NOTIFICATION_SIZE + 1) {
2971 tptr = dat + BGP_NOTIFICATION_SIZE;
2972 shutdown_comm_length = GET_U_1(tptr);
2973 remainder_offset = 0;
2974 /* garbage, hexdump it all */
2975 if (shutdown_comm_length > BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN ||
2976 shutdown_comm_length > length - (BGP_NOTIFICATION_SIZE + 1)) {
2977 ND_PRINT(", invalid Shutdown Communication length");
2978 }
2979 else if (shutdown_comm_length == 0) {
2980 ND_PRINT(", empty Shutdown Communication");
2981 remainder_offset += 1;
2982 }
2983 /* a proper shutdown communication */
2984 else {
2985 ND_TCHECK_LEN(tptr + 1, shutdown_comm_length);
2986 ND_PRINT(", Shutdown Communication (length: %u): \"", shutdown_comm_length);
2987 nd_printjn(ndo, tptr+1, shutdown_comm_length);
2988 ND_PRINT("\"");
2989 remainder_offset += shutdown_comm_length + 1;
2990 }
2991 /* if there is trailing data, hexdump it */
2992 if(length - (remainder_offset + BGP_NOTIFICATION_SIZE) > 0) {
2993 ND_PRINT(", Data: (length: %u)", length - (remainder_offset + BGP_NOTIFICATION_SIZE));
2994 hex_print(ndo, "\n\t\t", tptr + remainder_offset, length - (remainder_offset + BGP_NOTIFICATION_SIZE));
2995 }
2996 }
2997 break;
2998 default:
2999 break;
3000 }
3001
3002 return;
3003 trunc:
3004 nd_print_trunc(ndo);
3005 }
3006
3007 static void
3008 bgp_route_refresh_print(netdissect_options *ndo,
3009 const u_char *pptr, u_int len)
3010 {
3011 const struct bgp_route_refresh *bgp_route_refresh_header;
3012
3013 ND_TCHECK_LEN(pptr, BGP_ROUTE_REFRESH_SIZE);
3014
3015 /* some little sanity checking */
3016 if (len<BGP_ROUTE_REFRESH_SIZE)
3017 return;
3018
3019 bgp_route_refresh_header = (const struct bgp_route_refresh *)pptr;
3020
3021 ND_PRINT("\n\t AFI %s (%u), SAFI %s (%u)",
3022 tok2str(af_values,"Unknown",
3023 GET_BE_U_2(bgp_route_refresh_header->afi)),
3024 GET_BE_U_2(bgp_route_refresh_header->afi),
3025 tok2str(bgp_safi_values,"Unknown",
3026 GET_U_1(bgp_route_refresh_header->safi)),
3027 GET_U_1(bgp_route_refresh_header->safi));
3028
3029 if (ndo->ndo_vflag > 1) {
3030 ND_TCHECK_LEN(pptr, len);
3031 print_unknown_data(ndo, pptr, "\n\t ", len);
3032 }
3033
3034 return;
3035 trunc:
3036 nd_print_trunc(ndo);
3037 }
3038
3039 static int
3040 bgp_pdu_print(netdissect_options *ndo,
3041 const u_char *dat, u_int length)
3042 {
3043 const struct bgp *bgp_header;
3044 uint8_t bgp_type;
3045
3046 ND_TCHECK_LEN(dat, BGP_SIZE);
3047 bgp_header = (const struct bgp *)dat;
3048 bgp_type = GET_U_1(bgp_header->bgp_type);
3049
3050 ND_PRINT("\n\t%s Message (%u), length: %u",
3051 tok2str(bgp_msg_values, "Unknown", bgp_type),
3052 bgp_type,
3053 length);
3054
3055 switch (bgp_type) {
3056 case BGP_OPEN:
3057 bgp_open_print(ndo, dat, length);
3058 break;
3059 case BGP_UPDATE:
3060 bgp_update_print(ndo, dat, length);
3061 break;
3062 case BGP_NOTIFICATION:
3063 bgp_notification_print(ndo, dat, length);
3064 break;
3065 case BGP_KEEPALIVE:
3066 break;
3067 case BGP_ROUTE_REFRESH:
3068 bgp_route_refresh_print(ndo, dat, length);
3069 break;
3070 default:
3071 /* we have no decoder for the BGP message */
3072 ND_TCHECK_LEN(dat, length);
3073 ND_PRINT("\n\t no Message %u decoder", bgp_type);
3074 print_unknown_data(ndo, dat, "\n\t ", length);
3075 break;
3076 }
3077 return 1;
3078 trunc:
3079 nd_print_trunc(ndo);
3080 return 0;
3081 }
3082
3083 void
3084 bgp_print(netdissect_options *ndo,
3085 const u_char *dat, u_int length _U_)
3086 {
3087 const u_char *p;
3088 const u_char *ep = ndo->ndo_snapend;
3089 const u_char *start;
3090 const u_char marker[] = {
3091 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3092 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3093 };
3094 const struct bgp *bgp_header;
3095 uint16_t hlen;
3096
3097 ndo->ndo_protocol = "bgp";
3098 ND_PRINT(": BGP");
3099
3100 if (ndo->ndo_vflag < 1) /* lets be less chatty */
3101 return;
3102
3103 p = dat;
3104 start = p;
3105 while (p < ep) {
3106 if (!ND_TTEST_1(p))
3107 break;
3108 if (GET_U_1(p) != 0xff) {
3109 p++;
3110 continue;
3111 }
3112
3113 if (!ND_TTEST_LEN(p, sizeof(marker)))
3114 break;
3115 if (memcmp(p, marker, sizeof(marker)) != 0) {
3116 p++;
3117 continue;
3118 }
3119
3120 /* found BGP header */
3121 ND_TCHECK_LEN(p, BGP_SIZE);
3122 bgp_header = (const struct bgp *)p;
3123
3124 if (start != p)
3125 nd_print_trunc(ndo);
3126
3127 hlen = GET_BE_U_2(bgp_header->bgp_len);
3128 if (hlen < BGP_SIZE) {
3129 ND_PRINT("\nmessage length %u < %u", hlen, BGP_SIZE);
3130 nd_print_invalid(ndo);
3131 break;
3132 }
3133
3134 if (ND_TTEST_LEN(p, hlen)) {
3135 if (!bgp_pdu_print(ndo, p, hlen))
3136 return;
3137 p += hlen;
3138 start = p;
3139 } else {
3140 ND_PRINT("\n[|BGP %s]",
3141 tok2str(bgp_msg_values,
3142 "Unknown Message Type",
3143 GET_U_1(bgp_header->bgp_type)));
3144 break;
3145 }
3146 }
3147
3148 return;
3149
3150 trunc:
3151 nd_print_trunc(ndo);
3152 }