]> The Tcpdump Group git mirrors - tcpdump/blob - print-ospf.c
Add bounds checking.
[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.50 2004-01-27 13:33:24 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 TCHECK(lsap->lsa_un.un_nla.nla_mask);
365 printf("\n\t Mask %s",
366 ipaddr_string(&lsap->lsa_un.un_asla.asla_mask));
367
368 TCHECK(lsap->lsa_un.un_sla.sla_tosmetric);
369 almp = lsap->lsa_un.un_asla.asla_metric;
370 while ((u_char *)almp < ls_end) {
371 register u_int32_t ul;
372
373 TCHECK(almp->asla_tosmetric);
374 ul = EXTRACT_32BITS(&almp->asla_tosmetric);
375 printf(", type %d, tos %d metric:",
376 (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1,
377 (ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS);
378 if ((ul & ASLA_MASK_METRIC)==0xffffff)
379 printf(" infinite");
380 else
381 printf(" %d", (ul & ASLA_MASK_METRIC));
382
383 TCHECK(almp->asla_forward);
384 if (almp->asla_forward.s_addr) {
385 printf(", forward %s",
386 ipaddr_string(&almp->asla_forward));
387 }
388 TCHECK(almp->asla_tag);
389 if (almp->asla_tag.s_addr) {
390 printf(", tag %s",
391 ipaddr_string(&almp->asla_tag));
392 }
393 ++almp;
394 }
395 break;
396
397 case LS_TYPE_GROUP:
398 /* Multicast extensions as of 23 July 1991 */
399 mcp = lsap->lsa_un.un_mcla;
400 while ((u_char *)mcp < ls_end) {
401 TCHECK(mcp->mcla_vid);
402 switch (EXTRACT_32BITS(&mcp->mcla_vtype)) {
403
404 case MCLA_VERTEX_ROUTER:
405 printf("\n\t Router Router-ID %s",
406 ipaddr_string(&mcp->mcla_vid));
407 break;
408
409 case MCLA_VERTEX_NETWORK:
410 printf("\n\t Network Designated Router %s",
411 ipaddr_string(&mcp->mcla_vid));
412 break;
413
414 default:
415 printf("\n\t unknown VertexType (%u)",
416 EXTRACT_32BITS(&mcp->mcla_vtype));
417 break;
418 }
419 ++mcp;
420 }
421 break;
422
423 case LS_TYPE_OPAQUE_LL: /* fall through */
424 case LS_TYPE_OPAQUE_AL:
425 case LS_TYPE_OPAQUE_DW:
426
427 switch (*(&lsap->ls_hdr.un_lsa_id.opaque_field.opaque_type)) {
428 case LS_OPAQUE_TYPE_GRACE:
429 tptr = (u_int8_t *)(&lsap->lsa_un.un_grace_tlv.type);
430
431 while (ls_length != 0) {
432 if (!TTEST2(*tptr, 4))
433 goto trunc;
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 switch(tlv_type) {
455
456 case LS_OPAQUE_GRACE_TLV_PERIOD:
457 if (tlv_length != 4) {
458 printf("\n\t Bogus length %u != 4", tlv_length);
459 return(ls_end);
460 }
461 printf("%us",EXTRACT_32BITS(tptr));
462 break;
463 case LS_OPAQUE_GRACE_TLV_REASON:
464 if (tlv_length != 1) {
465 printf("\n\t Bogus length %u != 1", tlv_length);
466 return(ls_end);
467 }
468 printf("%s (%u)",
469 tok2str(lsa_opaque_grace_tlv_reason_values, "Unknown", *tptr),
470 *tptr);
471 break;
472 case LS_OPAQUE_GRACE_TLV_INT_ADDRESS:
473 if (tlv_length != 4) {
474 printf("\n\t Bogus length %u != 4", tlv_length);
475 return(ls_end);
476 }
477 printf("%s", ipaddr_string(tptr));
478 break;
479 default:
480 if (vflag <= 1) {
481 if(!print_unknown_data(tptr,"\n\t ",tlv_length))
482 return(ls_end);
483 }
484 break;
485
486 }
487 tptr+=tlv_length;
488 }
489
490 break;
491 case LS_OPAQUE_TYPE_TE:
492 tptr = (u_int8_t *)(&lsap->lsa_un.un_te_lsa_tlv.type);
493
494 while (ls_length != 0) {
495 if (!TTEST2(*tptr, 4))
496 goto trunc;
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 if (!TTEST2(*tptr, 4))
526 goto trunc;
527 subtlv_type = EXTRACT_16BITS(tptr);
528 subtlv_length = EXTRACT_16BITS(tptr+2);
529 tptr+=4;
530 tlv_length-=4;
531
532 printf("\n\t %s subTLV (%u), length: %u",
533 tok2str(lsa_opaque_te_link_tlv_subtlv_values,"unknown",subtlv_type),
534 subtlv_type,
535 subtlv_length);
536
537 if (!TTEST2(*tptr, subtlv_length))
538 goto trunc;
539 switch(subtlv_type) {
540 case LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP:
541 printf(", 0x%08x", EXTRACT_32BITS(tptr));
542 break;
543 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID:
544 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID:
545 printf(", %s (0x%08x)",
546 ipaddr_string(tptr),
547 EXTRACT_32BITS(tptr));
548 if (subtlv_length == 8) /* draft-ietf-ccamp-ospf-gmpls-extensions */
549 printf(", %s (0x%08x)",
550 ipaddr_string(tptr+4),
551 EXTRACT_32BITS(tptr+4));
552 break;
553 case LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP:
554 case LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP:
555 printf(", %s", ipaddr_string(tptr));
556 break;
557 case LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW:
558 case LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW:
559 bw.i = EXTRACT_32BITS(tptr);
560 printf(", %.3f Mbps", bw.f*8/1000000 );
561 break;
562 case LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW:
563 for (priority_level = 0; priority_level < 8; priority_level++) {
564 bw.i = EXTRACT_32BITS(tptr+priority_level*4);
565 printf("\n\t\tpriority level %d: %.3f Mbps",
566 priority_level,
567 bw.f*8/1000000 );
568 }
569 break;
570 case LS_OPAQUE_TE_LINK_SUBTLV_DIFFSERV_TE:
571 printf("\n\t\tBandwidth Constraints Model ID: (%u)", *tptr);
572 for (bandwidth_constraint = 0; bandwidth_constraint < 8; bandwidth_constraint++) {
573 bw.i = EXTRACT_32BITS(tptr+4+bandwidth_constraint*4);
574 printf("\n\t\t Bandwidth constraint %d: %.3f Mbps",
575 bandwidth_constraint,
576 bw.f*8/1000000 );
577 }
578 break;
579 case LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC:
580 printf(", Metric %u", EXTRACT_32BITS(tptr));
581 break;
582 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE:
583 printf(", %s, Priority %u",
584 bittok2str(gmpls_link_prot_values, "none", *tptr),
585 *(tptr+1));
586 break;
587 case LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR:
588 printf("\n\t\tInterface Switching Capability: %s",
589 tok2str(gmpls_switch_cap_values, "Unknown", *(tptr)));
590 printf("\n\t\tLSP Encoding: %s\n\t\tMax LSP Bandwidth:",
591 tok2str(gmpls_encoding_values, "Unknown", *(tptr+1)));
592 for (priority_level = 0; priority_level < 8; priority_level++) {
593 bw.i = EXTRACT_32BITS(tptr+4+(priority_level*4));
594 printf("\n\t\t priority level %d: %.3f Mbps",
595 priority_level,
596 bw.f*8/1000000 );
597 }
598 break;
599 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE:
600 printf(", %s (%u)",
601 tok2str(lsa_opaque_te_tlv_link_type_sub_tlv_values,"unknown",*tptr),
602 *tptr);
603 break;
604
605 case LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP:
606 count_srlg = subtlv_length / 4;
607 if (count_srlg != 0)
608 printf("\n\t\t Shared risk group: ");
609 while (count_srlg > 0) {
610 bw.i = EXTRACT_32BITS(tptr);
611 printf("%d",bw.i);
612 tptr+=4;
613 count_srlg--;
614 if (count_srlg > 0)
615 printf(", ");
616 }
617 break;
618
619 default:
620 if (vflag <= 1) {
621 if(!print_unknown_data(tptr,"\n\t\t",subtlv_length))
622 return(ls_end);
623 }
624 break;
625 }
626 /* in OSPF everything has to be 32-bit aligned, including TLVs */
627 if (subtlv_length%4 != 0)
628 subtlv_length+=4-(subtlv_length%4);
629
630 tlv_length-=subtlv_length;
631 tptr+=subtlv_length;
632
633 }
634 break;
635
636 case LS_OPAQUE_TE_TLV_ROUTER:
637 printf(", %s", ipaddr_string(tptr));
638 break;
639
640 default:
641 if (vflag <= 1) {
642 if(!print_unknown_data(tptr,"\n\t ",tlv_length))
643 return(ls_end);
644 }
645 break;
646 }
647 tptr+=tlv_length;
648 }
649 break;
650 }
651 break;
652 default:
653 if (vflag <= 1) {
654 if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown,
655 "\n\t ", ls_length))
656 return(ls_end);
657 }
658 break;
659 }
660
661 /* do we want to see an additionally hexdump ? */
662 if (vflag> 1)
663 if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown,
664 "\n\t ", ls_length)) {
665 return(ls_end);
666 }
667
668 return (ls_end);
669 trunc:
670 return (NULL);
671 }
672
673 static int
674 ospf_decode_v2(register const struct ospfhdr *op,
675 register const u_char *dataend)
676 {
677 register const struct in_addr *ap;
678 register const struct lsr *lsrp;
679 register const struct lsa_hdr *lshp;
680 register const struct lsa *lsap;
681 register u_int32_t lsa_count,lsa_count_max;
682
683 switch (op->ospf_type) {
684
685 case OSPF_TYPE_UMD:
686 /*
687 * Rob Coltun's special monitoring packets;
688 * do nothing
689 */
690 break;
691
692 case OSPF_TYPE_HELLO:
693 printf("\n\tOptions: [%s]",
694 bittok2str(ospf_option_values,"none",op->ospf_hello.hello_options));
695
696 TCHECK(op->ospf_hello.hello_deadint);
697 printf("\n\t Hello Timer: %us, Dead Timer %us, Mask: %s, Priority: %u",
698 EXTRACT_16BITS(&op->ospf_hello.hello_helloint),
699 EXTRACT_32BITS(&op->ospf_hello.hello_deadint),
700 ipaddr_string(&op->ospf_hello.hello_mask),
701 op->ospf_hello.hello_priority);
702
703 TCHECK(op->ospf_hello.hello_dr);
704 if (op->ospf_hello.hello_dr.s_addr != 0)
705 printf("\n\t Designated Router %s",
706 ipaddr_string(&op->ospf_hello.hello_dr));
707
708 TCHECK(op->ospf_hello.hello_bdr);
709 if (op->ospf_hello.hello_bdr.s_addr != 0)
710 printf(", Backup Designated Router %s",
711 ipaddr_string(&op->ospf_hello.hello_bdr));
712
713 ap = op->ospf_hello.hello_neighbor;
714 if ((u_char *)ap < dataend)
715 printf("\n\t Neighbor List:");
716 while ((u_char *)ap < dataend) {
717 TCHECK(*ap);
718 printf("\n\t %s", ipaddr_string(ap));
719 ++ap;
720 }
721 break; /* HELLO */
722
723 case OSPF_TYPE_DD:
724 TCHECK(op->ospf_db.db_options);
725 printf("\n\tOptions: [%s]",
726 bittok2str(ospf_option_values,"none",op->ospf_db.db_options));
727 TCHECK(op->ospf_db.db_flags);
728 printf(", DD Flags: [%s]",
729 bittok2str(ospf_dd_flag_values,"none",op->ospf_db.db_flags));
730
731 if (vflag) {
732 /* Print all the LS adv's */
733 lshp = op->ospf_db.db_lshdr;
734 while (ospf_print_lshdr(lshp) != -1) {
735 ++lshp;
736 }
737 }
738 break;
739
740 case OSPF_TYPE_LS_REQ:
741 lsrp = op->ospf_lsr;
742 while ((u_char *)lsrp < dataend) {
743 TCHECK(*lsrp);
744
745 printf("\n\t Advertising Router: %s, %s LSA (%u)",
746 ipaddr_string(&lsrp->ls_router),
747 tok2str(lsa_values,"unknown",EXTRACT_32BITS(lsrp->ls_type)),
748 EXTRACT_32BITS(&lsrp->ls_type));
749
750 switch (EXTRACT_32BITS(lsrp->ls_type)) {
751 /* the LSA header for opaque LSAs was slightly changed */
752 case LS_TYPE_OPAQUE_LL:
753 case LS_TYPE_OPAQUE_AL:
754 case LS_TYPE_OPAQUE_DW:
755 printf(", Opaque-Type: %s LSA (%u), Opaque-ID: %u",
756 tok2str(lsa_opaque_values, "unknown",lsrp->un_ls_stateid.opaque_field.opaque_type),
757 lsrp->un_ls_stateid.opaque_field.opaque_type,
758 EXTRACT_24BITS(&lsrp->un_ls_stateid.opaque_field.opaque_id));
759 break;
760 default:
761 printf(", LSA-ID: %s",
762 ipaddr_string(&lsrp->un_ls_stateid.ls_stateid));
763 break;
764 }
765
766 ++lsrp;
767 }
768 break;
769
770 case OSPF_TYPE_LS_UPDATE:
771 lsap = op->ospf_lsu.lsu_lsa;
772 TCHECK(op->ospf_lsu.lsu_count);
773 lsa_count_max = EXTRACT_32BITS(&op->ospf_lsu.lsu_count);
774 printf(", %d LSA%s",lsa_count_max, lsa_count_max > 1 ? "s" : "");
775 for (lsa_count=1;lsa_count <= lsa_count_max;lsa_count++) {
776 printf("\n\t LSA #%u",lsa_count);
777 lsap = (const struct lsa *)ospf_print_lsa(lsap);
778 if (lsap == NULL)
779 goto trunc;
780 }
781 break;
782
783 case OSPF_TYPE_LS_ACK:
784 lshp = op->ospf_lsa.lsa_lshdr;
785 while (ospf_print_lshdr(lshp) != -1) {
786 ++lshp;
787 }
788 break;
789
790 default:
791 printf("v2 type (%d)", op->ospf_type);
792 break;
793 }
794 return (0);
795 trunc:
796 return (1);
797 }
798
799 void
800 ospf_print(register const u_char *bp, register u_int length,
801 register const u_char *bp2)
802 {
803 register const struct ospfhdr *op;
804 register const struct ip *ip;
805 register const u_char *dataend;
806 register const char *cp;
807
808 op = (struct ospfhdr *)bp;
809 ip = (struct ip *)bp2;
810
811 /* XXX Before we do anything else, strip off the MD5 trailer */
812 TCHECK(op->ospf_authtype);
813 if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) {
814 length -= OSPF_AUTH_MD5_LEN;
815 snapend -= OSPF_AUTH_MD5_LEN;
816 }
817
818 /* If the type is valid translate it, or just print the type */
819 /* value. If it's not valid, say so and return */
820 TCHECK(op->ospf_type);
821 cp = tok2str(type2str, "unknown LS-type", op->ospf_type);
822 printf("OSPFv%u, %s (%u), length: %u",
823 op->ospf_version,
824 cp,
825 op->ospf_type,
826 length);
827 if (*cp == 'u')
828 return;
829
830 if(!vflag) /* non verbose - so lets bail out here */
831 return;
832
833 TCHECK(op->ospf_len);
834 if (length != EXTRACT_16BITS(&op->ospf_len)) {
835 printf(" [len %d]", EXTRACT_16BITS(&op->ospf_len));
836 return;
837 }
838 dataend = bp + length;
839
840 TCHECK(op->ospf_routerid);
841 printf("\n\tRouter-ID: %s", ipaddr_string(&op->ospf_routerid));
842
843 TCHECK(op->ospf_areaid);
844 if (op->ospf_areaid.s_addr != 0)
845 printf(", Area %s", ipaddr_string(&op->ospf_areaid));
846 else
847 printf(", Backbone Area");
848
849 if (vflag) {
850 /* Print authentication data (should we really do this?) */
851 TCHECK2(op->ospf_authdata[0], sizeof(op->ospf_authdata));
852
853 printf(", Authentication Type: %s (%u)",
854 tok2str(ospf_authtype_values,"unknown",EXTRACT_16BITS(&op->ospf_authtype)),
855 EXTRACT_16BITS(&op->ospf_authtype));
856
857 switch (EXTRACT_16BITS(&op->ospf_authtype)) {
858
859 case OSPF_AUTH_NONE:
860 break;
861
862 case OSPF_AUTH_SIMPLE:
863 (void)fn_printn(op->ospf_authdata,
864 sizeof(op->ospf_authdata), NULL);
865 printf("\"");
866 break;
867
868 case OSPF_AUTH_MD5:
869 printf("\n\tKey-ID: %u, Auth-Length: %u, Crypto Sequence Number: 0x%08x",
870 *((op->ospf_authdata)+2),
871 *((op->ospf_authdata)+3),
872 EXTRACT_32BITS((op->ospf_authdata)+4));
873 break;
874
875 default:
876 return;
877 }
878 }
879 /* Do rest according to version. */
880 switch (op->ospf_version) {
881
882 case 2:
883 /* ospf version 2 */
884 if (ospf_decode_v2(op, dataend))
885 goto trunc;
886 break;
887
888 default:
889 printf(" ospf [version %d]", op->ospf_version);
890 break;
891 } /* end switch on version */
892
893 return;
894 trunc:
895 fputs(tstr, stdout);
896 }