xref: /netbsd-src/external/bsd/tcpdump/dist/print-ospf.c (revision ba65fde2d7fefa7d39838fa5fa855e62bd606b5e)
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 #include <sys/cdefs.h>
25 #ifndef lint
26 #if 0
27 static const char rcsid[] _U_ =
28     "@(#) Header: /tcpdump/master/tcpdump/print-ospf.c,v 1.66 2007-10-08 07:53:21 hannes Exp (LBL)";
29 #else
30 __RCSID("$NetBSD: print-ospf.c,v 1.2 2010/12/05 05:11:30 christos Exp $");
31 #endif
32 #endif
33 
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37 
38 #include <tcpdump-stdinc.h>
39 
40 #include <stdio.h>
41 
42 #include "interface.h"
43 #include "addrtoname.h"
44 #include "extract.h"
45 #include "gmpls.h"
46 
47 #include "ospf.h"
48 
49 #include "ip.h"
50 
51 static struct tok ospf_option_values[] = {
52         { OSPF_OPTION_T,	"MultiTopology" }, /* draft-ietf-ospf-mt-09 */
53 	{ OSPF_OPTION_E,	"External" },
54 	{ OSPF_OPTION_MC,	"Multicast" },
55 	{ OSPF_OPTION_NP,	"NSSA" },
56         { OSPF_OPTION_L,        "LLS" },
57 	{ OSPF_OPTION_DC,	"Demand Circuit" },
58 	{ OSPF_OPTION_O,	"Opaque" },
59 	{ OSPF_OPTION_DN,	"Up/Down" },
60 	{ 0,			NULL }
61 };
62 
63 static struct tok ospf_authtype_values[] = {
64 	{ OSPF_AUTH_NONE,	"none" },
65 	{ OSPF_AUTH_SIMPLE,	"simple" },
66 	{ OSPF_AUTH_MD5,	"MD5" },
67 	{ 0,			NULL }
68 };
69 
70 static struct tok ospf_rla_flag_values[] = {
71 	{ RLA_FLAG_B,		"ABR" },
72 	{ RLA_FLAG_E,		"ASBR" },
73 	{ RLA_FLAG_W1,		"Virtual" },
74 	{ RLA_FLAG_W2,		"W2" },
75 	{ 0,			NULL }
76 };
77 
78 static struct tok type2str[] = {
79 	{ OSPF_TYPE_UMD,	"UMD" },
80 	{ OSPF_TYPE_HELLO,	"Hello" },
81 	{ OSPF_TYPE_DD,		"Database Description" },
82 	{ OSPF_TYPE_LS_REQ,	"LS-Request" },
83 	{ OSPF_TYPE_LS_UPDATE,	"LS-Update" },
84 	{ OSPF_TYPE_LS_ACK,	"LS-Ack" },
85 	{ 0,			NULL }
86 };
87 
88 static struct tok lsa_values[] = {
89 	{ LS_TYPE_ROUTER,       "Router" },
90 	{ LS_TYPE_NETWORK,      "Network" },
91 	{ LS_TYPE_SUM_IP,       "Summary" },
92 	{ LS_TYPE_SUM_ABR,      "ASBR Summary" },
93 	{ LS_TYPE_ASE,          "External" },
94 	{ LS_TYPE_GROUP,        "Multicast Group" },
95 	{ LS_TYPE_NSSA,         "NSSA" },
96 	{ LS_TYPE_OPAQUE_LL,    "Link Local Opaque" },
97 	{ LS_TYPE_OPAQUE_AL,    "Area Local Opaque" },
98 	{ LS_TYPE_OPAQUE_DW,    "Domain Wide Opaque" },
99 	{ 0,			NULL }
100 };
101 
102 static struct tok ospf_dd_flag_values[] = {
103 	{ OSPF_DB_INIT,	        "Init" },
104 	{ OSPF_DB_MORE,	        "More" },
105 	{ OSPF_DB_MASTER,	"Master" },
106     { OSPF_DB_RESYNC,	"OOBResync" },
107 	{ 0,			NULL }
108 };
109 
110 static struct tok lsa_opaque_values[] = {
111 	{ LS_OPAQUE_TYPE_TE,    "Traffic Engineering" },
112 	{ LS_OPAQUE_TYPE_GRACE, "Graceful restart" },
113 	{ LS_OPAQUE_TYPE_RI,    "Router Information" },
114 	{ 0,			NULL }
115 };
116 
117 static struct tok lsa_opaque_te_tlv_values[] = {
118 	{ LS_OPAQUE_TE_TLV_ROUTER, "Router Address" },
119 	{ LS_OPAQUE_TE_TLV_LINK,   "Link" },
120 	{ 0,			NULL }
121 };
122 
123 static struct tok lsa_opaque_te_link_tlv_subtlv_values[] = {
124 	{ LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE,            "Link Type" },
125 	{ LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID,              "Link ID" },
126 	{ LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP,             "Local Interface IP address" },
127 	{ LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP,            "Remote Interface IP address" },
128 	{ LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC,            "Traffic Engineering Metric" },
129 	{ LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW,               "Maximum Bandwidth" },
130 	{ LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW,           "Maximum Reservable Bandwidth" },
131 	{ LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW,             "Unreserved Bandwidth" },
132 	{ LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP,          "Administrative Group" },
133 	{ LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier" },
134 	{ LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE, "Link Protection Type" },
135 	{ LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR,    "Interface Switching Capability" },
136 	{ LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP,    "Shared Risk Link Group" },
137 	{ LS_OPAQUE_TE_LINK_SUBTLV_BW_CONSTRAINTS,       "Bandwidth Constraints" },
138 	{ 0,			NULL }
139 };
140 
141 static struct tok lsa_opaque_grace_tlv_values[] = {
142 	{ LS_OPAQUE_GRACE_TLV_PERIOD,             "Grace Period" },
143 	{ LS_OPAQUE_GRACE_TLV_REASON,             "Graceful restart Reason" },
144 	{ LS_OPAQUE_GRACE_TLV_INT_ADDRESS,        "IPv4 interface address" },
145 	{ 0,		        NULL }
146 };
147 
148 static struct tok lsa_opaque_grace_tlv_reason_values[] = {
149 	{ LS_OPAQUE_GRACE_TLV_REASON_UNKNOWN,     "Unknown" },
150 	{ LS_OPAQUE_GRACE_TLV_REASON_SW_RESTART,  "Software Restart" },
151 	{ LS_OPAQUE_GRACE_TLV_REASON_SW_UPGRADE,  "Software Reload/Upgrade" },
152 	{ LS_OPAQUE_GRACE_TLV_REASON_CP_SWITCH,   "Control Processor Switch" },
153 	{ 0,		        NULL }
154 };
155 
156 static struct tok lsa_opaque_te_tlv_link_type_sub_tlv_values[] = {
157 	{ LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_PTP, "Point-to-point" },
158 	{ LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_MA,  "Multi-Access" },
159 	{ 0,			NULL }
160 };
161 
162 static struct tok lsa_opaque_ri_tlv_values[] = {
163 	{ LS_OPAQUE_RI_TLV_CAP, "Router Capabilities" },
164 	{ 0,		        NULL }
165 };
166 
167 static struct tok lsa_opaque_ri_tlv_cap_values[] = {
168 	{ 1, "Reserved" },
169 	{ 2, "Reserved" },
170 	{ 4, "Reserved" },
171 	{ 8, "Reserved" },
172 	{ 16, "graceful restart capable" },
173 	{ 32, "graceful restart helper" },
174 	{ 64, "Stub router support" },
175 	{ 128, "Traffic engineering" },
176 	{ 256, "p2p over LAN" },
177 	{ 512, "path computation server" },
178 	{ 0,		        NULL }
179 };
180 
181 static struct tok ospf_lls_tlv_values[] = {
182 	{ OSPF_LLS_EO,	"Extended Options" },
183 	{ OSPF_LLS_MD5,	"MD5 Authentication" },
184 	{ 0,	NULL }
185 };
186 
187 static struct tok ospf_lls_eo_options[] = {
188 	{ OSPF_LLS_EO_LR,	"LSDB resync" },
189 	{ OSPF_LLS_EO_RS,	"Restart" },
190 	{ 0,	NULL }
191 };
192 
193 static char tstr[] = " [|ospf2]";
194 
195 #ifdef WIN32
196 #define inline __inline
197 #endif /* WIN32 */
198 
199 static int ospf_print_lshdr(const struct lsa_hdr *);
200 static const u_char *ospf_print_lsa(const struct lsa *);
201 static int ospf_decode_v2(const struct ospfhdr *, const u_char *);
202 static int ospf_decode_lls(const struct ospfhdr *, register u_int);
203 
204 int
205 ospf_print_grace_lsa (u_int8_t *tptr, u_int ls_length) {
206 
207     u_int tlv_type, tlv_length;
208 
209 
210     while (ls_length > 0) {
211         TCHECK2(*tptr, 4);
212         if (ls_length < 4) {
213             printf("\n\t    Remaining LS length %u < 4", ls_length);
214             return -1;
215         }
216         tlv_type = EXTRACT_16BITS(tptr);
217         tlv_length = EXTRACT_16BITS(tptr+2);
218         tptr+=4;
219         ls_length-=4;
220 
221         printf("\n\t    %s TLV (%u), length %u, value: ",
222                tok2str(lsa_opaque_grace_tlv_values,"unknown",tlv_type),
223                tlv_type,
224                tlv_length);
225 
226         if (tlv_length > ls_length) {
227             printf("\n\t    Bogus length %u > %u", tlv_length,
228                    ls_length);
229             return -1;
230         }
231 
232         /* Infinite loop protection. */
233         if (tlv_type == 0 || tlv_length ==0) {
234             return -1;
235         }
236 
237         TCHECK2(*tptr, tlv_length);
238         switch(tlv_type) {
239 
240         case LS_OPAQUE_GRACE_TLV_PERIOD:
241             if (tlv_length != 4) {
242                 printf("\n\t    Bogus length %u != 4", tlv_length);
243                 return -1;
244             }
245             printf("%us",EXTRACT_32BITS(tptr));
246             break;
247 
248         case LS_OPAQUE_GRACE_TLV_REASON:
249             if (tlv_length != 1) {
250                 printf("\n\t    Bogus length %u != 1", tlv_length);
251                 return -1;
252             }
253             printf("%s (%u)",
254                    tok2str(lsa_opaque_grace_tlv_reason_values, "Unknown", *tptr),
255                    *tptr);
256             break;
257 
258         case LS_OPAQUE_GRACE_TLV_INT_ADDRESS:
259             if (tlv_length != 4) {
260                 printf("\n\t    Bogus length %u != 4", tlv_length);
261                 return -1;
262             }
263             printf("%s", ipaddr_string(tptr));
264             break;
265 
266         default:
267             if (vflag <= 1) {
268                 if(!print_unknown_data(tptr,"\n\t      ",tlv_length))
269                     return -1;
270             }
271             break;
272 
273         }
274         /* in OSPF everything has to be 32-bit aligned, including TLVs */
275         if (tlv_length%4 != 0)
276             tlv_length+=4-(tlv_length%4);
277         ls_length-=tlv_length;
278         tptr+=tlv_length;
279     }
280 
281     return 0;
282 trunc:
283     return -1;
284 }
285 
286 int
287 ospf_print_te_lsa (u_int8_t *tptr, u_int ls_length) {
288 
289     u_int tlv_type, tlv_length, subtlv_type, subtlv_length;
290     u_int priority_level, te_class, count_srlg;
291     union { /* int to float conversion buffer for several subTLVs */
292         float f;
293         u_int32_t i;
294     } bw;
295 
296     while (ls_length != 0) {
297         TCHECK2(*tptr, 4);
298         if (ls_length < 4) {
299             printf("\n\t    Remaining LS length %u < 4", ls_length);
300             return -1;
301         }
302         tlv_type = EXTRACT_16BITS(tptr);
303         tlv_length = EXTRACT_16BITS(tptr+2);
304         tptr+=4;
305         ls_length-=4;
306 
307         printf("\n\t    %s TLV (%u), length: %u",
308                tok2str(lsa_opaque_te_tlv_values,"unknown",tlv_type),
309                tlv_type,
310                tlv_length);
311 
312         if (tlv_length > ls_length) {
313             printf("\n\t    Bogus length %u > %u", tlv_length,
314                    ls_length);
315             return -1;
316         }
317 
318         /* Infinite loop protection. */
319         if (tlv_type == 0 || tlv_length ==0) {
320             return -1;
321         }
322 
323         switch(tlv_type) {
324         case LS_OPAQUE_TE_TLV_LINK:
325             while (tlv_length >= sizeof(subtlv_type) + sizeof(subtlv_length)) {
326                 if (tlv_length < 4) {
327                     printf("\n\t    Remaining TLV length %u < 4",
328                            tlv_length);
329                     return -1;
330                 }
331                 TCHECK2(*tptr, 4);
332                 subtlv_type = EXTRACT_16BITS(tptr);
333                 subtlv_length = EXTRACT_16BITS(tptr+2);
334                 tptr+=4;
335                 tlv_length-=4;
336 
337                 printf("\n\t      %s subTLV (%u), length: %u",
338                        tok2str(lsa_opaque_te_link_tlv_subtlv_values,"unknown",subtlv_type),
339                        subtlv_type,
340                        subtlv_length);
341 
342                 TCHECK2(*tptr, subtlv_length);
343                 switch(subtlv_type) {
344                 case LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP:
345                     printf(", 0x%08x", EXTRACT_32BITS(tptr));
346                     break;
347                 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID:
348                 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID:
349                     printf(", %s (0x%08x)",
350                            ipaddr_string(tptr),
351                            EXTRACT_32BITS(tptr));
352                     if (subtlv_length == 8) /* rfc4203 */
353                         printf(", %s (0x%08x)",
354                                ipaddr_string(tptr+4),
355                                EXTRACT_32BITS(tptr+4));
356                     break;
357                 case LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP:
358                 case LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP:
359                     printf(", %s", ipaddr_string(tptr));
360                     break;
361                 case LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW:
362                 case LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW:
363                     bw.i = EXTRACT_32BITS(tptr);
364                     printf(", %.3f Mbps", bw.f*8/1000000 );
365                     break;
366                 case LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW:
367                     for (te_class = 0; te_class < 8; te_class++) {
368                         bw.i = EXTRACT_32BITS(tptr+te_class*4);
369                         printf("\n\t\tTE-Class %u: %.3f Mbps",
370                                te_class,
371                                bw.f*8/1000000 );
372                     }
373                     break;
374                 case LS_OPAQUE_TE_LINK_SUBTLV_BW_CONSTRAINTS:
375                     printf("\n\t\tBandwidth Constraints Model ID: %s (%u)",
376                            tok2str(diffserv_te_bc_values, "unknown", *tptr),
377                            *tptr);
378                     /* decode BCs until the subTLV ends */
379                     for (te_class = 0; te_class < (subtlv_length-4)/4; te_class++) {
380                         bw.i = EXTRACT_32BITS(tptr+4+te_class*4);
381                         printf("\n\t\t  Bandwidth constraint CT%u: %.3f Mbps",
382                                te_class,
383                                bw.f*8/1000000 );
384                     }
385                     break;
386                 case LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC:
387                     printf(", Metric %u", EXTRACT_32BITS(tptr));
388                     break;
389                 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE:
390                     printf(", %s, Priority %u",
391                            bittok2str(gmpls_link_prot_values, "none", *tptr),
392                            *(tptr+1));
393                     break;
394                 case LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR:
395                     printf("\n\t\tInterface Switching Capability: %s",
396                            tok2str(gmpls_switch_cap_values, "Unknown", *(tptr)));
397                     printf("\n\t\tLSP Encoding: %s\n\t\tMax LSP Bandwidth:",
398                            tok2str(gmpls_encoding_values, "Unknown", *(tptr+1)));
399                     for (priority_level = 0; priority_level < 8; priority_level++) {
400                         bw.i = EXTRACT_32BITS(tptr+4+(priority_level*4));
401                         printf("\n\t\t  priority level %d: %.3f Mbps",
402                                priority_level,
403                                bw.f*8/1000000 );
404                     }
405                     break;
406                 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE:
407                     printf(", %s (%u)",
408                            tok2str(lsa_opaque_te_tlv_link_type_sub_tlv_values,"unknown",*tptr),
409                            *tptr);
410                     break;
411 
412                 case LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP:
413                     count_srlg = subtlv_length / 4;
414                     if (count_srlg != 0)
415                         printf("\n\t\t  Shared risk group: ");
416                     while (count_srlg > 0) {
417                         bw.i = EXTRACT_32BITS(tptr);
418                         printf("%d",bw.i);
419                         tptr+=4;
420                         count_srlg--;
421                         if (count_srlg > 0)
422                             printf(", ");
423                     }
424                     break;
425 
426                 default:
427                     if (vflag <= 1) {
428                         if(!print_unknown_data(tptr,"\n\t\t",subtlv_length))
429                             return -1;
430                     }
431                     break;
432                 }
433                 /* in OSPF everything has to be 32-bit aligned, including subTLVs */
434                 if (subtlv_length%4 != 0)
435                     subtlv_length+=4-(subtlv_length%4);
436 
437                 tlv_length-=subtlv_length;
438                 tptr+=subtlv_length;
439 
440             }
441             break;
442 
443         case LS_OPAQUE_TE_TLV_ROUTER:
444             if (tlv_length < 4) {
445                 printf("\n\t    TLV length %u < 4", tlv_length);
446                 return -1;
447             }
448             TCHECK2(*tptr, 4);
449             printf(", %s", ipaddr_string(tptr));
450             break;
451 
452         default:
453             if (vflag <= 1) {
454                 if(!print_unknown_data(tptr,"\n\t      ",tlv_length))
455                     return -1;
456             }
457             break;
458         }
459         /* in OSPF everything has to be 32-bit aligned, including TLVs */
460         if (tlv_length%4 != 0)
461             tlv_length+=4-(tlv_length%4);
462         ls_length-=tlv_length;
463         tptr+=tlv_length;
464     }
465     return 0;
466 trunc:
467     return -1;
468 }
469 
470 
471 static int
472 ospf_print_lshdr(register const struct lsa_hdr *lshp)
473 {
474         u_int ls_length;
475 
476         TCHECK(lshp->ls_length);
477         ls_length = EXTRACT_16BITS(&lshp->ls_length);
478         if (ls_length < sizeof(struct lsa_hdr)) {
479                 printf("\n\t    Bogus length %u < header (%lu)", ls_length,
480                     (unsigned long)sizeof(struct lsa_hdr));
481                 return(-1);
482         }
483 
484         TCHECK(lshp->ls_seq);	/* XXX - ls_length check checked this */
485 	printf("\n\t  Advertising Router %s, seq 0x%08x, age %us, length %u",
486 	       ipaddr_string(&lshp->ls_router),
487 	       EXTRACT_32BITS(&lshp->ls_seq),
488 	       EXTRACT_16BITS(&lshp->ls_age),
489                ls_length-(u_int)sizeof(struct lsa_hdr));
490 
491 	TCHECK(lshp->ls_type);	/* XXX - ls_length check checked this */
492         switch (lshp->ls_type) {
493 	/* the LSA header for opaque LSAs was slightly changed */
494         case LS_TYPE_OPAQUE_LL:
495         case LS_TYPE_OPAQUE_AL:
496         case LS_TYPE_OPAQUE_DW:
497             printf("\n\t    %s LSA (%d), Opaque-Type %s LSA (%u), Opaque-ID %u",
498                    tok2str(lsa_values,"unknown",lshp->ls_type),
499                    lshp->ls_type,
500 
501 		   tok2str(lsa_opaque_values,
502 			   "unknown",
503 			   *(&lshp->un_lsa_id.opaque_field.opaque_type)),
504 		   *(&lshp->un_lsa_id.opaque_field.opaque_type),
505 		   EXTRACT_24BITS(&lshp->un_lsa_id.opaque_field.opaque_id)
506 
507                    );
508             break;
509 
510 	/* all other LSA types use regular style LSA headers */
511 	default:
512             printf("\n\t    %s LSA (%d), LSA-ID: %s",
513                    tok2str(lsa_values,"unknown",lshp->ls_type),
514                    lshp->ls_type,
515                    ipaddr_string(&lshp->un_lsa_id.lsa_id));
516             break;
517         }
518 
519 	TCHECK(lshp->ls_options);	/* XXX - ls_length check checked this */
520         printf("\n\t    Options: [%s]", bittok2str(ospf_option_values,"none",lshp->ls_options));
521 
522         return (ls_length);
523 trunc:
524 	return (-1);
525 }
526 
527 /* draft-ietf-ospf-mt-09 */
528 static struct tok ospf_topology_values[] = {
529     { 0, "default " },
530     { 1, "multicast " },
531     { 2, "management " },
532     { 0, NULL }
533 };
534 
535 /*
536  * Print all the per-topology metrics.
537  */
538 static void
539 ospf_print_tos_metrics(const union un_tos *tos)
540 {
541     int metric_count;
542     int toscount;
543 
544     toscount = tos->link.link_tos_count+1;
545     metric_count = 0;
546 
547     /*
548      * All but the first metric contain a valid topology id.
549      */
550     while (toscount) {
551         printf("\n\t\ttopology %s(%u), metric %u",
552                tok2str(ospf_topology_values, "",
553                        metric_count ? tos->metrics.tos_type : 0),
554                metric_count ? tos->metrics.tos_type : 0,
555                EXTRACT_16BITS(&tos->metrics.tos_metric));
556         metric_count++;
557         tos++;
558         toscount--;
559     }
560 }
561 
562 /*
563  * Print a single link state advertisement.  If truncated or if LSA length
564  * field is less than the length of the LSA header, return NULl, else
565  * return pointer to data past end of LSA.
566  */
567 static const u_int8_t *
568 ospf_print_lsa(register const struct lsa *lsap)
569 {
570 	register const u_int8_t *ls_end;
571 	register const struct rlalink *rlp;
572 	register const struct in_addr *ap;
573 	register const struct aslametric *almp;
574 	register const struct mcla *mcp;
575 	register const u_int32_t *lp;
576 	register int j, tlv_type, tlv_length, topology;
577 	register int ls_length;
578 	const u_int8_t *tptr;
579 
580 	tptr = (u_int8_t *)lsap->lsa_un.un_unknown; /* squelch compiler warnings */
581         ls_length = ospf_print_lshdr(&lsap->ls_hdr);
582         if (ls_length == -1)
583                 return(NULL);
584 	ls_end = (u_int8_t *)lsap + ls_length;
585 	ls_length -= sizeof(struct lsa_hdr);
586 
587 	switch (lsap->ls_hdr.ls_type) {
588 
589 	case LS_TYPE_ROUTER:
590 		TCHECK(lsap->lsa_un.un_rla.rla_flags);
591                 printf("\n\t    Router LSA Options: [%s]", bittok2str(ospf_rla_flag_values,"none",lsap->lsa_un.un_rla.rla_flags));
592 
593 		TCHECK(lsap->lsa_un.un_rla.rla_count);
594 		j = EXTRACT_16BITS(&lsap->lsa_un.un_rla.rla_count);
595 		TCHECK(lsap->lsa_un.un_rla.rla_link);
596 		rlp = lsap->lsa_un.un_rla.rla_link;
597 		while (j--) {
598 			TCHECK(*rlp);
599 			switch (rlp->un_tos.link.link_type) {
600 
601 			case RLA_TYPE_VIRTUAL:
602 				printf("\n\t      Virtual Link: Neighbor Router-ID: %s, Interface Address: %s",
603 				    ipaddr_string(&rlp->link_id),
604 				    ipaddr_string(&rlp->link_data));
605                                 break;
606 
607 			case RLA_TYPE_ROUTER:
608 				printf("\n\t      Neighbor Router-ID: %s, Interface Address: %s",
609 				    ipaddr_string(&rlp->link_id),
610 				    ipaddr_string(&rlp->link_data));
611 				break;
612 
613 			case RLA_TYPE_TRANSIT:
614 				printf("\n\t      Neighbor Network-ID: %s, Interface Address: %s",
615 				    ipaddr_string(&rlp->link_id),
616 				    ipaddr_string(&rlp->link_data));
617 				break;
618 
619 			case RLA_TYPE_STUB:
620 				printf("\n\t      Stub Network: %s, Mask: %s",
621 				    ipaddr_string(&rlp->link_id),
622 				    ipaddr_string(&rlp->link_data));
623 				break;
624 
625 			default:
626 				printf("\n\t      Unknown Router Link Type (%u)",
627 				    rlp->un_tos.link.link_type);
628 				return (ls_end);
629 			}
630 
631                         ospf_print_tos_metrics(&rlp->un_tos);
632 
633 			rlp = (struct rlalink *)((u_char *)(rlp + 1) +
634 			    ((rlp->un_tos.link.link_tos_count) * sizeof(union un_tos)));
635 		}
636 		break;
637 
638 	case LS_TYPE_NETWORK:
639 		TCHECK(lsap->lsa_un.un_nla.nla_mask);
640 		printf("\n\t    Mask %s\n\t    Connected Routers:",
641 		    ipaddr_string(&lsap->lsa_un.un_nla.nla_mask));
642 		ap = lsap->lsa_un.un_nla.nla_router;
643 		while ((u_char *)ap < ls_end) {
644 			TCHECK(*ap);
645 			printf("\n\t      %s", ipaddr_string(ap));
646 			++ap;
647 		}
648 		break;
649 
650 	case LS_TYPE_SUM_IP:
651 		TCHECK(lsap->lsa_un.un_nla.nla_mask);
652 		printf("\n\t    Mask %s",
653 		    ipaddr_string(&lsap->lsa_un.un_sla.sla_mask));
654 		TCHECK(lsap->lsa_un.un_sla.sla_tosmetric);
655 		lp = lsap->lsa_un.un_sla.sla_tosmetric;
656 		while ((u_char *)lp < ls_end) {
657 			register u_int32_t ul;
658 
659 			TCHECK(*lp);
660 			ul = EXTRACT_32BITS(lp);
661                         topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS;
662 			printf("\n\t\ttopology %s(%u) metric %d",
663                                tok2str(ospf_topology_values, "", topology),
664                                topology,
665                                ul & SLA_MASK_METRIC);
666 			++lp;
667 		}
668 		break;
669 
670 	case LS_TYPE_SUM_ABR:
671 		TCHECK(lsap->lsa_un.un_sla.sla_tosmetric);
672 		lp = lsap->lsa_un.un_sla.sla_tosmetric;
673 		while ((u_char *)lp < ls_end) {
674 			register u_int32_t ul;
675 
676 			TCHECK(*lp);
677 			ul = EXTRACT_32BITS(lp);
678                         topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS;
679 			printf("\n\t\ttopology %s(%u) metric %d",
680                                tok2str(ospf_topology_values, "", topology),
681                                topology,
682                                ul & SLA_MASK_METRIC);
683 			++lp;
684 		}
685 		break;
686 
687 	case LS_TYPE_ASE:
688         case LS_TYPE_NSSA: /* fall through - those LSAs share the same format */
689 		TCHECK(lsap->lsa_un.un_nla.nla_mask);
690 		printf("\n\t    Mask %s",
691 		    ipaddr_string(&lsap->lsa_un.un_asla.asla_mask));
692 
693 		TCHECK(lsap->lsa_un.un_sla.sla_tosmetric);
694 		almp = lsap->lsa_un.un_asla.asla_metric;
695 		while ((u_char *)almp < ls_end) {
696 			register u_int32_t ul;
697 
698 			TCHECK(almp->asla_tosmetric);
699 			ul = EXTRACT_32BITS(&almp->asla_tosmetric);
700                         topology = ((ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS);
701 			printf("\n\t\ttopology %s(%u), type %d, metric",
702                                tok2str(ospf_topology_values, "", topology),
703                                topology,
704                                (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1);
705                         if ((ul & ASLA_MASK_METRIC)==0xffffff)
706                             printf(" infinite");
707                         else
708                             printf(" %d", (ul & ASLA_MASK_METRIC));
709 
710 			TCHECK(almp->asla_forward);
711 			if (almp->asla_forward.s_addr) {
712 				printf(", forward %s",
713 				    ipaddr_string(&almp->asla_forward));
714 			}
715 			TCHECK(almp->asla_tag);
716 			if (almp->asla_tag.s_addr) {
717 				printf(", tag %s",
718 				    ipaddr_string(&almp->asla_tag));
719 			}
720 			++almp;
721 		}
722 		break;
723 
724 	case LS_TYPE_GROUP:
725 		/* Multicast extensions as of 23 July 1991 */
726 		mcp = lsap->lsa_un.un_mcla;
727 		while ((u_char *)mcp < ls_end) {
728 			TCHECK(mcp->mcla_vid);
729 			switch (EXTRACT_32BITS(&mcp->mcla_vtype)) {
730 
731 			case MCLA_VERTEX_ROUTER:
732 				printf("\n\t    Router Router-ID %s",
733 				    ipaddr_string(&mcp->mcla_vid));
734 				break;
735 
736 			case MCLA_VERTEX_NETWORK:
737 				printf("\n\t    Network Designated Router %s",
738 				    ipaddr_string(&mcp->mcla_vid));
739 				break;
740 
741 			default:
742 				printf("\n\t    unknown VertexType (%u)",
743 				    EXTRACT_32BITS(&mcp->mcla_vtype));
744 				break;
745 			}
746 		++mcp;
747 		}
748 		break;
749 
750 	case LS_TYPE_OPAQUE_LL: /* fall through */
751 	case LS_TYPE_OPAQUE_AL:
752 	case LS_TYPE_OPAQUE_DW:
753 
754 	    switch (*(&lsap->ls_hdr.un_lsa_id.opaque_field.opaque_type)) {
755             case LS_OPAQUE_TYPE_RI:
756 		tptr = (u_int8_t *)(&lsap->lsa_un.un_ri_tlv.type);
757 
758 		while (ls_length != 0) {
759                     TCHECK2(*tptr, 4);
760 		    if (ls_length < 4) {
761                         printf("\n\t    Remaining LS length %u < 4", ls_length);
762                         return(ls_end);
763                     }
764                     tlv_type = EXTRACT_16BITS(tptr);
765                     tlv_length = EXTRACT_16BITS(tptr+2);
766                     tptr+=4;
767                     ls_length-=4;
768 
769                     printf("\n\t    %s TLV (%u), length: %u, value: ",
770                            tok2str(lsa_opaque_ri_tlv_values,"unknown",tlv_type),
771                            tlv_type,
772                            tlv_length);
773 
774                     if (tlv_length > ls_length) {
775                         printf("\n\t    Bogus length %u > %u", tlv_length,
776                             ls_length);
777                         return(ls_end);
778                     }
779                     TCHECK2(*tptr, tlv_length);
780                     switch(tlv_type) {
781 
782                     case LS_OPAQUE_RI_TLV_CAP:
783                         if (tlv_length != 4) {
784                             printf("\n\t    Bogus length %u != 4", tlv_length);
785                             return(ls_end);
786                         }
787                         printf("Capabilities: %s",
788                                bittok2str(lsa_opaque_ri_tlv_cap_values, "Unknown", EXTRACT_32BITS(tptr)));
789                         break;
790                     default:
791                         if (vflag <= 1) {
792                             if(!print_unknown_data(tptr,"\n\t      ",tlv_length))
793                                 return(ls_end);
794                         }
795                         break;
796 
797                     }
798                     tptr+=tlv_length;
799                     ls_length-=tlv_length;
800                 }
801                 break;
802 
803             case LS_OPAQUE_TYPE_GRACE:
804                 if (ospf_print_grace_lsa((u_int8_t *)(&lsap->lsa_un.un_grace_tlv.type),
805                                          ls_length) == -1) {
806                     return(ls_end);
807                 }
808                 break;
809 
810 	    case LS_OPAQUE_TYPE_TE:
811                 if (ospf_print_te_lsa((u_int8_t *)(&lsap->lsa_un.un_te_lsa_tlv.type),
812                                       ls_length) == -1) {
813                     return(ls_end);
814                 }
815                 break;
816 
817             default:
818                 if (vflag <= 1) {
819                     if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown,
820                                            "\n\t    ", ls_length))
821                         return(ls_end);
822                 }
823                 break;
824             }
825         }
826 
827         /* do we want to see an additionally hexdump ? */
828         if (vflag> 1)
829             if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown,
830                                    "\n\t    ", ls_length)) {
831                 return(ls_end);
832             }
833 
834 	return (ls_end);
835 trunc:
836 	return (NULL);
837 }
838 
839 static int
840 ospf_decode_lls(register const struct ospfhdr *op,
841 		register u_int length)
842 {
843     register const u_char *dptr;
844     register const u_char *dataend;
845     register u_int length2;
846     register u_int16_t lls_type, lls_len;
847     register u_int32_t lls_flags;
848 
849     switch (op->ospf_type) {
850 
851     case OSPF_TYPE_HELLO:
852         if (!(op->ospf_hello.hello_options & OSPF_OPTION_L))
853             return (0);
854         break;
855 
856     case OSPF_TYPE_DD:
857         if (!(op->ospf_db.db_options & OSPF_OPTION_L))
858             return (0);
859         break;
860 
861     default:
862         return (0);
863     }
864 
865     /* dig deeper if LLS data is available; see RFC4813 */
866     length2 = EXTRACT_16BITS(&op->ospf_len);
867     dptr = (u_char *)op + length2;
868     dataend = (u_char *)op + length;
869 
870     if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) {
871         dptr = dptr + op->ospf_authdata[3];
872         length2 += op->ospf_authdata[3];
873     }
874     if (length2 >= length) {
875         printf("\n\t[LLS truncated]");
876         return (1);
877     }
878     TCHECK2(*dptr, 2);
879     printf("\n\t  LLS: checksum: 0x%04x", (u_int)EXTRACT_16BITS(dptr));
880 
881     dptr += 2;
882     TCHECK2(*dptr, 2);
883     length2 = EXTRACT_16BITS(dptr);
884     printf(", length: %u", length2);
885 
886     dptr += 2;
887     TCHECK(*dptr);
888     while (dptr < dataend) {
889         TCHECK2(*dptr, 2);
890         lls_type = EXTRACT_16BITS(dptr);
891         printf("\n\t    %s (%u)",
892                tok2str(ospf_lls_tlv_values,"Unknown TLV",lls_type),
893                lls_type);
894         dptr += 2;
895         TCHECK2(*dptr, 2);
896         lls_len = EXTRACT_16BITS(dptr);
897         printf(", length: %u", lls_len);
898         dptr += 2;
899         switch (lls_type) {
900 
901         case OSPF_LLS_EO:
902             if (lls_len != 4) {
903                 printf(" [should be 4]");
904                 lls_len = 4;
905             }
906             TCHECK2(*dptr, 4);
907             lls_flags = EXTRACT_32BITS(dptr);
908             printf("\n\t      Options: 0x%08x [%s]", lls_flags,
909                    bittok2str(ospf_lls_eo_options,"?",lls_flags));
910 
911             break;
912 
913         case OSPF_LLS_MD5:
914             if (lls_len != 20) {
915                 printf(" [should be 20]");
916                 lls_len = 20;
917             }
918 			TCHECK2(*dptr, 4);
919             printf("\n\t      Sequence number: 0x%08x", EXTRACT_32BITS(dptr));
920             break;
921         }
922 
923         dptr += lls_len;
924     }
925 
926     return (0);
927 trunc:
928     return (1);
929 }
930 
931 static int
932 ospf_decode_v2(register const struct ospfhdr *op,
933     register const u_char *dataend)
934 {
935 	register const struct in_addr *ap;
936 	register const struct lsr *lsrp;
937 	register const struct lsa_hdr *lshp;
938 	register const struct lsa *lsap;
939 	register u_int32_t lsa_count,lsa_count_max;
940 
941 	switch (op->ospf_type) {
942 
943 	case OSPF_TYPE_UMD:
944 		/*
945 		 * Rob Coltun's special monitoring packets;
946 		 * do nothing
947 		 */
948 		break;
949 
950 	case OSPF_TYPE_HELLO:
951                 printf("\n\tOptions [%s]",
952                        bittok2str(ospf_option_values,"none",op->ospf_hello.hello_options));
953 
954                 TCHECK(op->ospf_hello.hello_deadint);
955                 printf("\n\t  Hello Timer %us, Dead Timer %us, Mask %s, Priority %u",
956                        EXTRACT_16BITS(&op->ospf_hello.hello_helloint),
957                        EXTRACT_32BITS(&op->ospf_hello.hello_deadint),
958                        ipaddr_string(&op->ospf_hello.hello_mask),
959                        op->ospf_hello.hello_priority);
960 
961 		TCHECK(op->ospf_hello.hello_dr);
962 		if (op->ospf_hello.hello_dr.s_addr != 0)
963 			printf("\n\t  Designated Router %s",
964 			    ipaddr_string(&op->ospf_hello.hello_dr));
965 
966 		TCHECK(op->ospf_hello.hello_bdr);
967 		if (op->ospf_hello.hello_bdr.s_addr != 0)
968 			printf(", Backup Designated Router %s",
969 			    ipaddr_string(&op->ospf_hello.hello_bdr));
970 
971                 ap = op->ospf_hello.hello_neighbor;
972                 if ((u_char *)ap < dataend)
973                         printf("\n\t  Neighbor List:");
974                 while ((u_char *)ap < dataend) {
975                         TCHECK(*ap);
976                         printf("\n\t    %s", ipaddr_string(ap));
977                         ++ap;
978                 }
979 		break;	/* HELLO */
980 
981 	case OSPF_TYPE_DD:
982 		TCHECK(op->ospf_db.db_options);
983                 printf("\n\tOptions [%s]",
984                        bittok2str(ospf_option_values,"none",op->ospf_db.db_options));
985 		TCHECK(op->ospf_db.db_flags);
986                 printf(", DD Flags [%s]",
987                        bittok2str(ospf_dd_flag_values,"none",op->ospf_db.db_flags));
988                 TCHECK(op->ospf_db.db_ifmtu);
989                 if (op->ospf_db.db_ifmtu) {
990                         printf(", MTU: %u", EXTRACT_16BITS(&op->ospf_db.db_ifmtu));
991                 }
992                 TCHECK(op->ospf_db.db_seq);
993                 printf(", Sequence: 0x%08x", EXTRACT_32BITS(&op->ospf_db.db_seq));
994 
995                 /* Print all the LS adv's */
996                 lshp = op->ospf_db.db_lshdr;
997                 while (((u_char *)lshp < dataend) && ospf_print_lshdr(lshp) != -1) {
998                     ++lshp;
999                 }
1000 		break;
1001 
1002 	case OSPF_TYPE_LS_REQ:
1003                 lsrp = op->ospf_lsr;
1004                 while ((u_char *)lsrp < dataend) {
1005                     TCHECK(*lsrp);
1006 
1007                     printf("\n\t  Advertising Router: %s, %s LSA (%u)",
1008                            ipaddr_string(&lsrp->ls_router),
1009                            tok2str(lsa_values,"unknown",EXTRACT_32BITS(lsrp->ls_type)),
1010                            EXTRACT_32BITS(&lsrp->ls_type));
1011 
1012                     switch (EXTRACT_32BITS(lsrp->ls_type)) {
1013                         /* the LSA header for opaque LSAs was slightly changed */
1014                     case LS_TYPE_OPAQUE_LL:
1015                     case LS_TYPE_OPAQUE_AL:
1016                     case LS_TYPE_OPAQUE_DW:
1017                         printf(", Opaque-Type: %s LSA (%u), Opaque-ID: %u",
1018                                tok2str(lsa_opaque_values, "unknown",lsrp->un_ls_stateid.opaque_field.opaque_type),
1019                                lsrp->un_ls_stateid.opaque_field.opaque_type,
1020                                EXTRACT_24BITS(&lsrp->un_ls_stateid.opaque_field.opaque_id));
1021                         break;
1022                     default:
1023                         printf(", LSA-ID: %s",
1024                                ipaddr_string(&lsrp->un_ls_stateid.ls_stateid));
1025                         break;
1026                     }
1027 
1028                     ++lsrp;
1029                 }
1030 		break;
1031 
1032 	case OSPF_TYPE_LS_UPDATE:
1033                 lsap = op->ospf_lsu.lsu_lsa;
1034                 TCHECK(op->ospf_lsu.lsu_count);
1035                 lsa_count_max = EXTRACT_32BITS(&op->ospf_lsu.lsu_count);
1036                 printf(", %d LSA%s",lsa_count_max, lsa_count_max > 1 ? "s" : "");
1037                 for (lsa_count=1;lsa_count <= lsa_count_max;lsa_count++) {
1038                     printf("\n\t  LSA #%u",lsa_count);
1039                         lsap = (const struct lsa *)ospf_print_lsa(lsap);
1040                         if (lsap == NULL)
1041                                 goto trunc;
1042                 }
1043 		break;
1044 
1045 	case OSPF_TYPE_LS_ACK:
1046                 lshp = op->ospf_lsa.lsa_lshdr;
1047                 while (ospf_print_lshdr(lshp) != -1) {
1048                     ++lshp;
1049                 }
1050                 break;
1051 
1052 	default:
1053 		break;
1054 	}
1055 	return (0);
1056 trunc:
1057 	return (1);
1058 }
1059 
1060 void
1061 ospf_print(register const u_char *bp, register u_int length,
1062     const u_char *bp2 _U_)
1063 {
1064 	register const struct ospfhdr *op;
1065 	register const u_char *dataend;
1066 	register const char *cp;
1067 
1068 	op = (struct ospfhdr *)bp;
1069 
1070         /* XXX Before we do anything else, strip off the MD5 trailer */
1071         TCHECK(op->ospf_authtype);
1072         if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) {
1073                 length -= OSPF_AUTH_MD5_LEN;
1074                 snapend -= OSPF_AUTH_MD5_LEN;
1075         }
1076 
1077 	/* If the type is valid translate it, or just print the type */
1078 	/* value.  If it's not valid, say so and return */
1079 	TCHECK(op->ospf_type);
1080 	cp = tok2str(type2str, "unknown LS-type", op->ospf_type);
1081 	printf("OSPFv%u, %s, length %u",
1082 	       op->ospf_version,
1083 	       cp,
1084 	       length);
1085 	if (*cp == 'u')
1086 		return;
1087 
1088         if(!vflag) { /* non verbose - so lets bail out here */
1089                 return;
1090         }
1091 
1092 	TCHECK(op->ospf_len);
1093 	if (length != EXTRACT_16BITS(&op->ospf_len)) {
1094 		printf(" [len %d]", EXTRACT_16BITS(&op->ospf_len));
1095 	}
1096 
1097 	if (length > EXTRACT_16BITS(&op->ospf_len)) {
1098 		dataend = bp + EXTRACT_16BITS(&op->ospf_len);
1099 	} else {
1100 		dataend = bp + length;
1101 	}
1102 
1103 	TCHECK(op->ospf_routerid);
1104         printf("\n\tRouter-ID %s", ipaddr_string(&op->ospf_routerid));
1105 
1106 	TCHECK(op->ospf_areaid);
1107 	if (op->ospf_areaid.s_addr != 0)
1108 		printf(", Area %s", ipaddr_string(&op->ospf_areaid));
1109 	else
1110 		printf(", Backbone Area");
1111 
1112 	if (vflag) {
1113 		/* Print authentication data (should we really do this?) */
1114 		TCHECK2(op->ospf_authdata[0], sizeof(op->ospf_authdata));
1115 
1116                 printf(", Authentication Type: %s (%u)",
1117                        tok2str(ospf_authtype_values,"unknown",EXTRACT_16BITS(&op->ospf_authtype)),
1118                        EXTRACT_16BITS(&op->ospf_authtype));
1119 
1120 		switch (EXTRACT_16BITS(&op->ospf_authtype)) {
1121 
1122 		case OSPF_AUTH_NONE:
1123 			break;
1124 
1125 		case OSPF_AUTH_SIMPLE:
1126                         printf("\n\tSimple text password: ");
1127                         safeputs((const char *)op->ospf_authdata, OSPF_AUTH_SIMPLE_LEN);
1128 			break;
1129 
1130 		case OSPF_AUTH_MD5:
1131                         printf("\n\tKey-ID: %u, Auth-Length: %u, Crypto Sequence Number: 0x%08x",
1132                                *((op->ospf_authdata)+2),
1133                                *((op->ospf_authdata)+3),
1134                                EXTRACT_32BITS((op->ospf_authdata)+4));
1135 			break;
1136 
1137 		default:
1138 			return;
1139 		}
1140 	}
1141 	/* Do rest according to version.	 */
1142 	switch (op->ospf_version) {
1143 
1144 	case 2:
1145 		/* ospf version 2 */
1146 		if (ospf_decode_v2(op, dataend))
1147 			goto trunc;
1148 		if (length > EXTRACT_16BITS(&op->ospf_len)) {
1149 			if (ospf_decode_lls(op, length))
1150 				goto trunc;
1151 		}
1152 		break;
1153 
1154 	default:
1155 		printf(" ospf [version %d]", op->ospf_version);
1156 		break;
1157 	}			/* end switch on version */
1158 
1159 	return;
1160 trunc:
1161 	fputs(tstr, stdout);
1162 }
1163