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 struct tok ospf6_option_values
[] = {
46 { OSPF6_OPTION_V6
, "V6" },
47 { OSPF6_OPTION_E
, "External" },
48 { OSPF6_OPTION_MC
, "Multicast" },
49 { OSPF6_OPTION_N
, "NSSA" },
50 { OSPF6_OPTION_R
, "Router" },
51 { OSPF6_OPTION_DC
, "Demand Circuit" },
55 static const struct tok ospf6_rla_flag_values
[] = {
56 { RLA_FLAG_B
, "ABR" },
57 { RLA_FLAG_E
, "External" },
58 { RLA_FLAG_V
, "Virtual-Link Endpoint" },
59 { RLA_FLAG_W
, "Wildcard Receiver" },
60 { RLA_FLAG_N
, "NSSA Translator" },
64 static const struct tok ospf6_asla_flag_values
[] = {
65 { ASLA_FLAG_EXTERNAL
, "External Type 2" },
66 { ASLA_FLAG_FWDADDR
, "Fforwarding" },
67 { ASLA_FLAG_ROUTETAG
, "Tag" },
71 static struct tok ospf6_type_values
[] = {
72 { OSPF_TYPE_HELLO
, "Hello" },
73 { OSPF_TYPE_DD
, "Database Description" },
74 { OSPF_TYPE_LS_REQ
, "LS-Request" },
75 { OSPF_TYPE_LS_UPDATE
, "LS-Update" },
76 { OSPF_TYPE_LS_ACK
, "LS-Ack" },
80 static struct tok ospf6_lsa_values
[] = {
81 { LS_TYPE_ROUTER
, "Router" },
82 { LS_TYPE_NETWORK
, "Network" },
83 { LS_TYPE_INTER_AP
, "Inter-Area Prefix" },
84 { LS_TYPE_INTER_AR
, "Inter-Area Router" },
85 { LS_TYPE_ASE
, "External" },
86 { LS_TYPE_GROUP
, "Multicast Group" },
87 { LS_TYPE_NSSA
, "NSSA" },
88 { LS_TYPE_LINK
, "Link" },
89 { LS_TYPE_INTRA_AP
, "Intra-Area Prefix" },
90 { LS_TYPE_INTRA_ATE
, "Intra-Area TE" },
91 { LS_TYPE_GRACE
, "Grace" },
95 static struct tok ospf6_ls_scope_values
[] = {
96 { LS_SCOPE_LINKLOCAL
, "Link Local" },
97 { LS_SCOPE_AREA
, "Area Local" },
98 { LS_SCOPE_AS
, "Domain Wide" },
102 static struct tok ospf6_dd_flag_values
[] = {
103 { OSPF6_DB_INIT
, "Init" },
104 { OSPF6_DB_MORE
, "More" },
105 { OSPF6_DB_MASTER
, "Master" },
109 static struct tok ospf6_lsa_prefix_option_values
[] = {
110 { LSA_PREFIX_OPT_NU
, "No Unicast" },
111 { LSA_PREFIX_OPT_LA
, "Local address" },
112 { LSA_PREFIX_OPT_MC
, "Multicast" },
113 { LSA_PREFIX_OPT_P
, "Propagate" },
114 { LSA_PREFIX_OPT_DN
, "Down" },
118 static char tstr
[] = " [|ospf3]";
121 #define inline __inline
125 static void ospf6_print_ls_type(u_int
, const rtrid_t
*);
126 static int ospf6_print_lshdr(const struct lsa6_hdr
*);
127 static int ospf6_print_lsa(const struct lsa6
*);
128 static int ospf6_decode_v3(const struct ospf6hdr
*, const u_char
*);
132 ospf6_print_ls_type(register u_int ls_type
, register const rtrid_t
*ls_stateid
)
134 printf("\n\t %s LSA (%d), %s Scope%s, LSA-ID %s",
135 tok2str(ospf6_lsa_values
, "Unknown", ls_type
& LS_TYPE_MASK
),
136 ls_type
& LS_TYPE_MASK
,
137 tok2str(ospf6_ls_scope_values
, "Unknown", ls_type
& LS_SCOPE_MASK
),
138 ls_type
&0x8000 ? ", transitive" : "", /* U-bit */
139 ipaddr_string(ls_stateid
));
143 ospf6_print_lshdr(register const struct lsa6_hdr
*lshp
)
146 TCHECK(lshp
->ls_type
);
147 TCHECK(lshp
->ls_seq
);
149 printf("\n\t Advertising Router %s, seq 0x%08x, age %us, length %u",
150 ipaddr_string(&lshp
->ls_router
),
151 EXTRACT_32BITS(&lshp
->ls_seq
),
152 EXTRACT_16BITS(&lshp
->ls_age
),
153 EXTRACT_16BITS(&lshp
->ls_length
)-(u_int
)sizeof(struct lsa6_hdr
));
155 ospf6_print_ls_type(EXTRACT_16BITS(&lshp
->ls_type
), &lshp
->ls_stateid
);
163 ospf6_print_lsaprefix(register const struct lsa6_prefix
*lsapp
)
166 struct in6_addr prefix
;
169 wordlen
= (lsapp
->lsa_p_len
+ 31) / 32;
170 if (wordlen
* 4 > sizeof(struct in6_addr
)) {
171 printf(" bogus prefixlen /%d", lsapp
->lsa_p_len
);
174 memset(&prefix
, 0, sizeof(prefix
));
175 memcpy(&prefix
, lsapp
->lsa_p_prefix
, wordlen
* 4);
176 printf("\n\t\t%s/%d", ip6addr_string(&prefix
),
178 if (lsapp
->lsa_p_opt
) {
179 printf(", Options [%s]",
180 bittok2str(ospf6_lsa_prefix_option_values
,
181 "none", lsapp
->lsa_p_opt
));
183 printf(", metric %u", EXTRACT_16BITS(&lsapp
->lsa_p_metric
));
184 return sizeof(*lsapp
) - 4 + wordlen
* 4;
192 * Print a single link state advertisement. If truncated return 1, else 0.
195 ospf6_print_lsa(register const struct lsa6
*lsap
)
197 register const u_char
*ls_end
, *ls_opt
;
198 register const struct rlalink6
*rlp
;
200 register const struct tos_metric
*tosp
;
202 register const rtrid_t
*ap
;
204 register const struct aslametric
*almp
;
205 register const struct mcla
*mcp
;
207 register const struct llsa
*llsap
;
208 register const struct lsa6_prefix
*lsapp
;
210 register const u_int32_t
*lp
;
212 register u_int prefixes
;
213 register int bytelen
, length
, lsa_length
;
217 if (ospf6_print_lshdr(&lsap
->ls_hdr
))
219 TCHECK(lsap
->ls_hdr
.ls_length
);
220 length
= EXTRACT_16BITS(&lsap
->ls_hdr
.ls_length
);
221 lsa_length
= length
- sizeof(struct lsa6_hdr
);
222 ls_end
= (u_char
*)lsap
+ length
;
223 tptr
= (u_int8_t
*)lsap
+sizeof(struct lsa6_hdr
);
225 switch (EXTRACT_16BITS(&lsap
->ls_hdr
.ls_type
)) {
226 case LS_TYPE_ROUTER
| LS_SCOPE_AREA
:
227 TCHECK(lsap
->lsa_un
.un_rla
.rla_options
);
228 printf("\n\t Options [%s]",
229 bittok2str(ospf6_option_values
, "none",
230 EXTRACT_32BITS(&lsap
->lsa_un
.un_rla
.rla_options
)));
232 TCHECK(lsap
->lsa_un
.un_rla
.rla_flags
);
233 printf(", RLA-Flags [%s]",
234 bittok2str(ospf6_rla_flag_values
, "none",
235 lsap
->lsa_un
.un_rla
.rla_flags
));
238 TCHECK(lsap
->lsa_un
.un_rla
.rla_link
);
239 rlp
= lsap
->lsa_un
.un_rla
.rla_link
;
240 while (rlp
+ 1 <= (struct rlalink6
*)ls_end
) {
242 switch (rlp
->link_type
) {
244 case RLA_TYPE_VIRTUAL
:
245 printf("\n\t Virtual Link: Neighbor Router-ID %s"
246 "\n\t Neighbor Interface-ID %s, Interface %s",
247 ipaddr_string(&rlp
->link_nrtid
),
248 ipaddr_string(&rlp
->link_nifid
),
249 ipaddr_string(&rlp
->link_ifid
));
252 case RLA_TYPE_ROUTER
:
253 printf("\n\t Neighbor Router-ID %s"
254 "\n\t Neighbor Interface-ID %s, Interface %s",
255 ipaddr_string(&rlp
->link_nrtid
),
256 ipaddr_string(&rlp
->link_nifid
),
257 ipaddr_string(&rlp
->link_ifid
));
260 case RLA_TYPE_TRANSIT
:
261 printf("\n\t Neighbor Network-ID %s"
262 "\n\t Neighbor Interface-ID %s, Interface %s",
263 ipaddr_string(&rlp
->link_nrtid
),
264 ipaddr_string(&rlp
->link_nifid
),
265 ipaddr_string(&rlp
->link_ifid
));
269 printf("\n\t Unknown Router Links Type 0x%02x",
273 printf(", metric %d", EXTRACT_16BITS(&rlp
->link_metric
));
278 case LS_TYPE_NETWORK
| LS_SCOPE_AREA
:
279 TCHECK(lsap
->lsa_un
.un_nla
.nla_options
);
280 printf("\n\t Options [%s]",
281 bittok2str(ospf6_option_values
, "none",
282 EXTRACT_32BITS(&lsap
->lsa_un
.un_nla
.nla_options
)));
283 printf("\n\t Connected Routers:");
284 ap
= lsap
->lsa_un
.un_nla
.nla_router
;
285 while ((u_char
*)ap
< ls_end
) {
287 printf("\n\t\t%s", ipaddr_string(ap
));
292 case LS_TYPE_INTER_AP
| LS_SCOPE_AREA
:
293 TCHECK(lsap
->lsa_un
.un_inter_ap
.inter_ap_metric
);
294 printf(", metric %u",
295 EXTRACT_32BITS(&lsap
->lsa_un
.un_inter_ap
.inter_ap_metric
) & SLA_MASK_METRIC
);
296 lsapp
= lsap
->lsa_un
.un_inter_ap
.inter_ap_prefix
;
297 while (lsapp
+ 1 <= (struct lsa6_prefix
*)ls_end
) {
298 bytelen
= ospf6_print_lsaprefix(lsapp
);
301 lsapp
= (struct lsa6_prefix
*)(((u_char
*)lsapp
) + bytelen
);
304 case LS_SCOPE_AS
| LS_TYPE_ASE
:
305 TCHECK(lsap
->lsa_un
.un_asla
.asla_metric
);
306 flags32
= EXTRACT_32BITS(&lsap
->lsa_un
.un_asla
.asla_metric
);
307 printf("\n\t Flags [%s]",
308 bittok2str(ospf6_asla_flag_values
, "none", flags32
));
310 EXTRACT_32BITS(&lsap
->lsa_un
.un_asla
.asla_metric
) &
312 lsapp
= lsap
->lsa_un
.un_asla
.asla_prefix
;
313 bytelen
= ospf6_print_lsaprefix(lsapp
);
316 if ((ls_opt
= (u_char
*)(((u_char
*)lsapp
) + bytelen
)) < ls_end
) {
317 struct in6_addr
*fwdaddr6
;
319 if ((flags32
& ASLA_FLAG_FWDADDR
) != 0) {
320 fwdaddr6
= (struct in6_addr
*)ls_opt
;
322 printf(" forward %s",
323 ip6addr_string(fwdaddr6
));
325 ls_opt
+= sizeof(struct in6_addr
);
328 if ((flags32
& ASLA_FLAG_ROUTETAG
) != 0) {
329 TCHECK(*(u_int32_t
*)ls_opt
);
331 ipaddr_string((u_int32_t
*)ls_opt
));
333 ls_opt
+= sizeof(u_int32_t
);
336 if (lsapp
->lsa_p_metric
) {
337 TCHECK(*(u_int32_t
*)ls_opt
);
338 printf(" RefLSID: %s",
339 ipaddr_string((u_int32_t
*)ls_opt
));
341 ls_opt
+= sizeof(u_int32_t
);
348 llsap
= &lsap
->lsa_un
.un_llsa
;
349 TCHECK(llsap
->llsa_options
);
350 printf("\n\t Options [%s]",
351 bittok2str(ospf6_option_values
, "none",
352 EXTRACT_32BITS(&llsap
->llsa_options
)));
353 TCHECK(llsap
->llsa_nprefix
);
354 prefixes
= EXTRACT_32BITS(&llsap
->llsa_nprefix
);
355 printf("\n\t Priority %d, Link-local address %s, Prefixes %d:",
356 llsap
->llsa_priority
,
357 ip6addr_string(&llsap
->llsa_lladdr
),
360 tptr
= (u_int8_t
*)llsap
->llsa_prefix
;
361 while (prefixes
> 0) {
362 lsapp
= (struct lsa6_prefix
*)tptr
;
363 if ((bytelen
= ospf6_print_lsaprefix(lsapp
)) == -1) {
371 case LS_TYPE_INTRA_AP
| LS_SCOPE_AREA
:
372 /* Intra-Area-Prefix LSA */
373 TCHECK(lsap
->lsa_un
.un_intra_ap
.intra_ap_rtid
);
375 EXTRACT_16BITS(&lsap
->lsa_un
.un_intra_ap
.intra_ap_lstype
),
376 &lsap
->lsa_un
.un_intra_ap
.intra_ap_lsid
);
377 TCHECK(lsap
->lsa_un
.un_intra_ap
.intra_ap_nprefix
);
378 prefixes
= EXTRACT_16BITS(&lsap
->lsa_un
.un_intra_ap
.intra_ap_nprefix
);
379 printf("\n\t Prefixes %d:", prefixes
);
381 tptr
= (u_int8_t
*)lsap
->lsa_un
.un_intra_ap
.intra_ap_prefix
;
383 while (prefixes
> 0) {
384 lsapp
= (struct lsa6_prefix
*)tptr
;
385 if ((bytelen
= ospf6_print_lsaprefix(lsapp
)) == -1) {
393 case LS_TYPE_GRACE
| LS_SCOPE_LINKLOCAL
:
394 if (ospf_print_grace_lsa(tptr
, lsa_length
) == -1) {
400 case LS_TYPE_INTRA_ATE
| LS_SCOPE_LINKLOCAL
:
401 if (ospf_print_te_lsa(tptr
, lsa_length
) == -1) {
407 if(!print_unknown_data(tptr
,
420 ospf6_decode_v3(register const struct ospf6hdr
*op
,
421 register const u_char
*dataend
)
423 register const rtrid_t
*ap
;
424 register const struct lsr6
*lsrp
;
425 register const struct lsa6_hdr
*lshp
;
426 register const struct lsa6
*lsap
;
429 switch (op
->ospf6_type
) {
431 case OSPF_TYPE_HELLO
:
432 printf("\n\tOptions [%s]",
433 bittok2str(ospf6_option_values
, "none",
434 EXTRACT_32BITS(&op
->ospf6_hello
.hello_options
)));
436 TCHECK(op
->ospf6_hello
.hello_deadint
);
437 printf("\n\t Hello Timer %us, Dead Timer %us, Interface-ID %s, Priority %u",
438 EXTRACT_16BITS(&op
->ospf6_hello
.hello_helloint
),
439 EXTRACT_16BITS(&op
->ospf6_hello
.hello_deadint
),
440 ipaddr_string(&op
->ospf6_hello
.hello_ifid
),
441 op
->ospf6_hello
.hello_priority
);
443 TCHECK(op
->ospf6_hello
.hello_dr
);
444 if (op
->ospf6_hello
.hello_dr
!= 0)
445 printf("\n\t Designated Router %s",
446 ipaddr_string(&op
->ospf6_hello
.hello_dr
));
447 TCHECK(op
->ospf6_hello
.hello_bdr
);
448 if (op
->ospf6_hello
.hello_bdr
!= 0)
449 printf(", Backup Designated Router %s",
450 ipaddr_string(&op
->ospf6_hello
.hello_bdr
));
452 printf("\n\t Neighbor List:");
453 ap
= op
->ospf6_hello
.hello_neighbor
;
454 while ((u_char
*)ap
< dataend
) {
456 printf("\n\t %s", ipaddr_string(ap
));
463 TCHECK(op
->ospf6_db
.db_options
);
464 printf("\n\tOptions [%s]",
465 bittok2str(ospf6_option_values
, "none",
466 EXTRACT_32BITS(&op
->ospf6_db
.db_options
)));
467 TCHECK(op
->ospf6_db
.db_flags
);
468 printf(", DD Flags [%s]",
469 bittok2str(ospf6_dd_flag_values
,"none",op
->ospf6_db
.db_flags
));
471 TCHECK(op
->ospf6_db
.db_seq
);
472 printf(", MTU %u, DD-Sequence 0x%08x",
473 EXTRACT_16BITS(&op
->ospf6_db
.db_mtu
),
474 EXTRACT_32BITS(&op
->ospf6_db
.db_seq
));
476 /* Print all the LS adv's */
477 lshp
= op
->ospf6_db
.db_lshdr
;
478 while (!ospf6_print_lshdr(lshp
)) {
483 case OSPF_TYPE_LS_REQ
:
485 lsrp
= op
->ospf6_lsr
;
486 while ((u_char
*)lsrp
< dataend
) {
488 printf("\n\t Advertising Router %s",
489 ipaddr_string(&lsrp
->ls_router
));
490 ospf6_print_ls_type(EXTRACT_16BITS(&lsrp
->ls_type
),
497 case OSPF_TYPE_LS_UPDATE
:
499 lsap
= op
->ospf6_lsu
.lsu_lsa
;
500 TCHECK(op
->ospf6_lsu
.lsu_count
);
501 i
= EXTRACT_32BITS(&op
->ospf6_lsu
.lsu_count
);
503 if (ospf6_print_lsa(lsap
))
505 lsap
= (struct lsa6
*)((u_char
*)lsap
+
506 EXTRACT_16BITS(&lsap
->ls_hdr
.ls_length
));
512 case OSPF_TYPE_LS_ACK
:
514 lshp
= op
->ospf6_lsa
.lsa_lshdr
;
516 while (!ospf6_print_lshdr(lshp
)) {
531 ospf6_print(register const u_char
*bp
, register u_int length
)
533 register const struct ospf6hdr
*op
;
534 register const u_char
*dataend
;
535 register const char *cp
;
537 op
= (struct ospf6hdr
*)bp
;
539 /* If the type is valid translate it, or just print the type */
540 /* value. If it's not valid, say so and return */
541 TCHECK(op
->ospf6_type
);
542 cp
= tok2str(ospf6_type_values
, "unknown LS-type", op
->ospf6_type
);
543 printf("OSPFv%u, %s, length %d", op
->ospf6_version
, cp
, length
);
548 if(!vflag
) { /* non verbose - so lets bail out here */
552 TCHECK(op
->ospf6_len
);
553 if (length
!= EXTRACT_16BITS(&op
->ospf6_len
)) {
554 printf(" [len %d]", EXTRACT_16BITS(&op
->ospf6_len
));
557 dataend
= bp
+ length
;
559 /* Print the routerid if it is not the same as the source */
560 TCHECK(op
->ospf6_routerid
);
561 printf("\n\tRouter-ID %s", ipaddr_string(&op
->ospf6_routerid
));
563 TCHECK(op
->ospf6_areaid
);
564 if (op
->ospf6_areaid
!= 0)
565 printf(", Area %s", ipaddr_string(&op
->ospf6_areaid
));
567 printf(", Backbone Area");
568 TCHECK(op
->ospf6_instanceid
);
569 if (op
->ospf6_instanceid
)
570 printf(", Instance %u", op
->ospf6_instanceid
);
572 /* Do rest according to version. */
573 switch (op
->ospf6_version
) {
577 if (ospf6_decode_v3(op
, dataend
))
582 printf(" ospf [version %d]", op
->ospf6_version
);
584 } /* end switch on version */