12949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
22949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Copyright (C) 1999 WIDE Project.
32949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * All rights reserved.
42949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
52949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Redistribution and use in source and binary forms, with or without
62949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * modification, are permitted provided that the following conditions
72949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * are met:
82949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
92949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    documentation and/or other materials provided with the distribution.
132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 3. Neither the name of the project nor the names of its contributors
142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    may be used to endorse or promote products derived from this software
152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    without specific prior written permission.
162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * SUCH DAMAGE.
282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Extensively modified by Hannes Gredler (hannes@juniper.net) for more
302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * complete BGP support.
312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
33892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes#define NETDISSECT_REWORKED
342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_CONFIG_H
352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "config.h"
362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <tcpdump-stdinc.h>
392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <stdio.h>
412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <string.h>
422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "interface.h"
442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "addrtoname.h"
452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "extract.h"
462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "af.h"
4753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include "l2vpn.h"
482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstruct bgp {
50892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint8_t bgp_marker[16];
51892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t bgp_len;
52892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint8_t bgp_type;
532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_SIZE		19	/* unaligned */
552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_OPEN		1
572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_UPDATE		2
582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_NOTIFICATION	3
592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_KEEPALIVE		4
602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_ROUTE_REFRESH       5
612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6253f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_msg_values[] = {
632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_OPEN,                 "Open"},
642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_UPDATE,               "Update"},
652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_NOTIFICATION,         "Notification"},
662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_KEEPALIVE,            "Keepalive"},
672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_ROUTE_REFRESH,        "Route Refresh"},
682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL}
692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstruct bgp_open {
72892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint8_t bgpo_marker[16];
73892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t bgpo_len;
74892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint8_t bgpo_type;
75892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint8_t bgpo_version;
76892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t bgpo_myas;
77892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t bgpo_holdtime;
78892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint32_t bgpo_id;
79892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint8_t bgpo_optlen;
802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* options should follow */
812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_OPEN_SIZE		29	/* unaligned */
832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstruct bgp_opt {
85892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint8_t bgpopt_type;
86892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint8_t bgpopt_len;
872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* variable length */
882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_OPT_SIZE		2	/* some compilers may pad to 4 bytes */
9053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_CAP_HEADER_SIZE	2	/* some compilers may pad to 4 bytes */
912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstruct bgp_notification {
93892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint8_t bgpn_marker[16];
94892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t bgpn_len;
95892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint8_t bgpn_type;
96892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint8_t bgpn_major;
97892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint8_t bgpn_minor;
982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_NOTIFICATION_SIZE		21	/* unaligned */
1002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstruct bgp_route_refresh {
102892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t  bgp_marker[16];
103892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint16_t len;
104892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t  type;
105892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t  afi[2]; /* the compiler messes this structure up               */
106892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t  res;    /* when doing misaligned sequences of int8 and int16   */
107892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t  safi;   /* afi should be int16 - so we have to access it using */
108892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes};                    /* EXTRACT_16BITS(&bgp_route_refresh->afi) (sigh)      */
1092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_ROUTE_REFRESH_SIZE          23
1102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define bgp_attr_lenlen(flags, p) \
11253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	(((flags) & 0x10) ? 2 : 1)
11353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define bgp_attr_len(flags, p) \
11453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	(((flags) & 0x10) ? EXTRACT_16BITS(p) : *(p))
1152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGPTYPE_ORIGIN			1
1172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGPTYPE_AS_PATH			2
1182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGPTYPE_NEXT_HOP		3
1192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGPTYPE_MULTI_EXIT_DISC		4
1202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGPTYPE_LOCAL_PREF		5
1212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGPTYPE_ATOMIC_AGGREGATE	6
1222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGPTYPE_AGGREGATOR		7
1232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define	BGPTYPE_COMMUNITIES		8	/* RFC1997 */
1242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define	BGPTYPE_ORIGINATOR_ID		9	/* RFC1998 */
1252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define	BGPTYPE_CLUSTER_LIST		10	/* RFC1998 */
1262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define	BGPTYPE_DPA			11	/* draft-ietf-idr-bgp-dpa */
1272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define	BGPTYPE_ADVERTISERS		12	/* RFC1863 */
1282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define	BGPTYPE_RCID_PATH		13	/* RFC1863 */
1292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGPTYPE_MP_REACH_NLRI		14	/* RFC2283 */
1302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGPTYPE_MP_UNREACH_NLRI		15	/* RFC2283 */
1312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGPTYPE_EXTD_COMMUNITIES        16      /* draft-ietf-idr-bgp-ext-communities */
13253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGPTYPE_AS4_PATH	        17      /* RFC4893 */
13353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGPTYPE_AGGREGATOR4		18      /* RFC4893 */
13453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGPTYPE_PMSI_TUNNEL             22      /* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */
1352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGPTYPE_ATTR_SET               128      /* draft-marques-ppvpn-ibgp */
1362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_MP_NLRI_MINSIZE              3       /* End of RIB Marker detection */
1382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
13953f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_attr_values[] = {
1402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGPTYPE_ORIGIN,           "Origin"},
1412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGPTYPE_AS_PATH,          "AS Path"},
14253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGPTYPE_AS4_PATH,         "AS4 Path"},
1432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGPTYPE_NEXT_HOP,         "Next Hop"},
1442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGPTYPE_MULTI_EXIT_DISC,  "Multi Exit Discriminator"},
1452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGPTYPE_LOCAL_PREF,       "Local Preference"},
1462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGPTYPE_ATOMIC_AGGREGATE, "Atomic Aggregate"},
1472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGPTYPE_AGGREGATOR,       "Aggregator"},
14853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGPTYPE_AGGREGATOR4,      "Aggregator4"},
1492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGPTYPE_COMMUNITIES,      "Community"},
1502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGPTYPE_ORIGINATOR_ID,    "Originator ID"},
1512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGPTYPE_CLUSTER_LIST,     "Cluster List"},
1522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGPTYPE_DPA,              "DPA"},
1532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGPTYPE_ADVERTISERS,      "Advertisers"},
1542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGPTYPE_RCID_PATH,        "RCID Path / Cluster ID"},
1552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGPTYPE_MP_REACH_NLRI,    "Multi-Protocol Reach NLRI"},
1562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGPTYPE_MP_UNREACH_NLRI,  "Multi-Protocol Unreach NLRI"},
1572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGPTYPE_EXTD_COMMUNITIES, "Extended Community"},
15853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGPTYPE_PMSI_TUNNEL,      "PMSI Tunnel"},
1592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGPTYPE_ATTR_SET,         "Attribute Set"},
1602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 255,                      "Reserved for development"},
1612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL}
1622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
1632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_AS_SET             1
1652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_AS_SEQUENCE        2
1662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_CONFED_AS_SEQUENCE 3 /* draft-ietf-idr-rfc3065bis-01 */
1672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_CONFED_AS_SET      4 /* draft-ietf-idr-rfc3065bis-01  */
1682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
16953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_AS_SEG_TYPE_MIN    BGP_AS_SET
17053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_AS_SEG_TYPE_MAX    BGP_CONFED_AS_SET
17153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
17253f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_as_path_segment_open_values[] = {
1732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_AS_SEQUENCE,         ""},
1742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_AS_SET,              "{ "},
1752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_CONFED_AS_SEQUENCE,  "( "},
1762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_CONFED_AS_SET,       "({ "},
1772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL}
1782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
1792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
18053f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_as_path_segment_close_values[] = {
1812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_AS_SEQUENCE,         ""},
1822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_AS_SET,              "}"},
1832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_CONFED_AS_SEQUENCE,  ")"},
1842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_CONFED_AS_SET,       "})"},
1852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL}
1862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
1872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_OPT_AUTH                    1
1892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_OPT_CAP                     2
1902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
19253f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_opt_values[] = {
1932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_OPT_AUTH,             "Authentication Information"},
1942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_OPT_CAP,              "Capabilities Advertisement"},
1952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL}
1962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
1972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_CAPCODE_MP                  1
1992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_CAPCODE_RR                  2
2002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_CAPCODE_ORF                 3 /* XXX */
2012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_CAPCODE_RESTART            64 /* draft-ietf-idr-restart-05  */
2022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_CAPCODE_AS_NEW             65 /* XXX */
2032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_CAPCODE_DYN_CAP            67 /* XXX */
2042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_CAPCODE_RR_CISCO          128
2052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
20653f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_capcode_values[] = {
2072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_CAPCODE_MP,           "Multiprotocol Extensions"},
2082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_CAPCODE_RR,           "Route Refresh"},
2092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_CAPCODE_ORF,          "Cooperative Route Filtering"},
2102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_CAPCODE_RESTART,      "Graceful Restart"},
2112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_CAPCODE_AS_NEW,       "32-Bit AS Number"},
2122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_CAPCODE_DYN_CAP,      "Dynamic Capability"},
2132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_CAPCODE_RR_CISCO,     "Route Refresh (Cisco)"},
2142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL}
2152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
2162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_NOTIFY_MAJOR_MSG            1
2182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_NOTIFY_MAJOR_OPEN           2
2192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_NOTIFY_MAJOR_UPDATE         3
2202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_NOTIFY_MAJOR_HOLDTIME       4
2212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_NOTIFY_MAJOR_FSM            5
2222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_NOTIFY_MAJOR_CEASE          6
2232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_NOTIFY_MAJOR_CAP            7
2242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
22553f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_notify_major_values[] = {
2262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_NOTIFY_MAJOR_MSG,     "Message Header Error"},
2272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_NOTIFY_MAJOR_OPEN,    "OPEN Message Error"},
2282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_NOTIFY_MAJOR_UPDATE,  "UPDATE Message Error"},
2292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_NOTIFY_MAJOR_HOLDTIME,"Hold Timer Expired"},
2302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_NOTIFY_MAJOR_FSM,     "Finite State Machine Error"},
2312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_NOTIFY_MAJOR_CEASE,   "Cease"},
2322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_NOTIFY_MAJOR_CAP,     "Capability Message Error"},
2332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL}
2342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
2352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* draft-ietf-idr-cease-subcode-02 */
2372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_NOTIFY_MINOR_CEASE_MAXPRFX  1
23853f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_notify_minor_cease_values[] = {
2392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_NOTIFY_MINOR_CEASE_MAXPRFX, "Maximum Number of Prefixes Reached"},
2402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 2,                        "Administratively Shutdown"},
2412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 3,                        "Peer Unconfigured"},
2422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 4,                        "Administratively Reset"},
2432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 5,                        "Connection Rejected"},
2442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 6,                        "Other Configuration Change"},
2452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 7,                        "Connection Collision Resolution"},
2462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL}
2472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
2482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
24953f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_notify_minor_msg_values[] = {
2502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 1,                        "Connection Not Synchronized"},
2512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 2,                        "Bad Message Length"},
2522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 3,                        "Bad Message Type"},
2532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL}
2542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
2552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
25653f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_notify_minor_open_values[] = {
2572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 1,                        "Unsupported Version Number"},
2582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 2,                        "Bad Peer AS"},
2592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 3,                        "Bad BGP Identifier"},
2602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 4,                        "Unsupported Optional Parameter"},
2612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 5,                        "Authentication Failure"},
2622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 6,                        "Unacceptable Hold Time"},
26353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 7,                        "Capability Message Error"},
2642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL}
2652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
2662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
26753f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_notify_minor_update_values[] = {
2682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 1,                        "Malformed Attribute List"},
2692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 2,                        "Unrecognized Well-known Attribute"},
2702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 3,                        "Missing Well-known Attribute"},
2712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 4,                        "Attribute Flags Error"},
2722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 5,                        "Attribute Length Error"},
2732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 6,                        "Invalid ORIGIN Attribute"},
2742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 7,                        "AS Routing Loop"},
2752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 8,                        "Invalid NEXT_HOP Attribute"},
2762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 9,                        "Optional Attribute Error"},
2772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 10,                       "Invalid Network Field"},
2782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 11,                       "Malformed AS_PATH"},
2792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL}
2802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
2812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
28253f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_notify_minor_cap_values[] = {
2832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 1,                        "Invalid Action Value" },
2842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 2,                        "Invalid Capability Length" },
2852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 3,                        "Malformed Capability Value" },
2862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 4,                        "Unsupported Capability Code" },
2872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL }
2882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
2892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
29053f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_origin_values[] = {
2912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0,                        "IGP"},
2922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 1,                        "EGP"},
2932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 2,                        "Incomplete"},
2942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL}
2952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
2962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
29753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_PMSI_TUNNEL_RSVP_P2MP 1
29853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_PMSI_TUNNEL_LDP_P2MP  2
29953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_PMSI_TUNNEL_PIM_SSM   3
30053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_PMSI_TUNNEL_PIM_SM    4
30153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_PMSI_TUNNEL_PIM_BIDIR 5
30253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_PMSI_TUNNEL_INGRESS   6
30353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_PMSI_TUNNEL_LDP_MP2MP 7
30453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
30553f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_pmsi_tunnel_values[] = {
30653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGP_PMSI_TUNNEL_RSVP_P2MP, "RSVP-TE P2MP LSP"},
30753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGP_PMSI_TUNNEL_LDP_P2MP, "LDP P2MP LSP"},
30853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGP_PMSI_TUNNEL_PIM_SSM, "PIM-SSM Tree"},
30953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGP_PMSI_TUNNEL_PIM_SM, "PIM-SM Tree"},
31053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGP_PMSI_TUNNEL_PIM_BIDIR, "PIM-Bidir Tree"},
31153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGP_PMSI_TUNNEL_INGRESS, "Ingress Replication"},
31253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGP_PMSI_TUNNEL_LDP_MP2MP, "LDP MP2MP LSP"},
31353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0, NULL}
31453f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
31553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
31653f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_pmsi_flag_values[] = {
31753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0x01, "Leaf Information required"},
31853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0, NULL}
31953f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
32053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
32153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
3222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* Subsequent address family identifier, RFC2283 section 7 */
3232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define SAFNUM_RES                      0
3242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define SAFNUM_UNICAST                  1
3252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define SAFNUM_MULTICAST                2
3262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define SAFNUM_UNIMULTICAST             3
3272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* labeled BGP RFC3107 */
3282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define SAFNUM_LABUNICAST               4
32953f17a9db278d33517d9888dd77848f554522a38JP Abgrall/* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */
33053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define SAFNUM_MULTICAST_VPN            5
3312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define SAFNUM_TUNNEL                   64 /* XXX */
3322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define SAFNUM_VPLS                     65 /* XXX */
33353f17a9db278d33517d9888dd77848f554522a38JP Abgrall/* draft-nalawade-idr-mdt-safi-03 */
33453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define SAFNUM_MDT                      66
3352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* Section 4.3.4 of draft-rosen-rfc2547bis-03.txt  */
3362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define SAFNUM_VPNUNICAST               128
3372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define SAFNUM_VPNMULTICAST             129
3382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define SAFNUM_VPNUNIMULTICAST          130
3392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* draft-marques-ppvpn-rt-constrain-01.txt */
3402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define SAFNUM_RT_ROUTING_INFO          132
3412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_VPN_RD_LEN                  8
3432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
34453f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_safi_values[] = {
3452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { SAFNUM_RES,               "Reserved"},
3462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { SAFNUM_UNICAST,           "Unicast"},
3472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { SAFNUM_MULTICAST,         "Multicast"},
3482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { SAFNUM_UNIMULTICAST,      "Unicast+Multicast"},
3492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { SAFNUM_LABUNICAST,        "labeled Unicast"},
3502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { SAFNUM_TUNNEL,            "Tunnel"},
3512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { SAFNUM_VPLS,              "VPLS"},
3522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { SAFNUM_MDT,               "MDT"},
3532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { SAFNUM_VPNUNICAST,        "labeled VPN Unicast"},
3542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { SAFNUM_VPNMULTICAST,      "labeled VPN Multicast"},
3552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { SAFNUM_VPNUNIMULTICAST,   "labeled VPN Unicast+Multicast"},
35653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { SAFNUM_RT_ROUTING_INFO,   "Route Target Routing Information"},
35753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { SAFNUM_MULTICAST_VPN,     "Multicast VPN"},
3582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL }
3592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
3602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* well-known community */
3622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_COMMUNITY_NO_EXPORT			0xffffff01
3632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_COMMUNITY_NO_ADVERT			0xffffff02
3642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_COMMUNITY_NO_EXPORT_SUBCONFED	0xffffff03
3652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* Extended community type - draft-ietf-idr-bgp-ext-communities-05 */
3672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_RT_0        0x0002  /* Route Target,Format AS(2bytes):AN(4bytes) */
3682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_RT_1        0x0102  /* Route Target,Format IP address:AN(2bytes) */
3692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_RT_2        0x0202  /* Route Target,Format AN(4bytes):local(2bytes) */
3702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_RO_0        0x0003  /* Route Origin,Format AS(2bytes):AN(4bytes) */
3712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_RO_1        0x0103  /* Route Origin,Format IP address:AN(2bytes) */
3722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_RO_2        0x0203  /* Route Origin,Format AN(4bytes):local(2bytes) */
3732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_LINKBAND    0x4004  /* Link Bandwidth,Format AS(2B):Bandwidth(4B) */
3742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                        /* rfc2547 bgp-mpls-vpns */
3752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_VPN_ORIGIN  0x0005  /* OSPF Domain ID / VPN of Origin  - draft-rosen-vpns-ospf-bgp-mpls */
3762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_VPN_ORIGIN2 0x0105  /* duplicate - keep for backwards compatability */
3772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_VPN_ORIGIN3 0x0205  /* duplicate - keep for backwards compatability */
3782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_VPN_ORIGIN4 0x8005  /* duplicate - keep for backwards compatability */
3792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_OSPF_RTYPE  0x0306  /* OSPF Route Type,Format Area(4B):RouteType(1B):Options(1B) */
3812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_OSPF_RTYPE2 0x8000  /* duplicate - keep for backwards compatability */
3822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_OSPF_RID    0x0107  /* OSPF Router ID,Format RouterID(4B):Unused(2B) */
384892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes#define BGP_EXT_COM_OSPF_RID2   0x8001  /* duplicate - keep for backwards compatability */
3852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_L2INFO      0x800a  /* draft-kompella-ppvpn-l2vpn */
3872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
38853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_EXT_COM_SOURCE_AS   0x0009  /* RFC-ietf-l3vpn-2547bis-mcast-bgp-08.txt */
38953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_EXT_COM_VRF_RT_IMP  0x010b  /* RFC-ietf-l3vpn-2547bis-mcast-bgp-08.txt */
39053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_EXT_COM_L2VPN_RT_0  0x000a  /* L2VPN Identifier,Format AS(2bytes):AN(4bytes) */
39153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_EXT_COM_L2VPN_RT_1  0xF10a  /* L2VPN Identifier,Format IP address:AN(2bytes) */
39253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
39353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
3942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* http://www.cisco.com/en/US/tech/tk436/tk428/technologies_tech_note09186a00801eb09a.shtml  */
3952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_EIGRP_GEN   0x8800
3962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_EIGRP_METRIC_AS_DELAY  0x8801
3972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW 0x8802
3982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU  0x8803
3992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_EIGRP_EXT_REMAS_REMID  0x8804
4002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC 0x8805
4012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
40253f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_extd_comm_flag_values[] = {
4032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x8000,                  "vendor-specific"},
4042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x4000,                  "non-transitive"},
4052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL},
4062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
4072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
40853f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_extd_comm_subtype_values[] = {
4092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_RT_0,        "target"},
4102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_RT_1,        "target"},
4112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_RT_2,        "target"},
4122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_RO_0,        "origin"},
4132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_RO_1,        "origin"},
4142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_RO_2,        "origin"},
4152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_LINKBAND,    "link-BW"},
4162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_VPN_ORIGIN,  "ospf-domain"},
4172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_VPN_ORIGIN2, "ospf-domain"},
4182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_VPN_ORIGIN3, "ospf-domain"},
4192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_VPN_ORIGIN4, "ospf-domain"},
4202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_OSPF_RTYPE,  "ospf-route-type"},
4212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_OSPF_RTYPE2, "ospf-route-type"},
4222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_OSPF_RID,    "ospf-router-id"},
4232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_OSPF_RID2,   "ospf-router-id"},
424892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    { BGP_EXT_COM_L2INFO,      "layer2-info"},
4252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_EIGRP_GEN , "eigrp-general-route (flag, tag)" },
4262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_EIGRP_METRIC_AS_DELAY , "eigrp-route-metric (AS, delay)" },
4272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW , "eigrp-route-metric (reliability, nexthop, bandwidth)" },
4282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU , "eigrp-route-metric (load, MTU)" },
4292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_EIGRP_EXT_REMAS_REMID , "eigrp-external-route (remote-AS, remote-ID)" },
4302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC , "eigrp-external-route (remote-proto, remote-metric)" },
43153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGP_EXT_COM_SOURCE_AS, "source-AS" },
43253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGP_EXT_COM_VRF_RT_IMP, "vrf-route-import"},
43353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGP_EXT_COM_L2VPN_RT_0, "l2vpn-id"},
43453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGP_EXT_COM_L2VPN_RT_1, "l2vpn-id"},
4352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL},
4362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
4372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* OSPF codes for  BGP_EXT_COM_OSPF_RTYPE draft-rosen-vpns-ospf-bgp-mpls  */
4392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_OSPF_RTYPE_RTR      1 /* OSPF Router LSA */
4402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_OSPF_RTYPE_NET      2 /* OSPF Network LSA */
4412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_OSPF_RTYPE_SUM      3 /* OSPF Summary LSA */
4422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_OSPF_RTYPE_EXT      5 /* OSPF External LSA, note that ASBR doesn't apply to MPLS-VPN */
4432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_OSPF_RTYPE_NSSA     7 /* OSPF NSSA External*/
4442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_OSPF_RTYPE_SHAM     129 /* OSPF-MPLS-VPN Sham link */
4452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define BGP_OSPF_RTYPE_METRIC_TYPE 0x1 /* LSB of RTYPE Options Field */
4462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
44753f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_extd_comm_ospf_rtype_values[] = {
448892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes  { BGP_OSPF_RTYPE_RTR, "Router" },
449892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes  { BGP_OSPF_RTYPE_NET, "Network" },
450892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes  { BGP_OSPF_RTYPE_SUM, "Summary" },
451892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes  { BGP_OSPF_RTYPE_EXT, "External" },
4522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  { BGP_OSPF_RTYPE_NSSA,"NSSA External" },
453892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes  { BGP_OSPF_RTYPE_SHAM,"MPLS-VPN Sham" },
4542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  { 0, NULL },
4552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
4562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
45753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define TOKBUFSIZE 128
45853f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic char astostr[20];
45953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
46053f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
46153f17a9db278d33517d9888dd77848f554522a38JP Abgrall * as_printf
46253f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
46353f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Convert an AS number into a string and return string pointer.
46453f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
465892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * Depending on bflag is set or not, AS number is converted into ASDOT notation
46653f17a9db278d33517d9888dd77848f554522a38JP Abgrall * or plain number notation.
46753f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
46853f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
46953f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic char *
470892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesas_printf(netdissect_options *ndo,
471892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes          char *str, int size, u_int asnum)
47253f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
473892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (!ndo->ndo_bflag || asnum <= 0xFFFF) {
47453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		snprintf(str, size, "%u", asnum);
47553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	} else {
47653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		snprintf(str, size, "%u.%u", asnum >> 16, asnum & 0xFFFF);
47753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
47853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return str;
47953f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
48053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
48153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ITEMCHECK(minlen) if (itemlen < minlen) goto badtlv;
48253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
4832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint
484892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesdecode_prefix4(netdissect_options *ndo,
485892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               const u_char *pptr, u_int itemlen, char *buf, u_int buflen)
4862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
4872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct in_addr addr;
48853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int plen, plenbytes;
4892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
490892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(pptr[0]);
49153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	ITEMCHECK(1);
4922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	plen = pptr[0];
4932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (32 < plen)
4942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return -1;
49553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	itemlen -= 1;
4962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memset(&addr, 0, sizeof(addr));
49853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	plenbytes = (plen + 7) / 8;
499892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(pptr[1], plenbytes);
50053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	ITEMCHECK(plenbytes);
50153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	memcpy(&addr, &pptr[1], plenbytes);
5022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (plen % 8) {
50353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		((u_char *)&addr)[plenbytes - 1] &=
5042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			((0xff00 >> (plen % 8)) & 0xff);
5052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
506892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	snprintf(buf, buflen, "%s/%d", getname(ndo, (u_char *)&addr), plen);
50753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 1 + plenbytes;
5082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
5102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return -2;
51153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
51253f17a9db278d33517d9888dd77848f554522a38JP Abgrallbadtlv:
51353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -3;
5142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
5152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic int
517892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesdecode_labeled_prefix4(netdissect_options *ndo,
518892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                       const u_char *pptr, u_int itemlen, char *buf, u_int buflen)
5192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
5202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct in_addr addr;
52153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int plen, plenbytes;
5222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
52353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* prefix length and label = 4 bytes */
524892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(pptr[0], 4);
52553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	ITEMCHECK(4);
5262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	plen = pptr[0];   /* get prefix length */
5272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        /* this is one of the weirdnesses of rfc3107
5292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project           the label length (actually the label + COS bits)
5302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project           is added to the prefix length;
5312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project           we also do only read out just one label -
5322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project           there is no real application for advertisement of
533892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes           stacked labels in a single BGP message
5342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        */
5352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (24 > plen)
5372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return -1;
5382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        plen-=24; /* adjust prefixlen - labellength */
5402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (32 < plen)
5422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return -1;
54353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	itemlen -= 4;
5442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memset(&addr, 0, sizeof(addr));
54653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	plenbytes = (plen + 7) / 8;
547892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(pptr[4], plenbytes);
54853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	ITEMCHECK(plenbytes);
54953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	memcpy(&addr, &pptr[4], plenbytes);
5502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (plen % 8) {
55153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		((u_char *)&addr)[plenbytes - 1] &=
5522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			((0xff00 >> (plen % 8)) & 0xff);
5532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
5542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        /* the label may get offsetted by 4 bits so lets shift it right */
5552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	snprintf(buf, buflen, "%s/%d, label:%u %s",
556892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 getname(ndo, (u_char *)&addr),
5572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 plen,
5582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 EXTRACT_24BITS(pptr+1)>>4,
5592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
5602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
56153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 4 + plenbytes;
5622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
5642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return -2;
56553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
56653f17a9db278d33517d9888dd77848f554522a38JP Abgrallbadtlv:
56753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -3;
56853f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
56953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
57053f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
57153f17a9db278d33517d9888dd77848f554522a38JP Abgrall * bgp_vpn_ip_print
57253f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
57353f17a9db278d33517d9888dd77848f554522a38JP Abgrall * print an ipv4 or ipv6 address into a buffer dependend on address length.
57453f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
57553f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic char *
576892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesbgp_vpn_ip_print(netdissect_options *ndo,
577892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 const u_char *pptr, u_int addr_length)
578892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes{
57953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
58053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /* worst case string is s fully formatted v6 address */
58153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    static char addr[sizeof("1234:5678:89ab:cdef:1234:5678:89ab:cdef")];
58253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    char *pos = addr;
58353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
58453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    switch(addr_length) {
58553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    case (sizeof(struct in_addr) << 3): /* 32 */
586892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_TCHECK2(pptr[0], sizeof(struct in_addr));
587892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        snprintf(pos, sizeof(addr), "%s", ipaddr_string(ndo, pptr));
58853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        break;
58953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#ifdef INET6
59053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    case (sizeof(struct in6_addr) << 3): /* 128 */
591892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_TCHECK2(pptr[0], sizeof(struct in6_addr));
592892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        snprintf(pos, sizeof(addr), "%s", ip6addr_string(ndo, pptr));
59353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        break;
59453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#endif
59553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    default:
59653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        snprintf(pos, sizeof(addr), "bogus address length %u", addr_length);
59753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        break;
59853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
59953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    pos += strlen(pos);
60053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
60153f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
60253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    *(pos) = '\0';
60353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return (addr);
6042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
6052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
60653f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
60753f17a9db278d33517d9888dd77848f554522a38JP Abgrall * bgp_vpn_sg_print
60853f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
60953f17a9db278d33517d9888dd77848f554522a38JP Abgrall * print an multicast s,g entry into a buffer.
61053f17a9db278d33517d9888dd77848f554522a38JP Abgrall * the s,g entry is encoded like this.
61153f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
61253f17a9db278d33517d9888dd77848f554522a38JP Abgrall * +-----------------------------------+
61353f17a9db278d33517d9888dd77848f554522a38JP Abgrall * | Multicast Source Length (1 octet) |
61453f17a9db278d33517d9888dd77848f554522a38JP Abgrall * +-----------------------------------+
61553f17a9db278d33517d9888dd77848f554522a38JP Abgrall * |   Multicast Source (Variable)     |
61653f17a9db278d33517d9888dd77848f554522a38JP Abgrall * +-----------------------------------+
61753f17a9db278d33517d9888dd77848f554522a38JP Abgrall * |  Multicast Group Length (1 octet) |
61853f17a9db278d33517d9888dd77848f554522a38JP Abgrall * +-----------------------------------+
61953f17a9db278d33517d9888dd77848f554522a38JP Abgrall * |  Multicast Group   (Variable)     |
62053f17a9db278d33517d9888dd77848f554522a38JP Abgrall * +-----------------------------------+
62153f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
62253f17a9db278d33517d9888dd77848f554522a38JP Abgrall * return the number of bytes read from the wire.
62353f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
62453f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
625892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesbgp_vpn_sg_print(netdissect_options *ndo,
626892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 const u_char *pptr, char *buf, u_int buflen)
627892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes{
628892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t addr_length;
62953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    u_int total_length, offset;
63053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
63153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    total_length = 0;
63253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
63353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /* Source address length, encoded in bits */
634892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_TCHECK2(pptr[0], 1);
63553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    addr_length =  *pptr++;
63653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
63753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /* Source address */
638892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_TCHECK2(pptr[0], (addr_length >> 3));
63953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    total_length += (addr_length >> 3) + 1;
64053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    offset = strlen(buf);
64153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    if (addr_length) {
64253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        snprintf(buf + offset, buflen - offset, ", Source %s",
643892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 bgp_vpn_ip_print(ndo, pptr, addr_length));
64453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        pptr += (addr_length >> 3);
64553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
646892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
64753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /* Group address length, encoded in bits */
648892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_TCHECK2(pptr[0], 1);
64953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    addr_length =  *pptr++;
65053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
65153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /* Group address */
652892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_TCHECK2(pptr[0], (addr_length >> 3));
65353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    total_length += (addr_length >> 3) + 1;
65453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    offset = strlen(buf);
65553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    if (addr_length) {
65653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        snprintf(buf + offset, buflen - offset, ", Group %s",
657892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 bgp_vpn_ip_print(ndo, pptr, addr_length));
65853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        pptr += (addr_length >> 3);
65953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
66053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
66153f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
66253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return (total_length);
66353f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
66453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
66553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
6662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* RDs and RTs share the same semantics
6672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * we use bgp_vpn_rd_print for
6682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * printing route targets inside a NLRI */
6692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectchar *
670892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesbgp_vpn_rd_print(netdissect_options *ndo,
671892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 const u_char *pptr)
672892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes{
6732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   /* allocate space for the largest possible string */
6742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    static char rd[sizeof("xxxxxxxxxx:xxxxx (xxx.xxx.xxx.xxx:xxxxx)")];
6752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    char *pos = rd;
6762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    /* ok lets load the RD format */
6782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    switch (EXTRACT_16BITS(pptr)) {
6792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
68053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        /* 2-byte-AS:number fmt*/
6812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    case 0:
68253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        snprintf(pos, sizeof(rd) - (pos - rd), "%u:%u (= %u.%u.%u.%u)",
68353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                 EXTRACT_16BITS(pptr+2),
68453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                 EXTRACT_32BITS(pptr+4),
68553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                 *(pptr+4), *(pptr+5), *(pptr+6), *(pptr+7));
6862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        break;
6872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        /* IP-address:AS fmt*/
6882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    case 1:
6902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        snprintf(pos, sizeof(rd) - (pos - rd), "%u.%u.%u.%u:%u",
6912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            *(pptr+2), *(pptr+3), *(pptr+4), *(pptr+5), EXTRACT_16BITS(pptr+6));
6922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        break;
6932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        /* 4-byte-AS:number fmt*/
6952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    case 2:
69653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	snprintf(pos, sizeof(rd) - (pos - rd), "%s:%u (%u.%u.%u.%u:%u)",
697892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	    as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(pptr+2)),
69853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    EXTRACT_16BITS(pptr+6), *(pptr+2), *(pptr+3), *(pptr+4),
69953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    *(pptr+5), EXTRACT_16BITS(pptr+6));
7002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        break;
7012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    default:
7022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        snprintf(pos, sizeof(rd) - (pos - rd), "unknown RD format");
7032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        break;
7042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
7052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    pos += strlen(pos);
7062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    *(pos) = '\0';
7072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return (rd);
7082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
7092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic int
711892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesdecode_rt_routing_info(netdissect_options *ndo,
712892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                       const u_char *pptr, char *buf, u_int buflen)
7132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
714892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint8_t route_target[8];
7152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int plen;
7162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
717892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(pptr[0]);
7182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	plen = pptr[0];   /* get prefix length */
7192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
720892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (0 == plen) {
721892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		snprintf(buf, buflen, "default route target");
722892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		return 1;
723892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	}
7242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (32 > plen)
7262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return -1;
7272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        plen-=32; /* adjust prefix length */
7292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (64 < plen)
7312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return -1;
7322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memset(&route_target, 0, sizeof(route_target));
734892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(pptr[1], (plen + 7) / 8);
7352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memcpy(&route_target, &pptr[1], (plen + 7) / 8);
7362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (plen % 8) {
7372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		((u_char *)&route_target)[(plen + 7) / 8 - 1] &=
7382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			((0xff00 >> (plen % 8)) & 0xff);
7392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
74053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	snprintf(buf, buflen, "origin AS: %s, route target %s",
741892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	    as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(pptr+1)),
742892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	    bgp_vpn_rd_print(ndo, (u_char *)&route_target));
7432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return 5 + (plen + 7) / 8;
7452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
7472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return -2;
7482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
7492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic int
751892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesdecode_labeled_vpn_prefix4(netdissect_options *ndo,
752892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                           const u_char *pptr, char *buf, u_int buflen)
7532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
7542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct in_addr addr;
7552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int plen;
7562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
757892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(pptr[0]);
7582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	plen = pptr[0];   /* get prefix length */
7592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if ((24+64) > plen)
7612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return -1;
7622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        plen-=(24+64); /* adjust prefixlen - labellength - RD len*/
7642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (32 < plen)
7662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return -1;
7672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memset(&addr, 0, sizeof(addr));
769892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(pptr[12], (plen + 7) / 8);
7702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memcpy(&addr, &pptr[12], (plen + 7) / 8);
7712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (plen % 8) {
7722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		((u_char *)&addr)[(plen + 7) / 8 - 1] &=
7732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			((0xff00 >> (plen % 8)) & 0xff);
7742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
7752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        /* the label may get offsetted by 4 bits so lets shift it right */
7762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s",
777892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 bgp_vpn_rd_print(ndo, pptr+4),
778892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 getname(ndo, (u_char *)&addr),
7792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 plen,
7802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 EXTRACT_24BITS(pptr+1)>>4,
7812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
7822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return 12 + (plen + 7) / 8;
7842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
7862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return -2;
7872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
7882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
79053f17a9db278d33517d9888dd77848f554522a38JP Abgrall * +-------------------------------+
79153f17a9db278d33517d9888dd77848f554522a38JP Abgrall * |                               |
79253f17a9db278d33517d9888dd77848f554522a38JP Abgrall * |  RD:IPv4-address (12 octets)  |
79353f17a9db278d33517d9888dd77848f554522a38JP Abgrall * |                               |
79453f17a9db278d33517d9888dd77848f554522a38JP Abgrall * +-------------------------------+
79553f17a9db278d33517d9888dd77848f554522a38JP Abgrall * |  MDT Group-address (4 octets) |
79653f17a9db278d33517d9888dd77848f554522a38JP Abgrall * +-------------------------------+
79753f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
79853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
79953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define MDT_VPN_NLRI_LEN 16
80053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
80153f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
802892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesdecode_mdt_vpn_nlri(netdissect_options *ndo,
803892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    const u_char *pptr, char *buf, u_int buflen)
80453f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
80553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
80653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    const u_char *rd;
80753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    const u_char *vpn_ip;
808892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
809892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_TCHECK(pptr[0]);
81053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
81153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /* if the NLRI is not predefined length, quit.*/
812892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    if (*pptr != MDT_VPN_NLRI_LEN * 8)
81353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -1;
81453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    pptr++;
81553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
81653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /* RD */
817892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_TCHECK2(pptr[0], 8);
81853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    rd = pptr;
81953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    pptr+=8;
82053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
82153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /* IPv4 address */
822892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_TCHECK2(pptr[0], sizeof(struct in_addr));
82353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    vpn_ip = pptr;
82453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    pptr+=sizeof(struct in_addr);
82553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
82653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /* MDT Group Address */
827892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_TCHECK2(pptr[0], sizeof(struct in_addr));
82853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
82953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    snprintf(buf, buflen, "RD: %s, VPN IP Address: %s, MC Group Address: %s",
830892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	     bgp_vpn_rd_print(ndo, rd), ipaddr_string(ndo, vpn_ip), ipaddr_string(ndo, pptr));
831892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
83253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return MDT_VPN_NLRI_LEN + 1;
83353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
83453f17a9db278d33517d9888dd77848f554522a38JP Abgrall trunc:
83553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
83653f17a9db278d33517d9888dd77848f554522a38JP Abgrallreturn -2;
83753f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
83853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
83953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI   1
84053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI   2
84153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI            3
84253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF 4
84353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE     5
84453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN  6
84553f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN  7
84653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
84753f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok bgp_multicast_vpn_route_type_values[] = {
84853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI, "Intra-AS I-PMSI"},
84953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI, "Inter-AS I-PMSI"},
85053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI, "S-PMSI"},
85153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF, "Intra-AS Segment-Leaf"},
85253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE, "Source-Active"},
85353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN, "Shared Tree Join"},
85453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN, "Source Tree Join"},
85553f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
85653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
85753f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
858892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesdecode_multicast_vpn(netdissect_options *ndo,
859892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                     const u_char *pptr, char *buf, u_int buflen)
86053f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
861892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        uint8_t route_type, route_length, addr_length, sg_length;
86253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        u_int offset;
86353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
864892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(pptr[0], 2);
86553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        route_type = *pptr++;
86653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        route_length = *pptr++;
86753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
86853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        snprintf(buf, buflen, "Route-Type: %s (%u), length: %u",
86953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                 tok2str(bgp_multicast_vpn_route_type_values,
87053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                         "Unknown", route_type),
87153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                 route_type, route_length);
87253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
87353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        switch(route_type) {
87453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI:
875892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN);
87653f17a9db278d33517d9888dd77848f554522a38JP Abgrall            offset = strlen(buf);
87753f17a9db278d33517d9888dd77848f554522a38JP Abgrall            snprintf(buf + offset, buflen - offset, ", RD: %s, Originator %s",
878892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                     bgp_vpn_rd_print(ndo, pptr),
879892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                     bgp_vpn_ip_print(ndo, pptr + BGP_VPN_RD_LEN,
88053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                      (route_length - BGP_VPN_RD_LEN) << 3));
88153f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
88253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI:
883892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN + 4);
88453f17a9db278d33517d9888dd77848f554522a38JP Abgrall            offset = strlen(buf);
88553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s",
886892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		bgp_vpn_rd_print(ndo, pptr),
887892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		as_printf(ndo, astostr, sizeof(astostr),
88853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN)));
88953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
89053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
89153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI:
892892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN);
89353f17a9db278d33517d9888dd77848f554522a38JP Abgrall            offset = strlen(buf);
89453f17a9db278d33517d9888dd77848f554522a38JP Abgrall            snprintf(buf + offset, buflen - offset, ", RD: %s",
895892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                     bgp_vpn_rd_print(ndo, pptr));
89653f17a9db278d33517d9888dd77848f554522a38JP Abgrall            pptr += BGP_VPN_RD_LEN;
89753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
898892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            sg_length = bgp_vpn_sg_print(ndo, pptr, buf, buflen);
89953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            addr_length =  route_length - sg_length;
90053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
901892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_TCHECK2(pptr[0], addr_length);
90253f17a9db278d33517d9888dd77848f554522a38JP Abgrall            offset = strlen(buf);
90353f17a9db278d33517d9888dd77848f554522a38JP Abgrall            snprintf(buf + offset, buflen - offset, ", Originator %s",
904892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                     bgp_vpn_ip_print(ndo, pptr, addr_length << 3));
90553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
90653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
90753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE:
908892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN);
90953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            offset = strlen(buf);
91053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            snprintf(buf + offset, buflen - offset, ", RD: %s",
911892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                     bgp_vpn_rd_print(ndo, pptr));
91253f17a9db278d33517d9888dd77848f554522a38JP Abgrall            pptr += BGP_VPN_RD_LEN;
91353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
914892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            bgp_vpn_sg_print(ndo, pptr, buf, buflen);
91553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
91653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
91753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN: /* fall through */
91853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN:
919892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN);
92053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            offset = strlen(buf);
92153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s",
922892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		bgp_vpn_rd_print(ndo, pptr),
923892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		as_printf(ndo, astostr, sizeof(astostr),
92453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN)));
92553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            pptr += BGP_VPN_RD_LEN;
92653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
927892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            bgp_vpn_sg_print(ndo, pptr, buf, buflen);
92853f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
92953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
93053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            /*
93153f17a9db278d33517d9888dd77848f554522a38JP Abgrall             * no per route-type printing yet.
93253f17a9db278d33517d9888dd77848f554522a38JP Abgrall             */
93353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF:
93453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        default:
93553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
93653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
93753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
93853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        return route_length + 2;
93953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
94053f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
94153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -2;
94253f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
94353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
94453f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
9452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * As I remember, some versions of systems have an snprintf() that
9462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * returns -1 if the buffer would have overflowed.  If the return
9472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * value is negative, set buflen to 0, to indicate that we've filled
9482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * the buffer up.
9492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
9502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * If the return value is greater than buflen, that means that
9512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * the buffer would have overflowed; again, set buflen to 0 in
9522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * that case.
9532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
9542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define UPDATE_BUF_BUFLEN(buf, buflen, strlen) \
9552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (strlen<0) \
9562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project       	buflen=0; \
9572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    else if ((u_int)strlen>buflen) \
9582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        buflen=0; \
9592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    else { \
9602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        buflen-=strlen; \
9612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	buf+=strlen; \
9622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
9632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
9642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic int
965892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesdecode_labeled_vpn_l2(netdissect_options *ndo,
966892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                      const u_char *pptr, char *buf, u_int buflen)
9672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
9682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        int plen,tlen,strlen,tlv_type,tlv_len,ttlv_len;
9692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
970892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(pptr[0], 2);
9712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        plen=EXTRACT_16BITS(pptr);
9722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        tlen=plen;
9732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        pptr+=2;
97453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* Old and new L2VPN NLRI share AFI/SAFI
97553f17a9db278d33517d9888dd77848f554522a38JP Abgrall         *   -> Assume a 12 Byte-length NLRI is auto-discovery-only
97653f17a9db278d33517d9888dd77848f554522a38JP Abgrall         *      and > 17 as old format. Complain for the middle case
97753f17a9db278d33517d9888dd77848f554522a38JP Abgrall         */
978892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        if (plen==12) {
97953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    /* assume AD-only with RD, BGPNH */
980892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	    ND_TCHECK2(pptr[0],12);
98153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    buf[0]='\0';
98253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    strlen=snprintf(buf, buflen, "RD: %s, BGPNH: %s",
983892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			    bgp_vpn_rd_print(ndo, pptr),
984892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			    /* need something like getname(ndo, ) here */
985892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			    getname(ndo, pptr+8)
98653f17a9db278d33517d9888dd77848f554522a38JP Abgrall			    );
98753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    UPDATE_BUF_BUFLEN(buf, buflen, strlen);
98853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    pptr+=12;
98953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    tlen-=12;
99053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    return plen;
991892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        } else if (plen>17) {
99253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    /* assume old format */
99353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    /* RD, ID, LBLKOFF, LBLBASE */
99453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
995892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	    ND_TCHECK2(pptr[0],15);
99653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    buf[0]='\0';
99753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    strlen=snprintf(buf, buflen, "RD: %s, CE-ID: %u, Label-Block Offset: %u, Label Base %u",
998892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			    bgp_vpn_rd_print(ndo, pptr),
99953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			    EXTRACT_16BITS(pptr+8),
100053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			    EXTRACT_16BITS(pptr+10),
100153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			    EXTRACT_24BITS(pptr+12)>>4); /* the label is offsetted by 4 bits so lets shift it right */
100253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    UPDATE_BUF_BUFLEN(buf, buflen, strlen);
100353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    pptr+=15;
100453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    tlen-=15;
100553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
100653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    /* ok now the variable part - lets read out TLVs*/
100753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    while (tlen>0) {
100853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (tlen < 3)
100953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		    return -1;
1010892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK2(pptr[0], 3);
101153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		tlv_type=*pptr++;
101253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		tlv_len=EXTRACT_16BITS(pptr);
101353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		ttlv_len=tlv_len;
101453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		pptr+=2;
101553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
101653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		switch(tlv_type) {
101753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		case 1:
101853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		    if (buflen!=0) {
101953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			strlen=snprintf(buf,buflen, "\n\t\tcircuit status vector (%u) length: %u: 0x",
102053f17a9db278d33517d9888dd77848f554522a38JP Abgrall					tlv_type,
102153f17a9db278d33517d9888dd77848f554522a38JP Abgrall					tlv_len);
102253f17a9db278d33517d9888dd77848f554522a38JP Abgrall			UPDATE_BUF_BUFLEN(buf, buflen, strlen);
102353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		    }
102453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		    ttlv_len=ttlv_len/8+1; /* how many bytes do we need to read ? */
102553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		    while (ttlv_len>0) {
1026892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_TCHECK(pptr[0]);
102753f17a9db278d33517d9888dd77848f554522a38JP Abgrall			if (buflen!=0) {
102853f17a9db278d33517d9888dd77848f554522a38JP Abgrall			    strlen=snprintf(buf,buflen, "%02x",*pptr++);
102953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			    UPDATE_BUF_BUFLEN(buf, buflen, strlen);
103053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			}
103153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			ttlv_len--;
103253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		    }
103353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		    break;
103453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		default:
103553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		    if (buflen!=0) {
103653f17a9db278d33517d9888dd77848f554522a38JP Abgrall			strlen=snprintf(buf,buflen, "\n\t\tunknown TLV #%u, length: %u",
103753f17a9db278d33517d9888dd77848f554522a38JP Abgrall					tlv_type,
103853f17a9db278d33517d9888dd77848f554522a38JP Abgrall					tlv_len);
103953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			UPDATE_BUF_BUFLEN(buf, buflen, strlen);
104053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		    }
104153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		    break;
104253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
104353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		tlen-=(tlv_len<<3); /* the tlv-length is expressed in bits so lets shift it right */
104453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    }
104553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    return plen+2;
1046892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
104753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        } else {
104853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    /* complain bitterly ? */
104953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    /* fall through */
105053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            goto trunc;
10512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        }
10522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
10542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        return -2;
10552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
10562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6
10582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint
1059892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesdecode_prefix6(netdissect_options *ndo,
1060892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               const u_char *pd, u_int itemlen, char *buf, u_int buflen)
10612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
10622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct in6_addr addr;
106353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int plen, plenbytes;
10642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1065892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(pd[0]);
106653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	ITEMCHECK(1);
10672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	plen = pd[0];
10682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (128 < plen)
10692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return -1;
107053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	itemlen -= 1;
10712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memset(&addr, 0, sizeof(addr));
107353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	plenbytes = (plen + 7) / 8;
1074892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(pd[1], plenbytes);
107553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	ITEMCHECK(plenbytes);
107653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	memcpy(&addr, &pd[1], plenbytes);
10772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (plen % 8) {
107853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		addr.s6_addr[plenbytes - 1] &=
10792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			((0xff00 >> (plen % 8)) & 0xff);
10802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
1081892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	snprintf(buf, buflen, "%s/%d", getname6(ndo, (u_char *)&addr), plen);
108253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 1 + plenbytes;
10832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
10852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return -2;
108653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
108753f17a9db278d33517d9888dd77848f554522a38JP Abgrallbadtlv:
108853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -3;
10892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
10902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic int
1092892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesdecode_labeled_prefix6(netdissect_options *ndo,
1093892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                       const u_char *pptr, u_int itemlen, char *buf, u_int buflen)
10942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
10952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct in6_addr addr;
109653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int plen, plenbytes;
10972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
109853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	/* prefix length and label = 4 bytes */
1099892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(pptr[0], 4);
110053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	ITEMCHECK(4);
11012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	plen = pptr[0]; /* get prefix length */
11022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (24 > plen)
11042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return -1;
11052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        plen-=24; /* adjust prefixlen - labellength */
11072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (128 < plen)
11092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return -1;
111053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	itemlen -= 4;
11112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memset(&addr, 0, sizeof(addr));
111353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	plenbytes = (plen + 7) / 8;
1114892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(pptr[4], plenbytes);
111553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	memcpy(&addr, &pptr[4], plenbytes);
11162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (plen % 8) {
111753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		addr.s6_addr[plenbytes - 1] &=
11182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			((0xff00 >> (plen % 8)) & 0xff);
11192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
11202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        /* the label may get offsetted by 4 bits so lets shift it right */
11212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	snprintf(buf, buflen, "%s/%d, label:%u %s",
1122892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 getname6(ndo, (u_char *)&addr),
11232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 plen,
11242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 EXTRACT_24BITS(pptr+1)>>4,
11252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
11262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
112753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return 4 + plenbytes;
11282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
11302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return -2;
113153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
113253f17a9db278d33517d9888dd77848f554522a38JP Abgrallbadtlv:
113353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return -3;
11342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
11352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic int
1137892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesdecode_labeled_vpn_prefix6(netdissect_options *ndo,
1138892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                           const u_char *pptr, char *buf, u_int buflen)
11392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
11402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct in6_addr addr;
11412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int plen;
11422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1143892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(pptr[0]);
11442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	plen = pptr[0];   /* get prefix length */
11452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if ((24+64) > plen)
11472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return -1;
11482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        plen-=(24+64); /* adjust prefixlen - labellength - RD len*/
11502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (128 < plen)
11522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return -1;
11532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memset(&addr, 0, sizeof(addr));
1155892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(pptr[12], (plen + 7) / 8);
11562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memcpy(&addr, &pptr[12], (plen + 7) / 8);
11572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (plen % 8) {
11582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		addr.s6_addr[(plen + 7) / 8 - 1] &=
11592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			((0xff00 >> (plen % 8)) & 0xff);
11602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
11612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        /* the label may get offsetted by 4 bits so lets shift it right */
11622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s",
1163892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 bgp_vpn_rd_print(ndo, pptr+4),
1164892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 getname6(ndo, (u_char *)&addr),
11652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 plen,
11662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 EXTRACT_24BITS(pptr+1)>>4,
11672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
11682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return 12 + (plen + 7) / 8;
11702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
11722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return -2;
11732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
11742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
11752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic int
1177892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesdecode_clnp_prefix(netdissect_options *ndo,
1178892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                   const u_char *pptr, char *buf, u_int buflen)
11792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
1180892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        uint8_t addr[19];
11812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int plen;
11822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1183892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(pptr[0]);
11842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	plen = pptr[0]; /* get prefix length */
11852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (152 < plen)
11872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return -1;
11882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memset(&addr, 0, sizeof(addr));
1190892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(pptr[4], (plen + 7) / 8);
11912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memcpy(&addr, &pptr[4], (plen + 7) / 8);
11922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (plen % 8) {
11932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		addr[(plen + 7) / 8 - 1] &=
11942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			((0xff00 >> (plen % 8)) & 0xff);
11952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
11962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	snprintf(buf, buflen, "%s/%d",
11972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 isonsap_string(addr,(plen + 7) / 8),
11982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 plen);
11992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return 1 + (plen + 7) / 8;
12012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
12032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return -2;
12042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
12052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic int
1207892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesdecode_labeled_vpn_clnp_prefix(netdissect_options *ndo,
1208892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                               const u_char *pptr, char *buf, u_int buflen)
12092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
1210892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        uint8_t addr[19];
12112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int plen;
12122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1213892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(pptr[0]);
12142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	plen = pptr[0];   /* get prefix length */
12152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if ((24+64) > plen)
12172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return -1;
12182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        plen-=(24+64); /* adjust prefixlen - labellength - RD len*/
12202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (152 < plen)
12222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return -1;
12232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memset(&addr, 0, sizeof(addr));
1225892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(pptr[12], (plen + 7) / 8);
12262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memcpy(&addr, &pptr[12], (plen + 7) / 8);
12272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (plen % 8) {
12282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		addr[(plen + 7) / 8 - 1] &=
12292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			((0xff00 >> (plen % 8)) & 0xff);
12302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
12312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        /* the label may get offsetted by 4 bits so lets shift it right */
12322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s",
1233892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 bgp_vpn_rd_print(ndo, pptr+4),
12342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 isonsap_string(addr,(plen + 7) / 8),
12352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 plen,
12362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 EXTRACT_24BITS(pptr+1)>>4,
12372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
12382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return 12 + (plen + 7) / 8;
12402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
12422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return -2;
12432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
12442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
124553f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
124653f17a9db278d33517d9888dd77848f554522a38JP Abgrall * bgp_attr_get_as_size
124753f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
124853f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Try to find the size of the ASs encoded in an as-path. It is not obvious, as
124953f17a9db278d33517d9888dd77848f554522a38JP Abgrall * both Old speakers that do not support 4 byte AS, and the new speakers that do
125053f17a9db278d33517d9888dd77848f554522a38JP Abgrall * support, exchange AS-Path with the same path-attribute type value 0x02.
125153f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
125253f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
1253892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesbgp_attr_get_as_size(netdissect_options *ndo,
1254892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                     uint8_t bgpa_type, const u_char *pptr, int len)
125553f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
125653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    const u_char *tptr = pptr;
125753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
125853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /*
125953f17a9db278d33517d9888dd77848f554522a38JP Abgrall     * If the path attribute is the optional AS4 path type, then we already
126053f17a9db278d33517d9888dd77848f554522a38JP Abgrall     * know, that ASs must be encoded in 4 byte format.
126153f17a9db278d33517d9888dd77848f554522a38JP Abgrall     */
126253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    if (bgpa_type == BGPTYPE_AS4_PATH) {
126353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        return 4;
126453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
126553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
126653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /*
126753f17a9db278d33517d9888dd77848f554522a38JP Abgrall     * Let us assume that ASs are of 2 bytes in size, and check if the AS-Path
126853f17a9db278d33517d9888dd77848f554522a38JP Abgrall     * TLV is good. If not, ask the caller to try with AS encoded as 4 bytes
126953f17a9db278d33517d9888dd77848f554522a38JP Abgrall     * each.
127053f17a9db278d33517d9888dd77848f554522a38JP Abgrall     */
127153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    while (tptr < pptr + len) {
1272892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_TCHECK(tptr[0]);
127353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
127453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        /*
127553f17a9db278d33517d9888dd77848f554522a38JP Abgrall         * If we do not find a valid segment type, our guess might be wrong.
127653f17a9db278d33517d9888dd77848f554522a38JP Abgrall         */
127753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if (tptr[0] < BGP_AS_SEG_TYPE_MIN || tptr[0] > BGP_AS_SEG_TYPE_MAX) {
127853f17a9db278d33517d9888dd77848f554522a38JP Abgrall            goto trunc;
127953f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
1280892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_TCHECK(tptr[1]);
128153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        tptr += 2 + tptr[1] * 2;
128253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
128353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
128453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /*
128553f17a9db278d33517d9888dd77848f554522a38JP Abgrall     * If we correctly reached end of the AS path attribute data content,
128653f17a9db278d33517d9888dd77848f554522a38JP Abgrall     * then most likely ASs were indeed encoded as 2 bytes.
128753f17a9db278d33517d9888dd77848f554522a38JP Abgrall     */
128853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    if (tptr == pptr + len) {
128953f17a9db278d33517d9888dd77848f554522a38JP Abgrall        return 2;
129053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
129153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
129253f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
129353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
129453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /*
129553f17a9db278d33517d9888dd77848f554522a38JP Abgrall     * We can come here, either we did not have enough data, or if we
129653f17a9db278d33517d9888dd77848f554522a38JP Abgrall     * try to decode 4 byte ASs in 2 byte format. Either way, return 4,
129753f17a9db278d33517d9888dd77848f554522a38JP Abgrall     * so that calller can try to decode each AS as of 4 bytes. If indeed
129853f17a9db278d33517d9888dd77848f554522a38JP Abgrall     * there was not enough data, it will crib and end the parse anyways.
129953f17a9db278d33517d9888dd77848f554522a38JP Abgrall     */
130053f17a9db278d33517d9888dd77848f554522a38JP Abgrall   return 4;
130153f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
130253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
13032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic int
1304892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesbgp_attr_print(netdissect_options *ndo,
1305892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               u_int atype, const u_char *pptr, u_int len)
13062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
13072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int i;
1308892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t af;
1309892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint8_t safi, snpa, nhlen;
13102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        union { /* copy buffer for bandwidth values */
1311892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            float f;
1312892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            uint32_t i;
13132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        } bw;
13142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int advance;
131553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int tlen;
13162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *tptr;
13172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	char buf[MAXHOSTNAMELEN + 100];
13182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	char tokbuf[TOKBUFSIZE];
131953f17a9db278d33517d9888dd77848f554522a38JP Abgrall        int  as_size;
13202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
13212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        tptr = pptr;
13222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        tlen=len;
13232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
132453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	switch (atype) {
13252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case BGPTYPE_ORIGIN:
13262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len != 1)
1327892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "invalid len"));
13282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		else {
1329892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_TCHECK(*tptr);
1330892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "%s", tok2strbuf(bgp_origin_values,
13312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project						"Unknown Origin Typecode",
13322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project						tptr[0],
1333892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes						tokbuf, sizeof(tokbuf))));
13342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
13352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
13362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
133753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
133853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        /*
133953f17a9db278d33517d9888dd77848f554522a38JP Abgrall         * Process AS4 byte path and AS2 byte path attributes here.
134053f17a9db278d33517d9888dd77848f554522a38JP Abgrall         */
134153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	case BGPTYPE_AS4_PATH:
13422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case BGPTYPE_AS_PATH:
13432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len % 2) {
1344892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "invalid len"));
13452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
13462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
13472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                if (!len) {
1348892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "empty"));
13492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
13502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                }
13512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
135253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                /*
135353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                 * BGP updates exchanged between New speakers that support 4
135453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                 * byte AS, ASs are always encoded in 4 bytes. There is no
135553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                 * definitive way to find this, just by the packet's
135653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                 * contents. So, check for packet's TLV's sanity assuming
135753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                 * 2 bytes first, and it does not pass, assume that ASs are
135853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                 * encoded in 4 bytes format and move on.
135953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                 */
1360892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                as_size = bgp_attr_get_as_size(ndo, atype, pptr, len);
136153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
13622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		while (tptr < pptr + len) {
1363892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_TCHECK(tptr[0]);
1364892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, "%s", tok2strbuf(bgp_as_path_segment_open_values,
13652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project						"?", tptr[0],
1366892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes						tokbuf, sizeof(tokbuf))));
136753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        for (i = 0; i < tptr[1] * as_size; i += as_size) {
1368892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_TCHECK2(tptr[2 + i], as_size);
1369892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			    ND_PRINT((ndo, "%s ",
1370892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				as_printf(ndo, astostr, sizeof(astostr),
1371892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				as_size == 2 ?
137253f17a9db278d33517d9888dd77848f554522a38JP Abgrall				EXTRACT_16BITS(&tptr[2 + i]) :
1373892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				EXTRACT_32BITS(&tptr[2 + i]))));
13742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        }
1375892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_TCHECK(tptr[0]);
1376892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, "%s", tok2strbuf(bgp_as_path_segment_close_values,
13772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project						"?", tptr[0],
1378892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes						tokbuf, sizeof(tokbuf))));
1379892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_TCHECK(tptr[1]);
138053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        tptr += 2 + tptr[1] * as_size;
13812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
13822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
13832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case BGPTYPE_NEXT_HOP:
13842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len != 4)
1385892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "invalid len"));
13862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		else {
1387892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_TCHECK2(tptr[0], 4);
1388892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "%s", getname(ndo, tptr)));
13892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
13902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
13912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case BGPTYPE_MULTI_EXIT_DISC:
13922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case BGPTYPE_LOCAL_PREF:
13932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len != 4)
1394892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "invalid len"));
13952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		else {
1396892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_TCHECK2(tptr[0], 4);
1397892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "%u", EXTRACT_32BITS(tptr)));
13982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
13992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
14002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case BGPTYPE_ATOMIC_AGGREGATE:
14012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len != 0)
1402892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "invalid len"));
14032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
140453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case BGPTYPE_AGGREGATOR:
140553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
140653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                /*
140753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                 * Depending on the AS encoded is of 2 bytes or of 4 bytes,
140853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                 * the length of this PA can be either 6 bytes or 8 bytes.
140953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                 */
141053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if (len != 6 && len != 8) {
1411892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_PRINT((ndo, "invalid len"));
141253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    break;
141353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                }
1414892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_TCHECK2(tptr[0], len);
141553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if (len == 6) {
1416892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		    ND_PRINT((ndo, " AS #%s, origin %s",
1417892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			as_printf(ndo, astostr, sizeof(astostr), EXTRACT_16BITS(tptr)),
1418892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			getname(ndo, tptr + 2)));
141953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                } else {
1420892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		    ND_PRINT((ndo, " AS #%s, origin %s",
1421892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			as_printf(ndo, astostr, sizeof(astostr),
1422892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			EXTRACT_32BITS(tptr)), getname(ndo, tptr + 4)));
142353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                }
142453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                break;
142553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	case BGPTYPE_AGGREGATOR4:
142653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (len != 8) {
1427892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "invalid len"));
14282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
14292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
1430892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK2(tptr[0], 8);
1431892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, " AS #%s, origin %s",
1432892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	   	    as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(tptr)),
1433892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		    getname(ndo, tptr + 4)));
14342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
14352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case BGPTYPE_COMMUNITIES:
14362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len % 4) {
1437892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "invalid len"));
14382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
14392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
14402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		while (tlen>0) {
1441892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			uint32_t comm;
1442892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_TCHECK2(tptr[0], 4);
14432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			comm = EXTRACT_32BITS(tptr);
14442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			switch (comm) {
14452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			case BGP_COMMUNITY_NO_EXPORT:
1446892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, " NO_EXPORT"));
14472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
14482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			case BGP_COMMUNITY_NO_ADVERT:
1449892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, " NO_ADVERTISE"));
14502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
14512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			case BGP_COMMUNITY_NO_EXPORT_SUBCONFED:
1452892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, " NO_EXPORT_SUBCONFED"));
14532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
14542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			default:
1455892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, "%u:%u%s",
14562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                       (comm >> 16) & 0xffff,
14572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                       comm & 0xffff,
1458892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                       (tlen>4) ? ", " : ""));
14592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
14602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
14612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        tlen -=4;
14622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        tptr +=4;
14632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
14642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
14652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case BGPTYPE_ORIGINATOR_ID:
14662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len != 4) {
1467892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "invalid len"));
14682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
14692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
1470892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK2(tptr[0], 4);
1471892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_PRINT((ndo, "%s",getname(ndo, tptr)));
14722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                break;
14732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case BGPTYPE_CLUSTER_LIST:
14742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len % 4) {
1475892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "invalid len"));
14762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
14772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
14782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                while (tlen>0) {
1479892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_TCHECK2(tptr[0], 4);
1480892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, "%s%s",
1481892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                               getname(ndo, tptr),
1482892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                (tlen>4) ? ", " : ""));
14832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        tlen -=4;
14842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        tptr +=4;
14852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                }
14862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                break;
14872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case BGPTYPE_MP_REACH_NLRI:
1488892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK2(tptr[0], 3);
14892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		af = EXTRACT_16BITS(tptr);
14902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		safi = tptr[2];
1491892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
1492892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_PRINT((ndo, "\n\t    AFI: %s (%u), %sSAFI: %s (%u)",
14932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                       tok2strbuf(af_values, "Unknown AFI", af,
14942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				  tokbuf, sizeof(tokbuf)),
14952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                       af,
14962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                       (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */
14972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                       tok2strbuf(bgp_safi_values, "Unknown SAFI", safi,
14982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				  tokbuf, sizeof(tokbuf)),
1499892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                       safi));
15002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
15012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                switch(af<<8 | safi) {
15022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_INET<<8 | SAFNUM_UNICAST):
15032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
15042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
15052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
15062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
15072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
15082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
15092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
151053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN):
1511892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		case (AFNUM_INET<<8 | SAFNUM_MDT):
15122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6
15132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
15142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
15152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
15162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
15172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
15182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
15192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
15202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
15212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
15222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
15232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
15242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST):
15252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST):
15262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST):
15272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
15282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
15292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
15302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
15312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    break;
15322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                default:
1533892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_TCHECK2(tptr[0], tlen);
1534892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_PRINT((ndo, "\n\t    no AFI %u / SAFI %u decoder", af, safi));
1535892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    if (ndo->ndo_vflag <= 1)
1536892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        print_unknown_data(ndo, tptr, "\n\t    ", tlen);
15372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    goto done;
15382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    break;
15392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                }
15402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
15412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                tptr +=3;
15422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1543892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK(tptr[0]);
15442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		nhlen = tptr[0];
15452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                tlen = nhlen;
15462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                tptr++;
15472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
15482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (tlen) {
154953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    int nnh = 0;
1550892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_PRINT((ndo, "\n\t    nexthop: "));
15512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    while (tlen > 0) {
155253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        if ( nnh++ > 0 ) {
1553892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo,  ", " ));
155453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        }
15552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        switch(af<<8 | safi) {
15562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_INET<<8 | SAFNUM_UNICAST):
15572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
15582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
15592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
15602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
156153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN):
1562892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        case (AFNUM_INET<<8 | SAFNUM_MDT):
156353f17a9db278d33517d9888dd77848f554522a38JP Abgrall			    if (tlen < (int)sizeof(struct in_addr)) {
1564892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_PRINT((ndo, "invalid len"));
15652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                tlen = 0;
15662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            } else {
1567892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_TCHECK2(tptr[0], sizeof(struct in_addr));
1568892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_PRINT((ndo, "%s",getname(ndo, tptr)));
15692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                tlen -= sizeof(struct in_addr);
15702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                tptr += sizeof(struct in_addr);
15712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            }
15722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            break;
15732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
15742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
15752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
15762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            if (tlen < (int)(sizeof(struct in_addr)+BGP_VPN_RD_LEN)) {
1577892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_PRINT((ndo, "invalid len"));
15782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                tlen = 0;
15792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            } else {
1580892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_TCHECK2(tptr[0], sizeof(struct in_addr)+BGP_VPN_RD_LEN);
1581892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_PRINT((ndo, "RD: %s, %s",
1582892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                       bgp_vpn_rd_print(ndo, tptr),
1583892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                       getname(ndo, tptr+BGP_VPN_RD_LEN)));
15842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                tlen -= (sizeof(struct in_addr)+BGP_VPN_RD_LEN);
15852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                tptr += (sizeof(struct in_addr)+BGP_VPN_RD_LEN);
15862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            }
15872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            break;
15882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6
15892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
15902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
15912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
15922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
15932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            if (tlen < (int)sizeof(struct in6_addr)) {
1594892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_PRINT((ndo, "invalid len"));
15952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                tlen = 0;
15962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            } else {
1597892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_TCHECK2(tptr[0], sizeof(struct in6_addr));
1598892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_PRINT((ndo, "%s", getname6(ndo, tptr)));
15992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                tlen -= sizeof(struct in6_addr);
16002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                tptr += sizeof(struct in6_addr);
16012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            }
16022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            break;
16032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
16042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
16052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
16062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            if (tlen < (int)(sizeof(struct in6_addr)+BGP_VPN_RD_LEN)) {
1607892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_PRINT((ndo, "invalid len"));
16082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                tlen = 0;
16092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            } else {
1610892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_TCHECK2(tptr[0], sizeof(struct in6_addr)+BGP_VPN_RD_LEN);
1611892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_PRINT((ndo, "RD: %s, %s",
1612892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                       bgp_vpn_rd_print(ndo, tptr),
1613892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                       getname6(ndo, tptr+BGP_VPN_RD_LEN)));
16142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                tlen -= (sizeof(struct in6_addr)+BGP_VPN_RD_LEN);
16152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                tptr += (sizeof(struct in6_addr)+BGP_VPN_RD_LEN);
16162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            }
16172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            break;
16182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
16192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
16202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
16212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
16222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
16232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            if (tlen < (int)sizeof(struct in_addr)) {
1624892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_PRINT((ndo, "invalid len"));
16252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                tlen = 0;
16262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            } else {
1627892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_TCHECK2(tptr[0], sizeof(struct in_addr));
1628892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_PRINT((ndo, "%s", getname(ndo, tptr)));
16292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                tlen -= (sizeof(struct in_addr));
16302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                tptr += (sizeof(struct in_addr));
16312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            }
16322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            break;
16332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
16342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
16352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
1636892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_TCHECK2(tptr[0], tlen);
1637892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "%s", isonsap_string(tptr, tlen)));
16382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            tptr += tlen;
16392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            tlen = 0;
16402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            break;
16412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
16422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST):
16432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST):
16442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST):
16452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            if (tlen < BGP_VPN_RD_LEN+1) {
1646892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_PRINT((ndo, "invalid len"));
16472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                tlen = 0;
16482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            } else {
1649892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_TCHECK2(tptr[0], tlen);
1650892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_PRINT((ndo, "RD: %s, %s",
1651892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                       bgp_vpn_rd_print(ndo, tptr),
1652892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                       isonsap_string(tptr+BGP_VPN_RD_LEN,tlen-BGP_VPN_RD_LEN)));
16532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                /* rfc986 mapped IPv4 address ? */
16542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                if (EXTRACT_32BITS(tptr+BGP_VPN_RD_LEN) ==  0x47000601)
1655892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                    ND_PRINT((ndo, " = %s", getname(ndo, tptr+BGP_VPN_RD_LEN+4)));
16562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6
16572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                /* rfc1888 mapped IPv6 address ? */
16582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                else if (EXTRACT_24BITS(tptr+BGP_VPN_RD_LEN) ==  0x350000)
1659892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                    ND_PRINT((ndo, " = %s", getname6(ndo, tptr+BGP_VPN_RD_LEN+3)));
16602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
16612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                tptr += tlen;
16622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                tlen = 0;
16632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            }
16642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            break;
16652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        default:
1666892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_TCHECK2(tptr[0], tlen);
1667892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "no AFI %u/SAFI %u decoder", af, safi));
1668892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            if (ndo->ndo_vflag <= 1)
1669892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                print_unknown_data(ndo, tptr, "\n\t    ", tlen);
16702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            tptr += tlen;
16712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            tlen = 0;
16722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto done;
16732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            break;
16742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        }
16752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    }
16762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
1677892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, ", nh-length: %u", nhlen));
16782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		tptr += tlen;
16792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1680892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK(tptr[0]);
16812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		snpa = tptr[0];
16822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		tptr++;
16832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
16842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (snpa) {
1685892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "\n\t    %u SNPA", snpa));
16862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			for (/*nothing*/; snpa > 0; snpa--) {
1687892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_TCHECK(tptr[0]);
1688892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, "\n\t      %d bytes", tptr[0]));
16892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				tptr += tptr[0] + 1;
16902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
16912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		} else {
1692892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, ", no SNPA"));
16932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                }
16942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
16952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		while (len - (tptr - pptr) > 0) {
16962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    switch (af<<8 | safi) {
16972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET<<8 | SAFNUM_UNICAST):
16982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
16992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
1700892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_prefix4(ndo, tptr, len, buf, sizeof(buf));
17012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1702892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
17032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
17042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
170553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        else if (advance == -3)
170653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                            break; /* bytes left, but not enough */
17072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1708892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
17092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
17102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
1711892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_labeled_prefix4(ndo, tptr, len, buf, sizeof(buf));
17122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1713892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
17142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
17152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
171653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        else if (advance == -3)
171753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                            break; /* bytes left, but not enough */
17182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1719892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
17202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
17212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
17222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
17232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
1724892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_labeled_vpn_prefix4(ndo, tptr, buf, sizeof(buf));
17252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1726892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
17272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
17282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
17292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1730892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
17312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
17322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
1733892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_rt_routing_info(ndo, tptr, buf, sizeof(buf));
17342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1735892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
17362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
17372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
17382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1739892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
17402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
174153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */
174253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN):
1743892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_multicast_vpn(ndo, tptr, buf, sizeof(buf));
174453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        if (advance == -1)
1745892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
174653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        else if (advance == -2)
174753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                            goto trunc;
174853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        else
1749892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
175053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        break;
175153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
175253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		    case (AFNUM_INET<<8 | SAFNUM_MDT):
1753892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		      advance = decode_mdt_vpn_nlri(ndo, tptr, buf, sizeof(buf));
175453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		      if (advance == -1)
1755892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
175653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        else if (advance == -2)
175753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                            goto trunc;
175853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        else
1759892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
176053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		       break;
17612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6
17622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
17632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
17642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
1765892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_prefix6(ndo, tptr, len, buf, sizeof(buf));
17662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1767892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
17682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
17692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
177053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        else if (advance == -3)
177153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                            break; /* bytes left, but not enough */
17722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1773892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
17742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
17752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
1776892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_labeled_prefix6(ndo, tptr, len, buf, sizeof(buf));
17772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1778892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
17792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
17802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
178153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        else if (advance == -3)
178253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                            break; /* bytes left, but not enough */
17832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1784892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
17852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
17862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
17872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
17882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
1789892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_labeled_vpn_prefix6(ndo, tptr, buf, sizeof(buf));
17902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1791892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
17922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
17932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
17942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1795892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
17962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
17972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
17982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
17992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
18002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
18012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
1802892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_labeled_vpn_l2(ndo, tptr, buf, sizeof(buf));
18032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1804892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal length)"));
18052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
18062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
18072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1808892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
18092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
18102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
18112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
18122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
1813892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_clnp_prefix(ndo, tptr, buf, sizeof(buf));
18142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1815892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
18162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
18172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
18182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1819892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
18202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
18212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST):
18222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST):
18232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST):
1824892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_labeled_vpn_clnp_prefix(ndo, tptr, buf, sizeof(buf));
18252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1826892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
18272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
18282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
18292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1830892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
1831892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        break;
18322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    default:
1833892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_TCHECK2(*tptr,tlen);
1834892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, "\n\t    no AFI %u / SAFI %u decoder", af, safi));
1835892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        if (ndo->ndo_vflag <= 1)
1836892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            print_unknown_data(ndo, tptr, "\n\t    ", tlen);
18372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        advance = 0;
18382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        tptr = pptr + len;
18392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
18402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    }
18412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    if (advance < 0)
18422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
18432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    tptr += advance;
18442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
18452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        done:
18462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
18472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
18482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case BGPTYPE_MP_UNREACH_NLRI:
1849892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK2(tptr[0], BGP_MP_NLRI_MINSIZE);
18502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		af = EXTRACT_16BITS(tptr);
18512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		safi = tptr[2];
18522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1853892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_PRINT((ndo, "\n\t    AFI: %s (%u), %sSAFI: %s (%u)",
18542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                       tok2strbuf(af_values, "Unknown AFI", af,
18552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				  tokbuf, sizeof(tokbuf)),
18562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                       af,
18572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                       (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */
18582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                       tok2strbuf(bgp_safi_values, "Unknown SAFI", safi,
18592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				  tokbuf, sizeof(tokbuf)),
1860892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                       safi));
18612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
18622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                if (len == BGP_MP_NLRI_MINSIZE)
1863892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_PRINT((ndo, "\n\t      End-of-Rib Marker (empty NLRI)"));
18642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
18652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		tptr += 3;
1866892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
18672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		while (len - (tptr - pptr) > 0) {
18682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    switch (af<<8 | safi) {
18692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET<<8 | SAFNUM_UNICAST):
18702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
18712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
1872892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_prefix4(ndo, tptr, len, buf, sizeof(buf));
18732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1874892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
18752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
18762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
187753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        else if (advance == -3)
187853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                            break; /* bytes left, but not enough */
18792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1880892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
18812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
18822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
1883892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_labeled_prefix4(ndo, tptr, len, buf, sizeof(buf));
18842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1885892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
18862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
18872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
188853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        else if (advance == -3)
188953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                            break; /* bytes left, but not enough */
18902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1891892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
18922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
18932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
18942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
18952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
1896892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_labeled_vpn_prefix4(ndo, tptr, buf, sizeof(buf));
18972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1898892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
18992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
19002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
19012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1902892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
19032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
19042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6
19052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
19062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
19072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
1908892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_prefix6(ndo, tptr, len, buf, sizeof(buf));
19092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1910892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
19112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
19122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
191353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        else if (advance == -3)
191453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                            break; /* bytes left, but not enough */
19152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1916892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
19172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
19182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
1919892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_labeled_prefix6(ndo, tptr, len, buf, sizeof(buf));
19202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1921892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
19222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
19232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
192453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        else if (advance == -3)
192553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                            break; /* bytes left, but not enough */
19262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1927892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
19282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
19292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
19302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
19312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
1932892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_labeled_vpn_prefix6(ndo, tptr, buf, sizeof(buf));
19332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1934892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
19352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
19362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
19372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1938892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
19392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
19402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
19412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
19422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
19432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
19442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
1945892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_labeled_vpn_l2(ndo, tptr, buf, sizeof(buf));
19462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1947892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal length)"));
19482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
19492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
19502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1951892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
19522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
19532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
19542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
19552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
1956892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_clnp_prefix(ndo, tptr, buf, sizeof(buf));
19572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1958892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
19592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
19602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
19612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1962892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
19632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
19642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST):
19652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST):
19662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST):
1967892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_labeled_vpn_clnp_prefix(ndo, tptr, buf, sizeof(buf));
19682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (advance == -1)
1969892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
19702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else if (advance == -2)
19712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
19722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1973892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
1974892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        break;
197553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		    case (AFNUM_INET<<8 | SAFNUM_MDT):
1976892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		      advance = decode_mdt_vpn_nlri(ndo, tptr, buf, sizeof(buf));
197753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		      if (advance == -1)
1978892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
197953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        else if (advance == -2)
198053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                            goto trunc;
198153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        else
1982892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
198353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		       break;
198453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */
198553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN):
1986892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        advance = decode_multicast_vpn(ndo, tptr, buf, sizeof(buf));
198753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        if (advance == -1)
1988892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
198953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        else if (advance == -2)
199053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                            goto trunc;
199153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        else
1992892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "\n\t      %s", buf));
199353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        break;
19942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    default:
1995892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_TCHECK2(*(tptr-3),tlen);
1996892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, "no AFI %u / SAFI %u decoder", af, safi));
1997892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        if (ndo->ndo_vflag <= 1)
1998892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            print_unknown_data(ndo, tptr-3, "\n\t    ", tlen);
19992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        advance = 0;
20002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        tptr = pptr + len;
20012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
20022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    }
20032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    if (advance < 0)
20042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
20052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    tptr += advance;
20062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
20072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
20082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case BGPTYPE_EXTD_COMMUNITIES:
20092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len % 8) {
2010892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "invalid len"));
20112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
20122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
20132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                while (tlen>0) {
2014892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    uint16_t extd_comm;
20152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2016892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_TCHECK2(tptr[0], 2);
20172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    extd_comm=EXTRACT_16BITS(tptr);
20182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2019892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		    ND_PRINT((ndo, "\n\t    %s (0x%04x), Flags [%s]",
20202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			   tok2strbuf(bgp_extd_comm_subtype_values,
20212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				      "unknown extd community typecode",
20222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				      extd_comm, tokbuf, sizeof(tokbuf)),
20232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			   extd_comm,
2024892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			   bittok2str(bgp_extd_comm_flag_values, "none", extd_comm)));
20252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2026892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_TCHECK2(*(tptr+2), 6);
20272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    switch(extd_comm) {
20282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case BGP_EXT_COM_RT_0:
20292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case BGP_EXT_COM_RO_0:
203053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    case BGP_EXT_COM_L2VPN_RT_0:
2031892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, ": %u:%u (= %s)",
20322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               EXTRACT_16BITS(tptr+2),
203353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                               EXTRACT_32BITS(tptr+4),
2034892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                               getname(ndo, tptr+4)));
20352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
20362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case BGP_EXT_COM_RT_1:
20372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case BGP_EXT_COM_RO_1:
203853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    case BGP_EXT_COM_L2VPN_RT_1:
203953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    case BGP_EXT_COM_VRF_RT_IMP:
2040892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, ": %s:%u",
2041892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                               getname(ndo, tptr+2),
2042892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                               EXTRACT_16BITS(tptr+6)));
20432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
20442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case BGP_EXT_COM_RT_2:
20452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case BGP_EXT_COM_RO_2:
2046892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, ": %s:%u",
2047892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			    as_printf(ndo, astostr, sizeof(astostr),
2048892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			    EXTRACT_32BITS(tptr+2)), EXTRACT_16BITS(tptr+6)));
204953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
20502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case BGP_EXT_COM_LINKBAND:
20512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		        bw.i = EXTRACT_32BITS(tptr+2);
2052892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, ": bandwidth: %.3f Mbps",
2053892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                               bw.f*8/1000000));
20542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
20552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case BGP_EXT_COM_VPN_ORIGIN:
20562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case BGP_EXT_COM_VPN_ORIGIN2:
20572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case BGP_EXT_COM_VPN_ORIGIN3:
20582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case BGP_EXT_COM_VPN_ORIGIN4:
20592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case BGP_EXT_COM_OSPF_RID:
20602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case BGP_EXT_COM_OSPF_RID2:
2061892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, "%s", getname(ndo, tptr+2)));
20622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
20632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case BGP_EXT_COM_OSPF_RTYPE:
2064892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    case BGP_EXT_COM_OSPF_RTYPE2:
2065892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, ": area:%s, router-type:%s, metric-type:%s%s",
2066892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                               getname(ndo, tptr+2),
20672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               tok2strbuf(bgp_extd_comm_ospf_rtype_values,
20682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					  "unknown (0x%02x)",
20692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					  *(tptr+6),
20702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					  tokbuf, sizeof(tokbuf)),
20712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               (*(tptr+7) &  BGP_OSPF_RTYPE_METRIC_TYPE) ? "E2" : "",
2072892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                               ((*(tptr+6) == BGP_OSPF_RTYPE_EXT) || (*(tptr+6) == BGP_OSPF_RTYPE_NSSA)) ? "E1" : ""));
20732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
20742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case BGP_EXT_COM_L2INFO:
2075892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, ": %s Control Flags [0x%02x]:MTU %u",
20762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               tok2strbuf(l2vpn_encaps_values,
20772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					  "unknown encaps",
20782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					  *(tptr+2),
20792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					  tokbuf, sizeof(tokbuf)),
20802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                       *(tptr+3),
2081892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                               EXTRACT_16BITS(tptr+4)));
20822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
208353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    case BGP_EXT_COM_SOURCE_AS:
2084892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, ": AS %u", EXTRACT_16BITS(tptr+2)));
208553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        break;
20862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    default:
2087892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_TCHECK2(*tptr,8);
2088892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        print_unknown_data(ndo, tptr, "\n\t      ", 8);
20892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
20902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    }
20912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    tlen -=8;
20922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    tptr +=8;
20932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                }
20942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                break;
20952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
209653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case BGPTYPE_PMSI_TUNNEL:
209753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        {
2098892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                uint8_t tunnel_type, flags;
2099892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
210053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                tunnel_type = *(tptr+1);
210153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                flags = *tptr;
210253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                tlen = len;
210353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
2104892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_TCHECK2(tptr[0], 5);
2105892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_PRINT((ndo, "\n\t    Tunnel-type %s (%u), Flags [%s], MPLS Label %u",
210653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       tok2str(bgp_pmsi_tunnel_values, "Unknown", tunnel_type),
210753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       tunnel_type,
210853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       bittok2str(bgp_pmsi_flag_values, "none", flags),
2109892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                       EXTRACT_24BITS(tptr+2)>>4));
211053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
211153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                tptr +=5;
211253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                tlen -= 5;
211353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
211453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                switch (tunnel_type) {
211553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case BGP_PMSI_TUNNEL_PIM_SM: /* fall through */
211653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case BGP_PMSI_TUNNEL_PIM_BIDIR:
2117892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_TCHECK2(tptr[0], 8);
2118892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_PRINT((ndo, "\n\t      Sender %s, P-Group %s",
2119892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                           ipaddr_string(ndo, tptr),
2120892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                           ipaddr_string(ndo, tptr+4)));
212153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    break;
212253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
212353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case BGP_PMSI_TUNNEL_PIM_SSM:
2124892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_TCHECK2(tptr[0], 8);
2125892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_PRINT((ndo, "\n\t      Root-Node %s, P-Group %s",
2126892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                           ipaddr_string(ndo, tptr),
2127892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                           ipaddr_string(ndo, tptr+4)));
212853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    break;
212953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case BGP_PMSI_TUNNEL_INGRESS:
2130892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_TCHECK2(tptr[0], 4);
2131892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_PRINT((ndo, "\n\t      Tunnel-Endpoint %s",
2132892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                           ipaddr_string(ndo, tptr)));
213353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    break;
213453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case BGP_PMSI_TUNNEL_LDP_P2MP: /* fall through */
213553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case BGP_PMSI_TUNNEL_LDP_MP2MP:
2136892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_TCHECK2(tptr[0], 8);
2137892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_PRINT((ndo, "\n\t      Root-Node %s, LSP-ID 0x%08x",
2138892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                           ipaddr_string(ndo, tptr),
2139892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                           EXTRACT_32BITS(tptr+4)));
214053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    break;
214153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case BGP_PMSI_TUNNEL_RSVP_P2MP:
2142892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_TCHECK2(tptr[0], 8);
2143892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_PRINT((ndo, "\n\t      Extended-Tunnel-ID %s, P2MP-ID 0x%08x",
2144892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                           ipaddr_string(ndo, tptr),
2145892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                           EXTRACT_32BITS(tptr+4)));
214653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    break;
214753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                default:
2148892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    if (ndo->ndo_vflag <= 1) {
2149892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        print_unknown_data(ndo, tptr, "\n\t      ", tlen);
215053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    }
215153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                }
215253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                break;
215353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
21542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case BGPTYPE_ATTR_SET:
2155892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_TCHECK2(tptr[0], 4);
215653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if (len < 4)
215753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                	goto trunc;
2158892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\n\t    Origin AS: %s",
2159892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		    as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(tptr))));
216053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		tptr+=4;
21612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                len -=4;
21622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
216353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                while (len) {
216453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    u_int aflags, atype, alenlen, alen;
2165892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
2166892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_TCHECK2(tptr[0], 2);
216753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    if (len < 2)
216853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        goto trunc;
216953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    aflags = *tptr;
217053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    atype = *(tptr + 1);
217153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    tptr += 2;
217253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    len -= 2;
217353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    alenlen = bgp_attr_lenlen(aflags, tptr);
2174892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_TCHECK2(tptr[0], alenlen);
217553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    if (len < alenlen)
217653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        goto trunc;
217753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    alen = bgp_attr_len(aflags, tptr);
217853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    tptr += alenlen;
217953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    len -= alenlen;
2180892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
2181892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_PRINT((ndo, "\n\t      %s (%u), length: %u",
21822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                           tok2strbuf(bgp_attr_values,
218353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                      "Unknown Attribute", atype,
218453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                      tokbuf, sizeof(tokbuf)),
218553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                           atype,
2186892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                           alen));
2187892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
218853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    if (aflags) {
2189892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, ", Flags [%s%s%s%s",
219053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                               aflags & 0x80 ? "O" : "",
219153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                               aflags & 0x40 ? "T" : "",
219253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                               aflags & 0x20 ? "P" : "",
2193892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                               aflags & 0x10 ? "E" : ""));
219453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        if (aflags & 0xf)
2195892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            ND_PRINT((ndo, "+%x", aflags & 0xf));
2196892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, "]: "));
21972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    }
21982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    /* FIXME check for recursion */
2199892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    if (!bgp_attr_print(ndo, atype, tptr, alen))
22002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        return 0;
22012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    tptr += alen;
22022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    len -= alen;
22032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
22042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                break;
2205892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
22062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
22072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	default:
2208892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	    ND_TCHECK2(*pptr,len);
2209892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_PRINT((ndo, "\n\t    no Attribute %u decoder", atype)); /* we have no decoder for the attribute */
2210892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            if (ndo->ndo_vflag <= 1)
2211892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                print_unknown_data(ndo, pptr, "\n\t    ", len);
22122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            break;
22132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
2214892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        if (ndo->ndo_vflag > 1 && len) { /* omit zero length attributes*/
2215892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_TCHECK2(*pptr,len);
2216892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            print_unknown_data(ndo, pptr, "\n\t    ", len);
22172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        }
22182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        return 1;
22192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
22202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
22212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        return 0;
22222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
22232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
22242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
2225892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesbgp_capabilities_print(netdissect_options *ndo,
2226892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                       const u_char *opt, int caps_len)
222753f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
222853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	char tokbuf[TOKBUFSIZE];
222953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	char tokbuf2[TOKBUFSIZE];
223053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int cap_type, cap_len, tcap_len, cap_offset;
223153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        int i = 0;
223253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
223353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        while (i < caps_len) {
2234892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_TCHECK2(opt[i], BGP_CAP_HEADER_SIZE);
223553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                cap_type=opt[i];
223653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                cap_len=opt[i+1];
223753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                tcap_len=cap_len;
2238892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_PRINT((ndo, "\n\t      %s (%u), length: %u",
223953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       tok2strbuf(bgp_capcode_values, "Unknown",
224053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                  cap_type, tokbuf, sizeof(tokbuf)),
224153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       cap_type,
2242892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                       cap_len));
2243892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_TCHECK2(opt[i+2], cap_len);
224453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                switch (cap_type) {
224553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case BGP_CAPCODE_MP:
2246892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_PRINT((ndo, "\n\t\tAFI %s (%u), SAFI %s (%u)",
224753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                           tok2strbuf(af_values, "Unknown",
224853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                      EXTRACT_16BITS(opt+i+2),
224953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                      tokbuf, sizeof(tokbuf)),
225053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                           EXTRACT_16BITS(opt+i+2),
225153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                           tok2strbuf(bgp_safi_values, "Unknown",
225253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                      opt[i+5],
225353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                      tokbuf, sizeof(tokbuf)),
2254892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                           opt[i+5]));
225553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    break;
225653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case BGP_CAPCODE_RESTART:
2257892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_PRINT((ndo, "\n\t\tRestart Flags: [%s], Restart Time %us",
225853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                           ((opt[i+2])&0x80) ? "R" : "none",
2259892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                           EXTRACT_16BITS(opt+i+2)&0xfff));
226053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    tcap_len-=2;
226153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    cap_offset=4;
226253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    while(tcap_len>=4) {
2263892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, "\n\t\t  AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s",
226453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                               tok2strbuf(af_values,"Unknown",
226553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                          EXTRACT_16BITS(opt+i+cap_offset),
226653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                          tokbuf, sizeof(tokbuf)),
226753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                               EXTRACT_16BITS(opt+i+cap_offset),
226853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                               tok2strbuf(bgp_safi_values,"Unknown",
226953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                          opt[i+cap_offset+2],
227053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                          tokbuf2, sizeof(tokbuf2)),
227153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                               opt[i+cap_offset+2],
2272892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                               ((opt[i+cap_offset+3])&0x80) ? "yes" : "no" ));
227353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        tcap_len-=4;
227453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        cap_offset+=4;
227553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    }
227653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    break;
227753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case BGP_CAPCODE_RR:
227853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case BGP_CAPCODE_RR_CISCO:
227953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    break;
228053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case BGP_CAPCODE_AS_NEW:
228153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
228253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    /*
228353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                     * Extract the 4 byte AS number encoded.
228453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                     */
228553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    if (cap_len == 4) {
2286892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, "\n\t\t 4 Byte AS %s",
2287892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            as_printf(ndo, astostr, sizeof(astostr),
2288892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            EXTRACT_32BITS(opt + i + 2))));
228953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    }
229053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    break;
229153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                default:
2292892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_PRINT((ndo, "\n\t\tno decoder for Capability %u",
2293892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                           cap_type));
2294892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    if (ndo->ndo_vflag <= 1)
2295892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        print_unknown_data(ndo, &opt[i+2], "\n\t\t", cap_len);
229653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    break;
229753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                }
2298892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                if (ndo->ndo_vflag > 1 && cap_len > 0) {
2299892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    print_unknown_data(ndo, &opt[i+2], "\n\t\t", cap_len);
230053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                }
230153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                i += BGP_CAP_HEADER_SIZE + cap_len;
230253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
230353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        return;
230453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
230553f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
2306892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "[|BGP]"));
230753f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
230853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
230953f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic void
2310892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesbgp_open_print(netdissect_options *ndo,
2311892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               const u_char *dat, int length)
23122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
23132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct bgp_open bgpo;
23142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct bgp_opt bgpopt;
23152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *opt;
231653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int i;
23172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	char tokbuf[TOKBUFSIZE];
23182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2319892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(dat[0], BGP_OPEN_SIZE);
23202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memcpy(&bgpo, dat, BGP_OPEN_SIZE);
23212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2322892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "\n\t  Version %d, ", bgpo.bgpo_version));
2323892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "my AS %s, ",
2324892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	    as_printf(ndo, astostr, sizeof(astostr), ntohs(bgpo.bgpo_myas))));
2325892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "Holdtime %us, ", ntohs(bgpo.bgpo_holdtime)));
2326892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "ID %s", getname(ndo, (u_char *)&bgpo.bgpo_id)));
2327892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "\n\t  Optional parameters, length: %u", bgpo.bgpo_optlen));
23282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
23292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        /* some little sanity checking */
2330892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        if (length < bgpo.bgpo_optlen+BGP_OPEN_SIZE)
23312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            return;
23322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
23332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* ugly! */
23342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	opt = &((const struct bgp_open *)dat)->bgpo_optlen;
23352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	opt++;
23362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
23372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	i = 0;
23382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (i < bgpo.bgpo_optlen) {
2339892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK2(opt[i], BGP_OPT_SIZE);
23402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		memcpy(&bgpopt, &opt[i], BGP_OPT_SIZE);
23412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (i + 2 + bgpopt.bgpopt_len > bgpo.bgpo_optlen) {
2342892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "\n\t     Option %d, length: %u", bgpopt.bgpopt_type, bgpopt.bgpopt_len));
23432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
23442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
23452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2346892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\n\t    Option %s (%u), length: %u",
234753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		       tok2strbuf(bgp_opt_values,"Unknown",
23482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				  bgpopt.bgpopt_type,
23492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				  tokbuf, sizeof(tokbuf)),
235053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		       bgpopt.bgpopt_type,
2351892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		       bgpopt.bgpopt_len));
235253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
235353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		/* now let's decode the options we know*/
235453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		switch(bgpopt.bgpopt_type) {
23552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
235653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		case BGP_OPT_CAP:
2357892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			bgp_capabilities_print(ndo, &opt[i+BGP_OPT_SIZE],
235853f17a9db278d33517d9888dd77848f554522a38JP Abgrall			    bgpopt.bgpopt_len);
235953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
236053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
236153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		case BGP_OPT_AUTH:
236253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		default:
2363892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		       ND_PRINT((ndo, "\n\t      no decoder for option %u",
2364892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			   bgpopt.bgpopt_type));
236553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		       break;
236653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
23672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		i += BGP_OPT_SIZE + bgpopt.bgpopt_len;
23682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
23692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
23702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
2371892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "[|BGP]"));
23722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
23732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
23742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
2375892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesbgp_update_print(netdissect_options *ndo,
2376892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 const u_char *dat, int length)
23772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
23782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct bgp bgp;
23792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *p;
238053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int withdrawn_routes_len;
23812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int len;
23822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int i;
23832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	char tokbuf[TOKBUFSIZE];
238453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#ifndef INET6
238553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	char buf[MAXHOSTNAMELEN + 100];
238653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int wpfx;
238753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#endif
23882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2389892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(dat[0], BGP_SIZE);
239053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (length < BGP_SIZE)
239153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		goto trunc;
23922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memcpy(&bgp, dat, BGP_SIZE);
23932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	p = dat + BGP_SIZE;	/*XXX*/
239453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	length -= BGP_SIZE;
23952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
23962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* Unfeasible routes */
2397892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(p[0], 2);
239853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (length < 2)
239953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		goto trunc;
240053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	withdrawn_routes_len = EXTRACT_16BITS(p);
240153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	p += 2;
240253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	length -= 2;
240353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (withdrawn_routes_len) {
24042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/*
24052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		 * Without keeping state from the original NLRI message,
24062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		 * it's not possible to tell if this a v4 or v6 route,
24072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		 * so only try to decode it if we're not v6 enabled.
24082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	         */
2409892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK2(p[0], withdrawn_routes_len);
241053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (length < withdrawn_routes_len)
241153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			goto trunc;
24122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6
2413892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\n\t  Withdrawn routes: %d bytes", withdrawn_routes_len));
241453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		p += withdrawn_routes_len;
241553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		length -= withdrawn_routes_len;
24162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#else
241753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (withdrawn_routes_len < 2)
241853f17a9db278d33517d9888dd77848f554522a38JP Abgrall			goto trunc;
241953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		length -= 2;
242053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		withdrawn_routes_len -= 2;
24212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
24222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2423892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\n\t  Withdrawn routes:"));
24242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
242553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		while(withdrawn_routes_len > 0) {
2426892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			wpfx = decode_prefix4(ndo, p, withdrawn_routes_len, buf, sizeof(buf));
24272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (wpfx == -1) {
2428892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
24292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
24302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			} else if (wpfx == -2)
24312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				goto trunc;
243253f17a9db278d33517d9888dd77848f554522a38JP Abgrall			else if (wpfx == -3)
243353f17a9db278d33517d9888dd77848f554522a38JP Abgrall				goto trunc; /* bytes left, but not enough */
24342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			else {
2435892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, "\n\t    %s", buf));
243653f17a9db278d33517d9888dd77848f554522a38JP Abgrall				p += wpfx;
243753f17a9db278d33517d9888dd77848f554522a38JP Abgrall				length -= wpfx;
243853f17a9db278d33517d9888dd77848f554522a38JP Abgrall				withdrawn_routes_len -= wpfx;
24392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
24402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
24412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
24422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
24432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2444892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(p[0], 2);
244553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (length < 2)
244653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		goto trunc;
24472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	len = EXTRACT_16BITS(p);
244853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	p += 2;
244953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	length -= 2;
24502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
245153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if (withdrawn_routes_len == 0 && len == 0 && length == 0) {
245253f17a9db278d33517d9888dd77848f554522a38JP Abgrall            /* No withdrawn routes, no path attributes, no NLRI */
2453892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_PRINT((ndo, "\n\t  End-of-Rib Marker (empty NLRI)"));
24542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            return;
24552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        }
24562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
24572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (len) {
24582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/* do something more useful!*/
245953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		while (len) {
246053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			int aflags, atype, alenlen, alen;
246153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
2462892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_TCHECK2(p[0], 2);
246353f17a9db278d33517d9888dd77848f554522a38JP Abgrall			if (len < 2)
246453f17a9db278d33517d9888dd77848f554522a38JP Abgrall			    goto trunc;
246553f17a9db278d33517d9888dd77848f554522a38JP Abgrall			if (length < 2)
246653f17a9db278d33517d9888dd77848f554522a38JP Abgrall			    goto trunc;
246753f17a9db278d33517d9888dd77848f554522a38JP Abgrall			aflags = *p;
246853f17a9db278d33517d9888dd77848f554522a38JP Abgrall			atype = *(p + 1);
246953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			p += 2;
247053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			len -= 2;
247153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			length -= 2;
247253f17a9db278d33517d9888dd77848f554522a38JP Abgrall			alenlen = bgp_attr_lenlen(aflags, p);
2473892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_TCHECK2(p[0], alenlen);
247453f17a9db278d33517d9888dd77848f554522a38JP Abgrall			if (len < alenlen)
247553f17a9db278d33517d9888dd77848f554522a38JP Abgrall			    goto trunc;
247653f17a9db278d33517d9888dd77848f554522a38JP Abgrall			if (length < alenlen)
247753f17a9db278d33517d9888dd77848f554522a38JP Abgrall			    goto trunc;
247853f17a9db278d33517d9888dd77848f554522a38JP Abgrall			alen = bgp_attr_len(aflags, p);
247953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			p += alenlen;
248053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			len -= alenlen;
248153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			length -= alenlen;
248253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
2483892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "\n\t  %s (%u), length: %u",
24842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                              tok2strbuf(bgp_attr_values, "Unknown Attribute",
248553f17a9db278d33517d9888dd77848f554522a38JP Abgrall					 atype,
24862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					 tokbuf, sizeof(tokbuf)),
248753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                              atype,
2488892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                              alen));
24892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
249053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			if (aflags) {
2491892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, ", Flags [%s%s%s%s",
249253f17a9db278d33517d9888dd77848f554522a38JP Abgrall					aflags & 0x80 ? "O" : "",
249353f17a9db278d33517d9888dd77848f554522a38JP Abgrall					aflags & 0x40 ? "T" : "",
249453f17a9db278d33517d9888dd77848f554522a38JP Abgrall					aflags & 0x20 ? "P" : "",
2495892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes					aflags & 0x10 ? "E" : ""));
249653f17a9db278d33517d9888dd77848f554522a38JP Abgrall				if (aflags & 0xf)
2497892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes					ND_PRINT((ndo, "+%x", aflags & 0xf));
2498892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, "]: "));
24992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
250053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			if (len < alen)
250153f17a9db278d33517d9888dd77848f554522a38JP Abgrall				goto trunc;
250253f17a9db278d33517d9888dd77848f554522a38JP Abgrall			if (length < alen)
250353f17a9db278d33517d9888dd77848f554522a38JP Abgrall				goto trunc;
2504892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			if (!bgp_attr_print(ndo, atype, p, alen))
25052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				goto trunc;
250653f17a9db278d33517d9888dd77848f554522a38JP Abgrall			p += alen;
250753f17a9db278d33517d9888dd77848f554522a38JP Abgrall			len -= alen;
250853f17a9db278d33517d9888dd77848f554522a38JP Abgrall			length -= alen;
25092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
2510892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	}
25112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
251253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (length) {
251353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		/*
251453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * XXX - what if they're using the "Advertisement of
251553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * Multiple Paths in BGP" feature:
251653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 *
251753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * https://datatracker.ietf.org/doc/draft-ietf-idr-add-paths/
251853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 *
251953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 * http://tools.ietf.org/html/draft-ietf-idr-add-paths-06
252053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		 */
2521892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "\n\t  Updated routes:"));
252253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		while (length) {
25232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			char buf[MAXHOSTNAMELEN + 100];
2524892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			i = decode_prefix4(ndo, p, length, buf, sizeof(buf));
25252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (i == -1) {
2526892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
25272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
25282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			} else if (i == -2)
25292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				goto trunc;
253053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			else if (i == -3)
253153f17a9db278d33517d9888dd77848f554522a38JP Abgrall				goto trunc; /* bytes left, but not enough */
25322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			else {
2533892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_PRINT((ndo, "\n\t    %s", buf));
25342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				p += i;
253553f17a9db278d33517d9888dd77848f554522a38JP Abgrall				length -= i;
25362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
25372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
25382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
25392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
25402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
2541892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "[|BGP]"));
25422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
25432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
25442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
2545892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesbgp_notification_print(netdissect_options *ndo,
2546892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                       const u_char *dat, int length)
25472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
25482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct bgp_notification bgpn;
25492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *tptr;
25502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	char tokbuf[TOKBUFSIZE];
25512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	char tokbuf2[TOKBUFSIZE];
25522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2553892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(dat[0], BGP_NOTIFICATION_SIZE);
25542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memcpy(&bgpn, dat, BGP_NOTIFICATION_SIZE);
25552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
25562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        /* some little sanity checking */
25572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        if (length<BGP_NOTIFICATION_SIZE)
25582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            return;
25592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2560892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, ", %s (%u)",
25612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	       tok2strbuf(bgp_notify_major_values, "Unknown Error",
25622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			  bgpn.bgpn_major, tokbuf, sizeof(tokbuf)),
2563892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	       bgpn.bgpn_major));
25642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
25652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        switch (bgpn.bgpn_major) {
25662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
25672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case BGP_NOTIFY_MAJOR_MSG:
2568892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_PRINT((ndo, ", subcode %s (%u)",
25692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		   tok2strbuf(bgp_notify_minor_msg_values, "Unknown",
25702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			      bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)),
2571892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		   bgpn.bgpn_minor));
25722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            break;
25732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case BGP_NOTIFY_MAJOR_OPEN:
2574892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_PRINT((ndo, ", subcode %s (%u)",
25752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		   tok2strbuf(bgp_notify_minor_open_values, "Unknown",
25762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			      bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)),
2577892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		   bgpn.bgpn_minor));
25782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            break;
25792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case BGP_NOTIFY_MAJOR_UPDATE:
2580892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_PRINT((ndo, ", subcode %s (%u)",
25812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		   tok2strbuf(bgp_notify_minor_update_values, "Unknown",
25822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			      bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)),
2583892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		   bgpn.bgpn_minor));
25842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            break;
25852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case BGP_NOTIFY_MAJOR_CAP:
2586892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_PRINT((ndo, " subcode %s (%u)",
25872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		   tok2strbuf(bgp_notify_minor_cap_values, "Unknown",
25882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			      bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)),
2589892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		   bgpn.bgpn_minor));
25902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case BGP_NOTIFY_MAJOR_CEASE:
2591892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_PRINT((ndo, ", subcode %s (%u)",
25922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		   tok2strbuf(bgp_notify_minor_cease_values, "Unknown",
25932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			      bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)),
2594892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		   bgpn.bgpn_minor));
25952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
25962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    /* draft-ietf-idr-cease-subcode-02 mentions optionally 7 bytes
25972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project             * for the maxprefix subtype, which may contain AFI, SAFI and MAXPREFIXES
25982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project             */
25992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if(bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_MAXPRFX && length >= BGP_NOTIFICATION_SIZE + 7) {
26002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		tptr = dat + BGP_NOTIFICATION_SIZE;
2601892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK2(*tptr, 7);
2602892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, ", AFI %s (%u), SAFI %s (%u), Max Prefixes: %u",
26032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		       tok2strbuf(af_values, "Unknown",
26042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				  EXTRACT_16BITS(tptr), tokbuf, sizeof(tokbuf)),
26052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		       EXTRACT_16BITS(tptr),
26062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		       tok2strbuf(bgp_safi_values, "Unknown", *(tptr+2),
26072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				  tokbuf2, sizeof(tokbuf)),
26082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		       *(tptr+2),
2609892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		       EXTRACT_32BITS(tptr+3)));
26102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    }
26112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            break;
26122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        default:
26132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            break;
26142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        }
26152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
26162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
26172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
2618892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "[|BGP]"));
26192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
26202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
26212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
2622892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesbgp_route_refresh_print(netdissect_options *ndo,
2623892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        const u_char *pptr, int len)
2624892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes{
26252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        const struct bgp_route_refresh *bgp_route_refresh_header;
26262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	char tokbuf[TOKBUFSIZE];
26272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	char tokbuf2[TOKBUFSIZE];
26282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2629892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(pptr[0], BGP_ROUTE_REFRESH_SIZE);
26302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
26312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        /* some little sanity checking */
26322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        if (len<BGP_ROUTE_REFRESH_SIZE)
26332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            return;
26342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
26352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        bgp_route_refresh_header = (const struct bgp_route_refresh *)pptr;
26362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2637892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_PRINT((ndo, "\n\t  AFI %s (%u), SAFI %s (%u)",
26382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project               tok2strbuf(af_values,"Unknown",
26392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			  /* this stinks but the compiler pads the structure
26402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			   * weird */
26412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			  EXTRACT_16BITS(&bgp_route_refresh_header->afi),
2642892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			  tokbuf, sizeof(tokbuf)),
26432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project               EXTRACT_16BITS(&bgp_route_refresh_header->afi),
26442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project               tok2strbuf(bgp_safi_values,"Unknown",
26452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			  bgp_route_refresh_header->safi,
26462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			  tokbuf2, sizeof(tokbuf2)),
2647892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               bgp_route_refresh_header->safi));
26482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2649892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        if (ndo->ndo_vflag > 1) {
2650892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_TCHECK2(*pptr, len);
2651892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            print_unknown_data(ndo, pptr, "\n\t  ", len);
26522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        }
2653892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
26542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        return;
26552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
2656892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "[|BGP]"));
26572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
26582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
26592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic int
2660892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesbgp_header_print(netdissect_options *ndo,
2661892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 const u_char *dat, int length)
26622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
26632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct bgp bgp;
26642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	char tokbuf[TOKBUFSIZE];
26652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2666892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK2(dat[0], BGP_SIZE);
26672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memcpy(&bgp, dat, BGP_SIZE);
2668892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "\n\t%s Message (%u), length: %u",
26692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project               tok2strbuf(bgp_msg_values, "Unknown", bgp.bgp_type,
26702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			  tokbuf, sizeof(tokbuf)),
26712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project               bgp.bgp_type,
2672892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               length));
26732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
26742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	switch (bgp.bgp_type) {
26752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case BGP_OPEN:
2676892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		bgp_open_print(ndo, dat, length);
26772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
26782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case BGP_UPDATE:
2679892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		bgp_update_print(ndo, dat, length);
26802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
26812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case BGP_NOTIFICATION:
2682892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		bgp_notification_print(ndo, dat, length);
26832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
26842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case BGP_KEEPALIVE:
26852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                break;
26862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case BGP_ROUTE_REFRESH:
2687892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                bgp_route_refresh_print(ndo, dat, length);
26882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                break;
26892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        default:
26902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                /* we have no decoder for the BGP message */
2691892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_TCHECK2(*dat, length);
2692892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_PRINT((ndo, "\n\t  no Message %u decoder", bgp.bgp_type));
2693892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                print_unknown_data(ndo, dat, "\n\t  ", length);
26942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                break;
26952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
26962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return 1;
26972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
2698892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "[|BGP]"));
26992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return 0;
27002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
27012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
27022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid
2703892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesbgp_print(netdissect_options *ndo,
2704892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes          const u_char *dat, int length)
27052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
27062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *p;
27072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *ep;
27082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *start;
27092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char marker[] = {
27102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
27112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
27122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	};
27132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct bgp bgp;
2714892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t hlen;
27152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	char tokbuf[TOKBUFSIZE];
27162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
27172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ep = dat + length;
2718892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (ndo->ndo_snapend < dat + length)
2719892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ep = ndo->ndo_snapend;
27202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2721892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, ": BGP"));
27222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2723892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        if (ndo->ndo_vflag < 1) /* lets be less chatty */
27242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                return;
27252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
27262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	p = dat;
27272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	start = p;
27282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (p < ep) {
2729892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (!ND_TTEST2(p[0], 1))
27302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
27312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (p[0] != 0xff) {
27322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			p++;
27332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			continue;
27342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
27352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2736892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (!ND_TTEST2(p[0], sizeof(marker)))
27372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
27382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (memcmp(p, marker, sizeof(marker)) != 0) {
27392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			p++;
27402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			continue;
27412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
27422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
27432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/* found BGP header */
2744892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK2(p[0], BGP_SIZE);	/*XXX*/
27452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		memcpy(&bgp, p, BGP_SIZE);
27462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
27472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (start != p)
2748892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, " [|BGP]"));
27492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
27502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		hlen = ntohs(bgp.bgp_len);
27512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (hlen < BGP_SIZE) {
2752892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "\n[|BGP Bogus header length %u < %u]", hlen,
2753892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			    BGP_SIZE));
27542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
27552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
27562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2757892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (ND_TTEST2(p[0], hlen)) {
2758892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			if (!bgp_header_print(ndo, p, hlen))
27592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				return;
27602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			p += hlen;
27612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			start = p;
27622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		} else {
2763892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "\n[|BGP %s]",
27642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			       tok2strbuf(bgp_msg_values,
27652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					  "Unknown Message Type",
27662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					  bgp.bgp_type,
2767892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes					  tokbuf, sizeof(tokbuf))));
27682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
27692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
27702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
27712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
27722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
27732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
27742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
2775892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, " [|BGP]"));
27762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
277753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
277853f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
277953f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Local Variables:
278053f17a9db278d33517d9888dd77848f554522a38JP Abgrall * c-style: whitesmith
278153f17a9db278d33517d9888dd77848f554522a38JP Abgrall * c-basic-offset: 4
278253f17a9db278d33517d9888dd77848f554522a38JP Abgrall * End:
278353f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
2784