]>
The Tcpdump Group git mirrors - tcpdump/blob - print-ospf.c
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
[] =
26 "@(#) $Header: /tcpdump/master/tcpdump/print-ospf.c,v 1.35 2002-12-11 07:14:06 guy Exp $ (LBL)";
33 #include <tcpdump-stdinc.h>
37 #include "interface.h"
38 #include "addrtoname.h"
45 static struct tok ospf_option_values
[] = {
46 { OSPF_OPTION_T
, "TOS" },
47 { OSPF_OPTION_E
, "External" },
48 { OSPF_OPTION_MC
, "Multicast" },
49 { OSPF_OPTION_NP
, "NSSA" },
50 { OSPF_OPTION_EA
, "Advertise External" },
51 { OSPF_OPTION_DC
, "Demand Circuit" },
52 { OSPF_OPTION_O
, "Opaque" },
56 static struct tok ospf_rla_flag_values
[] = {
57 { RLA_FLAG_B
, "ABR" },
58 { RLA_FLAG_E
, "ASBR" },
59 { RLA_FLAG_W1
, "Virtual" },
60 { RLA_FLAG_W2
, "W2" },
64 static struct tok type2str
[] = {
65 { OSPF_TYPE_UMD
, "UMD" },
66 { OSPF_TYPE_HELLO
, "Hello" },
67 { OSPF_TYPE_DD
, "Database Description" },
68 { OSPF_TYPE_LS_REQ
, "LS-Request" },
69 { OSPF_TYPE_LS_UPDATE
, "LS-Update" },
70 { OSPF_TYPE_LS_ACK
, "LS-Ack" },
74 static struct tok lsa_values
[] = {
75 { LS_TYPE_ROUTER
, "Router" },
76 { LS_TYPE_NETWORK
, "Network" },
77 { LS_TYPE_SUM_IP
, "Summary" },
78 { LS_TYPE_SUM_ABR
, "ASBR Summary" },
79 { LS_TYPE_ASE
, "External" },
80 { LS_TYPE_GROUP
, "Multicast Group" },
81 { LS_TYPE_NSSA
, "NSSA" },
82 { LS_TYPE_OPAQUE_LL
, "Link Local Opaque" },
83 { LS_TYPE_OPAQUE_AL
, "Area Local Opaque" },
84 { LS_TYPE_OPAQUE_DW
, "Domain Wide Opaque" },
88 static struct tok ospf_dd_flag_values
[] = {
89 { OSPF_DB_INIT
, "Init" },
90 { OSPF_DB_MORE
, "More" },
91 { OSPF_DB_MASTER
, "Master" },
95 static char tstr
[] = " [|ospf]";
98 #define inline __inline
101 static int ospf_print_lshdr(const struct lsa_hdr
*);
102 static int ospf_print_lsa(const struct lsa
*);
103 static int ospf_decode_v2(const struct ospfhdr
*, const u_char
*);
106 ospf_print_lshdr(register const struct lsa_hdr
*lshp
) {
108 TCHECK(lshp
->ls_type
);
109 TCHECK(lshp
->ls_options
);
111 printf("\n\t %s LSA (%d), LSA-ID: %s, Advertising Router: %s, seq 0x%08x, age %us",
112 tok2str(lsa_values
,"unknown",lshp
->ls_type
),
114 ipaddr_string(&lshp
->ls_stateid
),
115 ipaddr_string(&lshp
->ls_router
),
116 EXTRACT_32BITS(&lshp
->ls_seq
),
117 EXTRACT_16BITS(&lshp
->ls_age
));
118 printf("\n\t Options: %s", bittok2str(ospf_option_values
,"none",lshp
->ls_options
));
126 * Print a single link state advertisement. If truncated return 1, else 0.
129 ospf_print_lsa(register const struct lsa
*lsap
)
131 register const u_char
*ls_end
;
132 register const struct rlalink
*rlp
;
133 register const struct tos_metric
*tosp
;
134 register const struct in_addr
*ap
;
135 register const struct aslametric
*almp
;
136 register const struct mcla
*mcp
;
137 register const u_int32_t
*lp
;
140 printf("\n\t %s LSA (%d), LSA-ID: %s, Advertising Router: %s, seq 0x%08x, age %us",
141 tok2str(lsa_values
,"unknown",lsap
->ls_hdr
.ls_type
),
142 lsap
->ls_hdr
.ls_type
,
143 ipaddr_string(&lsap
->ls_hdr
.ls_stateid
),
144 ipaddr_string(&lsap
->ls_hdr
.ls_router
),
145 EXTRACT_32BITS(&lsap
->ls_hdr
.ls_seq
),
146 EXTRACT_16BITS(&lsap
->ls_hdr
.ls_age
));
147 printf("\n\t Options: %s", bittok2str(ospf_option_values
,"none",lsap
->ls_hdr
.ls_options
));
149 TCHECK(lsap
->ls_hdr
.ls_length
);
150 ls_end
= (u_char
*)lsap
+ EXTRACT_16BITS(&lsap
->ls_hdr
.ls_length
);
151 switch (lsap
->ls_hdr
.ls_type
) {
154 TCHECK(lsap
->lsa_un
.un_rla
.rla_flags
);
155 printf("\n\t Router LSA Options: %s", bittok2str(ospf_rla_flag_values
,"unknown (%u)",lsap
->lsa_un
.un_rla
.rla_flags
));
157 TCHECK(lsap
->lsa_un
.un_rla
.rla_count
);
158 j
= EXTRACT_16BITS(&lsap
->lsa_un
.un_rla
.rla_count
);
159 TCHECK(lsap
->lsa_un
.un_rla
.rla_link
);
160 rlp
= lsap
->lsa_un
.un_rla
.rla_link
;
163 switch (rlp
->link_type
) {
165 case RLA_TYPE_VIRTUAL
:
166 printf("\n\t Virtual Link: Neighbor-Router-ID: %s, Interface-IP: %s",
167 ipaddr_string(&rlp
->link_id
),
168 ipaddr_string(&rlp
->link_data
));
171 case RLA_TYPE_ROUTER
:
172 printf("\n\t Neighbor-Router-ID: %s, Interface-IP: %s",
173 ipaddr_string(&rlp
->link_id
),
174 ipaddr_string(&rlp
->link_data
));
177 case RLA_TYPE_TRANSIT
:
178 printf("\n\t Neighbor-Network-ID: %s, Interface-IP: %s",
179 ipaddr_string(&rlp
->link_id
),
180 ipaddr_string(&rlp
->link_data
));
184 printf("\n\t Stub-Network: %s, mask: %s",
185 ipaddr_string(&rlp
->link_id
),
186 ipaddr_string(&rlp
->link_data
));
190 printf("\n\t unknown Router Links Type (%u)",
194 printf(", tos 0, metric: %d", EXTRACT_16BITS(&rlp
->link_tos0metric
));
195 tosp
= (struct tos_metric
*)
196 ((sizeof rlp
->link_tos0metric
) + (u_char
*) rlp
);
197 for (k
= 0; k
< (int) rlp
->link_toscount
; ++k
, ++tosp
) {
199 printf(", tos %d, metric: %d",
201 EXTRACT_16BITS(&tosp
->tos_metric
));
203 rlp
= (struct rlalink
*)((u_char
*)(rlp
+ 1) +
204 ((rlp
->link_toscount
) * sizeof(*tosp
)));
208 case LS_TYPE_NETWORK
:
209 TCHECK(lsap
->lsa_un
.un_nla
.nla_mask
);
210 printf("\n\t mask %s rtrs",
211 ipaddr_string(&lsap
->lsa_un
.un_nla
.nla_mask
));
212 ap
= lsap
->lsa_un
.un_nla
.nla_router
;
213 while ((u_char
*)ap
< ls_end
) {
215 printf(" %s", ipaddr_string(ap
));
221 TCHECK(lsap
->lsa_un
.un_nla
.nla_mask
);
222 printf("\n\t mask %s",
223 ipaddr_string(&lsap
->lsa_un
.un_sla
.sla_mask
));
224 TCHECK(lsap
->lsa_un
.un_sla
.sla_tosmetric
);
225 lp
= lsap
->lsa_un
.un_sla
.sla_tosmetric
;
226 /* suppress tos if its not supported */
227 if(!((lsap
->ls_hdr
.ls_options
)&OSPF_OPTION_T
)) {
228 printf(", metric: %u", EXTRACT_32BITS(lp
)&SLA_MASK_METRIC
);
231 while ((u_char
*)lp
< ls_end
) {
232 register u_int32_t ul
;
235 ul
= EXTRACT_32BITS(lp
);
236 printf(", tos %d metric %d",
237 (ul
& SLA_MASK_TOS
) >> SLA_SHIFT_TOS
,
238 ul
& SLA_MASK_METRIC
);
243 case LS_TYPE_SUM_ABR
:
244 TCHECK(lsap
->lsa_un
.un_sla
.sla_tosmetric
);
245 lp
= lsap
->lsa_un
.un_sla
.sla_tosmetric
;
246 /* suppress tos if its not supported */
247 if(!((lsap
->ls_hdr
.ls_options
)&OSPF_OPTION_T
)) {
248 printf(", metric: %u", EXTRACT_32BITS(lp
)&SLA_MASK_METRIC
);
251 while ((u_char
*)lp
< ls_end
) {
252 register u_int32_t ul
;
255 ul
= EXTRACT_32BITS(lp
);
256 printf(", tos %d metric %d",
257 (ul
& SLA_MASK_TOS
) >> SLA_SHIFT_TOS
,
258 ul
& SLA_MASK_METRIC
);
264 TCHECK(lsap
->lsa_un
.un_nla
.nla_mask
);
265 printf("\n\t mask %s",
266 ipaddr_string(&lsap
->lsa_un
.un_asla
.asla_mask
));
268 TCHECK(lsap
->lsa_un
.un_sla
.sla_tosmetric
);
269 almp
= lsap
->lsa_un
.un_asla
.asla_metric
;
270 while ((u_char
*)almp
< ls_end
) {
271 register u_int32_t ul
;
273 TCHECK(almp
->asla_tosmetric
);
274 ul
= EXTRACT_32BITS(&almp
->asla_tosmetric
);
275 printf(", type %d, tos %d metric:",
276 (ul
& ASLA_FLAG_EXTERNAL
) ? 2 : 1,
277 (ul
& ASLA_MASK_TOS
) >> ASLA_SHIFT_TOS
);
278 if ((ul
& ASLA_MASK_METRIC
)==0xffffff)
281 printf(" %d", (ul
& ASLA_MASK_METRIC
));
283 TCHECK(almp
->asla_forward
);
284 if (almp
->asla_forward
.s_addr
) {
285 printf(", forward %s",
286 ipaddr_string(&almp
->asla_forward
));
288 TCHECK(almp
->asla_tag
);
289 if (almp
->asla_tag
.s_addr
) {
291 ipaddr_string(&almp
->asla_tag
));
298 /* Multicast extensions as of 23 July 1991 */
299 mcp
= lsap
->lsa_un
.un_mcla
;
300 while ((u_char
*)mcp
< ls_end
) {
301 TCHECK(mcp
->mcla_vid
);
302 switch (EXTRACT_32BITS(&mcp
->mcla_vtype
)) {
304 case MCLA_VERTEX_ROUTER
:
305 printf("\n\t Router Router-ID %s",
306 ipaddr_string(&mcp
->mcla_vid
));
309 case MCLA_VERTEX_NETWORK
:
310 printf("\n\t Network Designated Router %s",
311 ipaddr_string(&mcp
->mcla_vid
));
315 printf("\n\t unknown VertexType (%u)",
316 EXTRACT_32BITS(&mcp
->mcla_vtype
));
329 ospf_decode_v2(register const struct ospfhdr
*op
,
330 register const u_char
*dataend
)
332 register const struct in_addr
*ap
;
333 register const struct lsr
*lsrp
;
334 register const struct lsa_hdr
*lshp
;
335 register const struct lsa
*lsap
;
336 register int lsa_count
;
338 switch (op
->ospf_type
) {
342 * Rob Coltun's special monitoring packets;
347 case OSPF_TYPE_HELLO
:
348 TCHECK(op
->ospf_hello
.hello_deadint
);
349 printf("\n\t Hello Timer: %us, Dead Timer %us, mask: %s, Priority: %u",
350 EXTRACT_16BITS(&op
->ospf_hello
.hello_helloint
),
351 EXTRACT_32BITS(&op
->ospf_hello
.hello_deadint
),
352 ipaddr_string(&op
->ospf_hello
.hello_mask
),
353 op
->ospf_hello
.hello_priority
);
355 printf("\n\t Options: %s",
356 bittok2str(ospf_option_values
,"none",op
->ospf_hello
.hello_options
));
358 TCHECK(op
->ospf_hello
.hello_dr
);
359 if (op
->ospf_hello
.hello_dr
.s_addr
!= 0)
360 printf("\n\t Designated Router %s",
361 ipaddr_string(&op
->ospf_hello
.hello_dr
));
363 TCHECK(op
->ospf_hello
.hello_bdr
);
364 if (op
->ospf_hello
.hello_bdr
.s_addr
!= 0)
365 printf(", Backup Designated Router %s",
366 ipaddr_string(&op
->ospf_hello
.hello_bdr
));
368 ap
= op
->ospf_hello
.hello_neighbor
;
369 if ((u_char
*)ap
< dataend
)
370 printf("\n\t Neighbor List:");
371 while ((u_char
*)ap
< dataend
) {
373 printf("\n\t %s", ipaddr_string(ap
));
379 TCHECK(op
->ospf_db
.db_options
);
380 printf("\n\t Options: %s",
381 bittok2str(ospf_option_values
,"none",op
->ospf_db
.db_options
));
382 TCHECK(op
->ospf_db
.db_flags
);
383 printf("\n\t DD Flags: %s",
384 bittok2str(ospf_dd_flag_values
,"none",op
->ospf_db
.db_flags
));
387 /* Print all the LS adv's */
388 lshp
= op
->ospf_db
.db_lshdr
;
389 while (!ospf_print_lshdr(lshp
)) {
395 case OSPF_TYPE_LS_REQ
:
397 while ((u_char
*)lsrp
< dataend
) {
400 printf("\n\t %s LSA (%d), LSA-ID: %s, Advertising Router: %s",
401 tok2str(lsa_values
,"unknown",lsrp
->ls_type
),
403 ipaddr_string(&lsrp
->ls_stateid
),
404 ipaddr_string(&lsrp
->ls_router
));
409 case OSPF_TYPE_LS_UPDATE
:
410 lsap
= op
->ospf_lsu
.lsu_lsa
;
411 TCHECK(op
->ospf_lsu
.lsu_count
);
412 lsa_count
= EXTRACT_32BITS(&op
->ospf_lsu
.lsu_count
);
413 printf(", %d LSA%s",lsa_count
, lsa_count
> 1 ? "s" : "");
414 while (lsa_count
--) {
415 if (ospf_print_lsa(lsap
))
417 lsap
= (struct lsa
*)((u_char
*)lsap
+
418 EXTRACT_16BITS(&lsap
->ls_hdr
.ls_length
));
422 case OSPF_TYPE_LS_ACK
:
423 lshp
= op
->ospf_lsa
.lsa_lshdr
;
424 while (!ospf_print_lshdr(lshp
)) {
430 printf("v2 type (%d)", op
->ospf_type
);
439 ospf_print(register const u_char
*bp
, register u_int length
,
440 register const u_char
*bp2
)
442 register const struct ospfhdr
*op
;
443 register const struct ip
*ip
;
444 register const u_char
*dataend
;
445 register const char *cp
;
447 op
= (struct ospfhdr
*)bp
;
448 ip
= (struct ip
*)bp2
;
450 /* XXX Before we do anything else, strip off the MD5 trailer */
451 TCHECK(op
->ospf_authtype
);
452 if (EXTRACT_16BITS(&op
->ospf_authtype
) == OSPF_AUTH_MD5
) {
453 length
-= OSPF_AUTH_MD5_LEN
;
454 snapend
-= OSPF_AUTH_MD5_LEN
;
457 /* If the type is valid translate it, or just print the type */
458 /* value. If it's not valid, say so and return */
459 TCHECK(op
->ospf_type
);
460 cp
= tok2str(type2str
, "unknown LS-Type %d", op
->ospf_type
);
461 printf("OSPFv%d %s length: %d", op
->ospf_version
, cp
, length
);
465 if(!vflag
) /* non verbose - so lets bail out here */
468 TCHECK(op
->ospf_len
);
469 if (length
!= EXTRACT_16BITS(&op
->ospf_len
)) {
470 printf(" [len %d]", EXTRACT_16BITS(&op
->ospf_len
));
473 dataend
= bp
+ length
;
475 /* Print the routerid if it is not the same as the source */
476 TCHECK(op
->ospf_routerid
);
477 if (ip
->ip_src
.s_addr
!= op
->ospf_routerid
.s_addr
)
478 printf("\n\tRouter-ID: %s", ipaddr_string(&op
->ospf_routerid
));
480 TCHECK(op
->ospf_areaid
);
481 if (op
->ospf_areaid
.s_addr
!= 0)
482 printf(", Area %s", ipaddr_string(&op
->ospf_areaid
));
484 printf(", Backbone Area");
487 /* Print authentication data (should we really do this?) */
488 TCHECK2(op
->ospf_authdata
[0], sizeof(op
->ospf_authdata
));
489 switch (EXTRACT_16BITS(&op
->ospf_authtype
)) {
494 case OSPF_AUTH_SIMPLE
:
495 printf(", simple Authentication \"");
496 (void)fn_printn(op
->ospf_authdata
,
497 sizeof(op
->ospf_authdata
), NULL
);
502 printf(", MD5 Authentication");
506 printf(", unknown Authentication Type %d", EXTRACT_16BITS(&op
->ospf_authtype
));
510 /* Do rest according to version. */
511 switch (op
->ospf_version
) {
515 if (ospf_decode_v2(op
, dataend
))
520 printf(" ospf [version %d]", op
->ospf_version
);
522 } /* end switch on version */