Home | History | Annotate | Line # | Download | only in dist
print-ospf.c revision 1.2.12.1
      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 (at) 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.12.1 2013/06/23 06:28:29 tls 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 (const 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 (const 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, PLURAL_SUFFIX(lsa_count_max));
   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