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