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
, "Multicast Group" },
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" },
100 static const struct tok ospf6_ls_scope_values
[] = {
101 { LS_SCOPE_LINKLOCAL
, "Link Local" },
102 { LS_SCOPE_AREA
, "Area Local" },
103 { LS_SCOPE_AS
, "Domain Wide" },
107 static const struct tok ospf6_dd_flag_values
[] = {
108 { OSPF6_DB_INIT
, "Init" },
109 { OSPF6_DB_MORE
, "More" },
110 { OSPF6_DB_MASTER
, "Master" },
114 static const struct tok ospf6_lsa_prefix_option_values
[] = {
115 { LSA_PREFIX_OPT_NU
, "No Unicast" },
116 { LSA_PREFIX_OPT_LA
, "Local address" },
117 { LSA_PREFIX_OPT_MC
, "Multicast" },
118 { LSA_PREFIX_OPT_P
, "Propagate" },
119 { LSA_PREFIX_OPT_DN
, "Down" },
124 static void ospf6_print_ls_type(u_int
, const rtrid_t
*);
125 static int ospf6_print_lshdr(const struct lsa6_hdr
*);
126 static int ospf6_print_lsa(const struct lsa6
*);
127 static int ospf6_decode_v3(const struct ospf6hdr
*, const u_char
*);
131 ospf6_print_ls_type(register u_int ls_type
, register const rtrid_t
*ls_stateid
)
133 printf("\n\t %s LSA (%d), %s Scope%s, LSA-ID %s",
134 tok2str(ospf6_lsa_values
, "Unknown", ls_type
& LS_TYPE_MASK
),
135 ls_type
& LS_TYPE_MASK
,
136 tok2str(ospf6_ls_scope_values
, "Unknown", ls_type
& LS_SCOPE_MASK
),
137 ls_type
&0x8000 ? ", transitive" : "", /* U-bit */
138 ipaddr_string(ls_stateid
));
142 ospf6_print_lshdr(register const struct lsa6_hdr
*lshp
)
145 TCHECK(lshp
->ls_type
);
146 TCHECK(lshp
->ls_seq
);
148 printf("\n\t Advertising Router %s, seq 0x%08x, age %us, length %u",
149 ipaddr_string(&lshp
->ls_router
),
150 EXTRACT_32BITS(&lshp
->ls_seq
),
151 EXTRACT_16BITS(&lshp
->ls_age
),
152 EXTRACT_16BITS(&lshp
->ls_length
)-(u_int
)sizeof(struct lsa6_hdr
));
154 ospf6_print_ls_type(EXTRACT_16BITS(&lshp
->ls_type
), &lshp
->ls_stateid
);
162 ospf6_print_lsaprefix(const u_int8_t
*tptr
, u_int lsa_length
)
164 const struct lsa6_prefix
*lsapp
= (struct lsa6_prefix
*)tptr
;
166 struct in6_addr prefix
;
168 if (lsa_length
< sizeof (*lsapp
) - 4)
170 lsa_length
-= sizeof (*lsapp
) - 4;
171 TCHECK2(*lsapp
, sizeof (*lsapp
) - 4);
172 wordlen
= (lsapp
->lsa_p_len
+ 31) / 32;
173 if (wordlen
* 4 > sizeof(struct in6_addr
)) {
174 printf(" bogus prefixlen /%d", lsapp
->lsa_p_len
);
177 if (lsa_length
< wordlen
* 4)
179 lsa_length
-= wordlen
* 4;
180 TCHECK2(lsapp
->lsa_p_prefix
, wordlen
* 4);
181 memset(&prefix
, 0, sizeof(prefix
));
182 memcpy(&prefix
, lsapp
->lsa_p_prefix
, wordlen
* 4);
183 printf("\n\t\t%s/%d", ip6addr_string(&prefix
),
185 if (lsapp
->lsa_p_opt
) {
186 printf(", Options [%s]",
187 bittok2str(ospf6_lsa_prefix_option_values
,
188 "none", lsapp
->lsa_p_opt
));
190 printf(", metric %u", EXTRACT_16BITS(&lsapp
->lsa_p_metric
));
191 return sizeof(*lsapp
) - 4 + wordlen
* 4;
199 * Print a single link state advertisement. If truncated return 1, else 0.
202 ospf6_print_lsa(register const struct lsa6
*lsap
)
204 register const struct rlalink6
*rlp
;
206 register const struct tos_metric
*tosp
;
208 register const rtrid_t
*ap
;
210 register const struct aslametric
*almp
;
211 register const struct mcla
*mcp
;
213 register const struct llsa
*llsap
;
214 register const struct lsa6_prefix
*lsapp
;
216 register const u_int32_t
*lp
;
218 register u_int prefixes
;
219 register int bytelen
;
220 register u_int length
, lsa_length
;
222 const u_int8_t
*tptr
;
224 if (ospf6_print_lshdr(&lsap
->ls_hdr
))
226 TCHECK(lsap
->ls_hdr
.ls_length
);
227 length
= EXTRACT_16BITS(&lsap
->ls_hdr
.ls_length
);
230 * The LSA length includes the length of the header;
231 * it must have a value that's at least that length.
232 * If it does, find the length of what follows the
235 if (length
< sizeof(struct lsa6_hdr
))
237 lsa_length
= length
- sizeof(struct lsa6_hdr
);
238 tptr
= (u_int8_t
*)lsap
+sizeof(struct lsa6_hdr
);
240 switch (EXTRACT_16BITS(&lsap
->ls_hdr
.ls_type
)) {
241 case LS_TYPE_ROUTER
| LS_SCOPE_AREA
:
242 if (lsa_length
< sizeof (lsap
->lsa_un
.un_rla
.rla_options
))
244 lsa_length
-= sizeof (lsap
->lsa_un
.un_rla
.rla_options
);
245 TCHECK(lsap
->lsa_un
.un_rla
.rla_options
);
246 printf("\n\t Options [%s]",
247 bittok2str(ospf6_option_values
, "none",
248 EXTRACT_32BITS(&lsap
->lsa_un
.un_rla
.rla_options
)));
249 printf(", RLA-Flags [%s]",
250 bittok2str(ospf6_rla_flag_values
, "none",
251 lsap
->lsa_un
.un_rla
.rla_flags
));
253 rlp
= lsap
->lsa_un
.un_rla
.rla_link
;
254 while (lsa_length
!= 0) {
255 if (lsa_length
< sizeof (*rlp
))
257 lsa_length
-= sizeof (*rlp
);
259 switch (rlp
->link_type
) {
261 case RLA_TYPE_VIRTUAL
:
262 printf("\n\t Virtual Link: Neighbor Router-ID %s"
263 "\n\t Neighbor Interface-ID %s, Interface %s",
264 ipaddr_string(&rlp
->link_nrtid
),
265 ipaddr_string(&rlp
->link_nifid
),
266 ipaddr_string(&rlp
->link_ifid
));
269 case RLA_TYPE_ROUTER
:
270 printf("\n\t Neighbor Router-ID %s"
271 "\n\t Neighbor Interface-ID %s, Interface %s",
272 ipaddr_string(&rlp
->link_nrtid
),
273 ipaddr_string(&rlp
->link_nifid
),
274 ipaddr_string(&rlp
->link_ifid
));
277 case RLA_TYPE_TRANSIT
:
278 printf("\n\t Neighbor Network-ID %s"
279 "\n\t Neighbor Interface-ID %s, Interface %s",
280 ipaddr_string(&rlp
->link_nrtid
),
281 ipaddr_string(&rlp
->link_nifid
),
282 ipaddr_string(&rlp
->link_ifid
));
286 printf("\n\t Unknown Router Links Type 0x%02x",
290 printf(", metric %d", EXTRACT_16BITS(&rlp
->link_metric
));
295 case LS_TYPE_NETWORK
| LS_SCOPE_AREA
:
296 if (lsa_length
< sizeof (lsap
->lsa_un
.un_nla
.nla_options
))
298 lsa_length
-= sizeof (lsap
->lsa_un
.un_nla
.nla_options
);
299 TCHECK(lsap
->lsa_un
.un_nla
.nla_options
);
300 printf("\n\t Options [%s]",
301 bittok2str(ospf6_option_values
, "none",
302 EXTRACT_32BITS(&lsap
->lsa_un
.un_nla
.nla_options
)));
304 printf("\n\t Connected Routers:");
305 ap
= lsap
->lsa_un
.un_nla
.nla_router
;
306 while (lsa_length
!= 0) {
307 if (lsa_length
< sizeof (*ap
))
309 lsa_length
-= sizeof (*ap
);
311 printf("\n\t\t%s", ipaddr_string(ap
));
316 case LS_TYPE_INTER_AP
| LS_SCOPE_AREA
:
317 if (lsa_length
< sizeof (lsap
->lsa_un
.un_inter_ap
.inter_ap_metric
))
319 lsa_length
-= sizeof (lsap
->lsa_un
.un_inter_ap
.inter_ap_metric
);
320 TCHECK(lsap
->lsa_un
.un_inter_ap
.inter_ap_metric
);
321 printf(", metric %u",
322 EXTRACT_32BITS(&lsap
->lsa_un
.un_inter_ap
.inter_ap_metric
) & SLA_MASK_METRIC
);
324 tptr
= (u_int8_t
*)lsap
->lsa_un
.un_inter_ap
.inter_ap_prefix
;
325 while (lsa_length
!= 0) {
326 bytelen
= ospf6_print_lsaprefix(tptr
, lsa_length
);
329 lsa_length
-= bytelen
;
334 case LS_TYPE_ASE
| LS_SCOPE_AS
:
335 if (lsa_length
< sizeof (lsap
->lsa_un
.un_asla
.asla_metric
))
337 lsa_length
-= sizeof (lsap
->lsa_un
.un_asla
.asla_metric
);
338 TCHECK(lsap
->lsa_un
.un_asla
.asla_metric
);
339 flags32
= EXTRACT_32BITS(&lsap
->lsa_un
.un_asla
.asla_metric
);
340 printf("\n\t Flags [%s]",
341 bittok2str(ospf6_asla_flag_values
, "none", flags32
));
343 EXTRACT_32BITS(&lsap
->lsa_un
.un_asla
.asla_metric
) &
346 tptr
= (u_int8_t
*)lsap
->lsa_un
.un_asla
.asla_prefix
;
347 lsapp
= (struct lsa6_prefix
*)tptr
;
348 bytelen
= ospf6_print_lsaprefix(tptr
, lsa_length
);
351 lsa_length
-= bytelen
;
354 if ((flags32
& ASLA_FLAG_FWDADDR
) != 0) {
355 struct in6_addr
*fwdaddr6
;
357 fwdaddr6
= (struct in6_addr
*)tptr
;
358 if (lsa_length
< sizeof (*fwdaddr6
))
360 lsa_length
-= sizeof (*fwdaddr6
);
362 printf(" forward %s",
363 ip6addr_string(fwdaddr6
));
364 tptr
+= sizeof(*fwdaddr6
);
367 if ((flags32
& ASLA_FLAG_ROUTETAG
) != 0) {
368 if (lsa_length
< sizeof (u_int32_t
))
370 lsa_length
-= sizeof (u_int32_t
);
371 TCHECK(*(u_int32_t
*)tptr
);
373 ipaddr_string((u_int32_t
*)tptr
));
374 tptr
+= sizeof(u_int32_t
);
377 if (lsapp
->lsa_p_metric
) {
378 if (lsa_length
< sizeof (u_int32_t
))
380 lsa_length
-= sizeof (u_int32_t
);
381 TCHECK(*(u_int32_t
*)tptr
);
382 printf(" RefLSID: %s",
383 ipaddr_string((u_int32_t
*)tptr
));
384 tptr
+= sizeof(u_int32_t
);
390 llsap
= &lsap
->lsa_un
.un_llsa
;
391 if (lsa_length
< sizeof (llsap
->llsa_priandopt
))
393 lsa_length
-= sizeof (llsap
->llsa_priandopt
);
394 TCHECK(llsap
->llsa_priandopt
);
395 printf("\n\t Options [%s]",
396 bittok2str(ospf6_option_values
, "none",
397 EXTRACT_32BITS(&llsap
->llsa_options
)));
399 if (lsa_length
< sizeof (llsap
->llsa_lladdr
) + sizeof (llsap
->llsa_nprefix
))
401 lsa_length
-= sizeof (llsap
->llsa_lladdr
) + sizeof (llsap
->llsa_nprefix
);
402 prefixes
= EXTRACT_32BITS(&llsap
->llsa_nprefix
);
403 printf("\n\t Priority %d, Link-local address %s, Prefixes %d:",
404 llsap
->llsa_priority
,
405 ip6addr_string(&llsap
->llsa_lladdr
),
408 tptr
= (u_int8_t
*)llsap
->llsa_prefix
;
409 while (prefixes
> 0) {
410 bytelen
= ospf6_print_lsaprefix(tptr
, lsa_length
);
414 lsa_length
-= bytelen
;
419 case LS_TYPE_INTRA_AP
| LS_SCOPE_AREA
:
420 /* Intra-Area-Prefix LSA */
421 if (lsa_length
< sizeof (lsap
->lsa_un
.un_intra_ap
.intra_ap_rtid
))
423 lsa_length
-= sizeof (lsap
->lsa_un
.un_intra_ap
.intra_ap_rtid
);
424 TCHECK(lsap
->lsa_un
.un_intra_ap
.intra_ap_rtid
);
426 EXTRACT_16BITS(&lsap
->lsa_un
.un_intra_ap
.intra_ap_lstype
),
427 &lsap
->lsa_un
.un_intra_ap
.intra_ap_lsid
);
429 if (lsa_length
< sizeof (lsap
->lsa_un
.un_intra_ap
.intra_ap_nprefix
))
431 lsa_length
-= sizeof (lsap
->lsa_un
.un_intra_ap
.intra_ap_nprefix
);
432 TCHECK(lsap
->lsa_un
.un_intra_ap
.intra_ap_nprefix
);
433 prefixes
= EXTRACT_16BITS(&lsap
->lsa_un
.un_intra_ap
.intra_ap_nprefix
);
434 printf("\n\t Prefixes %d:", prefixes
);
436 tptr
= (u_int8_t
*)lsap
->lsa_un
.un_intra_ap
.intra_ap_prefix
;
437 while (prefixes
> 0) {
438 bytelen
= ospf6_print_lsaprefix(tptr
, lsa_length
);
442 lsa_length
-= bytelen
;
447 case LS_TYPE_GRACE
| LS_SCOPE_LINKLOCAL
:
448 if (ospf_print_grace_lsa(tptr
, lsa_length
) == -1) {
453 case LS_TYPE_INTRA_ATE
| LS_SCOPE_LINKLOCAL
:
454 if (ospf_print_te_lsa(tptr
, lsa_length
) == -1) {
460 if(!print_unknown_data(tptr
,
474 ospf6_decode_v3(register const struct ospf6hdr
*op
,
475 register const u_char
*dataend
)
477 register const rtrid_t
*ap
;
478 register const struct lsr6
*lsrp
;
479 register const struct lsa6_hdr
*lshp
;
480 register const struct lsa6
*lsap
;
483 switch (op
->ospf6_type
) {
485 case OSPF_TYPE_HELLO
:
486 printf("\n\tOptions [%s]",
487 bittok2str(ospf6_option_values
, "none",
488 EXTRACT_32BITS(&op
->ospf6_hello
.hello_options
)));
490 TCHECK(op
->ospf6_hello
.hello_deadint
);
491 printf("\n\t Hello Timer %us, Dead Timer %us, Interface-ID %s, Priority %u",
492 EXTRACT_16BITS(&op
->ospf6_hello
.hello_helloint
),
493 EXTRACT_16BITS(&op
->ospf6_hello
.hello_deadint
),
494 ipaddr_string(&op
->ospf6_hello
.hello_ifid
),
495 op
->ospf6_hello
.hello_priority
);
497 TCHECK(op
->ospf6_hello
.hello_dr
);
498 if (op
->ospf6_hello
.hello_dr
!= 0)
499 printf("\n\t Designated Router %s",
500 ipaddr_string(&op
->ospf6_hello
.hello_dr
));
501 TCHECK(op
->ospf6_hello
.hello_bdr
);
502 if (op
->ospf6_hello
.hello_bdr
!= 0)
503 printf(", Backup Designated Router %s",
504 ipaddr_string(&op
->ospf6_hello
.hello_bdr
));
506 printf("\n\t Neighbor List:");
507 ap
= op
->ospf6_hello
.hello_neighbor
;
508 while ((u_char
*)ap
< dataend
) {
510 printf("\n\t %s", ipaddr_string(ap
));
517 TCHECK(op
->ospf6_db
.db_options
);
518 printf("\n\tOptions [%s]",
519 bittok2str(ospf6_option_values
, "none",
520 EXTRACT_32BITS(&op
->ospf6_db
.db_options
)));
521 TCHECK(op
->ospf6_db
.db_flags
);
522 printf(", DD Flags [%s]",
523 bittok2str(ospf6_dd_flag_values
,"none",op
->ospf6_db
.db_flags
));
525 TCHECK(op
->ospf6_db
.db_seq
);
526 printf(", MTU %u, DD-Sequence 0x%08x",
527 EXTRACT_16BITS(&op
->ospf6_db
.db_mtu
),
528 EXTRACT_32BITS(&op
->ospf6_db
.db_seq
));
530 /* Print all the LS adv's */
531 lshp
= op
->ospf6_db
.db_lshdr
;
532 while (!ospf6_print_lshdr(lshp
)) {
537 case OSPF_TYPE_LS_REQ
:
539 lsrp
= op
->ospf6_lsr
;
540 while ((u_char
*)lsrp
< dataend
) {
542 printf("\n\t Advertising Router %s",
543 ipaddr_string(&lsrp
->ls_router
));
544 ospf6_print_ls_type(EXTRACT_16BITS(&lsrp
->ls_type
),
551 case OSPF_TYPE_LS_UPDATE
:
553 lsap
= op
->ospf6_lsu
.lsu_lsa
;
554 TCHECK(op
->ospf6_lsu
.lsu_count
);
555 i
= EXTRACT_32BITS(&op
->ospf6_lsu
.lsu_count
);
557 if (ospf6_print_lsa(lsap
))
559 lsap
= (struct lsa6
*)((u_char
*)lsap
+
560 EXTRACT_16BITS(&lsap
->ls_hdr
.ls_length
));
566 case OSPF_TYPE_LS_ACK
:
568 lshp
= op
->ospf6_lsa
.lsa_lshdr
;
570 while (!ospf6_print_lshdr(lshp
)) {
585 ospf6_print(register const u_char
*bp
, register u_int length
)
587 register const struct ospf6hdr
*op
;
588 register const u_char
*dataend
;
589 register const char *cp
;
591 op
= (struct ospf6hdr
*)bp
;
593 /* If the type is valid translate it, or just print the type */
594 /* value. If it's not valid, say so and return */
595 TCHECK(op
->ospf6_type
);
596 cp
= tok2str(ospf6_type_values
, "unknown LS-type", op
->ospf6_type
);
597 printf("OSPFv%u, %s, length %d", op
->ospf6_version
, cp
, length
);
602 if(!vflag
) { /* non verbose - so lets bail out here */
606 TCHECK(op
->ospf6_len
);
607 if (length
!= EXTRACT_16BITS(&op
->ospf6_len
)) {
608 printf(" [len %d]", EXTRACT_16BITS(&op
->ospf6_len
));
611 dataend
= bp
+ length
;
613 /* Print the routerid if it is not the same as the source */
614 TCHECK(op
->ospf6_routerid
);
615 printf("\n\tRouter-ID %s", ipaddr_string(&op
->ospf6_routerid
));
617 TCHECK(op
->ospf6_areaid
);
618 if (op
->ospf6_areaid
!= 0)
619 printf(", Area %s", ipaddr_string(&op
->ospf6_areaid
));
621 printf(", Backbone Area");
622 TCHECK(op
->ospf6_instanceid
);
623 if (op
->ospf6_instanceid
)
624 printf(", Instance %u", op
->ospf6_instanceid
);
626 /* Do rest according to version. */
627 switch (op
->ospf6_version
) {
631 if (ospf6_decode_v3(op
, dataend
))
636 printf(" ospf [version %d]", op
->ospf6_version
);
638 } /* end switch on version */