]> The Tcpdump Group git mirrors - tcpdump/blob - print-ospf.c
add (cheap) support for NSSA LSAs
[tcpdump] / print-ospf.c
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@mitchell.cit.cornell.edu)
22 */
23
24 #ifndef lint
25 static const char rcsid[] _U_ =
26 "@(#) $Header: /tcpdump/master/tcpdump/print-ospf.c,v 1.52 2004-09-09 16:17:38 hannes Exp $ (LBL)";
27 #endif
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <tcpdump-stdinc.h>
34
35 #include <stdio.h>
36
37 #include "interface.h"
38 #include "addrtoname.h"
39 #include "extract.h"
40 #include "gmpls.h"
41
42 #include "ospf.h"
43
44 #include "ip.h"
45
46 static struct tok ospf_option_values[] = {
47 { OSPF_OPTION_T, "TOS" },
48 { OSPF_OPTION_E, "External" },
49 { OSPF_OPTION_MC, "Multicast" },
50 { OSPF_OPTION_NP, "NSSA" },
51 { OSPF_OPTION_EA, "Advertise External" },
52 { OSPF_OPTION_DC, "Demand Circuit" },
53 { OSPF_OPTION_O, "Opaque" },
54 { 0, NULL }
55 };
56
57 static struct tok ospf_authtype_values[] = {
58 { OSPF_AUTH_NONE, "none" },
59 { OSPF_AUTH_NONE, "simple" },
60 { OSPF_AUTH_MD5, "MD5" },
61 { 0, NULL }
62 };
63
64 static struct tok ospf_rla_flag_values[] = {
65 { RLA_FLAG_B, "ABR" },
66 { RLA_FLAG_E, "ASBR" },
67 { RLA_FLAG_W1, "Virtual" },
68 { RLA_FLAG_W2, "W2" },
69 { 0, NULL }
70 };
71
72 static struct tok type2str[] = {
73 { OSPF_TYPE_UMD, "UMD" },
74 { OSPF_TYPE_HELLO, "Hello" },
75 { OSPF_TYPE_DD, "Database Description" },
76 { OSPF_TYPE_LS_REQ, "LS-Request" },
77 { OSPF_TYPE_LS_UPDATE, "LS-Update" },
78 { OSPF_TYPE_LS_ACK, "LS-Ack" },
79 { 0, NULL }
80 };
81
82 static struct tok lsa_values[] = {
83 { LS_TYPE_ROUTER, "Router" },
84 { LS_TYPE_NETWORK, "Network" },
85 { LS_TYPE_SUM_IP, "Summary" },
86 { LS_TYPE_SUM_ABR, "ASBR Summary" },
87 { LS_TYPE_ASE, "External" },
88 { LS_TYPE_GROUP, "Multicast Group" },
89 { LS_TYPE_NSSA, "NSSA" },
90 { LS_TYPE_OPAQUE_LL, "Link Local Opaque" },
91 { LS_TYPE_OPAQUE_AL, "Area Local Opaque" },
92 { LS_TYPE_OPAQUE_DW, "Domain Wide Opaque" },
93 { 0, NULL }
94 };
95
96 static struct tok ospf_dd_flag_values[] = {
97 { OSPF_DB_INIT, "Init" },
98 { OSPF_DB_MORE, "More" },
99 { OSPF_DB_MASTER, "Master" },
100 { 0, NULL }
101 };
102
103 static struct tok lsa_opaque_values[] = {
104 { LS_OPAQUE_TYPE_TE, "Traffic Engineering" },
105 { LS_OPAQUE_TYPE_GRACE, "Graceful restart" },
106 { 0, NULL }
107 };
108
109 static struct tok lsa_opaque_te_tlv_values[] = {
110 { LS_OPAQUE_TE_TLV_ROUTER, "Router Address" },
111 { LS_OPAQUE_TE_TLV_LINK, "Link" },
112 { 0, NULL }
113 };
114
115 static struct tok lsa_opaque_te_link_tlv_subtlv_values[] = {
116 { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE, "Link Type" },
117 { LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID, "Link ID" },
118 { LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP, "Local Interface IP address" },
119 { LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP, "Remote Interface IP address" },
120 { LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC, "Traffic Engineering Metric" },
121 { LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW, "Maximum Bandwidth" },
122 { LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW, "Maximum Reservable Bandwidth" },
123 { LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW, "Unreserved Bandwidth" },
124 { LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP, "Administrative Group" },
125 { LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier" },
126 { LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE, "Link Protection Type" },
127 { LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR, "Interface Switching Capability" },
128 { LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP, "Shared Risk Link Group" },
129 { LS_OPAQUE_TE_LINK_SUBTLV_DIFFSERV_TE, "Diffserv TE" },
130 { 0, NULL }
131 };
132
133 static struct tok lsa_opaque_grace_tlv_values[] = {
134 { LS_OPAQUE_GRACE_TLV_PERIOD, "Grace Period" },
135 { LS_OPAQUE_GRACE_TLV_REASON, "Graceful restart Reason" },
136 { LS_OPAQUE_GRACE_TLV_INT_ADDRESS, "IPv4 interface address" },
137 { 0, NULL }
138 };
139
140 static struct tok lsa_opaque_grace_tlv_reason_values[] = {
141 { LS_OPAQUE_GRACE_TLV_REASON_UNKNOWN, "Unknown" },
142 { LS_OPAQUE_GRACE_TLV_REASON_SW_RESTART, "Software Restart" },
143 { LS_OPAQUE_GRACE_TLV_REASON_SW_UPGRADE, "Software Reload/Upgrade" },
144 { LS_OPAQUE_GRACE_TLV_REASON_CP_SWITCH, "Control Processor Switch" },
145 { 0, NULL }
146 };
147
148 static struct tok lsa_opaque_te_tlv_link_type_sub_tlv_values[] = {
149 { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_PTP, "Point-to-point" },
150 { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_MA, "Multi-Access" },
151 { 0, NULL }
152 };
153
154 static char tstr[] = " [|ospf]";
155
156 #ifdef WIN32
157 #define inline __inline
158 #endif /* WIN32 */
159
160 static int ospf_print_lshdr(const struct lsa_hdr *);
161 static const u_char *ospf_print_lsa(const struct lsa *);
162 static int ospf_decode_v2(const struct ospfhdr *, const u_char *);
163
164 static int
165 ospf_print_lshdr(register const struct lsa_hdr *lshp)
166 {
167 u_int ls_length;
168
169 TCHECK(lshp->ls_length);
170 ls_length = EXTRACT_16BITS(&lshp->ls_length);
171 if (ls_length < sizeof(struct lsa_hdr)) {
172 printf("\n\t Bogus length %u < %lu", ls_length,
173 (unsigned long)sizeof(struct lsa_hdr));
174 return(-1);
175 }
176
177 TCHECK(lshp->ls_seq); /* XXX - ls_length check checked this */
178 printf("\n\t Advertising Router: %s, seq 0x%08x, age %us, length: %u",
179 ipaddr_string(&lshp->ls_router),
180 EXTRACT_32BITS(&lshp->ls_seq),
181 EXTRACT_16BITS(&lshp->ls_age),
182 ls_length-(u_int)sizeof(struct lsa_hdr));
183
184 TCHECK(lshp->ls_type); /* XXX - ls_length check checked this */
185 switch (lshp->ls_type) {
186 /* the LSA header for opaque LSAs was slightly changed */
187 case LS_TYPE_OPAQUE_LL:
188 case LS_TYPE_OPAQUE_AL:
189 case LS_TYPE_OPAQUE_DW:
190 printf("\n\t %s LSA (%d), Opaque-Type: %s LSA (%u), Opaque-ID: %u",
191 tok2str(lsa_values,"unknown",lshp->ls_type),
192 lshp->ls_type,
193
194 tok2str(lsa_opaque_values,
195 "unknown",
196 *(&lshp->un_lsa_id.opaque_field.opaque_type)),
197 *(&lshp->un_lsa_id.opaque_field.opaque_type),
198 EXTRACT_24BITS(&lshp->un_lsa_id.opaque_field.opaque_id)
199
200 );
201 break;
202
203 /* all other LSA types use regular style LSA headers */
204 default:
205 printf("\n\t %s LSA (%d), LSA-ID: %s",
206 tok2str(lsa_values,"unknown",lshp->ls_type),
207 lshp->ls_type,
208 ipaddr_string(&lshp->un_lsa_id.lsa_id));
209 break;
210 }
211
212 TCHECK(lshp->ls_options); /* XXX - ls_length check checked this */
213 printf("\n\t Options: [%s]", bittok2str(ospf_option_values,"none",lshp->ls_options));
214
215 return (ls_length);
216 trunc:
217 return (-1);
218 }
219
220 /*
221 * Print a single link state advertisement. If truncated or if LSA length
222 * field is less than the length of the LSA header, return NULl, else
223 * return pointer to data past end of LSA.
224 */
225 static const u_int8_t *
226 ospf_print_lsa(register const struct lsa *lsap)
227 {
228 register const u_int8_t *ls_end;
229 register const struct rlalink *rlp;
230 register const struct tos_metric *tosp;
231 register const struct in_addr *ap;
232 register const struct aslametric *almp;
233 register const struct mcla *mcp;
234 register const u_int32_t *lp;
235 register int j, k, tlv_type, tlv_length, subtlv_type, subtlv_length, priority_level, bandwidth_constraint;
236 register int ls_length;
237 const u_int8_t *tptr;
238 int count_srlg;
239 union { /* int to float conversion buffer for several subTLVs */
240 float f;
241 u_int32_t i;
242 } bw;
243
244 tptr = (u_int8_t *)lsap->lsa_un.un_unknown; /* squelch compiler warnings */
245 ls_length = ospf_print_lshdr(&lsap->ls_hdr);
246 if (ls_length == -1)
247 return(NULL);
248 ls_end = (u_int8_t *)lsap + ls_length;
249 ls_length -= sizeof(struct lsa_hdr);
250
251 switch (lsap->ls_hdr.ls_type) {
252
253 case LS_TYPE_ROUTER:
254 TCHECK(lsap->lsa_un.un_rla.rla_flags);
255 printf("\n\t Router LSA Options: [%s]", bittok2str(ospf_rla_flag_values,"none",lsap->lsa_un.un_rla.rla_flags));
256
257 TCHECK(lsap->lsa_un.un_rla.rla_count);
258 j = EXTRACT_16BITS(&lsap->lsa_un.un_rla.rla_count);
259 TCHECK(lsap->lsa_un.un_rla.rla_link);
260 rlp = lsap->lsa_un.un_rla.rla_link;
261 while (j--) {
262 TCHECK(*rlp);
263 switch (rlp->link_type) {
264
265 case RLA_TYPE_VIRTUAL:
266 printf("\n\t Virtual Link: Neighbor Router-ID: %s, Interface Address: %s",
267 ipaddr_string(&rlp->link_id),
268 ipaddr_string(&rlp->link_data));
269 break;
270
271 case RLA_TYPE_ROUTER:
272 printf("\n\t Neighbor Router-ID: %s, Interface Address: %s",
273 ipaddr_string(&rlp->link_id),
274 ipaddr_string(&rlp->link_data));
275 break;
276
277 case RLA_TYPE_TRANSIT:
278 printf("\n\t Neighbor Network-ID: %s, Interface Address: %s",
279 ipaddr_string(&rlp->link_id),
280 ipaddr_string(&rlp->link_data));
281 break;
282
283 case RLA_TYPE_STUB:
284 printf("\n\t Stub Network: %s, Mask: %s",
285 ipaddr_string(&rlp->link_id),
286 ipaddr_string(&rlp->link_data));
287 break;
288
289 default:
290 printf("\n\t Unknown Router Link Type (%u)",
291 rlp->link_type);
292 return (ls_end);
293 }
294 printf(", tos 0, metric: %d", EXTRACT_16BITS(&rlp->link_tos0metric));
295 tosp = (struct tos_metric *)
296 ((sizeof rlp->link_tos0metric) + (u_char *) rlp);
297 for (k = 0; k < (int) rlp->link_toscount; ++k, ++tosp) {
298 TCHECK(*tosp);
299 printf(", tos %d, metric: %d",
300 tosp->tos_type,
301 EXTRACT_16BITS(&tosp->tos_metric));
302 }
303 rlp = (struct rlalink *)((u_char *)(rlp + 1) +
304 ((rlp->link_toscount) * sizeof(*tosp)));
305 }
306 break;
307
308 case LS_TYPE_NETWORK:
309 TCHECK(lsap->lsa_un.un_nla.nla_mask);
310 printf("\n\t Mask %s\n\t Connected Routers:",
311 ipaddr_string(&lsap->lsa_un.un_nla.nla_mask));
312 ap = lsap->lsa_un.un_nla.nla_router;
313 while ((u_char *)ap < ls_end) {
314 TCHECK(*ap);
315 printf("\n\t %s", ipaddr_string(ap));
316 ++ap;
317 }
318 break;
319
320 case LS_TYPE_SUM_IP:
321 TCHECK(lsap->lsa_un.un_nla.nla_mask);
322 printf("\n\t Mask %s",
323 ipaddr_string(&lsap->lsa_un.un_sla.sla_mask));
324 TCHECK(lsap->lsa_un.un_sla.sla_tosmetric);
325 lp = lsap->lsa_un.un_sla.sla_tosmetric;
326 /* suppress tos if its not supported */
327 if(!((lsap->ls_hdr.ls_options)&OSPF_OPTION_T)) {
328 printf(", metric: %u", EXTRACT_32BITS(lp)&SLA_MASK_METRIC);
329 break;
330 }
331 while ((u_char *)lp < ls_end) {
332 register u_int32_t ul;
333
334 TCHECK(*lp);
335 ul = EXTRACT_32BITS(lp);
336 printf(", tos %d metric %d",
337 (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS,
338 ul & SLA_MASK_METRIC);
339 ++lp;
340 }
341 break;
342
343 case LS_TYPE_SUM_ABR:
344 TCHECK(lsap->lsa_un.un_sla.sla_tosmetric);
345 lp = lsap->lsa_un.un_sla.sla_tosmetric;
346 /* suppress tos if its not supported */
347 if(!((lsap->ls_hdr.ls_options)&OSPF_OPTION_T)) {
348 printf(", metric: %u", EXTRACT_32BITS(lp)&SLA_MASK_METRIC);
349 break;
350 }
351 while ((u_char *)lp < ls_end) {
352 register u_int32_t ul;
353
354 TCHECK(*lp);
355 ul = EXTRACT_32BITS(lp);
356 printf(", tos %d metric %d",
357 (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS,
358 ul & SLA_MASK_METRIC);
359 ++lp;
360 }
361 break;
362
363 case LS_TYPE_ASE:
364 case LS_TYPE_NSSA: /* fall through - those LSAs share the same format */
365 TCHECK(lsap->lsa_un.un_nla.nla_mask);
366 printf("\n\t Mask %s",
367 ipaddr_string(&lsap->lsa_un.un_asla.asla_mask));
368
369 TCHECK(lsap->lsa_un.un_sla.sla_tosmetric);
370 almp = lsap->lsa_un.un_asla.asla_metric;
371 while ((u_char *)almp < ls_end) {
372 register u_int32_t ul;
373
374 TCHECK(almp->asla_tosmetric);
375 ul = EXTRACT_32BITS(&almp->asla_tosmetric);
376 printf(", type %d, tos %d metric:",
377 (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1,
378 (ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS);
379 if ((ul & ASLA_MASK_METRIC)==0xffffff)
380 printf(" infinite");
381 else
382 printf(" %d", (ul & ASLA_MASK_METRIC));
383
384 TCHECK(almp->asla_forward);
385 if (almp->asla_forward.s_addr) {
386 printf(", forward %s",
387 ipaddr_string(&almp->asla_forward));
388 }
389 TCHECK(almp->asla_tag);
390 if (almp->asla_tag.s_addr) {
391 printf(", tag %s",
392 ipaddr_string(&almp->asla_tag));
393 }
394 ++almp;
395 }
396 break;
397
398 case LS_TYPE_GROUP:
399 /* Multicast extensions as of 23 July 1991 */
400 mcp = lsap->lsa_un.un_mcla;
401 while ((u_char *)mcp < ls_end) {
402 TCHECK(mcp->mcla_vid);
403 switch (EXTRACT_32BITS(&mcp->mcla_vtype)) {
404
405 case MCLA_VERTEX_ROUTER:
406 printf("\n\t Router Router-ID %s",
407 ipaddr_string(&mcp->mcla_vid));
408 break;
409
410 case MCLA_VERTEX_NETWORK:
411 printf("\n\t Network Designated Router %s",
412 ipaddr_string(&mcp->mcla_vid));
413 break;
414
415 default:
416 printf("\n\t unknown VertexType (%u)",
417 EXTRACT_32BITS(&mcp->mcla_vtype));
418 break;
419 }
420 ++mcp;
421 }
422 break;
423
424 case LS_TYPE_OPAQUE_LL: /* fall through */
425 case LS_TYPE_OPAQUE_AL:
426 case LS_TYPE_OPAQUE_DW:
427
428 switch (*(&lsap->ls_hdr.un_lsa_id.opaque_field.opaque_type)) {
429 case LS_OPAQUE_TYPE_GRACE:
430 tptr = (u_int8_t *)(&lsap->lsa_un.un_grace_tlv.type);
431
432 while (ls_length != 0) {
433 TCHECK2(*tptr, 4);
434 if (ls_length < 4) {
435 printf("\n\t Remaining LS length %u < 4", ls_length);
436 return(ls_end);
437 }
438 tlv_type = EXTRACT_16BITS(tptr);
439 tlv_length = EXTRACT_16BITS(tptr+2);
440 tptr+=4;
441 ls_length-=4;
442
443 printf("\n\t %s TLV (%u), length: %u, value: ",
444 tok2str(lsa_opaque_grace_tlv_values,"unknown",tlv_type),
445 tlv_type,
446 tlv_length);
447
448 if (tlv_length > ls_length) {
449 printf("\n\t Bogus length %u > %u", tlv_length,
450 ls_length);
451 return(ls_end);
452 }
453 ls_length-=tlv_length;
454 TCHECK2(*tptr, tlv_length);
455 switch(tlv_type) {
456
457 case LS_OPAQUE_GRACE_TLV_PERIOD:
458 if (tlv_length != 4) {
459 printf("\n\t Bogus length %u != 4", tlv_length);
460 return(ls_end);
461 }
462 printf("%us",EXTRACT_32BITS(tptr));
463 break;
464 case LS_OPAQUE_GRACE_TLV_REASON:
465 if (tlv_length != 1) {
466 printf("\n\t Bogus length %u != 1", tlv_length);
467 return(ls_end);
468 }
469 printf("%s (%u)",
470 tok2str(lsa_opaque_grace_tlv_reason_values, "Unknown", *tptr),
471 *tptr);
472 break;
473 case LS_OPAQUE_GRACE_TLV_INT_ADDRESS:
474 if (tlv_length != 4) {
475 printf("\n\t Bogus length %u != 4", tlv_length);
476 return(ls_end);
477 }
478 printf("%s", ipaddr_string(tptr));
479 break;
480 default:
481 if (vflag <= 1) {
482 if(!print_unknown_data(tptr,"\n\t ",tlv_length))
483 return(ls_end);
484 }
485 break;
486
487 }
488 tptr+=tlv_length;
489 }
490
491 break;
492 case LS_OPAQUE_TYPE_TE:
493 tptr = (u_int8_t *)(&lsap->lsa_un.un_te_lsa_tlv.type);
494
495 while (ls_length != 0) {
496 TCHECK2(*tptr, 4);
497 if (ls_length < 4) {
498 printf("\n\t Remaining LS length %u < 4", ls_length);
499 return(ls_end);
500 }
501 tlv_type = EXTRACT_16BITS(tptr);
502 tlv_length = EXTRACT_16BITS(tptr+2);
503 tptr+=4;
504 ls_length-=4;
505
506 printf("\n\t %s TLV (%u), length: %u",
507 tok2str(lsa_opaque_te_tlv_values,"unknown",tlv_type),
508 tlv_type,
509 tlv_length);
510
511 if (tlv_length > ls_length) {
512 printf("\n\t Bogus length %u > %u", tlv_length,
513 ls_length);
514 return(ls_end);
515 }
516 ls_length-=tlv_length;
517 switch(tlv_type) {
518 case LS_OPAQUE_TE_TLV_LINK:
519 while (tlv_length != 0) {
520 if (tlv_length < 4) {
521 printf("\n\t Remaining TLV length %u < 4",
522 tlv_length);
523 return(ls_end);
524 }
525 TCHECK2(*tptr, 4);
526 subtlv_type = EXTRACT_16BITS(tptr);
527 subtlv_length = EXTRACT_16BITS(tptr+2);
528 tptr+=4;
529 tlv_length-=4;
530
531 printf("\n\t %s subTLV (%u), length: %u",
532 tok2str(lsa_opaque_te_link_tlv_subtlv_values,"unknown",subtlv_type),
533 subtlv_type,
534 subtlv_length);
535
536 TCHECK2(*tptr, subtlv_length);
537 switch(subtlv_type) {
538 case LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP:
539 printf(", 0x%08x", EXTRACT_32BITS(tptr));
540 break;
541 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID:
542 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID:
543 printf(", %s (0x%08x)",
544 ipaddr_string(tptr),
545 EXTRACT_32BITS(tptr));
546 if (subtlv_length == 8) /* draft-ietf-ccamp-ospf-gmpls-extensions */
547 printf(", %s (0x%08x)",
548 ipaddr_string(tptr+4),
549 EXTRACT_32BITS(tptr+4));
550 break;
551 case LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP:
552 case LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP:
553 printf(", %s", ipaddr_string(tptr));
554 break;
555 case LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW:
556 case LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW:
557 bw.i = EXTRACT_32BITS(tptr);
558 printf(", %.3f Mbps", bw.f*8/1000000 );
559 break;
560 case LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW:
561 for (priority_level = 0; priority_level < 8; priority_level++) {
562 bw.i = EXTRACT_32BITS(tptr+priority_level*4);
563 printf("\n\t\tpriority level %d: %.3f Mbps",
564 priority_level,
565 bw.f*8/1000000 );
566 }
567 break;
568 case LS_OPAQUE_TE_LINK_SUBTLV_DIFFSERV_TE:
569 printf("\n\t\tBandwidth Constraints Model ID: (%u)", *tptr);
570 for (bandwidth_constraint = 0; bandwidth_constraint < 8; bandwidth_constraint++) {
571 bw.i = EXTRACT_32BITS(tptr+4+bandwidth_constraint*4);
572 printf("\n\t\t Bandwidth constraint %d: %.3f Mbps",
573 bandwidth_constraint,
574 bw.f*8/1000000 );
575 }
576 break;
577 case LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC:
578 printf(", Metric %u", EXTRACT_32BITS(tptr));
579 break;
580 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE:
581 printf(", %s, Priority %u",
582 bittok2str(gmpls_link_prot_values, "none", *tptr),
583 *(tptr+1));
584 break;
585 case LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR:
586 printf("\n\t\tInterface Switching Capability: %s",
587 tok2str(gmpls_switch_cap_values, "Unknown", *(tptr)));
588 printf("\n\t\tLSP Encoding: %s\n\t\tMax LSP Bandwidth:",
589 tok2str(gmpls_encoding_values, "Unknown", *(tptr+1)));
590 for (priority_level = 0; priority_level < 8; priority_level++) {
591 bw.i = EXTRACT_32BITS(tptr+4+(priority_level*4));
592 printf("\n\t\t priority level %d: %.3f Mbps",
593 priority_level,
594 bw.f*8/1000000 );
595 }
596 break;
597 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE:
598 printf(", %s (%u)",
599 tok2str(lsa_opaque_te_tlv_link_type_sub_tlv_values,"unknown",*tptr),
600 *tptr);
601 break;
602
603 case LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP:
604 count_srlg = subtlv_length / 4;
605 if (count_srlg != 0)
606 printf("\n\t\t Shared risk group: ");
607 while (count_srlg > 0) {
608 bw.i = EXTRACT_32BITS(tptr);
609 printf("%d",bw.i);
610 tptr+=4;
611 count_srlg--;
612 if (count_srlg > 0)
613 printf(", ");
614 }
615 break;
616
617 default:
618 if (vflag <= 1) {
619 if(!print_unknown_data(tptr,"\n\t\t",subtlv_length))
620 return(ls_end);
621 }
622 break;
623 }
624 /* in OSPF everything has to be 32-bit aligned, including TLVs */
625 if (subtlv_length%4 != 0)
626 subtlv_length+=4-(subtlv_length%4);
627
628 tlv_length-=subtlv_length;
629 tptr+=subtlv_length;
630
631 }
632 break;
633
634 case LS_OPAQUE_TE_TLV_ROUTER:
635 if (tlv_length < 4) {
636 printf("\n\t TLV length %u < 4", tlv_length);
637 return(ls_end);
638 }
639 TCHECK2(*tptr, 4);
640 printf(", %s", ipaddr_string(tptr));
641 break;
642
643 default:
644 if (vflag <= 1) {
645 if(!print_unknown_data(tptr,"\n\t ",tlv_length))
646 return(ls_end);
647 }
648 break;
649 }
650 tptr+=tlv_length;
651 }
652 break;
653 }
654 break;
655 default:
656 if (vflag <= 1) {
657 if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown,
658 "\n\t ", ls_length))
659 return(ls_end);
660 }
661 break;
662 }
663
664 /* do we want to see an additionally hexdump ? */
665 if (vflag> 1)
666 if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown,
667 "\n\t ", ls_length)) {
668 return(ls_end);
669 }
670
671 return (ls_end);
672 trunc:
673 return (NULL);
674 }
675
676 static int
677 ospf_decode_v2(register const struct ospfhdr *op,
678 register const u_char *dataend)
679 {
680 register const struct in_addr *ap;
681 register const struct lsr *lsrp;
682 register const struct lsa_hdr *lshp;
683 register const struct lsa *lsap;
684 register u_int32_t lsa_count,lsa_count_max;
685
686 switch (op->ospf_type) {
687
688 case OSPF_TYPE_UMD:
689 /*
690 * Rob Coltun's special monitoring packets;
691 * do nothing
692 */
693 break;
694
695 case OSPF_TYPE_HELLO:
696 printf("\n\tOptions: [%s]",
697 bittok2str(ospf_option_values,"none",op->ospf_hello.hello_options));
698
699 TCHECK(op->ospf_hello.hello_deadint);
700 printf("\n\t Hello Timer: %us, Dead Timer %us, Mask: %s, Priority: %u",
701 EXTRACT_16BITS(&op->ospf_hello.hello_helloint),
702 EXTRACT_32BITS(&op->ospf_hello.hello_deadint),
703 ipaddr_string(&op->ospf_hello.hello_mask),
704 op->ospf_hello.hello_priority);
705
706 TCHECK(op->ospf_hello.hello_dr);
707 if (op->ospf_hello.hello_dr.s_addr != 0)
708 printf("\n\t Designated Router %s",
709 ipaddr_string(&op->ospf_hello.hello_dr));
710
711 TCHECK(op->ospf_hello.hello_bdr);
712 if (op->ospf_hello.hello_bdr.s_addr != 0)
713 printf(", Backup Designated Router %s",
714 ipaddr_string(&op->ospf_hello.hello_bdr));
715
716 ap = op->ospf_hello.hello_neighbor;
717 if ((u_char *)ap < dataend)
718 printf("\n\t Neighbor List:");
719 while ((u_char *)ap < dataend) {
720 TCHECK(*ap);
721 printf("\n\t %s", ipaddr_string(ap));
722 ++ap;
723 }
724 break; /* HELLO */
725
726 case OSPF_TYPE_DD:
727 TCHECK(op->ospf_db.db_options);
728 printf("\n\tOptions: [%s]",
729 bittok2str(ospf_option_values,"none",op->ospf_db.db_options));
730 TCHECK(op->ospf_db.db_flags);
731 printf(", DD Flags: [%s]",
732 bittok2str(ospf_dd_flag_values,"none",op->ospf_db.db_flags));
733
734 if (vflag) {
735 /* Print all the LS adv's */
736 lshp = op->ospf_db.db_lshdr;
737 while (ospf_print_lshdr(lshp) != -1) {
738 ++lshp;
739 }
740 }
741 break;
742
743 case OSPF_TYPE_LS_REQ:
744 lsrp = op->ospf_lsr;
745 while ((u_char *)lsrp < dataend) {
746 TCHECK(*lsrp);
747
748 printf("\n\t Advertising Router: %s, %s LSA (%u)",
749 ipaddr_string(&lsrp->ls_router),
750 tok2str(lsa_values,"unknown",EXTRACT_32BITS(lsrp->ls_type)),
751 EXTRACT_32BITS(&lsrp->ls_type));
752
753 switch (EXTRACT_32BITS(lsrp->ls_type)) {
754 /* the LSA header for opaque LSAs was slightly changed */
755 case LS_TYPE_OPAQUE_LL:
756 case LS_TYPE_OPAQUE_AL:
757 case LS_TYPE_OPAQUE_DW:
758 printf(", Opaque-Type: %s LSA (%u), Opaque-ID: %u",
759 tok2str(lsa_opaque_values, "unknown",lsrp->un_ls_stateid.opaque_field.opaque_type),
760 lsrp->un_ls_stateid.opaque_field.opaque_type,
761 EXTRACT_24BITS(&lsrp->un_ls_stateid.opaque_field.opaque_id));
762 break;
763 default:
764 printf(", LSA-ID: %s",
765 ipaddr_string(&lsrp->un_ls_stateid.ls_stateid));
766 break;
767 }
768
769 ++lsrp;
770 }
771 break;
772
773 case OSPF_TYPE_LS_UPDATE:
774 lsap = op->ospf_lsu.lsu_lsa;
775 TCHECK(op->ospf_lsu.lsu_count);
776 lsa_count_max = EXTRACT_32BITS(&op->ospf_lsu.lsu_count);
777 printf(", %d LSA%s",lsa_count_max, lsa_count_max > 1 ? "s" : "");
778 for (lsa_count=1;lsa_count <= lsa_count_max;lsa_count++) {
779 printf("\n\t LSA #%u",lsa_count);
780 lsap = (const struct lsa *)ospf_print_lsa(lsap);
781 if (lsap == NULL)
782 goto trunc;
783 }
784 break;
785
786 case OSPF_TYPE_LS_ACK:
787 lshp = op->ospf_lsa.lsa_lshdr;
788 while (ospf_print_lshdr(lshp) != -1) {
789 ++lshp;
790 }
791 break;
792
793 default:
794 printf("v2 type (%d)", op->ospf_type);
795 break;
796 }
797 return (0);
798 trunc:
799 return (1);
800 }
801
802 void
803 ospf_print(register const u_char *bp, register u_int length,
804 register const u_char *bp2)
805 {
806 register const struct ospfhdr *op;
807 register const struct ip *ip;
808 register const u_char *dataend;
809 register const char *cp;
810
811 op = (struct ospfhdr *)bp;
812 ip = (struct ip *)bp2;
813
814 /* XXX Before we do anything else, strip off the MD5 trailer */
815 TCHECK(op->ospf_authtype);
816 if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) {
817 length -= OSPF_AUTH_MD5_LEN;
818 snapend -= OSPF_AUTH_MD5_LEN;
819 }
820
821 /* If the type is valid translate it, or just print the type */
822 /* value. If it's not valid, say so and return */
823 TCHECK(op->ospf_type);
824 cp = tok2str(type2str, "unknown LS-type", op->ospf_type);
825 printf("OSPFv%u, %s (%u), length: %u",
826 op->ospf_version,
827 cp,
828 op->ospf_type,
829 length);
830 if (*cp == 'u')
831 return;
832
833 if(!vflag) /* non verbose - so lets bail out here */
834 return;
835
836 TCHECK(op->ospf_len);
837 if (length != EXTRACT_16BITS(&op->ospf_len)) {
838 printf(" [len %d]", EXTRACT_16BITS(&op->ospf_len));
839 return;
840 }
841 dataend = bp + length;
842
843 TCHECK(op->ospf_routerid);
844 printf("\n\tRouter-ID: %s", ipaddr_string(&op->ospf_routerid));
845
846 TCHECK(op->ospf_areaid);
847 if (op->ospf_areaid.s_addr != 0)
848 printf(", Area %s", ipaddr_string(&op->ospf_areaid));
849 else
850 printf(", Backbone Area");
851
852 if (vflag) {
853 /* Print authentication data (should we really do this?) */
854 TCHECK2(op->ospf_authdata[0], sizeof(op->ospf_authdata));
855
856 printf(", Authentication Type: %s (%u)",
857 tok2str(ospf_authtype_values,"unknown",EXTRACT_16BITS(&op->ospf_authtype)),
858 EXTRACT_16BITS(&op->ospf_authtype));
859
860 switch (EXTRACT_16BITS(&op->ospf_authtype)) {
861
862 case OSPF_AUTH_NONE:
863 break;
864
865 case OSPF_AUTH_SIMPLE:
866 (void)fn_printn(op->ospf_authdata,
867 sizeof(op->ospf_authdata), NULL);
868 printf("\"");
869 break;
870
871 case OSPF_AUTH_MD5:
872 printf("\n\tKey-ID: %u, Auth-Length: %u, Crypto Sequence Number: 0x%08x",
873 *((op->ospf_authdata)+2),
874 *((op->ospf_authdata)+3),
875 EXTRACT_32BITS((op->ospf_authdata)+4));
876 break;
877
878 default:
879 return;
880 }
881 }
882 /* Do rest according to version. */
883 switch (op->ospf_version) {
884
885 case 2:
886 /* ospf version 2 */
887 if (ospf_decode_v2(op, dataend))
888 goto trunc;
889 break;
890
891 default:
892 printf(" ospf [version %d]", op->ospf_version);
893 break;
894 } /* end switch on version */
895
896 return;
897 trunc:
898 fputs(tstr, stdout);
899 }