]> The Tcpdump Group git mirrors - tcpdump/blob - print-ospf.c
"if (!TTEST2(x, y)) goto trunc" is just "TCHECK2(x, y)".
[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.51 2004-03-24 02:32:27 guy 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 TCHECK2(*tptr, 4);
433 if (ls_length < 4) {
434 printf("\n\t Remaining LS length %u < 4", ls_length);
435 return(ls_end);
436 }
437 tlv_type = EXTRACT_16BITS(tptr);
438 tlv_length = EXTRACT_16BITS(tptr+2);
439 tptr+=4;
440 ls_length-=4;
441
442 printf("\n\t %s TLV (%u), length: %u, value: ",
443 tok2str(lsa_opaque_grace_tlv_values,"unknown",tlv_type),
444 tlv_type,
445 tlv_length);
446
447 if (tlv_length > ls_length) {
448 printf("\n\t Bogus length %u > %u", tlv_length,
449 ls_length);
450 return(ls_end);
451 }
452 ls_length-=tlv_length;
453 TCHECK2(*tptr, 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 TCHECK2(*tptr, 4);
496 if (ls_length < 4) {
497 printf("\n\t Remaining LS length %u < 4", ls_length);
498 return(ls_end);
499 }
500 tlv_type = EXTRACT_16BITS(tptr);
501 tlv_length = EXTRACT_16BITS(tptr+2);
502 tptr+=4;
503 ls_length-=4;
504
505 printf("\n\t %s TLV (%u), length: %u",
506 tok2str(lsa_opaque_te_tlv_values,"unknown",tlv_type),
507 tlv_type,
508 tlv_length);
509
510 if (tlv_length > ls_length) {
511 printf("\n\t Bogus length %u > %u", tlv_length,
512 ls_length);
513 return(ls_end);
514 }
515 ls_length-=tlv_length;
516 switch(tlv_type) {
517 case LS_OPAQUE_TE_TLV_LINK:
518 while (tlv_length != 0) {
519 if (tlv_length < 4) {
520 printf("\n\t Remaining TLV length %u < 4",
521 tlv_length);
522 return(ls_end);
523 }
524 TCHECK2(*tptr, 4);
525 subtlv_type = EXTRACT_16BITS(tptr);
526 subtlv_length = EXTRACT_16BITS(tptr+2);
527 tptr+=4;
528 tlv_length-=4;
529
530 printf("\n\t %s subTLV (%u), length: %u",
531 tok2str(lsa_opaque_te_link_tlv_subtlv_values,"unknown",subtlv_type),
532 subtlv_type,
533 subtlv_length);
534
535 TCHECK2(*tptr, subtlv_length);
536 switch(subtlv_type) {
537 case LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP:
538 printf(", 0x%08x", EXTRACT_32BITS(tptr));
539 break;
540 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID:
541 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID:
542 printf(", %s (0x%08x)",
543 ipaddr_string(tptr),
544 EXTRACT_32BITS(tptr));
545 if (subtlv_length == 8) /* draft-ietf-ccamp-ospf-gmpls-extensions */
546 printf(", %s (0x%08x)",
547 ipaddr_string(tptr+4),
548 EXTRACT_32BITS(tptr+4));
549 break;
550 case LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP:
551 case LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP:
552 printf(", %s", ipaddr_string(tptr));
553 break;
554 case LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW:
555 case LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW:
556 bw.i = EXTRACT_32BITS(tptr);
557 printf(", %.3f Mbps", bw.f*8/1000000 );
558 break;
559 case LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW:
560 for (priority_level = 0; priority_level < 8; priority_level++) {
561 bw.i = EXTRACT_32BITS(tptr+priority_level*4);
562 printf("\n\t\tpriority level %d: %.3f Mbps",
563 priority_level,
564 bw.f*8/1000000 );
565 }
566 break;
567 case LS_OPAQUE_TE_LINK_SUBTLV_DIFFSERV_TE:
568 printf("\n\t\tBandwidth Constraints Model ID: (%u)", *tptr);
569 for (bandwidth_constraint = 0; bandwidth_constraint < 8; bandwidth_constraint++) {
570 bw.i = EXTRACT_32BITS(tptr+4+bandwidth_constraint*4);
571 printf("\n\t\t Bandwidth constraint %d: %.3f Mbps",
572 bandwidth_constraint,
573 bw.f*8/1000000 );
574 }
575 break;
576 case LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC:
577 printf(", Metric %u", EXTRACT_32BITS(tptr));
578 break;
579 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE:
580 printf(", %s, Priority %u",
581 bittok2str(gmpls_link_prot_values, "none", *tptr),
582 *(tptr+1));
583 break;
584 case LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR:
585 printf("\n\t\tInterface Switching Capability: %s",
586 tok2str(gmpls_switch_cap_values, "Unknown", *(tptr)));
587 printf("\n\t\tLSP Encoding: %s\n\t\tMax LSP Bandwidth:",
588 tok2str(gmpls_encoding_values, "Unknown", *(tptr+1)));
589 for (priority_level = 0; priority_level < 8; priority_level++) {
590 bw.i = EXTRACT_32BITS(tptr+4+(priority_level*4));
591 printf("\n\t\t priority level %d: %.3f Mbps",
592 priority_level,
593 bw.f*8/1000000 );
594 }
595 break;
596 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE:
597 printf(", %s (%u)",
598 tok2str(lsa_opaque_te_tlv_link_type_sub_tlv_values,"unknown",*tptr),
599 *tptr);
600 break;
601
602 case LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP:
603 count_srlg = subtlv_length / 4;
604 if (count_srlg != 0)
605 printf("\n\t\t Shared risk group: ");
606 while (count_srlg > 0) {
607 bw.i = EXTRACT_32BITS(tptr);
608 printf("%d",bw.i);
609 tptr+=4;
610 count_srlg--;
611 if (count_srlg > 0)
612 printf(", ");
613 }
614 break;
615
616 default:
617 if (vflag <= 1) {
618 if(!print_unknown_data(tptr,"\n\t\t",subtlv_length))
619 return(ls_end);
620 }
621 break;
622 }
623 /* in OSPF everything has to be 32-bit aligned, including TLVs */
624 if (subtlv_length%4 != 0)
625 subtlv_length+=4-(subtlv_length%4);
626
627 tlv_length-=subtlv_length;
628 tptr+=subtlv_length;
629
630 }
631 break;
632
633 case LS_OPAQUE_TE_TLV_ROUTER:
634 if (tlv_length < 4) {
635 printf("\n\t TLV length %u < 4", tlv_length);
636 return(ls_end);
637 }
638 TCHECK2(*tptr, 4);
639 printf(", %s", ipaddr_string(tptr));
640 break;
641
642 default:
643 if (vflag <= 1) {
644 if(!print_unknown_data(tptr,"\n\t ",tlv_length))
645 return(ls_end);
646 }
647 break;
648 }
649 tptr+=tlv_length;
650 }
651 break;
652 }
653 break;
654 default:
655 if (vflag <= 1) {
656 if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown,
657 "\n\t ", ls_length))
658 return(ls_end);
659 }
660 break;
661 }
662
663 /* do we want to see an additionally hexdump ? */
664 if (vflag> 1)
665 if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown,
666 "\n\t ", ls_length)) {
667 return(ls_end);
668 }
669
670 return (ls_end);
671 trunc:
672 return (NULL);
673 }
674
675 static int
676 ospf_decode_v2(register const struct ospfhdr *op,
677 register const u_char *dataend)
678 {
679 register const struct in_addr *ap;
680 register const struct lsr *lsrp;
681 register const struct lsa_hdr *lshp;
682 register const struct lsa *lsap;
683 register u_int32_t lsa_count,lsa_count_max;
684
685 switch (op->ospf_type) {
686
687 case OSPF_TYPE_UMD:
688 /*
689 * Rob Coltun's special monitoring packets;
690 * do nothing
691 */
692 break;
693
694 case OSPF_TYPE_HELLO:
695 printf("\n\tOptions: [%s]",
696 bittok2str(ospf_option_values,"none",op->ospf_hello.hello_options));
697
698 TCHECK(op->ospf_hello.hello_deadint);
699 printf("\n\t Hello Timer: %us, Dead Timer %us, Mask: %s, Priority: %u",
700 EXTRACT_16BITS(&op->ospf_hello.hello_helloint),
701 EXTRACT_32BITS(&op->ospf_hello.hello_deadint),
702 ipaddr_string(&op->ospf_hello.hello_mask),
703 op->ospf_hello.hello_priority);
704
705 TCHECK(op->ospf_hello.hello_dr);
706 if (op->ospf_hello.hello_dr.s_addr != 0)
707 printf("\n\t Designated Router %s",
708 ipaddr_string(&op->ospf_hello.hello_dr));
709
710 TCHECK(op->ospf_hello.hello_bdr);
711 if (op->ospf_hello.hello_bdr.s_addr != 0)
712 printf(", Backup Designated Router %s",
713 ipaddr_string(&op->ospf_hello.hello_bdr));
714
715 ap = op->ospf_hello.hello_neighbor;
716 if ((u_char *)ap < dataend)
717 printf("\n\t Neighbor List:");
718 while ((u_char *)ap < dataend) {
719 TCHECK(*ap);
720 printf("\n\t %s", ipaddr_string(ap));
721 ++ap;
722 }
723 break; /* HELLO */
724
725 case OSPF_TYPE_DD:
726 TCHECK(op->ospf_db.db_options);
727 printf("\n\tOptions: [%s]",
728 bittok2str(ospf_option_values,"none",op->ospf_db.db_options));
729 TCHECK(op->ospf_db.db_flags);
730 printf(", DD Flags: [%s]",
731 bittok2str(ospf_dd_flag_values,"none",op->ospf_db.db_flags));
732
733 if (vflag) {
734 /* Print all the LS adv's */
735 lshp = op->ospf_db.db_lshdr;
736 while (ospf_print_lshdr(lshp) != -1) {
737 ++lshp;
738 }
739 }
740 break;
741
742 case OSPF_TYPE_LS_REQ:
743 lsrp = op->ospf_lsr;
744 while ((u_char *)lsrp < dataend) {
745 TCHECK(*lsrp);
746
747 printf("\n\t Advertising Router: %s, %s LSA (%u)",
748 ipaddr_string(&lsrp->ls_router),
749 tok2str(lsa_values,"unknown",EXTRACT_32BITS(lsrp->ls_type)),
750 EXTRACT_32BITS(&lsrp->ls_type));
751
752 switch (EXTRACT_32BITS(lsrp->ls_type)) {
753 /* the LSA header for opaque LSAs was slightly changed */
754 case LS_TYPE_OPAQUE_LL:
755 case LS_TYPE_OPAQUE_AL:
756 case LS_TYPE_OPAQUE_DW:
757 printf(", Opaque-Type: %s LSA (%u), Opaque-ID: %u",
758 tok2str(lsa_opaque_values, "unknown",lsrp->un_ls_stateid.opaque_field.opaque_type),
759 lsrp->un_ls_stateid.opaque_field.opaque_type,
760 EXTRACT_24BITS(&lsrp->un_ls_stateid.opaque_field.opaque_id));
761 break;
762 default:
763 printf(", LSA-ID: %s",
764 ipaddr_string(&lsrp->un_ls_stateid.ls_stateid));
765 break;
766 }
767
768 ++lsrp;
769 }
770 break;
771
772 case OSPF_TYPE_LS_UPDATE:
773 lsap = op->ospf_lsu.lsu_lsa;
774 TCHECK(op->ospf_lsu.lsu_count);
775 lsa_count_max = EXTRACT_32BITS(&op->ospf_lsu.lsu_count);
776 printf(", %d LSA%s",lsa_count_max, lsa_count_max > 1 ? "s" : "");
777 for (lsa_count=1;lsa_count <= lsa_count_max;lsa_count++) {
778 printf("\n\t LSA #%u",lsa_count);
779 lsap = (const struct lsa *)ospf_print_lsa(lsap);
780 if (lsap == NULL)
781 goto trunc;
782 }
783 break;
784
785 case OSPF_TYPE_LS_ACK:
786 lshp = op->ospf_lsa.lsa_lshdr;
787 while (ospf_print_lshdr(lshp) != -1) {
788 ++lshp;
789 }
790 break;
791
792 default:
793 printf("v2 type (%d)", op->ospf_type);
794 break;
795 }
796 return (0);
797 trunc:
798 return (1);
799 }
800
801 void
802 ospf_print(register const u_char *bp, register u_int length,
803 register const u_char *bp2)
804 {
805 register const struct ospfhdr *op;
806 register const struct ip *ip;
807 register const u_char *dataend;
808 register const char *cp;
809
810 op = (struct ospfhdr *)bp;
811 ip = (struct ip *)bp2;
812
813 /* XXX Before we do anything else, strip off the MD5 trailer */
814 TCHECK(op->ospf_authtype);
815 if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) {
816 length -= OSPF_AUTH_MD5_LEN;
817 snapend -= OSPF_AUTH_MD5_LEN;
818 }
819
820 /* If the type is valid translate it, or just print the type */
821 /* value. If it's not valid, say so and return */
822 TCHECK(op->ospf_type);
823 cp = tok2str(type2str, "unknown LS-type", op->ospf_type);
824 printf("OSPFv%u, %s (%u), length: %u",
825 op->ospf_version,
826 cp,
827 op->ospf_type,
828 length);
829 if (*cp == 'u')
830 return;
831
832 if(!vflag) /* non verbose - so lets bail out here */
833 return;
834
835 TCHECK(op->ospf_len);
836 if (length != EXTRACT_16BITS(&op->ospf_len)) {
837 printf(" [len %d]", EXTRACT_16BITS(&op->ospf_len));
838 return;
839 }
840 dataend = bp + length;
841
842 TCHECK(op->ospf_routerid);
843 printf("\n\tRouter-ID: %s", ipaddr_string(&op->ospf_routerid));
844
845 TCHECK(op->ospf_areaid);
846 if (op->ospf_areaid.s_addr != 0)
847 printf(", Area %s", ipaddr_string(&op->ospf_areaid));
848 else
849 printf(", Backbone Area");
850
851 if (vflag) {
852 /* Print authentication data (should we really do this?) */
853 TCHECK2(op->ospf_authdata[0], sizeof(op->ospf_authdata));
854
855 printf(", Authentication Type: %s (%u)",
856 tok2str(ospf_authtype_values,"unknown",EXTRACT_16BITS(&op->ospf_authtype)),
857 EXTRACT_16BITS(&op->ospf_authtype));
858
859 switch (EXTRACT_16BITS(&op->ospf_authtype)) {
860
861 case OSPF_AUTH_NONE:
862 break;
863
864 case OSPF_AUTH_SIMPLE:
865 (void)fn_printn(op->ospf_authdata,
866 sizeof(op->ospf_authdata), NULL);
867 printf("\"");
868 break;
869
870 case OSPF_AUTH_MD5:
871 printf("\n\tKey-ID: %u, Auth-Length: %u, Crypto Sequence Number: 0x%08x",
872 *((op->ospf_authdata)+2),
873 *((op->ospf_authdata)+3),
874 EXTRACT_32BITS((op->ospf_authdata)+4));
875 break;
876
877 default:
878 return;
879 }
880 }
881 /* Do rest according to version. */
882 switch (op->ospf_version) {
883
884 case 2:
885 /* ospf version 2 */
886 if (ospf_decode_v2(op, dataend))
887 goto trunc;
888 break;
889
890 default:
891 printf(" ospf [version %d]", op->ospf_version);
892 break;
893 } /* end switch on version */
894
895 return;
896 trunc:
897 fputs(tstr, stdout);
898 }