xref: /dflybsd-src/contrib/tcpdump/print-ospf6.c (revision 59c07fbdf8168fa08c76c515186d561b5a92690c)
141c99275SPeter Avalos /*
241c99275SPeter Avalos  * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997
341c99275SPeter Avalos  *	The Regents of the University of California.  All rights reserved.
441c99275SPeter Avalos  *
541c99275SPeter Avalos  * Redistribution and use in source and binary forms, with or without
641c99275SPeter Avalos  * modification, are permitted provided that: (1) source code distributions
741c99275SPeter Avalos  * retain the above copyright notice and this paragraph in its entirety, (2)
841c99275SPeter Avalos  * distributions including binary code include the above copyright notice and
941c99275SPeter Avalos  * this paragraph in its entirety in the documentation or other materials
1041c99275SPeter Avalos  * provided with the distribution, and (3) all advertising materials mentioning
1141c99275SPeter Avalos  * features or use of this software display the following acknowledgement:
1241c99275SPeter Avalos  * ``This product includes software developed by the University of California,
1341c99275SPeter Avalos  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1441c99275SPeter Avalos  * the University nor the names of its contributors may be used to endorse
1541c99275SPeter Avalos  * or promote products derived from this software without specific prior
1641c99275SPeter Avalos  * written permission.
1741c99275SPeter Avalos  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1841c99275SPeter Avalos  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1941c99275SPeter Avalos  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2041c99275SPeter Avalos  *
2141c99275SPeter Avalos  * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu)
2241c99275SPeter Avalos  */
2341c99275SPeter Avalos 
24411677aeSAaron LI /* \summary: IPv6 Open Shortest Path First (OSPFv3) printer */
2541c99275SPeter Avalos 
2641c99275SPeter Avalos #ifdef HAVE_CONFIG_H
27*ed775ee7SAntonio Huete Jimenez #include <config.h>
2841c99275SPeter Avalos #endif
2941c99275SPeter Avalos 
30*ed775ee7SAntonio Huete Jimenez #include "netdissect-stdinc.h"
3141c99275SPeter Avalos 
3241c99275SPeter Avalos #include <string.h>
3341c99275SPeter Avalos 
34411677aeSAaron LI #include "netdissect.h"
3541c99275SPeter Avalos #include "addrtoname.h"
3641c99275SPeter Avalos #include "extract.h"
3741c99275SPeter Avalos 
38ea7b4bf5SPeter Avalos #include "ospf.h"
39411677aeSAaron LI 
40411677aeSAaron LI #define	OSPF_TYPE_HELLO         1	/* Hello */
41411677aeSAaron LI #define	OSPF_TYPE_DD            2	/* Database Description */
42411677aeSAaron LI #define	OSPF_TYPE_LS_REQ        3	/* Link State Request */
43411677aeSAaron LI #define	OSPF_TYPE_LS_UPDATE     4	/* Link State Update */
44411677aeSAaron LI #define	OSPF_TYPE_LS_ACK        5	/* Link State Ack */
45411677aeSAaron LI 
46411677aeSAaron LI /* Options *_options	*/
47411677aeSAaron LI #define OSPF6_OPTION_V6	0x01	/* V6 bit: A bit for peeping tom */
48411677aeSAaron LI #define OSPF6_OPTION_E	0x02	/* E bit: External routes advertised	*/
49411677aeSAaron LI #define OSPF6_OPTION_MC	0x04	/* MC bit: Multicast capable */
50411677aeSAaron LI #define OSPF6_OPTION_N	0x08	/* N bit: For type-7 LSA */
51411677aeSAaron LI #define OSPF6_OPTION_R	0x10	/* R bit: Router bit */
52411677aeSAaron LI #define OSPF6_OPTION_DC	0x20	/* DC bit: Demand circuits */
53411677aeSAaron LI /* The field is actually 24-bit (RFC5340 Section A.2). */
54411677aeSAaron LI #define OSPF6_OPTION_AF	0x0100	/* AF bit: Multiple address families */
55411677aeSAaron LI #define OSPF6_OPTION_L	0x0200	/* L bit: Link-local signaling (LLS) */
56411677aeSAaron LI #define OSPF6_OPTION_AT	0x0400	/* AT bit: Authentication trailer */
57411677aeSAaron LI 
58411677aeSAaron LI 
59411677aeSAaron LI /* db_flags	*/
60411677aeSAaron LI #define	OSPF6_DB_INIT		0x04	    /*	*/
61411677aeSAaron LI #define	OSPF6_DB_MORE		0x02
62411677aeSAaron LI #define	OSPF6_DB_MASTER		0x01
63411677aeSAaron LI #define	OSPF6_DB_M6		0x10  /* IPv6 MTU */
64411677aeSAaron LI 
65411677aeSAaron LI /* ls_type	*/
66411677aeSAaron LI #define	LS_TYPE_ROUTER		1   /* router link */
67411677aeSAaron LI #define	LS_TYPE_NETWORK		2   /* network link */
68411677aeSAaron LI #define	LS_TYPE_INTER_AP	3   /* Inter-Area-Prefix */
69411677aeSAaron LI #define	LS_TYPE_INTER_AR	4   /* Inter-Area-Router */
70411677aeSAaron LI #define	LS_TYPE_ASE		5   /* ASE */
71411677aeSAaron LI #define	LS_TYPE_GROUP		6   /* Group membership */
72411677aeSAaron LI #define	LS_TYPE_NSSA		7   /* NSSA */
73411677aeSAaron LI #define	LS_TYPE_LINK		8   /* Link LSA */
74411677aeSAaron LI #define	LS_TYPE_INTRA_AP	9   /* Intra-Area-Prefix */
75411677aeSAaron LI #define LS_TYPE_INTRA_ATE       10  /* Intra-Area-TE */
76411677aeSAaron LI #define LS_TYPE_GRACE           11  /* Grace LSA */
77411677aeSAaron LI #define LS_TYPE_RI		12  /* Router information */
78411677aeSAaron LI #define LS_TYPE_INTER_ASTE	13  /* Inter-AS-TE */
79411677aeSAaron LI #define LS_TYPE_L1VPN		14  /* L1VPN */
80411677aeSAaron LI #define LS_TYPE_MASK		0x1fff
81411677aeSAaron LI 
82411677aeSAaron LI #define LS_SCOPE_LINKLOCAL	0x0000
83411677aeSAaron LI #define LS_SCOPE_AREA		0x2000
84411677aeSAaron LI #define LS_SCOPE_AS		0x4000
85411677aeSAaron LI #define LS_SCOPE_MASK		0x6000
86411677aeSAaron LI #define LS_SCOPE_U              0x8000
87411677aeSAaron LI 
88411677aeSAaron LI /* rla_link.link_type	*/
89411677aeSAaron LI #define	RLA_TYPE_ROUTER		1   /* point-to-point to another router	*/
90411677aeSAaron LI #define	RLA_TYPE_TRANSIT	2   /* connection to transit network	*/
91411677aeSAaron LI #define RLA_TYPE_VIRTUAL	4   /* virtual link			*/
92411677aeSAaron LI 
93411677aeSAaron LI /* rla_flags	*/
94411677aeSAaron LI #define	RLA_FLAG_B	0x01
95411677aeSAaron LI #define	RLA_FLAG_E	0x02
96411677aeSAaron LI #define	RLA_FLAG_V	0x04
97411677aeSAaron LI #define	RLA_FLAG_W	0x08
98*ed775ee7SAntonio Huete Jimenez #define	RLA_FLAG_Nt	0x10
99411677aeSAaron LI 
100411677aeSAaron LI /* lsa_prefix options */
101411677aeSAaron LI #define LSA_PREFIX_OPT_NU 0x01
102411677aeSAaron LI #define LSA_PREFIX_OPT_LA 0x02
103411677aeSAaron LI #define LSA_PREFIX_OPT_MC 0x04
104411677aeSAaron LI #define LSA_PREFIX_OPT_P  0x08
105411677aeSAaron LI #define LSA_PREFIX_OPT_DN 0x10
106*ed775ee7SAntonio Huete Jimenez #define LSA_PREFIX_OPT_N  0x20
107411677aeSAaron LI 
108411677aeSAaron LI /* sla_tosmetric breakdown	*/
109411677aeSAaron LI #define	SLA_MASK_TOS		0x7f000000
110411677aeSAaron LI #define	SLA_MASK_METRIC		0x00ffffff
111411677aeSAaron LI #define SLA_SHIFT_TOS		24
112411677aeSAaron LI 
113411677aeSAaron LI /* asla_metric */
114411677aeSAaron LI #define ASLA_FLAG_FWDADDR	0x02000000
115411677aeSAaron LI #define ASLA_FLAG_ROUTETAG	0x01000000
116411677aeSAaron LI #define	ASLA_MASK_METRIC	0x00ffffff
117411677aeSAaron LI 
118411677aeSAaron LI /* RFC6506 Section 4.1 */
119411677aeSAaron LI #define OSPF6_AT_HDRLEN             16U
120411677aeSAaron LI #define OSPF6_AUTH_TYPE_HMAC        0x0001
121411677aeSAaron LI 
122*ed775ee7SAntonio Huete Jimenez typedef nd_uint32_t rtrid_t;
123411677aeSAaron LI 
124411677aeSAaron LI /* link state advertisement header */
125411677aeSAaron LI struct lsa6_hdr {
126*ed775ee7SAntonio Huete Jimenez     nd_uint16_t ls_age;
127*ed775ee7SAntonio Huete Jimenez     nd_uint16_t ls_type;
128411677aeSAaron LI     rtrid_t ls_stateid;
129411677aeSAaron LI     rtrid_t ls_router;
130*ed775ee7SAntonio Huete Jimenez     nd_uint32_t ls_seq;
131*ed775ee7SAntonio Huete Jimenez     nd_uint16_t ls_chksum;
132*ed775ee7SAntonio Huete Jimenez     nd_uint16_t ls_length;
133411677aeSAaron LI };
134411677aeSAaron LI 
135411677aeSAaron LI /* Length of an IPv6 address, in bytes. */
136411677aeSAaron LI #define IPV6_ADDR_LEN_BYTES (128/8)
137411677aeSAaron LI 
138411677aeSAaron LI struct lsa6_prefix {
139*ed775ee7SAntonio Huete Jimenez     nd_uint8_t lsa_p_len;
140*ed775ee7SAntonio Huete Jimenez     nd_uint8_t lsa_p_opt;
141*ed775ee7SAntonio Huete Jimenez     nd_uint16_t lsa_p_metric;
142*ed775ee7SAntonio Huete Jimenez     nd_byte lsa_p_prefix[IPV6_ADDR_LEN_BYTES]; /* maximum length */
143411677aeSAaron LI };
144411677aeSAaron LI 
145411677aeSAaron LI /* link state advertisement */
146411677aeSAaron LI struct lsa6 {
147411677aeSAaron LI     struct lsa6_hdr ls_hdr;
148411677aeSAaron LI 
149411677aeSAaron LI     /* Link state types */
150411677aeSAaron LI     union {
151411677aeSAaron LI 	/* Router links advertisements */
152411677aeSAaron LI 	struct {
153411677aeSAaron LI 	    union {
154*ed775ee7SAntonio Huete Jimenez 		nd_uint8_t flg;
155*ed775ee7SAntonio Huete Jimenez 		nd_uint32_t opt;
156411677aeSAaron LI 	    } rla_flgandopt;
157411677aeSAaron LI #define rla_flags	rla_flgandopt.flg
158411677aeSAaron LI #define rla_options	rla_flgandopt.opt
159411677aeSAaron LI 	    struct rlalink6 {
160*ed775ee7SAntonio Huete Jimenez 		nd_uint8_t link_type;
161*ed775ee7SAntonio Huete Jimenez 		nd_byte link_zero;
162*ed775ee7SAntonio Huete Jimenez 		nd_uint16_t link_metric;
163*ed775ee7SAntonio Huete Jimenez 		nd_uint32_t link_ifid;
164*ed775ee7SAntonio Huete Jimenez 		nd_uint32_t link_nifid;
165411677aeSAaron LI 		rtrid_t link_nrtid;
166411677aeSAaron LI 	    } rla_link[1];		/* may repeat	*/
167411677aeSAaron LI 	} un_rla;
168411677aeSAaron LI 
169411677aeSAaron LI 	/* Network links advertisements */
170411677aeSAaron LI 	struct {
171*ed775ee7SAntonio Huete Jimenez 	    nd_uint32_t nla_options;
172411677aeSAaron LI 	    rtrid_t nla_router[1];	/* may repeat	*/
173411677aeSAaron LI 	} un_nla;
174411677aeSAaron LI 
175411677aeSAaron LI 	/* Inter Area Prefix LSA */
176411677aeSAaron LI 	struct {
177*ed775ee7SAntonio Huete Jimenez 	    nd_uint32_t inter_ap_metric;
178411677aeSAaron LI 	    struct lsa6_prefix inter_ap_prefix[1];
179411677aeSAaron LI 	} un_inter_ap;
180411677aeSAaron LI 
181411677aeSAaron LI 	/* AS external links advertisements */
182411677aeSAaron LI 	struct {
183*ed775ee7SAntonio Huete Jimenez 	    nd_uint32_t asla_metric;
184411677aeSAaron LI 	    struct lsa6_prefix asla_prefix[1];
185411677aeSAaron LI 	    /* some optional fields follow */
186411677aeSAaron LI 	} un_asla;
187411677aeSAaron LI 
188411677aeSAaron LI #if 0
189411677aeSAaron LI 	/* Summary links advertisements */
190411677aeSAaron LI 	struct {
191*ed775ee7SAntonio Huete Jimenez 	    nd_ipv4     sla_mask;
192*ed775ee7SAntonio Huete Jimenez 	    nd_uint32_t sla_tosmetric[1];	/* may repeat	*/
193411677aeSAaron LI 	} un_sla;
194411677aeSAaron LI 
195411677aeSAaron LI 	/* Multicast group membership */
196411677aeSAaron LI 	struct mcla {
197*ed775ee7SAntonio Huete Jimenez 	    nd_uint32_t mcla_vtype;
198*ed775ee7SAntonio Huete Jimenez 	    nd_ipv4     mcla_vid;
199411677aeSAaron LI 	} un_mcla[1];
200411677aeSAaron LI #endif
201411677aeSAaron LI 
202411677aeSAaron LI 	/* Type 7 LSA */
203411677aeSAaron LI 
204411677aeSAaron LI 	/* Link LSA */
205411677aeSAaron LI 	struct llsa {
206411677aeSAaron LI 	    union {
207*ed775ee7SAntonio Huete Jimenez 		nd_uint8_t pri;
208*ed775ee7SAntonio Huete Jimenez 		nd_uint32_t opt;
209411677aeSAaron LI 	    } llsa_priandopt;
210411677aeSAaron LI #define llsa_priority	llsa_priandopt.pri
211411677aeSAaron LI #define llsa_options	llsa_priandopt.opt
212*ed775ee7SAntonio Huete Jimenez 	    nd_ipv6	llsa_lladdr;
213*ed775ee7SAntonio Huete Jimenez 	    nd_uint32_t llsa_nprefix;
214411677aeSAaron LI 	    struct lsa6_prefix llsa_prefix[1];
215411677aeSAaron LI 	} un_llsa;
216411677aeSAaron LI 
217411677aeSAaron LI 	/* Intra-Area-Prefix */
218411677aeSAaron LI 	struct {
219*ed775ee7SAntonio Huete Jimenez 	    nd_uint16_t intra_ap_nprefix;
220*ed775ee7SAntonio Huete Jimenez 	    nd_uint16_t intra_ap_lstype;
221411677aeSAaron LI 	    rtrid_t intra_ap_lsid;
222411677aeSAaron LI 	    rtrid_t intra_ap_rtid;
223411677aeSAaron LI 	    struct lsa6_prefix intra_ap_prefix[1];
224411677aeSAaron LI 	} un_intra_ap;
225411677aeSAaron LI     } lsa_un;
226411677aeSAaron LI };
227411677aeSAaron LI 
228411677aeSAaron LI /*
229411677aeSAaron LI  * the main header
230411677aeSAaron LI  */
231411677aeSAaron LI struct ospf6hdr {
232*ed775ee7SAntonio Huete Jimenez     nd_uint8_t ospf6_version;
233*ed775ee7SAntonio Huete Jimenez     nd_uint8_t ospf6_type;
234*ed775ee7SAntonio Huete Jimenez     nd_uint16_t ospf6_len;
235411677aeSAaron LI     rtrid_t ospf6_routerid;
236411677aeSAaron LI     rtrid_t ospf6_areaid;
237*ed775ee7SAntonio Huete Jimenez     nd_uint16_t ospf6_chksum;
238*ed775ee7SAntonio Huete Jimenez     nd_uint8_t ospf6_instanceid;
239*ed775ee7SAntonio Huete Jimenez     nd_uint8_t ospf6_rsvd;
240411677aeSAaron LI };
241411677aeSAaron LI 
242411677aeSAaron LI /*
243411677aeSAaron LI  * The OSPF6 header length is 16 bytes, regardless of how your compiler
244411677aeSAaron LI  * might choose to pad the above structure.
245411677aeSAaron LI  */
246411677aeSAaron LI #define OSPF6HDR_LEN    16
247411677aeSAaron LI 
248411677aeSAaron LI /* Hello packet */
249411677aeSAaron LI struct hello6 {
250*ed775ee7SAntonio Huete Jimenez     nd_uint32_t hello_ifid;
251411677aeSAaron LI     union {
252*ed775ee7SAntonio Huete Jimenez 	nd_uint8_t pri;
253*ed775ee7SAntonio Huete Jimenez 	nd_uint32_t opt;
254411677aeSAaron LI     } hello_priandopt;
255411677aeSAaron LI #define hello_priority	hello_priandopt.pri
256411677aeSAaron LI #define hello_options	hello_priandopt.opt
257*ed775ee7SAntonio Huete Jimenez     nd_uint16_t hello_helloint;
258*ed775ee7SAntonio Huete Jimenez     nd_uint16_t hello_deadint;
259411677aeSAaron LI     rtrid_t hello_dr;
260411677aeSAaron LI     rtrid_t hello_bdr;
261411677aeSAaron LI     rtrid_t hello_neighbor[1]; /* may repeat	*/
262411677aeSAaron LI };
263411677aeSAaron LI 
264411677aeSAaron LI /* Database Description packet */
265411677aeSAaron LI struct dd6 {
266*ed775ee7SAntonio Huete Jimenez     nd_uint32_t db_options;
267*ed775ee7SAntonio Huete Jimenez     nd_uint16_t db_mtu;
268*ed775ee7SAntonio Huete Jimenez     nd_uint8_t db_mbz;
269*ed775ee7SAntonio Huete Jimenez     nd_uint8_t db_flags;
270*ed775ee7SAntonio Huete Jimenez     nd_uint32_t db_seq;
271411677aeSAaron LI     struct lsa6_hdr db_lshdr[1]; /* may repeat	*/
272411677aeSAaron LI };
273411677aeSAaron LI 
274411677aeSAaron LI /* Link State Request */
275411677aeSAaron LI struct lsr6 {
276*ed775ee7SAntonio Huete Jimenez     nd_uint16_t ls_mbz;
277*ed775ee7SAntonio Huete Jimenez     nd_uint16_t ls_type;
278411677aeSAaron LI     rtrid_t ls_stateid;
279411677aeSAaron LI     rtrid_t ls_router;
280411677aeSAaron LI };
281411677aeSAaron LI 
282411677aeSAaron LI /* Link State Update */
283411677aeSAaron LI struct lsu6 {
284*ed775ee7SAntonio Huete Jimenez     nd_uint32_t lsu_count;
285411677aeSAaron LI     struct lsa6 lsu_lsa[1]; /* may repeat	*/
286411677aeSAaron LI };
287411677aeSAaron LI 
28841c99275SPeter Avalos 
289ea7b4bf5SPeter Avalos static const struct tok ospf6_option_values[] = {
29041c99275SPeter Avalos 	{ OSPF6_OPTION_V6,	"V6" },
291ea7b4bf5SPeter Avalos 	{ OSPF6_OPTION_E,	"External" },
292411677aeSAaron LI 	{ OSPF6_OPTION_MC,	"Deprecated" },
293ea7b4bf5SPeter Avalos 	{ OSPF6_OPTION_N,	"NSSA" },
294ea7b4bf5SPeter Avalos 	{ OSPF6_OPTION_R,	"Router" },
295ea7b4bf5SPeter Avalos 	{ OSPF6_OPTION_DC,	"Demand Circuit" },
296411677aeSAaron LI 	{ OSPF6_OPTION_AF,	"AFs Support" },
297411677aeSAaron LI 	{ OSPF6_OPTION_L,	"LLS" },
298411677aeSAaron LI 	{ OSPF6_OPTION_AT,	"Authentication Trailer" },
29941c99275SPeter Avalos 	{ 0,			NULL }
30041c99275SPeter Avalos };
30141c99275SPeter Avalos 
302ea7b4bf5SPeter Avalos static const struct tok ospf6_rla_flag_values[] = {
303ea7b4bf5SPeter Avalos 	{ RLA_FLAG_B,		"ABR" },
304ea7b4bf5SPeter Avalos 	{ RLA_FLAG_E,		"External" },
305ea7b4bf5SPeter Avalos 	{ RLA_FLAG_V,		"Virtual-Link Endpoint" },
306*ed775ee7SAntonio Huete Jimenez 	{ RLA_FLAG_W,		"Deprecated" },
307*ed775ee7SAntonio Huete Jimenez 	{ RLA_FLAG_Nt,		"NSSA Translator" },
30841c99275SPeter Avalos 	{ 0,			NULL }
30941c99275SPeter Avalos };
31041c99275SPeter Avalos 
311ea7b4bf5SPeter Avalos static const struct tok ospf6_asla_flag_values[] = {
312ea7b4bf5SPeter Avalos 	{ ASLA_FLAG_EXTERNAL,	"External Type 2" },
313411677aeSAaron LI 	{ ASLA_FLAG_FWDADDR,	"Forwarding" },
314ea7b4bf5SPeter Avalos 	{ ASLA_FLAG_ROUTETAG,	"Tag" },
31541c99275SPeter Avalos 	{ 0,			NULL }
31641c99275SPeter Avalos };
31741c99275SPeter Avalos 
318411677aeSAaron LI static const struct tok ospf6_type_values[] = {
319ea7b4bf5SPeter Avalos 	{ OSPF_TYPE_HELLO,	"Hello" },
320ea7b4bf5SPeter Avalos 	{ OSPF_TYPE_DD,		"Database Description" },
321ea7b4bf5SPeter Avalos 	{ OSPF_TYPE_LS_REQ,	"LS-Request" },
322ea7b4bf5SPeter Avalos 	{ OSPF_TYPE_LS_UPDATE,	"LS-Update" },
323ea7b4bf5SPeter Avalos 	{ OSPF_TYPE_LS_ACK,	"LS-Ack" },
32441c99275SPeter Avalos 	{ 0,			NULL }
32541c99275SPeter Avalos };
32641c99275SPeter Avalos 
327411677aeSAaron LI static const struct tok ospf6_lsa_values[] = {
328ea7b4bf5SPeter Avalos 	{ LS_TYPE_ROUTER,       "Router" },
329ea7b4bf5SPeter Avalos 	{ LS_TYPE_NETWORK,      "Network" },
330ea7b4bf5SPeter Avalos 	{ LS_TYPE_INTER_AP,     "Inter-Area Prefix" },
331ea7b4bf5SPeter Avalos 	{ LS_TYPE_INTER_AR,     "Inter-Area Router" },
332ea7b4bf5SPeter Avalos 	{ LS_TYPE_ASE,          "External" },
333411677aeSAaron LI 	{ LS_TYPE_GROUP,        "Deprecated" },
334ea7b4bf5SPeter Avalos 	{ LS_TYPE_NSSA,         "NSSA" },
335ea7b4bf5SPeter Avalos 	{ LS_TYPE_LINK,         "Link" },
336ea7b4bf5SPeter Avalos 	{ LS_TYPE_INTRA_AP,     "Intra-Area Prefix" },
337ea7b4bf5SPeter Avalos         { LS_TYPE_INTRA_ATE,    "Intra-Area TE" },
338ea7b4bf5SPeter Avalos         { LS_TYPE_GRACE,        "Grace" },
339411677aeSAaron LI 	{ LS_TYPE_RI,           "Router Information" },
340411677aeSAaron LI 	{ LS_TYPE_INTER_ASTE,   "Inter-AS-TE" },
341411677aeSAaron LI 	{ LS_TYPE_L1VPN,        "Layer 1 VPN" },
342ea7b4bf5SPeter Avalos 	{ 0,			NULL }
343ea7b4bf5SPeter Avalos };
344ea7b4bf5SPeter Avalos 
345411677aeSAaron LI static const struct tok ospf6_ls_scope_values[] = {
346ea7b4bf5SPeter Avalos 	{ LS_SCOPE_LINKLOCAL,   "Link Local" },
347ea7b4bf5SPeter Avalos 	{ LS_SCOPE_AREA,        "Area Local" },
348ea7b4bf5SPeter Avalos 	{ LS_SCOPE_AS,          "Domain Wide" },
349ea7b4bf5SPeter Avalos 	{ 0,			NULL }
350ea7b4bf5SPeter Avalos };
351ea7b4bf5SPeter Avalos 
352411677aeSAaron LI static const struct tok ospf6_dd_flag_values[] = {
353ea7b4bf5SPeter Avalos 	{ OSPF6_DB_INIT,	"Init" },
354ea7b4bf5SPeter Avalos 	{ OSPF6_DB_MORE,	"More" },
355ea7b4bf5SPeter Avalos 	{ OSPF6_DB_MASTER,	"Master" },
356411677aeSAaron LI 	{ OSPF6_DB_M6,		"IPv6 MTU" },
357ea7b4bf5SPeter Avalos 	{ 0,			NULL }
358ea7b4bf5SPeter Avalos };
359ea7b4bf5SPeter Avalos 
360411677aeSAaron LI static const struct tok ospf6_lsa_prefix_option_values[] = {
361ea7b4bf5SPeter Avalos         { LSA_PREFIX_OPT_NU, "No Unicast" },
362ea7b4bf5SPeter Avalos         { LSA_PREFIX_OPT_LA, "Local address" },
363411677aeSAaron LI         { LSA_PREFIX_OPT_MC, "Deprecated" },
364ea7b4bf5SPeter Avalos         { LSA_PREFIX_OPT_P, "Propagate" },
365ea7b4bf5SPeter Avalos         { LSA_PREFIX_OPT_DN, "Down" },
366*ed775ee7SAntonio Huete Jimenez         { LSA_PREFIX_OPT_N, "N-bit" },
367ea7b4bf5SPeter Avalos 	{ 0, NULL }
368ea7b4bf5SPeter Avalos };
369ea7b4bf5SPeter Avalos 
370411677aeSAaron LI static const struct tok ospf6_auth_type_str[] = {
371411677aeSAaron LI 	{ OSPF6_AUTH_TYPE_HMAC,        "HMAC" },
372411677aeSAaron LI 	{ 0, NULL }
373411677aeSAaron LI };
37441c99275SPeter Avalos 
37541c99275SPeter Avalos static void
ospf6_print_ls_type(netdissect_options * ndo,u_int ls_type,const rtrid_t * ls_stateid)376411677aeSAaron LI ospf6_print_ls_type(netdissect_options *ndo,
377*ed775ee7SAntonio Huete Jimenez                     u_int ls_type, const rtrid_t *ls_stateid)
37841c99275SPeter Avalos {
379*ed775ee7SAntonio Huete Jimenez         ND_PRINT("\n\t    %s LSA (%u), %s Scope%s, LSA-ID %s",
380ea7b4bf5SPeter Avalos                tok2str(ospf6_lsa_values, "Unknown", ls_type & LS_TYPE_MASK),
381ea7b4bf5SPeter Avalos                ls_type & LS_TYPE_MASK,
382ea7b4bf5SPeter Avalos                tok2str(ospf6_ls_scope_values, "Unknown", ls_type & LS_SCOPE_MASK),
383ea7b4bf5SPeter Avalos                ls_type &0x8000 ? ", transitive" : "", /* U-bit */
384*ed775ee7SAntonio Huete Jimenez                GET_IPADDR_STRING((const u_char *)ls_stateid));
38541c99275SPeter Avalos }
38641c99275SPeter Avalos 
38741c99275SPeter Avalos static int
ospf6_print_lshdr(netdissect_options * ndo,const struct lsa6_hdr * lshp,const u_char * dataend)388411677aeSAaron LI ospf6_print_lshdr(netdissect_options *ndo,
389*ed775ee7SAntonio Huete Jimenez                   const struct lsa6_hdr *lshp, const u_char *dataend)
39041c99275SPeter Avalos {
391411677aeSAaron LI 	if ((const u_char *)(lshp + 1) > dataend)
392411677aeSAaron LI 		goto trunc;
39341c99275SPeter Avalos 
394*ed775ee7SAntonio Huete Jimenez 	ND_PRINT("\n\t  Advertising Router %s, seq 0x%08x, age %us, length %zu",
395*ed775ee7SAntonio Huete Jimenez 		 GET_IPADDR_STRING(lshp->ls_router),
396*ed775ee7SAntonio Huete Jimenez 		 GET_BE_U_4(lshp->ls_seq),
397*ed775ee7SAntonio Huete Jimenez 		 GET_BE_U_2(lshp->ls_age),
398*ed775ee7SAntonio Huete Jimenez 		 GET_BE_U_2(lshp->ls_length)-sizeof(struct lsa6_hdr));
399ea7b4bf5SPeter Avalos 
400*ed775ee7SAntonio Huete Jimenez 	ospf6_print_ls_type(ndo, GET_BE_U_2(lshp->ls_type),
401*ed775ee7SAntonio Huete Jimenez 			    &lshp->ls_stateid);
40241c99275SPeter Avalos 
40341c99275SPeter Avalos 	return (0);
40441c99275SPeter Avalos trunc:
40541c99275SPeter Avalos 	return (1);
40641c99275SPeter Avalos }
40741c99275SPeter Avalos 
40841c99275SPeter Avalos static int
ospf6_print_lsaprefix(netdissect_options * ndo,const uint8_t * tptr,u_int lsa_length)409411677aeSAaron LI ospf6_print_lsaprefix(netdissect_options *ndo,
410411677aeSAaron LI                       const uint8_t *tptr, u_int lsa_length)
41141c99275SPeter Avalos {
412411677aeSAaron LI 	const struct lsa6_prefix *lsapp = (const struct lsa6_prefix *)tptr;
413ea7b4bf5SPeter Avalos 	u_int wordlen;
414*ed775ee7SAntonio Huete Jimenez 	nd_ipv6 prefix;
41541c99275SPeter Avalos 
416411677aeSAaron LI 	if (lsa_length < sizeof (*lsapp) - IPV6_ADDR_LEN_BYTES)
4176263709fSPeter Avalos 		goto trunc;
418411677aeSAaron LI 	lsa_length -= sizeof (*lsapp) - IPV6_ADDR_LEN_BYTES;
419*ed775ee7SAntonio Huete Jimenez 	ND_TCHECK_LEN(lsapp, sizeof(*lsapp) - IPV6_ADDR_LEN_BYTES);
420*ed775ee7SAntonio Huete Jimenez 	wordlen = (GET_U_1(lsapp->lsa_p_len) + 31) / 32;
421*ed775ee7SAntonio Huete Jimenez 	if (wordlen * 4 > sizeof(nd_ipv6)) {
422*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(" bogus prefixlen /%u", GET_U_1(lsapp->lsa_p_len));
42341c99275SPeter Avalos 		goto trunc;
42441c99275SPeter Avalos 	}
4256263709fSPeter Avalos 	if (lsa_length < wordlen * 4)
4266263709fSPeter Avalos 		goto trunc;
4276263709fSPeter Avalos 	lsa_length -= wordlen * 4;
428*ed775ee7SAntonio Huete Jimenez 	memset(prefix, 0, sizeof(prefix));
429*ed775ee7SAntonio Huete Jimenez 	GET_CPY_BYTES(prefix, lsapp->lsa_p_prefix, wordlen * 4);
430*ed775ee7SAntonio Huete Jimenez 	ND_PRINT("\n\t\t%s/%u", ip6addr_string(ndo, prefix), /* local buffer, not packet data; don't use GET_IP6ADDR_STRING() */
431*ed775ee7SAntonio Huete Jimenez 		 GET_U_1(lsapp->lsa_p_len));
432*ed775ee7SAntonio Huete Jimenez         if (GET_U_1(lsapp->lsa_p_opt)) {
433*ed775ee7SAntonio Huete Jimenez             ND_PRINT(", Options [%s]",
434ea7b4bf5SPeter Avalos                    bittok2str(ospf6_lsa_prefix_option_values,
435*ed775ee7SAntonio Huete Jimenez                               "none", GET_U_1(lsapp->lsa_p_opt)));
436ea7b4bf5SPeter Avalos         }
437*ed775ee7SAntonio Huete Jimenez         ND_PRINT(", metric %u", GET_BE_U_2(lsapp->lsa_p_metric));
438411677aeSAaron LI 	return sizeof(*lsapp) - IPV6_ADDR_LEN_BYTES + wordlen * 4;
43941c99275SPeter Avalos 
44041c99275SPeter Avalos trunc:
44141c99275SPeter Avalos 	return -1;
44241c99275SPeter Avalos }
44341c99275SPeter Avalos 
44441c99275SPeter Avalos 
44541c99275SPeter Avalos /*
44641c99275SPeter Avalos  * Print a single link state advertisement.  If truncated return 1, else 0.
44741c99275SPeter Avalos  */
44841c99275SPeter Avalos static int
ospf6_print_lsa(netdissect_options * ndo,const struct lsa6 * lsap,const u_char * dataend)449411677aeSAaron LI ospf6_print_lsa(netdissect_options *ndo,
450*ed775ee7SAntonio Huete Jimenez                 const struct lsa6 *lsap, const u_char *dataend)
45141c99275SPeter Avalos {
452*ed775ee7SAntonio Huete Jimenez 	const struct rlalink6 *rlp;
45341c99275SPeter Avalos #if 0
454*ed775ee7SAntonio Huete Jimenez 	const struct tos_metric *tosp;
45541c99275SPeter Avalos #endif
456*ed775ee7SAntonio Huete Jimenez 	const rtrid_t *ap;
45741c99275SPeter Avalos #if 0
458*ed775ee7SAntonio Huete Jimenez 	const struct aslametric *almp;
459*ed775ee7SAntonio Huete Jimenez 	const struct mcla *mcp;
46041c99275SPeter Avalos #endif
461*ed775ee7SAntonio Huete Jimenez 	const struct llsa *llsap;
462*ed775ee7SAntonio Huete Jimenez 	const struct lsa6_prefix *lsapp;
46341c99275SPeter Avalos #if 0
464*ed775ee7SAntonio Huete Jimenez 	const uint32_t *lp;
46541c99275SPeter Avalos #endif
466*ed775ee7SAntonio Huete Jimenez 	u_int prefixes;
467*ed775ee7SAntonio Huete Jimenez 	int bytelen;
468*ed775ee7SAntonio Huete Jimenez 	u_int length, lsa_length;
469411677aeSAaron LI 	uint32_t flags32;
470411677aeSAaron LI 	const uint8_t *tptr;
47141c99275SPeter Avalos 
472411677aeSAaron LI 	if (ospf6_print_lshdr(ndo, &lsap->ls_hdr, dataend))
47341c99275SPeter Avalos 		return (1);
474*ed775ee7SAntonio Huete Jimenez         length = GET_BE_U_2(lsap->ls_hdr.ls_length);
4756263709fSPeter Avalos 
4766263709fSPeter Avalos 	/*
4776263709fSPeter Avalos 	 * The LSA length includes the length of the header;
4786263709fSPeter Avalos 	 * it must have a value that's at least that length.
4796263709fSPeter Avalos 	 * If it does, find the length of what follows the
4806263709fSPeter Avalos 	 * header.
4816263709fSPeter Avalos 	 */
482411677aeSAaron LI         if (length < sizeof(struct lsa6_hdr) || (const u_char *)lsap + length > dataend)
4836263709fSPeter Avalos 		return (1);
484ea7b4bf5SPeter Avalos         lsa_length = length - sizeof(struct lsa6_hdr);
485411677aeSAaron LI         tptr = (const uint8_t *)lsap+sizeof(struct lsa6_hdr);
486ea7b4bf5SPeter Avalos 
487*ed775ee7SAntonio Huete Jimenez 	switch (GET_BE_U_2(lsap->ls_hdr.ls_type)) {
48841c99275SPeter Avalos 	case LS_TYPE_ROUTER | LS_SCOPE_AREA:
4896263709fSPeter Avalos 		if (lsa_length < sizeof (lsap->lsa_un.un_rla.rla_options))
4906263709fSPeter Avalos 			return (1);
4916263709fSPeter Avalos 		lsa_length -= sizeof (lsap->lsa_un.un_rla.rla_options);
492*ed775ee7SAntonio Huete Jimenez 		ND_PRINT("\n\t      Options [%s]",
493ea7b4bf5SPeter Avalos 		          bittok2str(ospf6_option_values, "none",
494*ed775ee7SAntonio Huete Jimenez 		          GET_BE_U_4(lsap->lsa_un.un_rla.rla_options)));
495*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(", RLA-Flags [%s]",
496ea7b4bf5SPeter Avalos 		          bittok2str(ospf6_rla_flag_values, "none",
497*ed775ee7SAntonio Huete Jimenez 		          GET_U_1(lsap->lsa_un.un_rla.rla_flags)));
498ea7b4bf5SPeter Avalos 
49941c99275SPeter Avalos 		rlp = lsap->lsa_un.un_rla.rla_link;
5006263709fSPeter Avalos 		while (lsa_length != 0) {
5016263709fSPeter Avalos 			if (lsa_length < sizeof (*rlp))
5026263709fSPeter Avalos 				return (1);
5036263709fSPeter Avalos 			lsa_length -= sizeof (*rlp);
504*ed775ee7SAntonio Huete Jimenez 			ND_TCHECK_SIZE(rlp);
505*ed775ee7SAntonio Huete Jimenez 			switch (GET_U_1(rlp->link_type)) {
50641c99275SPeter Avalos 
50741c99275SPeter Avalos 			case RLA_TYPE_VIRTUAL:
508*ed775ee7SAntonio Huete Jimenez 				ND_PRINT("\n\t      Virtual Link: Neighbor Router-ID %s"
509ea7b4bf5SPeter Avalos                                        "\n\t      Neighbor Interface-ID %s, Interface %s",
510*ed775ee7SAntonio Huete Jimenez                                        GET_IPADDR_STRING(rlp->link_nrtid),
511*ed775ee7SAntonio Huete Jimenez                                        GET_IPADDR_STRING(rlp->link_nifid),
512*ed775ee7SAntonio Huete Jimenez                                        GET_IPADDR_STRING(rlp->link_ifid));
513ea7b4bf5SPeter Avalos                                 break;
51441c99275SPeter Avalos 
51541c99275SPeter Avalos 			case RLA_TYPE_ROUTER:
516*ed775ee7SAntonio Huete Jimenez 				ND_PRINT("\n\t      Neighbor Router-ID %s"
517ea7b4bf5SPeter Avalos                                        "\n\t      Neighbor Interface-ID %s, Interface %s",
518*ed775ee7SAntonio Huete Jimenez                                        GET_IPADDR_STRING(rlp->link_nrtid),
519*ed775ee7SAntonio Huete Jimenez                                        GET_IPADDR_STRING(rlp->link_nifid),
520*ed775ee7SAntonio Huete Jimenez                                        GET_IPADDR_STRING(rlp->link_ifid));
52141c99275SPeter Avalos 				break;
52241c99275SPeter Avalos 
52341c99275SPeter Avalos 			case RLA_TYPE_TRANSIT:
524*ed775ee7SAntonio Huete Jimenez 				ND_PRINT("\n\t      Neighbor Network-ID %s"
525ea7b4bf5SPeter Avalos                                        "\n\t      Neighbor Interface-ID %s, Interface %s",
526*ed775ee7SAntonio Huete Jimenez 				    GET_IPADDR_STRING(rlp->link_nrtid),
527*ed775ee7SAntonio Huete Jimenez 				    GET_IPADDR_STRING(rlp->link_nifid),
528*ed775ee7SAntonio Huete Jimenez 				    GET_IPADDR_STRING(rlp->link_ifid));
52941c99275SPeter Avalos 				break;
53041c99275SPeter Avalos 
53141c99275SPeter Avalos 			default:
532*ed775ee7SAntonio Huete Jimenez 				ND_PRINT("\n\t      Unknown Router Links Type 0x%02x",
533*ed775ee7SAntonio Huete Jimenez 				    GET_U_1(rlp->link_type));
53441c99275SPeter Avalos 				return (0);
53541c99275SPeter Avalos 			}
536*ed775ee7SAntonio Huete Jimenez 			ND_PRINT(", metric %u", GET_BE_U_2(rlp->link_metric));
53741c99275SPeter Avalos 			rlp++;
53841c99275SPeter Avalos 		}
53941c99275SPeter Avalos 		break;
54041c99275SPeter Avalos 
54141c99275SPeter Avalos 	case LS_TYPE_NETWORK | LS_SCOPE_AREA:
5426263709fSPeter Avalos 		if (lsa_length < sizeof (lsap->lsa_un.un_nla.nla_options))
5436263709fSPeter Avalos 			return (1);
5446263709fSPeter Avalos 		lsa_length -= sizeof (lsap->lsa_un.un_nla.nla_options);
545*ed775ee7SAntonio Huete Jimenez 		ND_PRINT("\n\t      Options [%s]",
546ea7b4bf5SPeter Avalos 		          bittok2str(ospf6_option_values, "none",
547*ed775ee7SAntonio Huete Jimenez 		          GET_BE_U_4(lsap->lsa_un.un_nla.nla_options)));
5486263709fSPeter Avalos 
549*ed775ee7SAntonio Huete Jimenez 		ND_PRINT("\n\t      Connected Routers:");
55041c99275SPeter Avalos 		ap = lsap->lsa_un.un_nla.nla_router;
5516263709fSPeter Avalos 		while (lsa_length != 0) {
5526263709fSPeter Avalos 			if (lsa_length < sizeof (*ap))
5536263709fSPeter Avalos 				return (1);
5546263709fSPeter Avalos 			lsa_length -= sizeof (*ap);
555*ed775ee7SAntonio Huete Jimenez 			ND_TCHECK_SIZE(ap);
556*ed775ee7SAntonio Huete Jimenez 			ND_PRINT("\n\t\t%s", GET_IPADDR_STRING(*ap));
55741c99275SPeter Avalos 			++ap;
55841c99275SPeter Avalos 		}
55941c99275SPeter Avalos 		break;
56041c99275SPeter Avalos 
56141c99275SPeter Avalos 	case LS_TYPE_INTER_AP | LS_SCOPE_AREA:
5626263709fSPeter Avalos 		if (lsa_length < sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric))
5636263709fSPeter Avalos 			return (1);
5646263709fSPeter Avalos 		lsa_length -= sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric);
565*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(", metric %u",
566*ed775ee7SAntonio Huete Jimenez 			GET_BE_U_4(lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC);
5676263709fSPeter Avalos 
568411677aeSAaron LI 		tptr = (const uint8_t *)lsap->lsa_un.un_inter_ap.inter_ap_prefix;
5696263709fSPeter Avalos 		while (lsa_length != 0) {
570411677aeSAaron LI 			bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length);
5716263709fSPeter Avalos 			if (bytelen < 0)
57241c99275SPeter Avalos 				goto trunc;
573*ed775ee7SAntonio Huete Jimenez 			/*
574*ed775ee7SAntonio Huete Jimenez 			 * ospf6_print_lsaprefix() will return -1 if
575*ed775ee7SAntonio Huete Jimenez 			 * the length is too high, so this will not
576*ed775ee7SAntonio Huete Jimenez 			 * underflow.
577*ed775ee7SAntonio Huete Jimenez 			 */
5786263709fSPeter Avalos 			lsa_length -= bytelen;
5796263709fSPeter Avalos 			tptr += bytelen;
58041c99275SPeter Avalos 		}
58141c99275SPeter Avalos 		break;
5826263709fSPeter Avalos 
5836263709fSPeter Avalos 	case LS_TYPE_ASE | LS_SCOPE_AS:
5846263709fSPeter Avalos 		if (lsa_length < sizeof (lsap->lsa_un.un_asla.asla_metric))
5856263709fSPeter Avalos 			return (1);
5866263709fSPeter Avalos 		lsa_length -= sizeof (lsap->lsa_un.un_asla.asla_metric);
587*ed775ee7SAntonio Huete Jimenez 		flags32 = GET_BE_U_4(lsap->lsa_un.un_asla.asla_metric);
588*ed775ee7SAntonio Huete Jimenez 		ND_PRINT("\n\t     Flags [%s]",
589*ed775ee7SAntonio Huete Jimenez 		          bittok2str(ospf6_asla_flag_values, "none", flags32));
590*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(" metric %u",
591*ed775ee7SAntonio Huete Jimenez 		       GET_BE_U_4(lsap->lsa_un.un_asla.asla_metric) &
592*ed775ee7SAntonio Huete Jimenez 		       ASLA_MASK_METRIC);
5936263709fSPeter Avalos 
594411677aeSAaron LI 		tptr = (const uint8_t *)lsap->lsa_un.un_asla.asla_prefix;
595411677aeSAaron LI 		lsapp = (const struct lsa6_prefix *)tptr;
596411677aeSAaron LI 		bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length);
597ea7b4bf5SPeter Avalos 		if (bytelen < 0)
59841c99275SPeter Avalos 			goto trunc;
599*ed775ee7SAntonio Huete Jimenez 		/*
600*ed775ee7SAntonio Huete Jimenez 		 * ospf6_print_lsaprefix() will return -1 if
601*ed775ee7SAntonio Huete Jimenez 		 * the length is too high, so this will not
602*ed775ee7SAntonio Huete Jimenez 		 * underflow.
603*ed775ee7SAntonio Huete Jimenez 		 */
6046263709fSPeter Avalos 		lsa_length -= bytelen;
6056263709fSPeter Avalos 		tptr += bytelen;
60641c99275SPeter Avalos 
60741c99275SPeter Avalos 		if ((flags32 & ASLA_FLAG_FWDADDR) != 0) {
608*ed775ee7SAntonio Huete Jimenez 			if (lsa_length < sizeof (nd_ipv6))
6096263709fSPeter Avalos 				return (1);
610*ed775ee7SAntonio Huete Jimenez 			lsa_length -= sizeof (nd_ipv6);
611*ed775ee7SAntonio Huete Jimenez 			ND_PRINT(" forward %s",
612*ed775ee7SAntonio Huete Jimenez 				 GET_IP6ADDR_STRING(tptr));
613*ed775ee7SAntonio Huete Jimenez 			tptr += sizeof(nd_ipv6);
61441c99275SPeter Avalos 		}
61541c99275SPeter Avalos 
61641c99275SPeter Avalos 		if ((flags32 & ASLA_FLAG_ROUTETAG) != 0) {
617411677aeSAaron LI 			if (lsa_length < sizeof (uint32_t))
6186263709fSPeter Avalos 				return (1);
619411677aeSAaron LI 			lsa_length -= sizeof (uint32_t);
620*ed775ee7SAntonio Huete Jimenez 			ND_PRINT(" tag %s",
621*ed775ee7SAntonio Huete Jimenez 			       GET_IPADDR_STRING(tptr));
622411677aeSAaron LI 			tptr += sizeof(uint32_t);
62341c99275SPeter Avalos 		}
62441c99275SPeter Avalos 
625*ed775ee7SAntonio Huete Jimenez 		if (GET_U_1(lsapp->lsa_p_metric)) {
626411677aeSAaron LI 			if (lsa_length < sizeof (uint32_t))
6276263709fSPeter Avalos 				return (1);
628411677aeSAaron LI 			lsa_length -= sizeof (uint32_t);
629*ed775ee7SAntonio Huete Jimenez 			ND_PRINT(" RefLSID: %s",
630*ed775ee7SAntonio Huete Jimenez 			       GET_IPADDR_STRING(tptr));
631411677aeSAaron LI 			tptr += sizeof(uint32_t);
63241c99275SPeter Avalos 		}
63341c99275SPeter Avalos 		break;
63441c99275SPeter Avalos 
63541c99275SPeter Avalos 	case LS_TYPE_LINK:
63641c99275SPeter Avalos 		/* Link LSA */
63741c99275SPeter Avalos 		llsap = &lsap->lsa_un.un_llsa;
6386263709fSPeter Avalos 		if (lsa_length < sizeof (llsap->llsa_priandopt))
6396263709fSPeter Avalos 			return (1);
6406263709fSPeter Avalos 		lsa_length -= sizeof (llsap->llsa_priandopt);
641*ed775ee7SAntonio Huete Jimenez 		ND_TCHECK_SIZE(&llsap->llsa_priandopt);
642*ed775ee7SAntonio Huete Jimenez 		ND_PRINT("\n\t      Options [%s]",
643ea7b4bf5SPeter Avalos 		          bittok2str(ospf6_option_values, "none",
644*ed775ee7SAntonio Huete Jimenez 		          GET_BE_U_4(llsap->llsa_options)));
6456263709fSPeter Avalos 
6466263709fSPeter Avalos 		if (lsa_length < sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix))
6476263709fSPeter Avalos 			return (1);
6486263709fSPeter Avalos 		lsa_length -= sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix);
649*ed775ee7SAntonio Huete Jimenez                 prefixes = GET_BE_U_4(llsap->llsa_nprefix);
650*ed775ee7SAntonio Huete Jimenez 		ND_PRINT("\n\t      Priority %u, Link-local address %s, Prefixes %u:",
651*ed775ee7SAntonio Huete Jimenez                        GET_U_1(llsap->llsa_priority),
652*ed775ee7SAntonio Huete Jimenez                        GET_IP6ADDR_STRING(llsap->llsa_lladdr),
653*ed775ee7SAntonio Huete Jimenez                        prefixes);
654ea7b4bf5SPeter Avalos 
655411677aeSAaron LI 		tptr = (const uint8_t *)llsap->llsa_prefix;
656ea7b4bf5SPeter Avalos 		while (prefixes > 0) {
657411677aeSAaron LI 			bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length);
6586263709fSPeter Avalos 			if (bytelen < 0)
65941c99275SPeter Avalos 				goto trunc;
660ea7b4bf5SPeter Avalos 			prefixes--;
661*ed775ee7SAntonio Huete Jimenez 			/*
662*ed775ee7SAntonio Huete Jimenez 			 * ospf6_print_lsaprefix() will return -1 if
663*ed775ee7SAntonio Huete Jimenez 			 * the length is too high, so this will not
664*ed775ee7SAntonio Huete Jimenez 			 * underflow.
665*ed775ee7SAntonio Huete Jimenez 			 */
6666263709fSPeter Avalos 			lsa_length -= bytelen;
667ea7b4bf5SPeter Avalos 			tptr += bytelen;
66841c99275SPeter Avalos 		}
66941c99275SPeter Avalos 		break;
67041c99275SPeter Avalos 
67141c99275SPeter Avalos 	case LS_TYPE_INTRA_AP | LS_SCOPE_AREA:
67241c99275SPeter Avalos 		/* Intra-Area-Prefix LSA */
6736263709fSPeter Avalos 		if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid))
6746263709fSPeter Avalos 			return (1);
6756263709fSPeter Avalos 		lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid);
676*ed775ee7SAntonio Huete Jimenez 		ND_TCHECK_4(lsap->lsa_un.un_intra_ap.intra_ap_rtid);
677411677aeSAaron LI 		ospf6_print_ls_type(ndo,
678*ed775ee7SAntonio Huete Jimenez 			GET_BE_U_2(lsap->lsa_un.un_intra_ap.intra_ap_lstype),
679ea7b4bf5SPeter Avalos 			&lsap->lsa_un.un_intra_ap.intra_ap_lsid);
6806263709fSPeter Avalos 
6816263709fSPeter Avalos 		if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix))
6826263709fSPeter Avalos 			return (1);
6836263709fSPeter Avalos 		lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix);
684*ed775ee7SAntonio Huete Jimenez                 prefixes = GET_BE_U_2(lsap->lsa_un.un_intra_ap.intra_ap_nprefix);
685*ed775ee7SAntonio Huete Jimenez 		ND_PRINT("\n\t      Prefixes %u:", prefixes);
68641c99275SPeter Avalos 
687411677aeSAaron LI 		tptr = (const uint8_t *)lsap->lsa_un.un_intra_ap.intra_ap_prefix;
688ea7b4bf5SPeter Avalos 		while (prefixes > 0) {
689411677aeSAaron LI 			bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length);
6906263709fSPeter Avalos 			if (bytelen < 0)
69141c99275SPeter Avalos 				goto trunc;
692ea7b4bf5SPeter Avalos 			prefixes--;
693*ed775ee7SAntonio Huete Jimenez 			/*
694*ed775ee7SAntonio Huete Jimenez 			 * ospf6_print_lsaprefix() will return -1 if
695*ed775ee7SAntonio Huete Jimenez 			 * the length is too high, so this will not
696*ed775ee7SAntonio Huete Jimenez 			 * underflow.
697*ed775ee7SAntonio Huete Jimenez 			 */
6986263709fSPeter Avalos 			lsa_length -= bytelen;
699ea7b4bf5SPeter Avalos 			tptr += bytelen;
700ea7b4bf5SPeter Avalos 		}
701ea7b4bf5SPeter Avalos 		break;
702ea7b4bf5SPeter Avalos 
703ea7b4bf5SPeter Avalos         case LS_TYPE_GRACE | LS_SCOPE_LINKLOCAL:
704*ed775ee7SAntonio Huete Jimenez                 if (ospf_grace_lsa_print(ndo, tptr, lsa_length) == -1) {
705ea7b4bf5SPeter Avalos                     return 1;
706ea7b4bf5SPeter Avalos                 }
707ea7b4bf5SPeter Avalos                 break;
708ea7b4bf5SPeter Avalos 
709ea7b4bf5SPeter Avalos         case LS_TYPE_INTRA_ATE | LS_SCOPE_LINKLOCAL:
710*ed775ee7SAntonio Huete Jimenez                 if (ospf_te_lsa_print(ndo, tptr, lsa_length) == -1) {
711ea7b4bf5SPeter Avalos                     return 1;
71241c99275SPeter Avalos                 }
71341c99275SPeter Avalos                 break;
71441c99275SPeter Avalos 
71541c99275SPeter Avalos 	default:
716411677aeSAaron LI                 if(!print_unknown_data(ndo,tptr,
717ea7b4bf5SPeter Avalos                                        "\n\t      ",
718ea7b4bf5SPeter Avalos                                        lsa_length)) {
719ea7b4bf5SPeter Avalos                     return (1);
720ea7b4bf5SPeter Avalos                 }
7216263709fSPeter Avalos                 break;
72241c99275SPeter Avalos 	}
72341c99275SPeter Avalos 
72441c99275SPeter Avalos 	return (0);
72541c99275SPeter Avalos trunc:
72641c99275SPeter Avalos 	return (1);
72741c99275SPeter Avalos }
72841c99275SPeter Avalos 
72941c99275SPeter Avalos static int
ospf6_decode_v3(netdissect_options * ndo,const struct ospf6hdr * op,const u_char * dataend)730411677aeSAaron LI ospf6_decode_v3(netdissect_options *ndo,
731*ed775ee7SAntonio Huete Jimenez                 const struct ospf6hdr *op,
732*ed775ee7SAntonio Huete Jimenez                 const u_char *dataend)
73341c99275SPeter Avalos {
734*ed775ee7SAntonio Huete Jimenez 	const rtrid_t *ap;
735*ed775ee7SAntonio Huete Jimenez 	const struct lsr6 *lsrp;
736*ed775ee7SAntonio Huete Jimenez 	const struct lsa6_hdr *lshp;
737*ed775ee7SAntonio Huete Jimenez 	const struct lsa6 *lsap;
738*ed775ee7SAntonio Huete Jimenez 	int i;
73941c99275SPeter Avalos 
740*ed775ee7SAntonio Huete Jimenez 	switch (GET_U_1(op->ospf6_type)) {
74141c99275SPeter Avalos 
742411677aeSAaron LI 	case OSPF_TYPE_HELLO: {
743*ed775ee7SAntonio Huete Jimenez 		const struct hello6 *hellop = (const struct hello6 *)((const uint8_t *)op + OSPF6HDR_LEN);
744411677aeSAaron LI 
745*ed775ee7SAntonio Huete Jimenez 		ND_PRINT("\n\tOptions [%s]",
746ea7b4bf5SPeter Avalos 		          bittok2str(ospf6_option_values, "none",
747*ed775ee7SAntonio Huete Jimenez 		          GET_BE_U_4(hellop->hello_options)));
748ea7b4bf5SPeter Avalos 
749*ed775ee7SAntonio Huete Jimenez 		ND_PRINT("\n\t  Hello Timer %us, Dead Timer %us, Interface-ID %s, Priority %u",
750*ed775ee7SAntonio Huete Jimenez 		          GET_BE_U_2(hellop->hello_helloint),
751*ed775ee7SAntonio Huete Jimenez 		          GET_BE_U_2(hellop->hello_deadint),
752*ed775ee7SAntonio Huete Jimenez 		          GET_IPADDR_STRING(hellop->hello_ifid),
753*ed775ee7SAntonio Huete Jimenez 		          GET_U_1(hellop->hello_priority));
754ea7b4bf5SPeter Avalos 
755*ed775ee7SAntonio Huete Jimenez 		if (GET_BE_U_4(hellop->hello_dr) != 0)
756*ed775ee7SAntonio Huete Jimenez 			ND_PRINT("\n\t  Designated Router %s",
757*ed775ee7SAntonio Huete Jimenez 			    GET_IPADDR_STRING(hellop->hello_dr));
758*ed775ee7SAntonio Huete Jimenez 		if (GET_BE_U_4(hellop->hello_bdr) != 0)
759*ed775ee7SAntonio Huete Jimenez 			ND_PRINT(", Backup Designated Router %s",
760*ed775ee7SAntonio Huete Jimenez 			    GET_IPADDR_STRING(hellop->hello_bdr));
761411677aeSAaron LI 		if (ndo->ndo_vflag > 1) {
762*ed775ee7SAntonio Huete Jimenez 			ND_PRINT("\n\t  Neighbor List:");
763411677aeSAaron LI 			ap = hellop->hello_neighbor;
764411677aeSAaron LI 			while ((const u_char *)ap < dataend) {
765*ed775ee7SAntonio Huete Jimenez 				ND_TCHECK_SIZE(ap);
766*ed775ee7SAntonio Huete Jimenez 				ND_PRINT("\n\t    %s", GET_IPADDR_STRING(*ap));
76741c99275SPeter Avalos 				++ap;
76841c99275SPeter Avalos 			}
76941c99275SPeter Avalos 		}
77041c99275SPeter Avalos 		break;	/* HELLO */
771411677aeSAaron LI 	}
77241c99275SPeter Avalos 
773411677aeSAaron LI 	case OSPF_TYPE_DD: {
774*ed775ee7SAntonio Huete Jimenez 		const struct dd6 *ddp = (const struct dd6 *)((const uint8_t *)op + OSPF6HDR_LEN);
775411677aeSAaron LI 
776*ed775ee7SAntonio Huete Jimenez 		ND_PRINT("\n\tOptions [%s]",
777ea7b4bf5SPeter Avalos 		          bittok2str(ospf6_option_values, "none",
778*ed775ee7SAntonio Huete Jimenez 		          GET_BE_U_4(ddp->db_options)));
779*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(", DD Flags [%s]",
780*ed775ee7SAntonio Huete Jimenez 		          bittok2str(ospf6_dd_flag_values,"none",GET_U_1(ddp->db_flags)));
781ea7b4bf5SPeter Avalos 
782*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(", MTU %u, DD-Sequence 0x%08x",
783*ed775ee7SAntonio Huete Jimenez                        GET_BE_U_2(ddp->db_mtu),
784*ed775ee7SAntonio Huete Jimenez                        GET_BE_U_4(ddp->db_seq));
785411677aeSAaron LI 		if (ndo->ndo_vflag > 1) {
78641c99275SPeter Avalos 			/* Print all the LS adv's */
787411677aeSAaron LI 			lshp = ddp->db_lshdr;
788411677aeSAaron LI 			while ((const u_char *)lshp < dataend) {
789411677aeSAaron LI 				if (ospf6_print_lshdr(ndo, lshp++, dataend))
790411677aeSAaron LI 					goto trunc;
791411677aeSAaron LI 			}
79241c99275SPeter Avalos 		}
79341c99275SPeter Avalos 		break;
794411677aeSAaron LI 	}
79541c99275SPeter Avalos 
796ea7b4bf5SPeter Avalos 	case OSPF_TYPE_LS_REQ:
797411677aeSAaron LI 		if (ndo->ndo_vflag > 1) {
798411677aeSAaron LI 			lsrp = (const struct lsr6 *)((const uint8_t *)op + OSPF6HDR_LEN);
799411677aeSAaron LI 			while ((const u_char *)lsrp < dataend) {
800*ed775ee7SAntonio Huete Jimenez 				ND_TCHECK_SIZE(lsrp);
801*ed775ee7SAntonio Huete Jimenez 				ND_PRINT("\n\t  Advertising Router %s",
802*ed775ee7SAntonio Huete Jimenez 				          GET_IPADDR_STRING(lsrp->ls_router));
803*ed775ee7SAntonio Huete Jimenez 				ospf6_print_ls_type(ndo,
804*ed775ee7SAntonio Huete Jimenez                                                     GET_BE_U_2(lsrp->ls_type),
805ea7b4bf5SPeter Avalos                                                     &lsrp->ls_stateid);
80641c99275SPeter Avalos 				++lsrp;
80741c99275SPeter Avalos 			}
80841c99275SPeter Avalos 		}
80941c99275SPeter Avalos 		break;
81041c99275SPeter Avalos 
811ea7b4bf5SPeter Avalos 	case OSPF_TYPE_LS_UPDATE:
812411677aeSAaron LI 		if (ndo->ndo_vflag > 1) {
813*ed775ee7SAntonio Huete Jimenez 			const struct lsu6 *lsup = (const struct lsu6 *)((const uint8_t *)op + OSPF6HDR_LEN);
814411677aeSAaron LI 
815*ed775ee7SAntonio Huete Jimenez 			i = GET_BE_U_4(lsup->lsu_count);
816411677aeSAaron LI 			lsap = lsup->lsu_lsa;
817411677aeSAaron LI 			while ((const u_char *)lsap < dataend && i--) {
818411677aeSAaron LI 				if (ospf6_print_lsa(ndo, lsap, dataend))
81941c99275SPeter Avalos 					goto trunc;
820411677aeSAaron LI 				lsap = (const struct lsa6 *)((const u_char *)lsap +
821*ed775ee7SAntonio Huete Jimenez 				    GET_BE_U_2(lsap->ls_hdr.ls_length));
82241c99275SPeter Avalos 			}
82341c99275SPeter Avalos 		}
82441c99275SPeter Avalos 		break;
82541c99275SPeter Avalos 
826ea7b4bf5SPeter Avalos 	case OSPF_TYPE_LS_ACK:
827411677aeSAaron LI 		if (ndo->ndo_vflag > 1) {
828411677aeSAaron LI 			lshp = (const struct lsa6_hdr *)((const uint8_t *)op + OSPF6HDR_LEN);
829411677aeSAaron LI 			while ((const u_char *)lshp < dataend) {
830411677aeSAaron LI 				if (ospf6_print_lshdr(ndo, lshp++, dataend))
831411677aeSAaron LI 					goto trunc;
83241c99275SPeter Avalos 			}
83341c99275SPeter Avalos 		}
83441c99275SPeter Avalos 		break;
83541c99275SPeter Avalos 
83641c99275SPeter Avalos 	default:
83741c99275SPeter Avalos 		break;
83841c99275SPeter Avalos 	}
83941c99275SPeter Avalos 	return (0);
84041c99275SPeter Avalos trunc:
84141c99275SPeter Avalos 	return (1);
84241c99275SPeter Avalos }
84341c99275SPeter Avalos 
844411677aeSAaron LI /* RFC5613 Section 2.2 (w/o the TLVs) */
845411677aeSAaron LI static int
ospf6_print_lls(netdissect_options * ndo,const u_char * cp,const u_int len)846411677aeSAaron LI ospf6_print_lls(netdissect_options *ndo,
847411677aeSAaron LI                 const u_char *cp, const u_int len)
848411677aeSAaron LI {
849411677aeSAaron LI 	uint16_t llsdatalen;
850411677aeSAaron LI 
851411677aeSAaron LI 	if (len == 0)
852411677aeSAaron LI 		return 0;
853411677aeSAaron LI 	if (len < OSPF_LLS_HDRLEN)
854411677aeSAaron LI 		goto trunc;
855411677aeSAaron LI 	/* Checksum */
856*ed775ee7SAntonio Huete Jimenez 	ND_PRINT("\n\tLLS Checksum 0x%04x", GET_BE_U_2(cp));
857411677aeSAaron LI 	cp += 2;
858411677aeSAaron LI 	/* LLS Data Length */
859*ed775ee7SAntonio Huete Jimenez 	llsdatalen = GET_BE_U_2(cp);
860*ed775ee7SAntonio Huete Jimenez 	ND_PRINT(", Data Length %u", llsdatalen);
861411677aeSAaron LI 	if (llsdatalen < OSPF_LLS_HDRLEN || llsdatalen > len)
862411677aeSAaron LI 		goto trunc;
863411677aeSAaron LI 	cp += 2;
864411677aeSAaron LI 	/* LLS TLVs */
865*ed775ee7SAntonio Huete Jimenez 	ND_TCHECK_LEN(cp, llsdatalen - OSPF_LLS_HDRLEN);
866411677aeSAaron LI 	/* FIXME: code in print-ospf.c can be reused to decode the TLVs */
867411677aeSAaron LI 
868411677aeSAaron LI 	return llsdatalen;
869411677aeSAaron LI trunc:
870411677aeSAaron LI 	return -1;
871411677aeSAaron LI }
872411677aeSAaron LI 
873411677aeSAaron LI /* RFC6506 Section 4.1 */
874411677aeSAaron LI static int
ospf6_decode_at(netdissect_options * ndo,const u_char * cp,const u_int len)875411677aeSAaron LI ospf6_decode_at(netdissect_options *ndo,
876411677aeSAaron LI                 const u_char *cp, const u_int len)
877411677aeSAaron LI {
878411677aeSAaron LI 	uint16_t authdatalen;
879411677aeSAaron LI 
880411677aeSAaron LI 	if (len == 0)
881411677aeSAaron LI 		return 0;
882411677aeSAaron LI 	if (len < OSPF6_AT_HDRLEN)
883411677aeSAaron LI 		goto trunc;
884411677aeSAaron LI 	/* Authentication Type */
885*ed775ee7SAntonio Huete Jimenez 	ND_PRINT("\n\tAuthentication Type %s",
886*ed775ee7SAntonio Huete Jimenez 		 tok2str(ospf6_auth_type_str, "unknown (0x%04x)", GET_BE_U_2(cp)));
887411677aeSAaron LI 	cp += 2;
888411677aeSAaron LI 	/* Auth Data Len */
889*ed775ee7SAntonio Huete Jimenez 	authdatalen = GET_BE_U_2(cp);
890*ed775ee7SAntonio Huete Jimenez 	ND_PRINT(", Length %u", authdatalen);
891411677aeSAaron LI 	if (authdatalen < OSPF6_AT_HDRLEN || authdatalen > len)
892411677aeSAaron LI 		goto trunc;
893411677aeSAaron LI 	cp += 2;
894411677aeSAaron LI 	/* Reserved */
895411677aeSAaron LI 	cp += 2;
896411677aeSAaron LI 	/* Security Association ID */
897*ed775ee7SAntonio Huete Jimenez 	ND_PRINT(", SAID %u", GET_BE_U_2(cp));
898411677aeSAaron LI 	cp += 2;
899411677aeSAaron LI 	/* Cryptographic Sequence Number (High-Order 32 Bits) */
900*ed775ee7SAntonio Huete Jimenez 	ND_PRINT(", CSN 0x%08x", GET_BE_U_4(cp));
901411677aeSAaron LI 	cp += 4;
902411677aeSAaron LI 	/* Cryptographic Sequence Number (Low-Order 32 Bits) */
903*ed775ee7SAntonio Huete Jimenez 	ND_PRINT(":%08x", GET_BE_U_4(cp));
904411677aeSAaron LI 	cp += 4;
905411677aeSAaron LI 	/* Authentication Data */
906*ed775ee7SAntonio Huete Jimenez 	ND_TCHECK_LEN(cp, authdatalen - OSPF6_AT_HDRLEN);
907411677aeSAaron LI 	if (ndo->ndo_vflag > 1)
908411677aeSAaron LI 		print_unknown_data(ndo,cp, "\n\tAuthentication Data ", authdatalen - OSPF6_AT_HDRLEN);
909411677aeSAaron LI 	return 0;
910411677aeSAaron LI 
911411677aeSAaron LI trunc:
912411677aeSAaron LI 	return 1;
913411677aeSAaron LI }
914411677aeSAaron LI 
915411677aeSAaron LI /* The trailing data may include LLS and/or AT data (in this specific order).
916411677aeSAaron LI  * LLS data may be present only in Hello and DBDesc packets with the L-bit set.
917411677aeSAaron LI  * AT data may be present in Hello and DBDesc packets with the AT-bit set or in
918411677aeSAaron LI  * any other packet type, thus decode the AT data regardless of the AT-bit.
919411677aeSAaron LI  */
920411677aeSAaron LI static int
ospf6_decode_v3_trailer(netdissect_options * ndo,const struct ospf6hdr * op,const u_char * cp,const unsigned len)921411677aeSAaron LI ospf6_decode_v3_trailer(netdissect_options *ndo,
922411677aeSAaron LI                         const struct ospf6hdr *op, const u_char *cp, const unsigned len)
923411677aeSAaron LI {
924*ed775ee7SAntonio Huete Jimenez 	uint8_t type;
925411677aeSAaron LI 	int llslen = 0;
926411677aeSAaron LI 	int lls_hello = 0;
927411677aeSAaron LI 	int lls_dd = 0;
928411677aeSAaron LI 
929*ed775ee7SAntonio Huete Jimenez 	type = GET_U_1(op->ospf6_type);
930*ed775ee7SAntonio Huete Jimenez 	if (type == OSPF_TYPE_HELLO) {
931411677aeSAaron LI 		const struct hello6 *hellop = (const struct hello6 *)((const uint8_t *)op + OSPF6HDR_LEN);
932*ed775ee7SAntonio Huete Jimenez 		if (GET_BE_U_4(hellop->hello_options) & OSPF6_OPTION_L)
933411677aeSAaron LI 			lls_hello = 1;
934*ed775ee7SAntonio Huete Jimenez 	} else if (type == OSPF_TYPE_DD) {
935411677aeSAaron LI 		const struct dd6 *ddp = (const struct dd6 *)((const uint8_t *)op + OSPF6HDR_LEN);
936*ed775ee7SAntonio Huete Jimenez 		if (GET_BE_U_4(ddp->db_options) & OSPF6_OPTION_L)
937411677aeSAaron LI 			lls_dd = 1;
938411677aeSAaron LI 	}
939411677aeSAaron LI 	if ((lls_hello || lls_dd) && (llslen = ospf6_print_lls(ndo, cp, len)) < 0)
940411677aeSAaron LI 		goto trunc;
941411677aeSAaron LI 	return ospf6_decode_at(ndo, cp + llslen, len - llslen);
942411677aeSAaron LI 
943411677aeSAaron LI trunc:
944411677aeSAaron LI 	return 1;
945411677aeSAaron LI }
946411677aeSAaron LI 
94741c99275SPeter Avalos void
ospf6_print(netdissect_options * ndo,const u_char * bp,u_int length)948411677aeSAaron LI ospf6_print(netdissect_options *ndo,
949*ed775ee7SAntonio Huete Jimenez             const u_char *bp, u_int length)
95041c99275SPeter Avalos {
951*ed775ee7SAntonio Huete Jimenez 	const struct ospf6hdr *op;
952*ed775ee7SAntonio Huete Jimenez 	const u_char *dataend;
953*ed775ee7SAntonio Huete Jimenez 	const char *cp;
954411677aeSAaron LI 	uint16_t datalen;
95541c99275SPeter Avalos 
956*ed775ee7SAntonio Huete Jimenez 	ndo->ndo_protocol = "ospf3";
957411677aeSAaron LI 	op = (const struct ospf6hdr *)bp;
95841c99275SPeter Avalos 
95941c99275SPeter Avalos 	/* If the type is valid translate it, or just print the type */
96041c99275SPeter Avalos 	/* value.  If it's not valid, say so and return */
961*ed775ee7SAntonio Huete Jimenez 	cp = tok2str(ospf6_type_values, "unknown packet type (%u)",
962*ed775ee7SAntonio Huete Jimenez 		     GET_U_1(op->ospf6_type));
963*ed775ee7SAntonio Huete Jimenez 	ND_PRINT("OSPFv%u, %s, length %u", GET_U_1(op->ospf6_version), cp,
964*ed775ee7SAntonio Huete Jimenez 		 length);
965ea7b4bf5SPeter Avalos 	if (*cp == 'u') {
96641c99275SPeter Avalos 		return;
967ea7b4bf5SPeter Avalos 	}
968ea7b4bf5SPeter Avalos 
969411677aeSAaron LI 	if(!ndo->ndo_vflag) { /* non verbose - so lets bail out here */
970ea7b4bf5SPeter Avalos 		return;
971ea7b4bf5SPeter Avalos 	}
97241c99275SPeter Avalos 
973411677aeSAaron LI 	/* OSPFv3 data always comes first and optional trailing data may follow. */
974*ed775ee7SAntonio Huete Jimenez 	datalen = GET_BE_U_2(op->ospf6_len);
975411677aeSAaron LI 	if (datalen > length) {
976*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(" [len %u]", datalen);
97741c99275SPeter Avalos 		return;
97841c99275SPeter Avalos 	}
979411677aeSAaron LI 	dataend = bp + datalen;
98041c99275SPeter Avalos 
981*ed775ee7SAntonio Huete Jimenez 	ND_PRINT("\n\tRouter-ID %s", GET_IPADDR_STRING(op->ospf6_routerid));
98241c99275SPeter Avalos 
983*ed775ee7SAntonio Huete Jimenez 	if (GET_BE_U_4(op->ospf6_areaid) != 0)
984*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(", Area %s", GET_IPADDR_STRING(op->ospf6_areaid));
98541c99275SPeter Avalos 	else
986*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(", Backbone Area");
987*ed775ee7SAntonio Huete Jimenez 	if (GET_U_1(op->ospf6_instanceid))
988*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(", Instance %u", GET_U_1(op->ospf6_instanceid));
98941c99275SPeter Avalos 
99041c99275SPeter Avalos 	/* Do rest according to version.	 */
991*ed775ee7SAntonio Huete Jimenez 	switch (GET_U_1(op->ospf6_version)) {
99241c99275SPeter Avalos 
99341c99275SPeter Avalos 	case 3:
99441c99275SPeter Avalos 		/* ospf version 3 */
995411677aeSAaron LI 		if (ospf6_decode_v3(ndo, op, dataend) ||
996411677aeSAaron LI 		    ospf6_decode_v3_trailer(ndo, op, dataend, length - datalen))
99741c99275SPeter Avalos 			goto trunc;
99841c99275SPeter Avalos 		break;
99941c99275SPeter Avalos 	}			/* end switch on version */
100041c99275SPeter Avalos 
100141c99275SPeter Avalos 	return;
100241c99275SPeter Avalos trunc:
1003*ed775ee7SAntonio Huete Jimenez 	nd_print_trunc(ndo);
100441c99275SPeter Avalos }
1005