print-ospf6.c revision 1.6 1 /*
2 * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * OSPF support contributed by Jeffrey Honig (jch (at) mitchell.cit.cornell.edu)
22 */
23
24 #include <sys/cdefs.h>
25 #ifndef lint
26 __RCSID("$NetBSD: print-ospf6.c,v 1.6 2017/01/24 23:29:14 christos Exp $");
27 #endif
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <netdissect-stdinc.h>
34
35 #include <string.h>
36
37 #include "netdissect.h"
38 #include "addrtoname.h"
39 #include "extract.h"
40
41 #include "ospf.h"
42
43 #define OSPF_TYPE_HELLO 1 /* Hello */
44 #define OSPF_TYPE_DD 2 /* Database Description */
45 #define OSPF_TYPE_LS_REQ 3 /* Link State Request */
46 #define OSPF_TYPE_LS_UPDATE 4 /* Link State Update */
47 #define OSPF_TYPE_LS_ACK 5 /* Link State Ack */
48
49 /* Options *_options */
50 #define OSPF6_OPTION_V6 0x01 /* V6 bit: A bit for peeping tom */
51 #define OSPF6_OPTION_E 0x02 /* E bit: External routes advertised */
52 #define OSPF6_OPTION_MC 0x04 /* MC bit: Multicast capable */
53 #define OSPF6_OPTION_N 0x08 /* N bit: For type-7 LSA */
54 #define OSPF6_OPTION_R 0x10 /* R bit: Router bit */
55 #define OSPF6_OPTION_DC 0x20 /* DC bit: Demand circuits */
56 /* The field is actually 24-bit (RFC5340 Section A.2). */
57 #define OSPF6_OPTION_AF 0x0100 /* AF bit: Multiple address families */
58 #define OSPF6_OPTION_L 0x0200 /* L bit: Link-local signaling (LLS) */
59 #define OSPF6_OPTION_AT 0x0400 /* AT bit: Authentication trailer */
60
61
62 /* db_flags */
63 #define OSPF6_DB_INIT 0x04 /* */
64 #define OSPF6_DB_MORE 0x02
65 #define OSPF6_DB_MASTER 0x01
66 #define OSPF6_DB_M6 0x10 /* IPv6 MTU */
67
68 /* ls_type */
69 #define LS_TYPE_ROUTER 1 /* router link */
70 #define LS_TYPE_NETWORK 2 /* network link */
71 #define LS_TYPE_INTER_AP 3 /* Inter-Area-Prefix */
72 #define LS_TYPE_INTER_AR 4 /* Inter-Area-Router */
73 #define LS_TYPE_ASE 5 /* ASE */
74 #define LS_TYPE_GROUP 6 /* Group membership */
75 #define LS_TYPE_NSSA 7 /* NSSA */
76 #define LS_TYPE_LINK 8 /* Link LSA */
77 #define LS_TYPE_INTRA_AP 9 /* Intra-Area-Prefix */
78 #define LS_TYPE_INTRA_ATE 10 /* Intra-Area-TE */
79 #define LS_TYPE_GRACE 11 /* Grace LSA */
80 #define LS_TYPE_RI 12 /* Router information */
81 #define LS_TYPE_INTER_ASTE 13 /* Inter-AS-TE */
82 #define LS_TYPE_L1VPN 14 /* L1VPN */
83 #define LS_TYPE_MASK 0x1fff
84
85 #define LS_SCOPE_LINKLOCAL 0x0000
86 #define LS_SCOPE_AREA 0x2000
87 #define LS_SCOPE_AS 0x4000
88 #define LS_SCOPE_MASK 0x6000
89 #define LS_SCOPE_U 0x8000
90
91 /* rla_link.link_type */
92 #define RLA_TYPE_ROUTER 1 /* point-to-point to another router */
93 #define RLA_TYPE_TRANSIT 2 /* connection to transit network */
94 #define RLA_TYPE_VIRTUAL 4 /* virtual link */
95
96 /* rla_flags */
97 #define RLA_FLAG_B 0x01
98 #define RLA_FLAG_E 0x02
99 #define RLA_FLAG_V 0x04
100 #define RLA_FLAG_W 0x08
101 #define RLA_FLAG_N 0x10
102
103 /* lsa_prefix options */
104 #define LSA_PREFIX_OPT_NU 0x01
105 #define LSA_PREFIX_OPT_LA 0x02
106 #define LSA_PREFIX_OPT_MC 0x04
107 #define LSA_PREFIX_OPT_P 0x08
108 #define LSA_PREFIX_OPT_DN 0x10
109
110 /* sla_tosmetric breakdown */
111 #define SLA_MASK_TOS 0x7f000000
112 #define SLA_MASK_METRIC 0x00ffffff
113 #define SLA_SHIFT_TOS 24
114
115 /* asla_metric */
116 #define ASLA_FLAG_FWDADDR 0x02000000
117 #define ASLA_FLAG_ROUTETAG 0x01000000
118 #define ASLA_MASK_METRIC 0x00ffffff
119
120 /* RFC6506 Section 4.1 */
121 #define OSPF6_AT_HDRLEN 16U
122 #define OSPF6_AUTH_TYPE_HMAC 0x0001
123
124 typedef uint32_t rtrid_t;
125
126 /* link state advertisement header */
127 struct lsa6_hdr {
128 uint16_t ls_age;
129 uint16_t ls_type;
130 rtrid_t ls_stateid;
131 rtrid_t ls_router;
132 uint32_t ls_seq;
133 uint16_t ls_chksum;
134 uint16_t ls_length;
135 };
136
137 /* Length of an IPv6 address, in bytes. */
138 #define IPV6_ADDR_LEN_BYTES (128/8)
139
140 struct lsa6_prefix {
141 uint8_t lsa_p_len;
142 uint8_t lsa_p_opt;
143 uint16_t lsa_p_metric;
144 uint8_t lsa_p_prefix[IPV6_ADDR_LEN_BYTES]; /* maximum length */
145 };
146
147 /* link state advertisement */
148 struct lsa6 {
149 struct lsa6_hdr ls_hdr;
150
151 /* Link state types */
152 union {
153 /* Router links advertisements */
154 struct {
155 union {
156 uint8_t flg;
157 uint32_t opt;
158 } rla_flgandopt;
159 #define rla_flags rla_flgandopt.flg
160 #define rla_options rla_flgandopt.opt
161 struct rlalink6 {
162 uint8_t link_type;
163 uint8_t link_zero[1];
164 uint16_t link_metric;
165 uint32_t link_ifid;
166 uint32_t link_nifid;
167 rtrid_t link_nrtid;
168 } rla_link[1]; /* may repeat */
169 } un_rla;
170
171 /* Network links advertisements */
172 struct {
173 uint32_t nla_options;
174 rtrid_t nla_router[1]; /* may repeat */
175 } un_nla;
176
177 /* Inter Area Prefix LSA */
178 struct {
179 uint32_t inter_ap_metric;
180 struct lsa6_prefix inter_ap_prefix[1];
181 } un_inter_ap;
182
183 /* AS external links advertisements */
184 struct {
185 uint32_t asla_metric;
186 struct lsa6_prefix asla_prefix[1];
187 /* some optional fields follow */
188 } un_asla;
189
190 #if 0
191 /* Summary links advertisements */
192 struct {
193 struct in_addr sla_mask;
194 uint32_t sla_tosmetric[1]; /* may repeat */
195 } un_sla;
196
197 /* Multicast group membership */
198 struct mcla {
199 uint32_t mcla_vtype;
200 struct in_addr mcla_vid;
201 } un_mcla[1];
202 #endif
203
204 /* Type 7 LSA */
205
206 /* Link LSA */
207 struct llsa {
208 union {
209 uint8_t pri;
210 uint32_t opt;
211 } llsa_priandopt;
212 #define llsa_priority llsa_priandopt.pri
213 #define llsa_options llsa_priandopt.opt
214 struct in6_addr llsa_lladdr;
215 uint32_t llsa_nprefix;
216 struct lsa6_prefix llsa_prefix[1];
217 } un_llsa;
218
219 /* Intra-Area-Prefix */
220 struct {
221 uint16_t intra_ap_nprefix;
222 uint16_t intra_ap_lstype;
223 rtrid_t intra_ap_lsid;
224 rtrid_t intra_ap_rtid;
225 struct lsa6_prefix intra_ap_prefix[1];
226 } un_intra_ap;
227 } lsa_un;
228 };
229
230 /*
231 * the main header
232 */
233 struct ospf6hdr {
234 uint8_t ospf6_version;
235 uint8_t ospf6_type;
236 uint16_t ospf6_len;
237 rtrid_t ospf6_routerid;
238 rtrid_t ospf6_areaid;
239 uint16_t ospf6_chksum;
240 uint8_t ospf6_instanceid;
241 uint8_t ospf6_rsvd;
242 };
243
244 /*
245 * The OSPF6 header length is 16 bytes, regardless of how your compiler
246 * might choose to pad the above structure.
247 */
248 #define OSPF6HDR_LEN 16
249
250 /* Hello packet */
251 struct hello6 {
252 uint32_t hello_ifid;
253 union {
254 uint8_t pri;
255 uint32_t opt;
256 } hello_priandopt;
257 #define hello_priority hello_priandopt.pri
258 #define hello_options hello_priandopt.opt
259 uint16_t hello_helloint;
260 uint16_t hello_deadint;
261 rtrid_t hello_dr;
262 rtrid_t hello_bdr;
263 rtrid_t hello_neighbor[1]; /* may repeat */
264 };
265
266 /* Database Description packet */
267 struct dd6 {
268 uint32_t db_options;
269 uint16_t db_mtu;
270 uint8_t db_mbz;
271 uint8_t db_flags;
272 uint32_t db_seq;
273 struct lsa6_hdr db_lshdr[1]; /* may repeat */
274 };
275
276 /* Link State Request */
277 struct lsr6 {
278 uint16_t ls_mbz;
279 uint16_t ls_type;
280 rtrid_t ls_stateid;
281 rtrid_t ls_router;
282 };
283
284 /* Link State Update */
285 struct lsu6 {
286 uint32_t lsu_count;
287 struct lsa6 lsu_lsa[1]; /* may repeat */
288 };
289
290 static const char tstr[] = " [|ospf3]";
291
292 static const struct tok ospf6_option_values[] = {
293 { OSPF6_OPTION_V6, "V6" },
294 { OSPF6_OPTION_E, "External" },
295 { OSPF6_OPTION_MC, "Deprecated" },
296 { OSPF6_OPTION_N, "NSSA" },
297 { OSPF6_OPTION_R, "Router" },
298 { OSPF6_OPTION_DC, "Demand Circuit" },
299 { OSPF6_OPTION_AF, "AFs Support" },
300 { OSPF6_OPTION_L, "LLS" },
301 { OSPF6_OPTION_AT, "Authentication Trailer" },
302 { 0, NULL }
303 };
304
305 static const struct tok ospf6_rla_flag_values[] = {
306 { RLA_FLAG_B, "ABR" },
307 { RLA_FLAG_E, "External" },
308 { RLA_FLAG_V, "Virtual-Link Endpoint" },
309 { RLA_FLAG_W, "Wildcard Receiver" },
310 { RLA_FLAG_N, "NSSA Translator" },
311 { 0, NULL }
312 };
313
314 static const struct tok ospf6_asla_flag_values[] = {
315 { ASLA_FLAG_EXTERNAL, "External Type 2" },
316 { ASLA_FLAG_FWDADDR, "Forwarding" },
317 { ASLA_FLAG_ROUTETAG, "Tag" },
318 { 0, NULL }
319 };
320
321 static const struct tok ospf6_type_values[] = {
322 { OSPF_TYPE_HELLO, "Hello" },
323 { OSPF_TYPE_DD, "Database Description" },
324 { OSPF_TYPE_LS_REQ, "LS-Request" },
325 { OSPF_TYPE_LS_UPDATE, "LS-Update" },
326 { OSPF_TYPE_LS_ACK, "LS-Ack" },
327 { 0, NULL }
328 };
329
330 static const struct tok ospf6_lsa_values[] = {
331 { LS_TYPE_ROUTER, "Router" },
332 { LS_TYPE_NETWORK, "Network" },
333 { LS_TYPE_INTER_AP, "Inter-Area Prefix" },
334 { LS_TYPE_INTER_AR, "Inter-Area Router" },
335 { LS_TYPE_ASE, "External" },
336 { LS_TYPE_GROUP, "Deprecated" },
337 { LS_TYPE_NSSA, "NSSA" },
338 { LS_TYPE_LINK, "Link" },
339 { LS_TYPE_INTRA_AP, "Intra-Area Prefix" },
340 { LS_TYPE_INTRA_ATE, "Intra-Area TE" },
341 { LS_TYPE_GRACE, "Grace" },
342 { LS_TYPE_RI, "Router Information" },
343 { LS_TYPE_INTER_ASTE, "Inter-AS-TE" },
344 { LS_TYPE_L1VPN, "Layer 1 VPN" },
345 { 0, NULL }
346 };
347
348 static const struct tok ospf6_ls_scope_values[] = {
349 { LS_SCOPE_LINKLOCAL, "Link Local" },
350 { LS_SCOPE_AREA, "Area Local" },
351 { LS_SCOPE_AS, "Domain Wide" },
352 { 0, NULL }
353 };
354
355 static const struct tok ospf6_dd_flag_values[] = {
356 { OSPF6_DB_INIT, "Init" },
357 { OSPF6_DB_MORE, "More" },
358 { OSPF6_DB_MASTER, "Master" },
359 { OSPF6_DB_M6, "IPv6 MTU" },
360 { 0, NULL }
361 };
362
363 static const struct tok ospf6_lsa_prefix_option_values[] = {
364 { LSA_PREFIX_OPT_NU, "No Unicast" },
365 { LSA_PREFIX_OPT_LA, "Local address" },
366 { LSA_PREFIX_OPT_MC, "Deprecated" },
367 { LSA_PREFIX_OPT_P, "Propagate" },
368 { LSA_PREFIX_OPT_DN, "Down" },
369 { 0, NULL }
370 };
371
372 static const struct tok ospf6_auth_type_str[] = {
373 { OSPF6_AUTH_TYPE_HMAC, "HMAC" },
374 { 0, NULL }
375 };
376
377 static void
378 ospf6_print_ls_type(netdissect_options *ndo,
379 register u_int ls_type, register const rtrid_t *ls_stateid)
380 {
381 ND_PRINT((ndo, "\n\t %s LSA (%d), %s Scope%s, LSA-ID %s",
382 tok2str(ospf6_lsa_values, "Unknown", ls_type & LS_TYPE_MASK),
383 ls_type & LS_TYPE_MASK,
384 tok2str(ospf6_ls_scope_values, "Unknown", ls_type & LS_SCOPE_MASK),
385 ls_type &0x8000 ? ", transitive" : "", /* U-bit */
386 ipaddr_string(ndo, ls_stateid)));
387 }
388
389 static int
390 ospf6_print_lshdr(netdissect_options *ndo,
391 register const struct lsa6_hdr *lshp, const u_char *dataend)
392 {
393 if ((const u_char *)(lshp + 1) > dataend)
394 goto trunc;
395 ND_TCHECK(lshp->ls_type);
396 ND_TCHECK(lshp->ls_seq);
397
398 ND_PRINT((ndo, "\n\t Advertising Router %s, seq 0x%08x, age %us, length %u",
399 ipaddr_string(ndo, &lshp->ls_router),
400 EXTRACT_32BITS(&lshp->ls_seq),
401 EXTRACT_16BITS(&lshp->ls_age),
402 EXTRACT_16BITS(&lshp->ls_length)-(u_int)sizeof(struct lsa6_hdr)));
403
404 ospf6_print_ls_type(ndo, EXTRACT_16BITS(&lshp->ls_type), &lshp->ls_stateid);
405
406 return (0);
407 trunc:
408 return (1);
409 }
410
411 static int
412 ospf6_print_lsaprefix(netdissect_options *ndo,
413 const uint8_t *tptr, u_int lsa_length)
414 {
415 const struct lsa6_prefix *lsapp = (const struct lsa6_prefix *)tptr;
416 u_int wordlen;
417 struct in6_addr prefix;
418
419 if (lsa_length < sizeof (*lsapp) - IPV6_ADDR_LEN_BYTES)
420 goto trunc;
421 lsa_length -= sizeof (*lsapp) - IPV6_ADDR_LEN_BYTES;
422 ND_TCHECK2(*lsapp, sizeof (*lsapp) - IPV6_ADDR_LEN_BYTES);
423 wordlen = (lsapp->lsa_p_len + 31) / 32;
424 if (wordlen * 4 > sizeof(struct in6_addr)) {
425 ND_PRINT((ndo, " bogus prefixlen /%d", lsapp->lsa_p_len));
426 goto trunc;
427 }
428 if (lsa_length < wordlen * 4)
429 goto trunc;
430 lsa_length -= wordlen * 4;
431 ND_TCHECK2(lsapp->lsa_p_prefix, wordlen * 4);
432 memset(&prefix, 0, sizeof(prefix));
433 memcpy(&prefix, lsapp->lsa_p_prefix, wordlen * 4);
434 ND_PRINT((ndo, "\n\t\t%s/%d", ip6addr_string(ndo, &prefix),
435 lsapp->lsa_p_len));
436 if (lsapp->lsa_p_opt) {
437 ND_PRINT((ndo, ", Options [%s]",
438 bittok2str(ospf6_lsa_prefix_option_values,
439 "none", lsapp->lsa_p_opt)));
440 }
441 ND_PRINT((ndo, ", metric %u", EXTRACT_16BITS(&lsapp->lsa_p_metric)));
442 return sizeof(*lsapp) - IPV6_ADDR_LEN_BYTES + wordlen * 4;
443
444 trunc:
445 return -1;
446 }
447
448
449 /*
450 * Print a single link state advertisement. If truncated return 1, else 0.
451 */
452 static int
453 ospf6_print_lsa(netdissect_options *ndo,
454 register const struct lsa6 *lsap, const u_char *dataend)
455 {
456 register const struct rlalink6 *rlp;
457 #if 0
458 register const struct tos_metric *tosp;
459 #endif
460 register const rtrid_t *ap;
461 #if 0
462 register const struct aslametric *almp;
463 register const struct mcla *mcp;
464 #endif
465 register const struct llsa *llsap;
466 register const struct lsa6_prefix *lsapp;
467 #if 0
468 register const uint32_t *lp;
469 #endif
470 register u_int prefixes;
471 register int bytelen;
472 register u_int length, lsa_length;
473 uint32_t flags32;
474 const uint8_t *tptr;
475
476 if (ospf6_print_lshdr(ndo, &lsap->ls_hdr, dataend))
477 return (1);
478 ND_TCHECK(lsap->ls_hdr.ls_length);
479 length = EXTRACT_16BITS(&lsap->ls_hdr.ls_length);
480
481 /*
482 * The LSA length includes the length of the header;
483 * it must have a value that's at least that length.
484 * If it does, find the length of what follows the
485 * header.
486 */
487 if (length < sizeof(struct lsa6_hdr) || (const u_char *)lsap + length > dataend)
488 return (1);
489 lsa_length = length - sizeof(struct lsa6_hdr);
490 tptr = (const uint8_t *)lsap+sizeof(struct lsa6_hdr);
491
492 switch (EXTRACT_16BITS(&lsap->ls_hdr.ls_type)) {
493 case LS_TYPE_ROUTER | LS_SCOPE_AREA:
494 if (lsa_length < sizeof (lsap->lsa_un.un_rla.rla_options))
495 return (1);
496 lsa_length -= sizeof (lsap->lsa_un.un_rla.rla_options);
497 ND_TCHECK(lsap->lsa_un.un_rla.rla_options);
498 ND_PRINT((ndo, "\n\t Options [%s]",
499 bittok2str(ospf6_option_values, "none",
500 EXTRACT_32BITS(&lsap->lsa_un.un_rla.rla_options))));
501 ND_PRINT((ndo, ", RLA-Flags [%s]",
502 bittok2str(ospf6_rla_flag_values, "none",
503 lsap->lsa_un.un_rla.rla_flags)));
504
505 rlp = lsap->lsa_un.un_rla.rla_link;
506 while (lsa_length != 0) {
507 if (lsa_length < sizeof (*rlp))
508 return (1);
509 lsa_length -= sizeof (*rlp);
510 ND_TCHECK(*rlp);
511 switch (rlp->link_type) {
512
513 case RLA_TYPE_VIRTUAL:
514 ND_PRINT((ndo, "\n\t Virtual Link: Neighbor Router-ID %s"
515 "\n\t Neighbor Interface-ID %s, Interface %s",
516 ipaddr_string(ndo, &rlp->link_nrtid),
517 ipaddr_string(ndo, &rlp->link_nifid),
518 ipaddr_string(ndo, &rlp->link_ifid)));
519 break;
520
521 case RLA_TYPE_ROUTER:
522 ND_PRINT((ndo, "\n\t Neighbor Router-ID %s"
523 "\n\t Neighbor Interface-ID %s, Interface %s",
524 ipaddr_string(ndo, &rlp->link_nrtid),
525 ipaddr_string(ndo, &rlp->link_nifid),
526 ipaddr_string(ndo, &rlp->link_ifid)));
527 break;
528
529 case RLA_TYPE_TRANSIT:
530 ND_PRINT((ndo, "\n\t Neighbor Network-ID %s"
531 "\n\t Neighbor Interface-ID %s, Interface %s",
532 ipaddr_string(ndo, &rlp->link_nrtid),
533 ipaddr_string(ndo, &rlp->link_nifid),
534 ipaddr_string(ndo, &rlp->link_ifid)));
535 break;
536
537 default:
538 ND_PRINT((ndo, "\n\t Unknown Router Links Type 0x%02x",
539 rlp->link_type));
540 return (0);
541 }
542 ND_PRINT((ndo, ", metric %d", EXTRACT_16BITS(&rlp->link_metric)));
543 rlp++;
544 }
545 break;
546
547 case LS_TYPE_NETWORK | LS_SCOPE_AREA:
548 if (lsa_length < sizeof (lsap->lsa_un.un_nla.nla_options))
549 return (1);
550 lsa_length -= sizeof (lsap->lsa_un.un_nla.nla_options);
551 ND_TCHECK(lsap->lsa_un.un_nla.nla_options);
552 ND_PRINT((ndo, "\n\t Options [%s]",
553 bittok2str(ospf6_option_values, "none",
554 EXTRACT_32BITS(&lsap->lsa_un.un_nla.nla_options))));
555
556 ND_PRINT((ndo, "\n\t Connected Routers:"));
557 ap = lsap->lsa_un.un_nla.nla_router;
558 while (lsa_length != 0) {
559 if (lsa_length < sizeof (*ap))
560 return (1);
561 lsa_length -= sizeof (*ap);
562 ND_TCHECK(*ap);
563 ND_PRINT((ndo, "\n\t\t%s", ipaddr_string(ndo, ap)));
564 ++ap;
565 }
566 break;
567
568 case LS_TYPE_INTER_AP | LS_SCOPE_AREA:
569 if (lsa_length < sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric))
570 return (1);
571 lsa_length -= sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric);
572 ND_TCHECK(lsap->lsa_un.un_inter_ap.inter_ap_metric);
573 ND_PRINT((ndo, ", metric %u",
574 EXTRACT_32BITS(&lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC));
575
576 tptr = (const uint8_t *)lsap->lsa_un.un_inter_ap.inter_ap_prefix;
577 while (lsa_length != 0) {
578 bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length);
579 if (bytelen < 0)
580 goto trunc;
581 lsa_length -= bytelen;
582 tptr += bytelen;
583 }
584 break;
585
586 case LS_TYPE_ASE | LS_SCOPE_AS:
587 if (lsa_length < sizeof (lsap->lsa_un.un_asla.asla_metric))
588 return (1);
589 lsa_length -= sizeof (lsap->lsa_un.un_asla.asla_metric);
590 ND_TCHECK(lsap->lsa_un.un_asla.asla_metric);
591 flags32 = EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric);
592 ND_PRINT((ndo, "\n\t Flags [%s]",
593 bittok2str(ospf6_asla_flag_values, "none", flags32)));
594 ND_PRINT((ndo, " metric %u",
595 EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric) &
596 ASLA_MASK_METRIC));
597
598 tptr = (const uint8_t *)lsap->lsa_un.un_asla.asla_prefix;
599 lsapp = (const struct lsa6_prefix *)tptr;
600 bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length);
601 if (bytelen < 0)
602 goto trunc;
603 lsa_length -= bytelen;
604 tptr += bytelen;
605
606 if ((flags32 & ASLA_FLAG_FWDADDR) != 0) {
607 const struct in6_addr *fwdaddr6;
608
609 fwdaddr6 = (const struct in6_addr *)tptr;
610 if (lsa_length < sizeof (*fwdaddr6))
611 return (1);
612 lsa_length -= sizeof (*fwdaddr6);
613 ND_TCHECK(*fwdaddr6);
614 ND_PRINT((ndo, " forward %s",
615 ip6addr_string(ndo, fwdaddr6)));
616 tptr += sizeof(*fwdaddr6);
617 }
618
619 if ((flags32 & ASLA_FLAG_ROUTETAG) != 0) {
620 if (lsa_length < sizeof (uint32_t))
621 return (1);
622 lsa_length -= sizeof (uint32_t);
623 ND_TCHECK(*(const uint32_t *)tptr);
624 ND_PRINT((ndo, " tag %s",
625 ipaddr_string(ndo, (const uint32_t *)tptr)));
626 tptr += sizeof(uint32_t);
627 }
628
629 if (lsapp->lsa_p_metric) {
630 if (lsa_length < sizeof (uint32_t))
631 return (1);
632 lsa_length -= sizeof (uint32_t);
633 ND_TCHECK(*(const uint32_t *)tptr);
634 ND_PRINT((ndo, " RefLSID: %s",
635 ipaddr_string(ndo, (const uint32_t *)tptr)));
636 tptr += sizeof(uint32_t);
637 }
638 break;
639
640 case LS_TYPE_LINK:
641 /* Link LSA */
642 llsap = &lsap->lsa_un.un_llsa;
643 if (lsa_length < sizeof (llsap->llsa_priandopt))
644 return (1);
645 lsa_length -= sizeof (llsap->llsa_priandopt);
646 ND_TCHECK(llsap->llsa_priandopt);
647 ND_PRINT((ndo, "\n\t Options [%s]",
648 bittok2str(ospf6_option_values, "none",
649 EXTRACT_32BITS(&llsap->llsa_options))));
650
651 if (lsa_length < sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix))
652 return (1);
653 lsa_length -= sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix);
654 prefixes = EXTRACT_32BITS(&llsap->llsa_nprefix);
655 ND_PRINT((ndo, "\n\t Priority %d, Link-local address %s, Prefixes %d:",
656 llsap->llsa_priority,
657 ip6addr_string(ndo, &llsap->llsa_lladdr),
658 prefixes));
659
660 tptr = (const uint8_t *)llsap->llsa_prefix;
661 while (prefixes > 0) {
662 bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length);
663 if (bytelen < 0)
664 goto trunc;
665 prefixes--;
666 lsa_length -= bytelen;
667 tptr += bytelen;
668 }
669 break;
670
671 case LS_TYPE_INTRA_AP | LS_SCOPE_AREA:
672 /* Intra-Area-Prefix LSA */
673 if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid))
674 return (1);
675 lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid);
676 ND_TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_rtid);
677 ospf6_print_ls_type(ndo,
678 EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_lstype),
679 &lsap->lsa_un.un_intra_ap.intra_ap_lsid);
680
681 if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix))
682 return (1);
683 lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix);
684 ND_TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_nprefix);
685 prefixes = EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_nprefix);
686 ND_PRINT((ndo, "\n\t Prefixes %d:", prefixes));
687
688 tptr = (const uint8_t *)lsap->lsa_un.un_intra_ap.intra_ap_prefix;
689 while (prefixes > 0) {
690 bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length);
691 if (bytelen < 0)
692 goto trunc;
693 prefixes--;
694 lsa_length -= bytelen;
695 tptr += bytelen;
696 }
697 break;
698
699 case LS_TYPE_GRACE | LS_SCOPE_LINKLOCAL:
700 if (ospf_print_grace_lsa(ndo, tptr, lsa_length) == -1) {
701 return 1;
702 }
703 break;
704
705 case LS_TYPE_INTRA_ATE | LS_SCOPE_LINKLOCAL:
706 if (ospf_print_te_lsa(ndo, tptr, lsa_length) == -1) {
707 return 1;
708 }
709 break;
710
711 default:
712 if(!print_unknown_data(ndo,tptr,
713 "\n\t ",
714 lsa_length)) {
715 return (1);
716 }
717 break;
718 }
719
720 return (0);
721 trunc:
722 return (1);
723 }
724
725 static int
726 ospf6_decode_v3(netdissect_options *ndo,
727 register const struct ospf6hdr *op,
728 register const u_char *dataend)
729 {
730 register const rtrid_t *ap;
731 register const struct lsr6 *lsrp;
732 register const struct lsa6_hdr *lshp;
733 register const struct lsa6 *lsap;
734 register int i;
735
736 switch (op->ospf6_type) {
737
738 case OSPF_TYPE_HELLO: {
739 register const struct hello6 *hellop = (const struct hello6 *)((const uint8_t *)op + OSPF6HDR_LEN);
740
741 ND_PRINT((ndo, "\n\tOptions [%s]",
742 bittok2str(ospf6_option_values, "none",
743 EXTRACT_32BITS(&hellop->hello_options))));
744
745 ND_TCHECK(hellop->hello_deadint);
746 ND_PRINT((ndo, "\n\t Hello Timer %us, Dead Timer %us, Interface-ID %s, Priority %u",
747 EXTRACT_16BITS(&hellop->hello_helloint),
748 EXTRACT_16BITS(&hellop->hello_deadint),
749 ipaddr_string(ndo, &hellop->hello_ifid),
750 hellop->hello_priority));
751
752 ND_TCHECK(hellop->hello_dr);
753 if (EXTRACT_32BITS(&hellop->hello_dr) != 0)
754 ND_PRINT((ndo, "\n\t Designated Router %s",
755 ipaddr_string(ndo, &hellop->hello_dr)));
756 ND_TCHECK(hellop->hello_bdr);
757 if (EXTRACT_32BITS(&hellop->hello_bdr) != 0)
758 ND_PRINT((ndo, ", Backup Designated Router %s",
759 ipaddr_string(ndo, &hellop->hello_bdr)));
760 if (ndo->ndo_vflag > 1) {
761 ND_PRINT((ndo, "\n\t Neighbor List:"));
762 ap = hellop->hello_neighbor;
763 while ((const u_char *)ap < dataend) {
764 ND_TCHECK(*ap);
765 ND_PRINT((ndo, "\n\t %s", ipaddr_string(ndo, ap)));
766 ++ap;
767 }
768 }
769 break; /* HELLO */
770 }
771
772 case OSPF_TYPE_DD: {
773 register const struct dd6 *ddp = (const struct dd6 *)((const uint8_t *)op + OSPF6HDR_LEN);
774
775 ND_TCHECK(ddp->db_options);
776 ND_PRINT((ndo, "\n\tOptions [%s]",
777 bittok2str(ospf6_option_values, "none",
778 EXTRACT_32BITS(&ddp->db_options))));
779 ND_TCHECK(ddp->db_flags);
780 ND_PRINT((ndo, ", DD Flags [%s]",
781 bittok2str(ospf6_dd_flag_values,"none",ddp->db_flags)));
782
783 ND_TCHECK(ddp->db_seq);
784 ND_PRINT((ndo, ", MTU %u, DD-Sequence 0x%08x",
785 EXTRACT_16BITS(&ddp->db_mtu),
786 EXTRACT_32BITS(&ddp->db_seq)));
787 if (ndo->ndo_vflag > 1) {
788 /* Print all the LS adv's */
789 lshp = ddp->db_lshdr;
790 while ((const u_char *)lshp < dataend) {
791 if (ospf6_print_lshdr(ndo, lshp++, dataend))
792 goto trunc;
793 }
794 }
795 break;
796 }
797
798 case OSPF_TYPE_LS_REQ:
799 if (ndo->ndo_vflag > 1) {
800 lsrp = (const struct lsr6 *)((const uint8_t *)op + OSPF6HDR_LEN);
801 while ((const u_char *)lsrp < dataend) {
802 ND_TCHECK(*lsrp);
803 ND_PRINT((ndo, "\n\t Advertising Router %s",
804 ipaddr_string(ndo, &lsrp->ls_router)));
805 ospf6_print_ls_type(ndo, EXTRACT_16BITS(&lsrp->ls_type),
806 &lsrp->ls_stateid);
807 ++lsrp;
808 }
809 }
810 break;
811
812 case OSPF_TYPE_LS_UPDATE:
813 if (ndo->ndo_vflag > 1) {
814 register const struct lsu6 *lsup = (const struct lsu6 *)((const uint8_t *)op + OSPF6HDR_LEN);
815
816 ND_TCHECK(lsup->lsu_count);
817 i = EXTRACT_32BITS(&lsup->lsu_count);
818 lsap = lsup->lsu_lsa;
819 while ((const u_char *)lsap < dataend && i--) {
820 if (ospf6_print_lsa(ndo, lsap, dataend))
821 goto trunc;
822 lsap = (const struct lsa6 *)((const u_char *)lsap +
823 EXTRACT_16BITS(&lsap->ls_hdr.ls_length));
824 }
825 }
826 break;
827
828 case OSPF_TYPE_LS_ACK:
829 if (ndo->ndo_vflag > 1) {
830 lshp = (const struct lsa6_hdr *)((const uint8_t *)op + OSPF6HDR_LEN);
831 while ((const u_char *)lshp < dataend) {
832 if (ospf6_print_lshdr(ndo, lshp++, dataend))
833 goto trunc;
834 }
835 }
836 break;
837
838 default:
839 break;
840 }
841 return (0);
842 trunc:
843 return (1);
844 }
845
846 /* RFC5613 Section 2.2 (w/o the TLVs) */
847 static int
848 ospf6_print_lls(netdissect_options *ndo,
849 const u_char *cp, const u_int len)
850 {
851 uint16_t llsdatalen;
852
853 if (len == 0)
854 return 0;
855 if (len < OSPF_LLS_HDRLEN)
856 goto trunc;
857 /* Checksum */
858 ND_TCHECK2(*cp, 2);
859 ND_PRINT((ndo, "\n\tLLS Checksum 0x%04x", EXTRACT_16BITS(cp)));
860 cp += 2;
861 /* LLS Data Length */
862 ND_TCHECK2(*cp, 2);
863 llsdatalen = EXTRACT_16BITS(cp);
864 ND_PRINT((ndo, ", Data Length %u", llsdatalen));
865 if (llsdatalen < OSPF_LLS_HDRLEN || llsdatalen > len)
866 goto trunc;
867 cp += 2;
868 /* LLS TLVs */
869 ND_TCHECK2(*cp, llsdatalen - OSPF_LLS_HDRLEN);
870 /* FIXME: code in print-ospf.c can be reused to decode the TLVs */
871
872 return llsdatalen;
873 trunc:
874 return -1;
875 }
876
877 /* RFC6506 Section 4.1 */
878 static int
879 ospf6_decode_at(netdissect_options *ndo,
880 const u_char *cp, const u_int len)
881 {
882 uint16_t authdatalen;
883
884 if (len == 0)
885 return 0;
886 if (len < OSPF6_AT_HDRLEN)
887 goto trunc;
888 /* Authentication Type */
889 ND_TCHECK2(*cp, 2);
890 ND_PRINT((ndo, "\n\tAuthentication Type %s", tok2str(ospf6_auth_type_str, "unknown (0x%04x)", EXTRACT_16BITS(cp))));
891 cp += 2;
892 /* Auth Data Len */
893 ND_TCHECK2(*cp, 2);
894 authdatalen = EXTRACT_16BITS(cp);
895 ND_PRINT((ndo, ", Length %u", authdatalen));
896 if (authdatalen < OSPF6_AT_HDRLEN || authdatalen > len)
897 goto trunc;
898 cp += 2;
899 /* Reserved */
900 ND_TCHECK2(*cp, 2);
901 cp += 2;
902 /* Security Association ID */
903 ND_TCHECK2(*cp, 2);
904 ND_PRINT((ndo, ", SAID %u", EXTRACT_16BITS(cp)));
905 cp += 2;
906 /* Cryptographic Sequence Number (High-Order 32 Bits) */
907 ND_TCHECK2(*cp, 4);
908 ND_PRINT((ndo, ", CSN 0x%08x", EXTRACT_32BITS(cp)));
909 cp += 4;
910 /* Cryptographic Sequence Number (Low-Order 32 Bits) */
911 ND_TCHECK2(*cp, 4);
912 ND_PRINT((ndo, ":%08x", EXTRACT_32BITS(cp)));
913 cp += 4;
914 /* Authentication Data */
915 ND_TCHECK2(*cp, authdatalen - OSPF6_AT_HDRLEN);
916 if (ndo->ndo_vflag > 1)
917 print_unknown_data(ndo,cp, "\n\tAuthentication Data ", authdatalen - OSPF6_AT_HDRLEN);
918 return 0;
919
920 trunc:
921 return 1;
922 }
923
924 /* The trailing data may include LLS and/or AT data (in this specific order).
925 * LLS data may be present only in Hello and DBDesc packets with the L-bit set.
926 * AT data may be present in Hello and DBDesc packets with the AT-bit set or in
927 * any other packet type, thus decode the AT data regardless of the AT-bit.
928 */
929 static int
930 ospf6_decode_v3_trailer(netdissect_options *ndo,
931 const struct ospf6hdr *op, const u_char *cp, const unsigned len)
932 {
933 int llslen = 0;
934 int lls_hello = 0;
935 int lls_dd = 0;
936
937 if (op->ospf6_type == OSPF_TYPE_HELLO) {
938 const struct hello6 *hellop = (const struct hello6 *)((const uint8_t *)op + OSPF6HDR_LEN);
939 if (EXTRACT_32BITS(&hellop->hello_options) & OSPF6_OPTION_L)
940 lls_hello = 1;
941 } else if (op->ospf6_type == OSPF_TYPE_DD) {
942 const struct dd6 *ddp = (const struct dd6 *)((const uint8_t *)op + OSPF6HDR_LEN);
943 if (EXTRACT_32BITS(&ddp->db_options) & OSPF6_OPTION_L)
944 lls_dd = 1;
945 }
946 if ((lls_hello || lls_dd) && (llslen = ospf6_print_lls(ndo, cp, len)) < 0)
947 goto trunc;
948 return ospf6_decode_at(ndo, cp + llslen, len - llslen);
949
950 trunc:
951 return 1;
952 }
953
954 void
955 ospf6_print(netdissect_options *ndo,
956 register const u_char *bp, register u_int length)
957 {
958 register const struct ospf6hdr *op;
959 register const u_char *dataend;
960 register const char *cp;
961 uint16_t datalen;
962
963 op = (const struct ospf6hdr *)bp;
964
965 /* If the type is valid translate it, or just print the type */
966 /* value. If it's not valid, say so and return */
967 ND_TCHECK(op->ospf6_type);
968 cp = tok2str(ospf6_type_values, "unknown packet type (%u)", op->ospf6_type);
969 ND_PRINT((ndo, "OSPFv%u, %s, length %d", op->ospf6_version, cp, length));
970 if (*cp == 'u') {
971 return;
972 }
973
974 if(!ndo->ndo_vflag) { /* non verbose - so lets bail out here */
975 return;
976 }
977
978 /* OSPFv3 data always comes first and optional trailing data may follow. */
979 ND_TCHECK(op->ospf6_len);
980 datalen = EXTRACT_16BITS(&op->ospf6_len);
981 if (datalen > length) {
982 ND_PRINT((ndo, " [len %d]", datalen));
983 return;
984 }
985 dataend = bp + datalen;
986
987 ND_TCHECK(op->ospf6_routerid);
988 ND_PRINT((ndo, "\n\tRouter-ID %s", ipaddr_string(ndo, &op->ospf6_routerid)));
989
990 ND_TCHECK(op->ospf6_areaid);
991 if (EXTRACT_32BITS(&op->ospf6_areaid) != 0)
992 ND_PRINT((ndo, ", Area %s", ipaddr_string(ndo, &op->ospf6_areaid)));
993 else
994 ND_PRINT((ndo, ", Backbone Area"));
995 ND_TCHECK(op->ospf6_instanceid);
996 if (op->ospf6_instanceid)
997 ND_PRINT((ndo, ", Instance %u", op->ospf6_instanceid));
998
999 /* Do rest according to version. */
1000 switch (op->ospf6_version) {
1001
1002 case 3:
1003 /* ospf version 3 */
1004 if (ospf6_decode_v3(ndo, op, dataend) ||
1005 ospf6_decode_v3_trailer(ndo, op, dataend, length - datalen))
1006 goto trunc;
1007 break;
1008 } /* end switch on version */
1009
1010 return;
1011 trunc:
1012 ND_PRINT((ndo, "%s", tstr));
1013 }
1014