2 * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997
3 * The Regents of the University of California. All rights reserved.
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
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.
21 * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu)
25 static const char rcsid
[] _U_
=
26 "@(#) $Header: /tcpdump/master/tcpdump/print-ospf6.c,v 1.15 2006-09-13 06:31:11 guy Exp $ (LBL)";
33 #include <tcpdump-stdinc.h>
38 #include "interface.h"
39 #include "addrtoname.h"
45 static const char tstr
[] = " [|ospf3]";
47 static const struct tok ospf6_option_values
[] = {
48 { OSPF6_OPTION_V6
, "V6" },
49 { OSPF6_OPTION_E
, "External" },
50 { OSPF6_OPTION_MC
, "Deprecated" },
51 { OSPF6_OPTION_N
, "NSSA" },
52 { OSPF6_OPTION_R
, "Router" },
53 { OSPF6_OPTION_DC
, "Demand Circuit" },
54 { OSPF6_OPTION_AF
, "AFs Support" },
55 { OSPF6_OPTION_L
, "LLS" },
56 { OSPF6_OPTION_AT
, "Authentication Trailer" },
60 static const struct tok ospf6_rla_flag_values
[] = {
61 { RLA_FLAG_B
, "ABR" },
62 { RLA_FLAG_E
, "External" },
63 { RLA_FLAG_V
, "Virtual-Link Endpoint" },
64 { RLA_FLAG_W
, "Wildcard Receiver" },
65 { RLA_FLAG_N
, "NSSA Translator" },
69 static const struct tok ospf6_asla_flag_values
[] = {
70 { ASLA_FLAG_EXTERNAL
, "External Type 2" },
71 { ASLA_FLAG_FWDADDR
, "Forwarding" },
72 { ASLA_FLAG_ROUTETAG
, "Tag" },
76 static const struct tok ospf6_type_values
[] = {
77 { OSPF_TYPE_HELLO
, "Hello" },
78 { OSPF_TYPE_DD
, "Database Description" },
79 { OSPF_TYPE_LS_REQ
, "LS-Request" },
80 { OSPF_TYPE_LS_UPDATE
, "LS-Update" },
81 { OSPF_TYPE_LS_ACK
, "LS-Ack" },
85 static const struct tok ospf6_lsa_values
[] = {
86 { LS_TYPE_ROUTER
, "Router" },
87 { LS_TYPE_NETWORK
, "Network" },
88 { LS_TYPE_INTER_AP
, "Inter-Area Prefix" },
89 { LS_TYPE_INTER_AR
, "Inter-Area Router" },
90 { LS_TYPE_ASE
, "External" },
91 { LS_TYPE_GROUP
, "Deprecated" },
92 { LS_TYPE_NSSA
, "NSSA" },
93 { LS_TYPE_LINK
, "Link" },
94 { LS_TYPE_INTRA_AP
, "Intra-Area Prefix" },
95 { LS_TYPE_INTRA_ATE
, "Intra-Area TE" },
96 { LS_TYPE_GRACE
, "Grace" },
97 { LS_TYPE_RI
, "Router Information" },
98 { LS_TYPE_INTER_ASTE
, "Inter-AS-TE" },
99 { LS_TYPE_L1VPN
, "Layer 1 VPN" },
103 static const struct tok ospf6_ls_scope_values
[] = {
104 { LS_SCOPE_LINKLOCAL
, "Link Local" },
105 { LS_SCOPE_AREA
, "Area Local" },
106 { LS_SCOPE_AS
, "Domain Wide" },
110 static const struct tok ospf6_dd_flag_values
[] = {
111 { OSPF6_DB_INIT
, "Init" },
112 { OSPF6_DB_MORE
, "More" },
113 { OSPF6_DB_MASTER
, "Master" },
114 { OSPF6_DB_M6
, "IPv6 MTU" },
118 static const struct tok ospf6_lsa_prefix_option_values
[] = {
119 { LSA_PREFIX_OPT_NU
, "No Unicast" },
120 { LSA_PREFIX_OPT_LA
, "Local address" },
121 { LSA_PREFIX_OPT_MC
, "Deprecated" },
122 { LSA_PREFIX_OPT_P
, "Propagate" },
123 { LSA_PREFIX_OPT_DN
, "Down" },
129 ospf6_print_ls_type(register u_int ls_type
, register const rtrid_t
*ls_stateid
)
131 printf("\n\t %s LSA (%d), %s Scope%s, LSA-ID %s",
132 tok2str(ospf6_lsa_values
, "Unknown", ls_type
& LS_TYPE_MASK
),
133 ls_type
& LS_TYPE_MASK
,
134 tok2str(ospf6_ls_scope_values
, "Unknown", ls_type
& LS_SCOPE_MASK
),
135 ls_type
&0x8000 ? ", transitive" : "", /* U-bit */
136 ipaddr_string(ls_stateid
));
140 ospf6_print_lshdr(register const struct lsa6_hdr
*lshp
)
143 TCHECK(lshp
->ls_type
);
144 TCHECK(lshp
->ls_seq
);
146 printf("\n\t Advertising Router %s, seq 0x%08x, age %us, length %u",
147 ipaddr_string(&lshp
->ls_router
),
148 EXTRACT_32BITS(&lshp
->ls_seq
),
149 EXTRACT_16BITS(&lshp
->ls_age
),
150 EXTRACT_16BITS(&lshp
->ls_length
)-(u_int
)sizeof(struct lsa6_hdr
));
152 ospf6_print_ls_type(EXTRACT_16BITS(&lshp
->ls_type
), &lshp
->ls_stateid
);
160 ospf6_print_lsaprefix(const u_int8_t
*tptr
, u_int lsa_length
)
162 const struct lsa6_prefix
*lsapp
= (struct lsa6_prefix
*)tptr
;
164 struct in6_addr prefix
;
166 if (lsa_length
< sizeof (*lsapp
) - 4)
168 lsa_length
-= sizeof (*lsapp
) - 4;
169 TCHECK2(*lsapp
, sizeof (*lsapp
) - 4);
170 wordlen
= (lsapp
->lsa_p_len
+ 31) / 32;
171 if (wordlen
* 4 > sizeof(struct in6_addr
)) {
172 printf(" bogus prefixlen /%d", lsapp
->lsa_p_len
);
175 if (lsa_length
< wordlen
* 4)
177 lsa_length
-= wordlen
* 4;
178 TCHECK2(lsapp
->lsa_p_prefix
, wordlen
* 4);
179 memset(&prefix
, 0, sizeof(prefix
));
180 memcpy(&prefix
, lsapp
->lsa_p_prefix
, wordlen
* 4);
181 printf("\n\t\t%s/%d", ip6addr_string(&prefix
),
183 if (lsapp
->lsa_p_opt
) {
184 printf(", Options [%s]",
185 bittok2str(ospf6_lsa_prefix_option_values
,
186 "none", lsapp
->lsa_p_opt
));
188 printf(", metric %u", EXTRACT_16BITS(&lsapp
->lsa_p_metric
));
189 return sizeof(*lsapp
) - 4 + wordlen
* 4;
197 * Print a single link state advertisement. If truncated return 1, else 0.
200 ospf6_print_lsa(register const struct lsa6
*lsap
)
202 register const struct rlalink6
*rlp
;
204 register const struct tos_metric
*tosp
;
206 register const rtrid_t
*ap
;
208 register const struct aslametric
*almp
;
209 register const struct mcla
*mcp
;
211 register const struct llsa
*llsap
;
212 register const struct lsa6_prefix
*lsapp
;
214 register const u_int32_t
*lp
;
216 register u_int prefixes
;
217 register int bytelen
;
218 register u_int length
, lsa_length
;
220 const u_int8_t
*tptr
;
222 if (ospf6_print_lshdr(&lsap
->ls_hdr
))
224 TCHECK(lsap
->ls_hdr
.ls_length
);
225 length
= EXTRACT_16BITS(&lsap
->ls_hdr
.ls_length
);
228 * The LSA length includes the length of the header;
229 * it must have a value that's at least that length.
230 * If it does, find the length of what follows the
233 if (length
< sizeof(struct lsa6_hdr
))
235 lsa_length
= length
- sizeof(struct lsa6_hdr
);
236 tptr
= (u_int8_t
*)lsap
+sizeof(struct lsa6_hdr
);
238 switch (EXTRACT_16BITS(&lsap
->ls_hdr
.ls_type
)) {
239 case LS_TYPE_ROUTER
| LS_SCOPE_AREA
:
240 if (lsa_length
< sizeof (lsap
->lsa_un
.un_rla
.rla_options
))
242 lsa_length
-= sizeof (lsap
->lsa_un
.un_rla
.rla_options
);
243 TCHECK(lsap
->lsa_un
.un_rla
.rla_options
);
244 printf("\n\t Options [%s]",
245 bittok2str(ospf6_option_values
, "none",
246 EXTRACT_32BITS(&lsap
->lsa_un
.un_rla
.rla_options
)));
247 printf(", RLA-Flags [%s]",
248 bittok2str(ospf6_rla_flag_values
, "none",
249 lsap
->lsa_un
.un_rla
.rla_flags
));
251 rlp
= lsap
->lsa_un
.un_rla
.rla_link
;
252 while (lsa_length
!= 0) {
253 if (lsa_length
< sizeof (*rlp
))
255 lsa_length
-= sizeof (*rlp
);
257 switch (rlp
->link_type
) {
259 case RLA_TYPE_VIRTUAL
:
260 printf("\n\t Virtual Link: Neighbor Router-ID %s"
261 "\n\t Neighbor Interface-ID %s, Interface %s",
262 ipaddr_string(&rlp
->link_nrtid
),
263 ipaddr_string(&rlp
->link_nifid
),
264 ipaddr_string(&rlp
->link_ifid
));
267 case RLA_TYPE_ROUTER
:
268 printf("\n\t Neighbor Router-ID %s"
269 "\n\t Neighbor Interface-ID %s, Interface %s",
270 ipaddr_string(&rlp
->link_nrtid
),
271 ipaddr_string(&rlp
->link_nifid
),
272 ipaddr_string(&rlp
->link_ifid
));
275 case RLA_TYPE_TRANSIT
:
276 printf("\n\t Neighbor Network-ID %s"
277 "\n\t Neighbor Interface-ID %s, Interface %s",
278 ipaddr_string(&rlp
->link_nrtid
),
279 ipaddr_string(&rlp
->link_nifid
),
280 ipaddr_string(&rlp
->link_ifid
));
284 printf("\n\t Unknown Router Links Type 0x%02x",
288 printf(", metric %d", EXTRACT_16BITS(&rlp
->link_metric
));
293 case LS_TYPE_NETWORK
| LS_SCOPE_AREA
:
294 if (lsa_length
< sizeof (lsap
->lsa_un
.un_nla
.nla_options
))
296 lsa_length
-= sizeof (lsap
->lsa_un
.un_nla
.nla_options
);
297 TCHECK(lsap
->lsa_un
.un_nla
.nla_options
);
298 printf("\n\t Options [%s]",
299 bittok2str(ospf6_option_values
, "none",
300 EXTRACT_32BITS(&lsap
->lsa_un
.un_nla
.nla_options
)));
302 printf("\n\t Connected Routers:");
303 ap
= lsap
->lsa_un
.un_nla
.nla_router
;
304 while (lsa_length
!= 0) {
305 if (lsa_length
< sizeof (*ap
))
307 lsa_length
-= sizeof (*ap
);
309 printf("\n\t\t%s", ipaddr_string(ap
));
314 case LS_TYPE_INTER_AP
| LS_SCOPE_AREA
:
315 if (lsa_length
< sizeof (lsap
->lsa_un
.un_inter_ap
.inter_ap_metric
))
317 lsa_length
-= sizeof (lsap
->lsa_un
.un_inter_ap
.inter_ap_metric
);
318 TCHECK(lsap
->lsa_un
.un_inter_ap
.inter_ap_metric
);
319 printf(", metric %u",
320 EXTRACT_32BITS(&lsap
->lsa_un
.un_inter_ap
.inter_ap_metric
) & SLA_MASK_METRIC
);
322 tptr
= (u_int8_t
*)lsap
->lsa_un
.un_inter_ap
.inter_ap_prefix
;
323 while (lsa_length
!= 0) {
324 bytelen
= ospf6_print_lsaprefix(tptr
, lsa_length
);
327 lsa_length
-= bytelen
;
332 case LS_TYPE_ASE
| LS_SCOPE_AS
:
333 if (lsa_length
< sizeof (lsap
->lsa_un
.un_asla
.asla_metric
))
335 lsa_length
-= sizeof (lsap
->lsa_un
.un_asla
.asla_metric
);
336 TCHECK(lsap
->lsa_un
.un_asla
.asla_metric
);
337 flags32
= EXTRACT_32BITS(&lsap
->lsa_un
.un_asla
.asla_metric
);
338 printf("\n\t Flags [%s]",
339 bittok2str(ospf6_asla_flag_values
, "none", flags32
));
341 EXTRACT_32BITS(&lsap
->lsa_un
.un_asla
.asla_metric
) &
344 tptr
= (u_int8_t
*)lsap
->lsa_un
.un_asla
.asla_prefix
;
345 lsapp
= (struct lsa6_prefix
*)tptr
;
346 bytelen
= ospf6_print_lsaprefix(tptr
, lsa_length
);
349 lsa_length
-= bytelen
;
352 if ((flags32
& ASLA_FLAG_FWDADDR
) != 0) {
353 struct in6_addr
*fwdaddr6
;
355 fwdaddr6
= (struct in6_addr
*)tptr
;
356 if (lsa_length
< sizeof (*fwdaddr6
))
358 lsa_length
-= sizeof (*fwdaddr6
);
360 printf(" forward %s",
361 ip6addr_string(fwdaddr6
));
362 tptr
+= sizeof(*fwdaddr6
);
365 if ((flags32
& ASLA_FLAG_ROUTETAG
) != 0) {
366 if (lsa_length
< sizeof (u_int32_t
))
368 lsa_length
-= sizeof (u_int32_t
);
369 TCHECK(*(u_int32_t
*)tptr
);
371 ipaddr_string((u_int32_t
*)tptr
));
372 tptr
+= sizeof(u_int32_t
);
375 if (lsapp
->lsa_p_metric
) {
376 if (lsa_length
< sizeof (u_int32_t
))
378 lsa_length
-= sizeof (u_int32_t
);
379 TCHECK(*(u_int32_t
*)tptr
);
380 printf(" RefLSID: %s",
381 ipaddr_string((u_int32_t
*)tptr
));
382 tptr
+= sizeof(u_int32_t
);
388 llsap
= &lsap
->lsa_un
.un_llsa
;
389 if (lsa_length
< sizeof (llsap
->llsa_priandopt
))
391 lsa_length
-= sizeof (llsap
->llsa_priandopt
);
392 TCHECK(llsap
->llsa_priandopt
);
393 printf("\n\t Options [%s]",
394 bittok2str(ospf6_option_values
, "none",
395 EXTRACT_32BITS(&llsap
->llsa_options
)));
397 if (lsa_length
< sizeof (llsap
->llsa_lladdr
) + sizeof (llsap
->llsa_nprefix
))
399 lsa_length
-= sizeof (llsap
->llsa_lladdr
) + sizeof (llsap
->llsa_nprefix
);
400 prefixes
= EXTRACT_32BITS(&llsap
->llsa_nprefix
);
401 printf("\n\t Priority %d, Link-local address %s, Prefixes %d:",
402 llsap
->llsa_priority
,
403 ip6addr_string(&llsap
->llsa_lladdr
),
406 tptr
= (u_int8_t
*)llsap
->llsa_prefix
;
407 while (prefixes
> 0) {
408 bytelen
= ospf6_print_lsaprefix(tptr
, lsa_length
);
412 lsa_length
-= bytelen
;
417 case LS_TYPE_INTRA_AP
| LS_SCOPE_AREA
:
418 /* Intra-Area-Prefix LSA */
419 if (lsa_length
< sizeof (lsap
->lsa_un
.un_intra_ap
.intra_ap_rtid
))
421 lsa_length
-= sizeof (lsap
->lsa_un
.un_intra_ap
.intra_ap_rtid
);
422 TCHECK(lsap
->lsa_un
.un_intra_ap
.intra_ap_rtid
);
424 EXTRACT_16BITS(&lsap
->lsa_un
.un_intra_ap
.intra_ap_lstype
),
425 &lsap
->lsa_un
.un_intra_ap
.intra_ap_lsid
);
427 if (lsa_length
< sizeof (lsap
->lsa_un
.un_intra_ap
.intra_ap_nprefix
))
429 lsa_length
-= sizeof (lsap
->lsa_un
.un_intra_ap
.intra_ap_nprefix
);
430 TCHECK(lsap
->lsa_un
.un_intra_ap
.intra_ap_nprefix
);
431 prefixes
= EXTRACT_16BITS(&lsap
->lsa_un
.un_intra_ap
.intra_ap_nprefix
);
432 printf("\n\t Prefixes %d:", prefixes
);
434 tptr
= (u_int8_t
*)lsap
->lsa_un
.un_intra_ap
.intra_ap_prefix
;
435 while (prefixes
> 0) {
436 bytelen
= ospf6_print_lsaprefix(tptr
, lsa_length
);
440 lsa_length
-= bytelen
;
445 case LS_TYPE_GRACE
| LS_SCOPE_LINKLOCAL
:
446 if (ospf_print_grace_lsa(tptr
, lsa_length
) == -1) {
451 case LS_TYPE_INTRA_ATE
| LS_SCOPE_LINKLOCAL
:
452 if (ospf_print_te_lsa(tptr
, lsa_length
) == -1) {
458 if(!print_unknown_data(tptr
,
472 ospf6_decode_v3(register const struct ospf6hdr
*op
,
473 register const u_char
*dataend
)
475 register const rtrid_t
*ap
;
476 register const struct lsr6
*lsrp
;
477 register const struct lsa6_hdr
*lshp
;
478 register const struct lsa6
*lsap
;
481 switch (op
->ospf6_type
) {
483 case OSPF_TYPE_HELLO
:
484 printf("\n\tOptions [%s]",
485 bittok2str(ospf6_option_values
, "none",
486 EXTRACT_32BITS(&op
->ospf6_hello
.hello_options
)));
488 TCHECK(op
->ospf6_hello
.hello_deadint
);
489 printf("\n\t Hello Timer %us, Dead Timer %us, Interface-ID %s, Priority %u",
490 EXTRACT_16BITS(&op
->ospf6_hello
.hello_helloint
),
491 EXTRACT_16BITS(&op
->ospf6_hello
.hello_deadint
),
492 ipaddr_string(&op
->ospf6_hello
.hello_ifid
),
493 op
->ospf6_hello
.hello_priority
);
495 TCHECK(op
->ospf6_hello
.hello_dr
);
496 if (op
->ospf6_hello
.hello_dr
!= 0)
497 printf("\n\t Designated Router %s",
498 ipaddr_string(&op
->ospf6_hello
.hello_dr
));
499 TCHECK(op
->ospf6_hello
.hello_bdr
);
500 if (op
->ospf6_hello
.hello_bdr
!= 0)
501 printf(", Backup Designated Router %s",
502 ipaddr_string(&op
->ospf6_hello
.hello_bdr
));
504 printf("\n\t Neighbor List:");
505 ap
= op
->ospf6_hello
.hello_neighbor
;
506 while ((u_char
*)ap
< dataend
) {
508 printf("\n\t %s", ipaddr_string(ap
));
515 TCHECK(op
->ospf6_db
.db_options
);
516 printf("\n\tOptions [%s]",
517 bittok2str(ospf6_option_values
, "none",
518 EXTRACT_32BITS(&op
->ospf6_db
.db_options
)));
519 TCHECK(op
->ospf6_db
.db_flags
);
520 printf(", DD Flags [%s]",
521 bittok2str(ospf6_dd_flag_values
,"none",op
->ospf6_db
.db_flags
));
523 TCHECK(op
->ospf6_db
.db_seq
);
524 printf(", MTU %u, DD-Sequence 0x%08x",
525 EXTRACT_16BITS(&op
->ospf6_db
.db_mtu
),
526 EXTRACT_32BITS(&op
->ospf6_db
.db_seq
));
528 /* Print all the LS adv's */
529 lshp
= op
->ospf6_db
.db_lshdr
;
530 while (!ospf6_print_lshdr(lshp
)) {
536 case OSPF_TYPE_LS_REQ
:
538 lsrp
= op
->ospf6_lsr
;
539 while ((u_char
*)lsrp
< dataend
) {
541 printf("\n\t Advertising Router %s",
542 ipaddr_string(&lsrp
->ls_router
));
543 ospf6_print_ls_type(EXTRACT_16BITS(&lsrp
->ls_type
),
550 case OSPF_TYPE_LS_UPDATE
:
552 lsap
= op
->ospf6_lsu
.lsu_lsa
;
553 TCHECK(op
->ospf6_lsu
.lsu_count
);
554 i
= EXTRACT_32BITS(&op
->ospf6_lsu
.lsu_count
);
556 if (ospf6_print_lsa(lsap
))
558 lsap
= (struct lsa6
*)((u_char
*)lsap
+
559 EXTRACT_16BITS(&lsap
->ls_hdr
.ls_length
));
565 case OSPF_TYPE_LS_ACK
:
567 lshp
= op
->ospf6_lsa
.lsa_lshdr
;
569 while (!ospf6_print_lshdr(lshp
)) {
584 ospf6_print(register const u_char
*bp
, register u_int length
)
586 register const struct ospf6hdr
*op
;
587 register const u_char
*dataend
;
588 register const char *cp
;
590 op
= (struct ospf6hdr
*)bp
;
592 /* If the type is valid translate it, or just print the type */
593 /* value. If it's not valid, say so and return */
594 TCHECK(op
->ospf6_type
);
595 cp
= tok2str(ospf6_type_values
, "unknown packet type (%u)", op
->ospf6_type
);
596 printf("OSPFv%u, %s, length %d", op
->ospf6_version
, cp
, length
);
601 if(!vflag
) { /* non verbose - so lets bail out here */
605 TCHECK(op
->ospf6_len
);
606 if (length
!= EXTRACT_16BITS(&op
->ospf6_len
)) {
607 printf(" [len %d]", EXTRACT_16BITS(&op
->ospf6_len
));
610 dataend
= bp
+ length
;
612 TCHECK(op
->ospf6_routerid
);
613 printf("\n\tRouter-ID %s", ipaddr_string(&op
->ospf6_routerid
));
615 TCHECK(op
->ospf6_areaid
);
616 if (op
->ospf6_areaid
!= 0)
617 printf(", Area %s", ipaddr_string(&op
->ospf6_areaid
));
619 printf(", Backbone Area");
620 TCHECK(op
->ospf6_instanceid
);
621 if (op
->ospf6_instanceid
)
622 printf(", Instance %u", op
->ospf6_instanceid
);
624 /* Do rest according to version. */
625 switch (op
->ospf6_version
) {
629 if (ospf6_decode_v3(op
, dataend
))
632 } /* end switch on version */