source: rtems-libbsd/freebsd/contrib/tcpdump/print-ospf.c @ 084d4db

4.11
Last change on this file since 084d4db was 8440506, checked in by Chris Johns <chrisj@…>, on 06/15/15 at 07:42:23

Add tcpdump and libpcap.

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