Retire old subvers file
[dragonfly.git] / contrib / tcpdump-3.8.3 / 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.45.2.4 2004/03/24 02:44:30 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         { 0,                    NULL }
130 };
131
132 #define LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_PTP        1  /* rfc3630 */
133 #define LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_MA         2  /* rfc3630 */
134
135 static struct tok lsa_opaque_te_tlv_link_type_sub_tlv_values[] = {
136         { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_PTP, "Point-to-point" },
137         { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_MA,  "Multi-Access" },
138         { 0,                    NULL }
139 };
140
141 static char tstr[] = " [|ospf]";
142
143 #ifdef WIN32
144 #define inline __inline
145 #endif /* WIN32 */
146
147 static int ospf_print_lshdr(const struct lsa_hdr *);
148 static const u_char *ospf_print_lsa(const struct lsa *);
149 static int ospf_decode_v2(const struct ospfhdr *, const u_char *);
150
151 static int
152 ospf_print_lshdr(register const struct lsa_hdr *lshp)
153 {
154         u_int ls_length;
155
156         TCHECK(lshp->ls_length);
157         ls_length = EXTRACT_16BITS(&lshp->ls_length);
158         if (ls_length < sizeof(struct lsa_hdr)) {
159                 printf("\n\t    Bogus length %u < %lu", ls_length,
160                     (unsigned long)sizeof(struct lsa_hdr));
161                 return(-1);
162         }
163
164         TCHECK(lshp->ls_seq);   /* XXX - ls_length check checked this */
165         printf("\n\t  Advertising Router: %s, seq 0x%08x, age %us, length: %u",
166                ipaddr_string(&lshp->ls_router),
167                EXTRACT_32BITS(&lshp->ls_seq),
168                EXTRACT_16BITS(&lshp->ls_age),
169                ls_length-(u_int)sizeof(struct lsa_hdr));
170
171         TCHECK(lshp->ls_type);  /* XXX - ls_length check checked this */
172         switch (lshp->ls_type) {
173         /* the LSA header for opaque LSAs was slightly changed */
174         case LS_TYPE_OPAQUE_LL:
175         case LS_TYPE_OPAQUE_AL:
176         case LS_TYPE_OPAQUE_DW:
177             printf("\n\t    %s LSA (%d), Opaque-Type: %s LSA (%u), Opaque-ID: %u",
178                    tok2str(lsa_values,"unknown",lshp->ls_type),
179                    lshp->ls_type,
180
181                    tok2str(lsa_opaque_values,
182                            "unknown",
183                            *(&lshp->un_lsa_id.opaque_field.opaque_type)),
184                    *(&lshp->un_lsa_id.opaque_field.opaque_type),
185                    EXTRACT_24BITS(&lshp->un_lsa_id.opaque_field.opaque_id)
186                    
187                    );
188             break;
189
190         /* all other LSA types use regular style LSA headers */
191         default:
192             printf("\n\t    %s LSA (%d), LSA-ID: %s",
193                    tok2str(lsa_values,"unknown",lshp->ls_type),
194                    lshp->ls_type,
195                    ipaddr_string(&lshp->un_lsa_id.lsa_id));
196             break;
197         }
198
199         TCHECK(lshp->ls_options);       /* XXX - ls_length check checked this */
200         printf("\n\t    Options: [%s]", bittok2str(ospf_option_values,"none",lshp->ls_options));
201
202         return (ls_length);
203 trunc:
204         return (-1);
205 }
206
207 /*
208  * Print a single link state advertisement.  If truncated or if LSA length
209  * field is less than the length of the LSA header, return NULl, else
210  * return pointer to data past end of LSA.
211  */
212 static const u_int8_t *
213 ospf_print_lsa(register const struct lsa *lsap)
214 {
215         register const u_int8_t *ls_end;
216         register const struct rlalink *rlp;
217         register const struct tos_metric *tosp;
218         register const struct in_addr *ap;
219         register const struct aslametric *almp;
220         register const struct mcla *mcp;
221         register const u_int32_t *lp;
222         register int j, k, tlv_type, tlv_length, subtlv_type, subtlv_length, priority_level;
223         register int ls_length;
224         const u_int8_t *tptr;
225         int count_srlg;
226         union { /* int to float conversion buffer for several subTLVs */
227             float f; 
228             u_int32_t i;
229         } bw;
230
231         tptr = (u_int8_t *)lsap->lsa_un.un_unknown; /* squelch compiler warnings */
232         ls_length = ospf_print_lshdr(&lsap->ls_hdr);
233         if (ls_length == -1)
234                 return(NULL);
235         ls_end = (u_int8_t *)lsap + ls_length;
236         ls_length -= sizeof(struct lsa_hdr);
237
238         switch (lsap->ls_hdr.ls_type) {
239
240         case LS_TYPE_ROUTER:
241                 TCHECK(lsap->lsa_un.un_rla.rla_flags);
242                 printf("\n\t    Router LSA Options: [%s]", bittok2str(ospf_rla_flag_values,"none",lsap->lsa_un.un_rla.rla_flags));
243
244                 TCHECK(lsap->lsa_un.un_rla.rla_count);
245                 j = EXTRACT_16BITS(&lsap->lsa_un.un_rla.rla_count);
246                 TCHECK(lsap->lsa_un.un_rla.rla_link);
247                 rlp = lsap->lsa_un.un_rla.rla_link;
248                 while (j--) {
249                         TCHECK(*rlp);
250                         switch (rlp->link_type) {
251
252                         case RLA_TYPE_VIRTUAL:
253                                 printf("\n\t      Virtual Link: Neighbor Router-ID: %s, Interface Address: %s",
254                                     ipaddr_string(&rlp->link_id),
255                                     ipaddr_string(&rlp->link_data)); 
256                                 break;
257
258                         case RLA_TYPE_ROUTER:
259                                 printf("\n\t      Neighbor Router-ID: %s, Interface Address: %s",
260                                     ipaddr_string(&rlp->link_id),
261                                     ipaddr_string(&rlp->link_data));
262                                 break;
263
264                         case RLA_TYPE_TRANSIT:
265                                 printf("\n\t      Neighbor Network-ID: %s, Interface Address: %s",
266                                     ipaddr_string(&rlp->link_id),
267                                     ipaddr_string(&rlp->link_data));
268                                 break;
269
270                         case RLA_TYPE_STUB:
271                                 printf("\n\t      Stub Network: %s, Mask: %s",
272                                     ipaddr_string(&rlp->link_id),
273                                     ipaddr_string(&rlp->link_data));
274                                 break;
275
276                         default:
277                                 printf("\n\t      Unknown Router Link Type (%u)",
278                                     rlp->link_type);
279                                 return (ls_end);
280                         }
281                         printf(", tos 0, metric: %d", EXTRACT_16BITS(&rlp->link_tos0metric));
282                         tosp = (struct tos_metric *)
283                             ((sizeof rlp->link_tos0metric) + (u_char *) rlp);
284                         for (k = 0; k < (int) rlp->link_toscount; ++k, ++tosp) {
285                                 TCHECK(*tosp);
286                                 printf(", tos %d, metric: %d",
287                                     tosp->tos_type,
288                                     EXTRACT_16BITS(&tosp->tos_metric));
289                         }
290                         rlp = (struct rlalink *)((u_char *)(rlp + 1) +
291                             ((rlp->link_toscount) * sizeof(*tosp)));
292                 }
293                 break;
294
295         case LS_TYPE_NETWORK:
296                 TCHECK(lsap->lsa_un.un_nla.nla_mask);
297                 printf("\n\t    Mask %s\n\t    Connected Routers:",
298                     ipaddr_string(&lsap->lsa_un.un_nla.nla_mask));
299                 ap = lsap->lsa_un.un_nla.nla_router;
300                 while ((u_char *)ap < ls_end) {
301                         TCHECK(*ap);
302                         printf("\n\t      %s", ipaddr_string(ap));
303                         ++ap;
304                 }
305                 break;
306
307         case LS_TYPE_SUM_IP:
308                 TCHECK(lsap->lsa_un.un_nla.nla_mask);
309                 printf("\n\t    Mask %s",
310                     ipaddr_string(&lsap->lsa_un.un_sla.sla_mask));
311                 TCHECK(lsap->lsa_un.un_sla.sla_tosmetric);
312                 lp = lsap->lsa_un.un_sla.sla_tosmetric;
313                 /* suppress tos if its not supported */
314                 if(!((lsap->ls_hdr.ls_options)&OSPF_OPTION_T)) {
315                     printf(", metric: %u", EXTRACT_32BITS(lp)&SLA_MASK_METRIC);
316                     break;
317                 }
318                 while ((u_char *)lp < ls_end) {
319                         register u_int32_t ul;
320
321                         TCHECK(*lp);
322                         ul = EXTRACT_32BITS(lp);
323                         printf(", tos %d metric %d",
324                             (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS,
325                             ul & SLA_MASK_METRIC);
326                         ++lp;
327                 }
328                 break;
329
330         case LS_TYPE_SUM_ABR:
331                 TCHECK(lsap->lsa_un.un_sla.sla_tosmetric);
332                 lp = lsap->lsa_un.un_sla.sla_tosmetric;
333                 /* suppress tos if its not supported */
334                 if(!((lsap->ls_hdr.ls_options)&OSPF_OPTION_T)) {
335                     printf(", metric: %u", EXTRACT_32BITS(lp)&SLA_MASK_METRIC);
336                     break;
337                 }
338                 while ((u_char *)lp < ls_end) {
339                         register u_int32_t ul;
340
341                         TCHECK(*lp);
342                         ul = EXTRACT_32BITS(lp);
343                         printf(", tos %d metric %d",
344                             (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS,
345                             ul & SLA_MASK_METRIC);
346                         ++lp;
347                 }
348                 break;
349
350         case LS_TYPE_ASE:
351                 TCHECK(lsap->lsa_un.un_nla.nla_mask);
352                 printf("\n\t    Mask %s",
353                     ipaddr_string(&lsap->lsa_un.un_asla.asla_mask));
354
355                 TCHECK(lsap->lsa_un.un_sla.sla_tosmetric);
356                 almp = lsap->lsa_un.un_asla.asla_metric;
357                 while ((u_char *)almp < ls_end) {
358                         register u_int32_t ul;
359
360                         TCHECK(almp->asla_tosmetric);
361                         ul = EXTRACT_32BITS(&almp->asla_tosmetric);
362                         printf(", type %d, tos %d metric:",
363                             (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1,
364                             (ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS);
365                         if ((ul & ASLA_MASK_METRIC)==0xffffff)
366                             printf(" infinite");
367                         else
368                             printf(" %d", (ul & ASLA_MASK_METRIC));
369
370                         TCHECK(almp->asla_forward);
371                         if (almp->asla_forward.s_addr) {
372                                 printf(", forward %s",
373                                     ipaddr_string(&almp->asla_forward));
374                         }
375                         TCHECK(almp->asla_tag);
376                         if (almp->asla_tag.s_addr) {
377                                 printf(", tag %s",
378                                     ipaddr_string(&almp->asla_tag));
379                         }
380                         ++almp;
381                 }
382                 break;
383
384         case LS_TYPE_GROUP:
385                 /* Multicast extensions as of 23 July 1991 */
386                 mcp = lsap->lsa_un.un_mcla;
387                 while ((u_char *)mcp < ls_end) {
388                         TCHECK(mcp->mcla_vid);
389                         switch (EXTRACT_32BITS(&mcp->mcla_vtype)) {
390
391                         case MCLA_VERTEX_ROUTER:
392                                 printf("\n\t    Router Router-ID %s",
393                                     ipaddr_string(&mcp->mcla_vid));
394                                 break;
395
396                         case MCLA_VERTEX_NETWORK:
397                                 printf("\n\t    Network Designated Router %s",
398                                     ipaddr_string(&mcp->mcla_vid));
399                                 break;
400
401                         default:
402                                 printf("\n\t    unknown VertexType (%u)",
403                                     EXTRACT_32BITS(&mcp->mcla_vtype));
404                                 break;
405                         }
406                 ++mcp;
407                 }
408                 break;
409
410         case LS_TYPE_OPAQUE_LL: /* fall through */
411         case LS_TYPE_OPAQUE_AL: 
412         case LS_TYPE_OPAQUE_DW:
413
414             switch (*(&lsap->ls_hdr.un_lsa_id.opaque_field.opaque_type)) {
415             case LS_OPAQUE_TYPE_TE:
416                 tptr = (u_int8_t *)(&lsap->lsa_un.un_te_lsa_tlv.type);
417
418                 while (ls_length != 0) {
419                     TCHECK2(*tptr, 4);
420                     if (ls_length < 4) {
421                         printf("\n\t    Remaining LS length %u < 4", ls_length);
422                         return(ls_end);
423                     }
424                     tlv_type = EXTRACT_16BITS(tptr);
425                     tlv_length = EXTRACT_16BITS(tptr+2);
426                     tptr+=4;
427                     ls_length-=4;
428                     
429                     printf("\n\t    %s TLV (%u), length: %u",
430                            tok2str(lsa_opaque_te_tlv_values,"unknown",tlv_type),
431                            tlv_type,
432                            tlv_length);
433
434                     if (tlv_length > ls_length) {
435                         printf("\n\t    Bogus length %u > %u", tlv_length,
436                             ls_length);
437                         return(ls_end);
438                     }
439                     ls_length-=tlv_length;
440                     switch(tlv_type) {
441                     case LS_OPAQUE_TE_TLV_LINK:
442                         while (tlv_length != 0) {
443                             if (tlv_length < 4) {
444                                 printf("\n\t    Remaining TLV length %u < 4",
445                                     tlv_length);
446                                 return(ls_end);
447                             }
448                             TCHECK2(*tptr, 4);
449                             subtlv_type = EXTRACT_16BITS(tptr);
450                             subtlv_length = EXTRACT_16BITS(tptr+2);
451                             tptr+=4;
452                             tlv_length-=4;
453                             
454                             printf("\n\t      %s subTLV (%u), length: %u",
455                                    tok2str(lsa_opaque_te_link_tlv_subtlv_values,"unknown",subtlv_type),
456                                    subtlv_type,
457                                    subtlv_length);
458                             
459                             TCHECK2(*tptr, subtlv_length);
460                             switch(subtlv_type) {
461                             case LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP:
462                                 printf(", 0x%08x", EXTRACT_32BITS(tptr));
463                                 break;
464                             case LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID:
465                             case LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID:
466                                 printf(", %s (0x%08x)",
467                                        ipaddr_string(tptr),
468                                        EXTRACT_32BITS(tptr));
469                                 if (subtlv_length == 8) /* draft-ietf-ccamp-ospf-gmpls-extensions */
470                                     printf(", %s (0x%08x)",
471                                            ipaddr_string(tptr+4),
472                                            EXTRACT_32BITS(tptr+4));
473                                 break;
474                             case LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP:
475                             case LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP:
476                                 printf(", %s", ipaddr_string(tptr));
477                                 break;
478                             case LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW:
479                             case LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW:
480                                 bw.i = EXTRACT_32BITS(tptr);
481                                 printf(", %.3f Mbps", bw.f*8/1000000 );
482                                 break;
483                             case LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW:
484                                 for (priority_level = 0; priority_level < 8; priority_level++) {
485                                     bw.i = EXTRACT_32BITS(tptr+priority_level*4);
486                                     printf("\n\t\tpriority level %d: %.3f Mbps",
487                                            priority_level,
488                                            bw.f*8/1000000 );
489                                 }
490                                 break;
491                             case LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC:
492                                 printf(", Metric %u", EXTRACT_32BITS(tptr));
493                                 break;
494                             case LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE:
495                                 printf(", %s, Priority %u",
496                                        bittok2str(gmpls_link_prot_values, "none", *tptr),
497                                        *(tptr+1));
498                                 break;
499                             case LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR:
500                                 printf("\n\t\tInterface Switching Capability: %s",
501                                        tok2str(gmpls_switch_cap_values, "Unknown", *(tptr)));
502                                 printf("\n\t\tLSP Encoding: %s\n\t\tMax LSP Bandwidth:",
503                                        tok2str(gmpls_encoding_values, "Unknown", *(tptr+1)));
504                                 for (priority_level = 0; priority_level < 8; priority_level++) {
505                                     bw.i = EXTRACT_32BITS(tptr+4+(priority_level*4));
506                                     printf("\n\t\t  priority level %d: %.3f Mbps",
507                                            priority_level,
508                                            bw.f*8/1000000 );
509                                 }
510                                 break;
511                             case LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE:
512                                 printf(", %s (%u)",
513                                        tok2str(lsa_opaque_te_tlv_link_type_sub_tlv_values,"unknown",*tptr),
514                                        *tptr);
515                                 break;
516
517                             case LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP:
518                                 count_srlg = subtlv_length / 4;
519                                 if (count_srlg != 0)
520                                      printf("\n\t\t  Shared risk group: ");
521                                 while (count_srlg > 0) {
522                                         bw.i = EXTRACT_32BITS(tptr);
523                                         printf("%d",bw.i);
524                                         tptr+=4;
525                                         count_srlg--;
526                                         if (count_srlg > 0)
527                                             printf(", ");
528                                 }
529                                 break;
530
531                             default:
532                                 if (vflag <= 1) {
533                                     if(!print_unknown_data(tptr,"\n\t\t",subtlv_length))
534                                         return(ls_end);
535                                 }
536                                 break;
537                             }
538                             /* in OSPF everything has to be 32-bit aligned, including TLVs */
539                             if (subtlv_length%4 != 0)
540                                 subtlv_length+=4-(subtlv_length%4);
541                             
542                             tlv_length-=subtlv_length;
543                             tptr+=subtlv_length;
544                             
545                         }
546                         break;
547                         
548                     case LS_OPAQUE_TE_TLV_ROUTER:
549                         if (tlv_length < 4) {
550                             printf("\n\t    TLV length %u < 4", tlv_length);
551                             return(ls_end);
552                         }
553                         TCHECK2(*tptr, 4);
554                         printf(", %s", ipaddr_string(tptr));
555                         break;
556                         
557                     default:
558                         if (vflag <= 1) {
559                             if(!print_unknown_data(tptr,"\n\t      ",tlv_length))
560                                 return(ls_end);
561                         }
562                         break;
563                     }
564                     tptr+=tlv_length;
565                 }
566                 break;
567             }
568             break;
569         default:
570             if (vflag <= 1) {
571                 if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown,
572                                        "\n\t    ", ls_length))
573                     return(ls_end);
574             } 
575             break;
576         }
577
578         /* do we want to see an additionally hexdump ? */
579         if (vflag> 1)
580             if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown,
581                                    "\n\t    ", ls_length)) {
582                 return(ls_end);
583             }
584         
585         return (ls_end);
586 trunc:
587         return (NULL);
588 }
589
590 static int
591 ospf_decode_v2(register const struct ospfhdr *op,
592     register const u_char *dataend)
593 {
594         register const struct in_addr *ap;
595         register const struct lsr *lsrp;
596         register const struct lsa_hdr *lshp;
597         register const struct lsa *lsap;
598         register u_int32_t lsa_count,lsa_count_max;
599
600         switch (op->ospf_type) {
601
602         case OSPF_TYPE_UMD:
603                 /*
604                  * Rob Coltun's special monitoring packets;
605                  * do nothing
606                  */
607                 break;
608
609         case OSPF_TYPE_HELLO:
610                 printf("\n\tOptions: [%s]",
611                        bittok2str(ospf_option_values,"none",op->ospf_hello.hello_options));
612
613                 TCHECK(op->ospf_hello.hello_deadint);
614                 printf("\n\t  Hello Timer: %us, Dead Timer %us, Mask: %s, Priority: %u",
615                        EXTRACT_16BITS(&op->ospf_hello.hello_helloint),
616                        EXTRACT_32BITS(&op->ospf_hello.hello_deadint),
617                        ipaddr_string(&op->ospf_hello.hello_mask),
618                        op->ospf_hello.hello_priority);
619
620                 TCHECK(op->ospf_hello.hello_dr);
621                 if (op->ospf_hello.hello_dr.s_addr != 0)
622                         printf("\n\t  Designated Router %s",
623                             ipaddr_string(&op->ospf_hello.hello_dr));
624
625                 TCHECK(op->ospf_hello.hello_bdr);
626                 if (op->ospf_hello.hello_bdr.s_addr != 0)
627                         printf(", Backup Designated Router %s",
628                             ipaddr_string(&op->ospf_hello.hello_bdr));
629
630                 ap = op->ospf_hello.hello_neighbor;
631                 if ((u_char *)ap < dataend)
632                         printf("\n\t  Neighbor List:");
633                 while ((u_char *)ap < dataend) {
634                         TCHECK(*ap);
635                         printf("\n\t    %s", ipaddr_string(ap));
636                         ++ap;
637                 }
638                 break;  /* HELLO */
639
640         case OSPF_TYPE_DD:
641                 TCHECK(op->ospf_db.db_options);
642                 printf("\n\tOptions: [%s]",
643                        bittok2str(ospf_option_values,"none",op->ospf_db.db_options));
644                 TCHECK(op->ospf_db.db_flags);
645                 printf(", DD Flags: [%s]",
646                        bittok2str(ospf_dd_flag_values,"none",op->ospf_db.db_flags));
647
648                 if (vflag) {
649                         /* Print all the LS adv's */
650                         lshp = op->ospf_db.db_lshdr;
651                         while (ospf_print_lshdr(lshp) != -1) {
652                                 ++lshp;
653                         }
654                 }
655                 break;
656
657         case OSPF_TYPE_LS_REQ:
658                 lsrp = op->ospf_lsr;
659                 while ((u_char *)lsrp < dataend) {
660                     TCHECK(*lsrp);
661
662                     printf("\n\t  Advertising Router: %s, %s LSA (%u)",
663                            ipaddr_string(&lsrp->ls_router),
664                            tok2str(lsa_values,"unknown",EXTRACT_32BITS(lsrp->ls_type)),
665                            EXTRACT_32BITS(&lsrp->ls_type));
666
667                     switch (EXTRACT_32BITS(lsrp->ls_type)) {
668                         /* the LSA header for opaque LSAs was slightly changed */
669                     case LS_TYPE_OPAQUE_LL:
670                     case LS_TYPE_OPAQUE_AL:
671                     case LS_TYPE_OPAQUE_DW:
672                         printf(", Opaque-Type: %s LSA (%u), Opaque-ID: %u",
673                                tok2str(lsa_opaque_values, "unknown",lsrp->un_ls_stateid.opaque_field.opaque_type),
674                                lsrp->un_ls_stateid.opaque_field.opaque_type,
675                                EXTRACT_24BITS(&lsrp->un_ls_stateid.opaque_field.opaque_id));
676                         break;
677                     default:
678                         printf(", LSA-ID: %s",
679                                ipaddr_string(&lsrp->un_ls_stateid.ls_stateid));
680                         break;
681                     }
682                     
683                     ++lsrp;
684                 }
685                 break;
686
687         case OSPF_TYPE_LS_UPDATE:
688                 lsap = op->ospf_lsu.lsu_lsa;
689                 TCHECK(op->ospf_lsu.lsu_count);
690                 lsa_count_max = EXTRACT_32BITS(&op->ospf_lsu.lsu_count);
691                 printf(", %d LSA%s",lsa_count_max, lsa_count_max > 1 ? "s" : "");
692                 for (lsa_count=1;lsa_count <= lsa_count_max;lsa_count++) {
693                     printf("\n\t  LSA #%u",lsa_count);
694                         lsap = (const struct lsa *)ospf_print_lsa(lsap);
695                         if (lsap == NULL)
696                                 goto trunc;
697                 }
698                 break;
699
700         case OSPF_TYPE_LS_ACK:
701                 lshp = op->ospf_lsa.lsa_lshdr;
702                 while (ospf_print_lshdr(lshp) != -1) {
703                     ++lshp;
704                 }
705                 break;
706
707         default:
708                 printf("v2 type (%d)", op->ospf_type);
709                 break;
710         }
711         return (0);
712 trunc:
713         return (1);
714 }
715
716 void
717 ospf_print(register const u_char *bp, register u_int length,
718     register const u_char *bp2)
719 {
720         register const struct ospfhdr *op;
721         register const struct ip *ip;
722         register const u_char *dataend;
723         register const char *cp;
724
725         op = (struct ospfhdr *)bp;
726         ip = (struct ip *)bp2;
727
728         /* XXX Before we do anything else, strip off the MD5 trailer */
729         TCHECK(op->ospf_authtype);
730         if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) {
731                 length -= OSPF_AUTH_MD5_LEN;
732                 snapend -= OSPF_AUTH_MD5_LEN;
733         }
734
735         /* If the type is valid translate it, or just print the type */
736         /* value.  If it's not valid, say so and return */
737         TCHECK(op->ospf_type);
738         cp = tok2str(type2str, "unknown LS-type", op->ospf_type);
739         printf("OSPFv%u, %s (%u), length: %u",
740                op->ospf_version,
741                cp,
742                op->ospf_type,
743                length);
744         if (*cp == 'u')
745                 return;
746
747         if(!vflag) /* non verbose - so lets bail out here */
748                 return;
749
750         TCHECK(op->ospf_len);
751         if (length != EXTRACT_16BITS(&op->ospf_len)) {
752                 printf(" [len %d]", EXTRACT_16BITS(&op->ospf_len));
753                 return;
754         }
755         dataend = bp + length;
756
757         TCHECK(op->ospf_routerid);
758         printf("\n\tRouter-ID: %s", ipaddr_string(&op->ospf_routerid));
759
760         TCHECK(op->ospf_areaid);
761         if (op->ospf_areaid.s_addr != 0)
762                 printf(", Area %s", ipaddr_string(&op->ospf_areaid));
763         else
764                 printf(", Backbone Area");
765
766         if (vflag) {
767                 /* Print authentication data (should we really do this?) */
768                 TCHECK2(op->ospf_authdata[0], sizeof(op->ospf_authdata));
769
770                 printf(", Authentication Type: %s (%u)",
771                        tok2str(ospf_authtype_values,"unknown",EXTRACT_16BITS(&op->ospf_authtype)),
772                        EXTRACT_16BITS(&op->ospf_authtype));
773
774                 switch (EXTRACT_16BITS(&op->ospf_authtype)) {
775
776                 case OSPF_AUTH_NONE:
777                         break;
778
779                 case OSPF_AUTH_SIMPLE:
780                         (void)fn_printn(op->ospf_authdata,
781                             sizeof(op->ospf_authdata), NULL);
782                         printf("\"");
783                         break;
784
785                 case OSPF_AUTH_MD5:
786                         printf("\n\tKey-ID: %u, Auth-Length: %u, Crypto Sequence Number: 0x%08x",
787                                *((op->ospf_authdata)+2),
788                                *((op->ospf_authdata)+3),
789                                EXTRACT_32BITS((op->ospf_authdata)+4));
790                         break;
791
792                 default:
793                         return;
794                 }
795         }
796         /* Do rest according to version.         */
797         switch (op->ospf_version) {
798
799         case 2:
800                 /* ospf version 2 */
801                 if (ospf_decode_v2(op, dataend))
802                         goto trunc;
803                 break;
804
805         default:
806                 printf(" ospf [version %d]", op->ospf_version);
807                 break;
808         }                       /* end switch on version */
809
810         return;
811 trunc:
812         fputs(tstr, stdout);
813 }