OSDN Git Service

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