source: rtems-libbsd/freebsd/contrib/tcpdump/print-ldp.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: 22.4 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3/*
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that: (1) source code
6 * distributions retain the above copyright notice and this paragraph
7 * in its entirety, and (2) distributions including binary code include
8 * the above copyright notice and this paragraph in its entirety in
9 * the documentation or other materials provided with the distribution.
10 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
11 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
12 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
13 * FOR A PARTICULAR PURPOSE.
14 *
15 * Original code by Hannes Gredler (hannes@juniper.net)
16 *  and Steinar Haug (sthaug@nethelp.no)
17 */
18
19#ifndef lint
20static const char rcsid[] _U_ =
21    "@(#) $Header: /tcpdump/master/tcpdump/print-ldp.c,v 1.20 2006-06-23 02:03:09 hannes Exp $";
22#endif
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include <tcpdump-stdinc.h>
29
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33
34#include "interface.h"
35#include "decode_prefix.h"
36#include "extract.h"
37#include "addrtoname.h"
38
39#include "l2vpn.h"
40#include "af.h"
41
42/*
43 * ldp common header
44 *
45 *  0                   1                   2                   3
46 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
47 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48 * |  Version                      |         PDU Length            |
49 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50 * |                         LDP Identifier                        |
51 * +                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52 * |                               |
53 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54 *
55 */
56
57struct ldp_common_header {
58    u_int8_t version[2];
59    u_int8_t pdu_length[2];
60    u_int8_t lsr_id[4];
61    u_int8_t label_space[2];
62};
63
64#define LDP_VERSION 1
65
66/*
67 * ldp message header
68 *
69 *  0                   1                   2                   3
70 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
71 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
72 * |U|   Message Type              |      Message Length           |
73 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
74 * |                     Message ID                                |
75 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
76 * |                                                               |
77 * +                                                               +
78 * |                     Mandatory Parameters                      |
79 * +                                                               +
80 * |                                                               |
81 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
82 * |                                                               |
83 * +                                                               +
84 * |                     Optional Parameters                       |
85 * +                                                               +
86 * |                                                               |
87 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
88 */
89
90struct ldp_msg_header {
91    u_int8_t type[2];
92    u_int8_t length[2];
93    u_int8_t id[4];
94};
95
96#define LDP_MASK_MSG_TYPE(x)  ((x)&0x7fff)
97#define LDP_MASK_U_BIT(x)     ((x)&0x8000)
98
99#define LDP_MSG_NOTIF                0x0001
100#define LDP_MSG_HELLO                0x0100
101#define LDP_MSG_INIT                 0x0200
102#define LDP_MSG_KEEPALIVE            0x0201
103#define LDP_MSG_ADDRESS              0x0300
104#define LDP_MSG_ADDRESS_WITHDRAW     0x0301
105#define LDP_MSG_LABEL_MAPPING        0x0400
106#define LDP_MSG_LABEL_REQUEST        0x0401
107#define LDP_MSG_LABEL_WITHDRAW       0x0402
108#define LDP_MSG_LABEL_RELEASE        0x0403
109#define LDP_MSG_LABEL_ABORT_REQUEST  0x0404
110
111#define LDP_VENDOR_PRIVATE_MIN       0x3e00
112#define LDP_VENDOR_PRIVATE_MAX       0x3eff
113#define LDP_EXPERIMENTAL_MIN         0x3f00
114#define LDP_EXPERIMENTAL_MAX         0x3fff
115
116static const struct tok ldp_msg_values[] = {
117    { LDP_MSG_NOTIF,                 "Notification" },
118    { LDP_MSG_HELLO,                 "Hello" },
119    { LDP_MSG_INIT,                  "Initialization" },
120    { LDP_MSG_KEEPALIVE,             "Keepalive" },
121    { LDP_MSG_ADDRESS,               "Address" },
122    { LDP_MSG_ADDRESS_WITHDRAW,      "Address Withdraw" },
123    { LDP_MSG_LABEL_MAPPING,         "Label Mapping" },
124    { LDP_MSG_LABEL_REQUEST,         "Label Request" },
125    { LDP_MSG_LABEL_WITHDRAW,        "Label Withdraw" },
126    { LDP_MSG_LABEL_RELEASE,         "Label Release" },
127    { LDP_MSG_LABEL_ABORT_REQUEST,   "Label Abort Request" },
128    { 0, NULL}
129};
130
131#define LDP_MASK_TLV_TYPE(x)  ((x)&0x3fff)
132#define LDP_MASK_F_BIT(x) ((x)&0x4000)
133
134#define LDP_TLV_FEC                  0x0100
135#define LDP_TLV_ADDRESS_LIST         0x0101
136#define LDP_TLV_ADDRESS_LIST_AFNUM_LEN 2
137#define LDP_TLV_HOP_COUNT            0x0103
138#define LDP_TLV_PATH_VECTOR          0x0104
139#define LDP_TLV_GENERIC_LABEL        0x0200
140#define LDP_TLV_ATM_LABEL            0x0201
141#define LDP_TLV_FR_LABEL             0x0202
142#define LDP_TLV_STATUS               0x0300
143#define LDP_TLV_EXTD_STATUS          0x0301
144#define LDP_TLV_RETURNED_PDU         0x0302
145#define LDP_TLV_RETURNED_MSG         0x0303
146#define LDP_TLV_COMMON_HELLO         0x0400
147#define LDP_TLV_IPV4_TRANSPORT_ADDR  0x0401
148#define LDP_TLV_CONFIG_SEQ_NUMBER    0x0402
149#define LDP_TLV_IPV6_TRANSPORT_ADDR  0x0403
150#define LDP_TLV_COMMON_SESSION       0x0500
151#define LDP_TLV_ATM_SESSION_PARM     0x0501
152#define LDP_TLV_FR_SESSION_PARM      0x0502
153#define LDP_TLV_FT_SESSION           0x0503
154#define LDP_TLV_LABEL_REQUEST_MSG_ID 0x0600
155#define LDP_TLV_MTU                  0x0601 /* rfc 3988 */
156
157static const struct tok ldp_tlv_values[] = {
158    { LDP_TLV_FEC,                   "FEC" },
159    { LDP_TLV_ADDRESS_LIST,          "Address List" },
160    { LDP_TLV_HOP_COUNT,             "Hop Count" },
161    { LDP_TLV_PATH_VECTOR,           "Path Vector" },
162    { LDP_TLV_GENERIC_LABEL,         "Generic Label" },
163    { LDP_TLV_ATM_LABEL,             "ATM Label" },
164    { LDP_TLV_FR_LABEL,              "Frame-Relay Label" },
165    { LDP_TLV_STATUS,                "Status" },
166    { LDP_TLV_EXTD_STATUS,           "Extended Status" },
167    { LDP_TLV_RETURNED_PDU,          "Returned PDU" },
168    { LDP_TLV_RETURNED_MSG,          "Returned Message" },
169    { LDP_TLV_COMMON_HELLO,          "Common Hello Parameters" },
170    { LDP_TLV_IPV4_TRANSPORT_ADDR,   "IPv4 Transport Address" },
171    { LDP_TLV_CONFIG_SEQ_NUMBER,     "Configuration Sequence Number" },
172    { LDP_TLV_IPV6_TRANSPORT_ADDR,   "IPv6 Transport Address" },
173    { LDP_TLV_COMMON_SESSION,        "Common Session Parameters" },
174    { LDP_TLV_ATM_SESSION_PARM,      "ATM Session Parameters" },
175    { LDP_TLV_FR_SESSION_PARM,       "Frame-Relay Session Parameters" },
176    { LDP_TLV_FT_SESSION,            "Fault-Tolerant Session Parameters" },
177    { LDP_TLV_LABEL_REQUEST_MSG_ID,  "Label Request Message ID" },
178    { LDP_TLV_MTU,                   "MTU" },
179    { 0, NULL}
180};
181
182#define LDP_FEC_WILDCARD        0x01
183#define LDP_FEC_PREFIX          0x02
184#define LDP_FEC_HOSTADDRESS     0x03
185/* From RFC 4906; should probably be updated to RFC 4447 (e.g., VC -> PW) */
186#define LDP_FEC_MARTINI_VC      0x80
187
188static const struct tok ldp_fec_values[] = {
189    { LDP_FEC_WILDCARD,         "Wildcard" },
190    { LDP_FEC_PREFIX,           "Prefix" },
191    { LDP_FEC_HOSTADDRESS,      "Host address" },
192    { LDP_FEC_MARTINI_VC,       "Martini VC" },
193    { 0, NULL}
194};
195
196#define LDP_FEC_MARTINI_IFPARM_MTU  0x01
197#define LDP_FEC_MARTINI_IFPARM_DESC 0x03
198#define LDP_FEC_MARTINI_IFPARM_VCCV 0x0c
199
200static const struct tok ldp_fec_martini_ifparm_values[] = {
201    { LDP_FEC_MARTINI_IFPARM_MTU, "MTU" },
202    { LDP_FEC_MARTINI_IFPARM_DESC, "Description" },
203    { LDP_FEC_MARTINI_IFPARM_VCCV, "VCCV" },
204    { 0, NULL}
205};
206
207/* draft-ietf-pwe3-vccv-04.txt */
208static const struct tok ldp_fec_martini_ifparm_vccv_cc_values[] = {
209    { 0x01, "PWE3 control word" },
210    { 0x02, "MPLS Router Alert Label" },
211    { 0x04, "MPLS inner label TTL = 1" },
212    { 0, NULL}
213};
214
215/* draft-ietf-pwe3-vccv-04.txt */
216static const struct tok ldp_fec_martini_ifparm_vccv_cv_values[] = {
217    { 0x01, "ICMP Ping" },
218    { 0x02, "LSP Ping" },
219    { 0x04, "BFD" },
220    { 0, NULL}
221};
222
223int ldp_msg_print(register const u_char *);
224int ldp_tlv_print(register const u_char *);
225   
226/*
227 * ldp tlv header
228 *
229 *  0                   1                   2                   3
230 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
231 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
232 * |U|F|        Type               |            Length             |
233 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
234 * |                                                               |
235 * |                             Value                             |
236 * ~                                                               ~
237 * |                                                               |
238 * |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
239 * |                               |
240 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
241 */
242
243#define TLV_TCHECK(minlen) \
244    TCHECK2(*tptr, minlen); if (tlv_tlen < minlen) goto badtlv;
245
246int
247ldp_tlv_print(register const u_char *tptr) {
248
249    struct ldp_tlv_header {
250        u_int8_t type[2];
251        u_int8_t length[2];
252    };
253
254    const struct ldp_tlv_header *ldp_tlv_header;
255    u_short tlv_type,tlv_len,tlv_tlen,af,ft_flags;
256    u_char fec_type;
257    u_int ui,vc_info_len, vc_info_tlv_type, vc_info_tlv_len,idx;
258    char buf[100];
259    int i;
260
261    ldp_tlv_header = (const struct ldp_tlv_header *)tptr;   
262    tlv_len=EXTRACT_16BITS(ldp_tlv_header->length);
263    tlv_tlen=tlv_len;
264    tlv_type=LDP_MASK_TLV_TYPE(EXTRACT_16BITS(ldp_tlv_header->type));
265
266    /* FIXME vendor private / experimental check */
267    printf("\n\t    %s TLV (0x%04x), length: %u, Flags: [%s and %s forward if unknown]",
268           tok2str(ldp_tlv_values,
269                   "Unknown",
270                   tlv_type),
271           tlv_type,
272           tlv_len,
273           LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "continue processing" : "ignore",
274           LDP_MASK_F_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "do" : "don't");
275
276    tptr+=sizeof(struct ldp_tlv_header);
277
278    switch(tlv_type) {
279
280    case LDP_TLV_COMMON_HELLO:
281        TLV_TCHECK(4);
282        printf("\n\t      Hold Time: %us, Flags: [%s Hello%s]",
283               EXTRACT_16BITS(tptr),
284               (EXTRACT_16BITS(tptr+2)&0x8000) ? "Targeted" : "Link",
285               (EXTRACT_16BITS(tptr+2)&0x4000) ? ", Request for targeted Hellos" : "");
286        break;
287
288    case LDP_TLV_IPV4_TRANSPORT_ADDR:
289        TLV_TCHECK(4);
290        printf("\n\t      IPv4 Transport Address: %s", ipaddr_string(tptr));
291        break;
292#ifdef INET6
293    case LDP_TLV_IPV6_TRANSPORT_ADDR:
294        TLV_TCHECK(16);
295        printf("\n\t      IPv6 Transport Address: %s", ip6addr_string(tptr));
296        break;
297#endif
298    case LDP_TLV_CONFIG_SEQ_NUMBER:
299        TLV_TCHECK(4);
300        printf("\n\t      Sequence Number: %u", EXTRACT_32BITS(tptr));
301        break;
302
303    case LDP_TLV_ADDRESS_LIST:
304        TLV_TCHECK(LDP_TLV_ADDRESS_LIST_AFNUM_LEN);
305        af = EXTRACT_16BITS(tptr);
306        tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
307        tlv_tlen -= LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
308        printf("\n\t      Address Family: %s, addresses",
309               tok2str(af_values, "Unknown (%u)", af));
310        switch (af) {
311        case AFNUM_INET:
312            while(tlv_tlen >= sizeof(struct in_addr)) {
313                TCHECK2(*tptr, sizeof(struct in_addr));
314                printf(" %s",ipaddr_string(tptr));
315                tlv_tlen-=sizeof(struct in_addr);
316                tptr+=sizeof(struct in_addr);               
317            }
318            break;
319#ifdef INET6
320        case AFNUM_INET6:
321            while(tlv_tlen >= sizeof(struct in6_addr)) {
322                TCHECK2(*tptr, sizeof(struct in6_addr));
323                printf(" %s",ip6addr_string(tptr));
324                tlv_tlen-=sizeof(struct in6_addr);
325                tptr+=sizeof(struct in6_addr);               
326            }
327            break;
328#endif
329        default:
330            /* unknown AF */
331            break;
332        }
333        break;
334
335    case LDP_TLV_COMMON_SESSION:
336        TLV_TCHECK(8);
337        printf("\n\t      Version: %u, Keepalive: %us, Flags: [Downstream %s, Loop Detection %s]",
338               EXTRACT_16BITS(tptr), EXTRACT_16BITS(tptr+2),
339               (EXTRACT_16BITS(tptr+6)&0x8000) ? "On Demand" : "Unsolicited",
340               (EXTRACT_16BITS(tptr+6)&0x4000) ? "Enabled" : "Disabled"
341               );
342        break;
343
344    case LDP_TLV_FEC:
345        TLV_TCHECK(1);
346        fec_type = *tptr;
347        printf("\n\t      %s FEC (0x%02x)",
348               tok2str(ldp_fec_values, "Unknown", fec_type),
349               fec_type);
350
351        tptr+=1;
352        tlv_tlen-=1;
353        switch(fec_type) {
354
355        case LDP_FEC_WILDCARD:
356            break;
357        case LDP_FEC_PREFIX:
358            TLV_TCHECK(2);
359            af = EXTRACT_16BITS(tptr);
360            tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
361            tlv_tlen-=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
362            if (af == AFNUM_INET) {
363                i=decode_prefix4(tptr,tlv_tlen,buf,sizeof(buf));
364                if (i == -2)
365                    goto trunc;
366                if (i == -3)
367                    printf(": IPv4 prefix (goes past end of TLV)");
368                else if (i == -1)
369                    printf(": IPv4 prefix (invalid length)");
370                else
371                    printf(": IPv4 prefix %s",buf);
372            }
373#ifdef INET6
374            else if (af == AFNUM_INET6) {
375                i=decode_prefix6(tptr,tlv_tlen,buf,sizeof(buf));
376                if (i == -2)
377                    goto trunc;
378                if (i == -3)
379                    printf(": IPv4 prefix (goes past end of TLV)");
380                else if (i == -1)
381                    printf(": IPv6 prefix (invalid length)");
382                else
383                    printf(": IPv6 prefix %s",buf);
384            }
385#endif
386            else
387                printf(": Address family %u prefix", af);
388            break;
389        case LDP_FEC_HOSTADDRESS:
390            break;
391        case LDP_FEC_MARTINI_VC:
392            /*
393             * According to RFC 4908, the VC info Length field can be zero,
394             * in which case not only are there no interface parameters,
395             * there's no VC ID.
396             */
397            TLV_TCHECK(7);
398            vc_info_len = *(tptr+2);
399
400            if (vc_info_len == 0) {
401                printf(": %s, %scontrol word, group-ID %u, VC-info-length: %u",
402                       tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff),
403                       EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ",
404                       EXTRACT_32BITS(tptr+3),
405                       vc_info_len);
406                break;
407            }
408
409            /* Make sure we have the VC ID as well */
410            TLV_TCHECK(11);
411            printf(": %s, %scontrol word, group-ID %u, VC-ID %u, VC-info-length: %u",
412                   tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff),
413                   EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ",
414                   EXTRACT_32BITS(tptr+3),
415                   EXTRACT_32BITS(tptr+7),
416                   vc_info_len);
417            if (vc_info_len < 4)
418                goto trunc; /* minimum 4, for the VC ID */
419            vc_info_len -= 4; /* subtract out the VC ID, giving the length of the interface parameters */
420
421            /* Skip past the fixed information and the VC ID */
422            tptr+=11;
423            tlv_tlen-=11;
424            TLV_TCHECK(vc_info_len);
425
426            while (vc_info_len > 2) {
427                vc_info_tlv_type = *tptr;
428                vc_info_tlv_len = *(tptr+1);
429                if (vc_info_tlv_len < 2)
430                    break;
431                if (vc_info_len < vc_info_tlv_len)
432                    break;
433
434                printf("\n\t\tInterface Parameter: %s (0x%02x), len %u",
435                       tok2str(ldp_fec_martini_ifparm_values,"Unknown",vc_info_tlv_type),
436                       vc_info_tlv_type,
437                       vc_info_tlv_len);
438
439                switch(vc_info_tlv_type) {
440                case LDP_FEC_MARTINI_IFPARM_MTU:
441                    printf(": %u",EXTRACT_16BITS(tptr+2));
442                    break;
443
444                case LDP_FEC_MARTINI_IFPARM_DESC:
445                    printf(": ");
446                    for (idx = 2; idx < vc_info_tlv_len; idx++)
447                        safeputchar(*(tptr+idx));
448                    break;
449
450                case LDP_FEC_MARTINI_IFPARM_VCCV:
451                    printf("\n\t\t  Control Channels (0x%02x) = [%s]",
452                           *(tptr+2),
453                           bittok2str(ldp_fec_martini_ifparm_vccv_cc_values,"none",*(tptr+2)));
454                    printf("\n\t\t  CV Types (0x%02x) = [%s]",
455                           *(tptr+3),
456                           bittok2str(ldp_fec_martini_ifparm_vccv_cv_values,"none",*(tptr+3)));
457                    break;
458
459                default:
460                    print_unknown_data(tptr+2,"\n\t\t  ",vc_info_tlv_len-2);
461                    break;
462                }
463
464                vc_info_len -= vc_info_tlv_len;
465                tptr += vc_info_tlv_len;
466            }
467            break;
468        }
469
470        break;
471
472    case LDP_TLV_GENERIC_LABEL:
473        TLV_TCHECK(4);
474        printf("\n\t      Label: %u", EXTRACT_32BITS(tptr) & 0xfffff);
475        break;
476
477    case LDP_TLV_STATUS:
478        TLV_TCHECK(8);
479        ui = EXTRACT_32BITS(tptr);
480        tptr+=4;
481        printf("\n\t      Status: 0x%02x, Flags: [%s and %s forward]",
482               ui&0x3fffffff,
483               ui&0x80000000 ? "Fatal error" : "Advisory Notification",
484               ui&0x40000000 ? "do" : "don't");
485        ui = EXTRACT_32BITS(tptr);
486        tptr+=4;
487        if (ui)
488            printf(", causing Message ID: 0x%08x", ui);
489        break;
490
491    case LDP_TLV_FT_SESSION:
492        TLV_TCHECK(8);
493        ft_flags = EXTRACT_16BITS(tptr);
494        printf("\n\t      Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]",
495               ft_flags&0x8000 ? "" : "No ",
496               ft_flags&0x8 ? "" : "Don't ",
497               ft_flags&0x4 ? "" : "No ",
498               ft_flags&0x2 ? "Sequence Numbered Label" : "All Labels",
499               ft_flags&0x1 ? "" : "Don't ");
500        tptr+=4;
501        ui = EXTRACT_32BITS(tptr);
502        if (ui)
503            printf(", Reconnect Timeout: %ums", ui);
504        tptr+=4;
505        ui = EXTRACT_32BITS(tptr);
506        if (ui)
507            printf(", Recovery Time: %ums", ui);
508        break;
509
510    case LDP_TLV_MTU:
511        TLV_TCHECK(2);
512        printf("\n\t      MTU: %u", EXTRACT_16BITS(tptr));
513        break;
514
515
516    /*
517     *  FIXME those are the defined TLVs that lack a decoder
518     *  you are welcome to contribute code ;-)
519     */
520
521    case LDP_TLV_HOP_COUNT:
522    case LDP_TLV_PATH_VECTOR:
523    case LDP_TLV_ATM_LABEL:
524    case LDP_TLV_FR_LABEL:
525    case LDP_TLV_EXTD_STATUS:
526    case LDP_TLV_RETURNED_PDU:
527    case LDP_TLV_RETURNED_MSG:
528    case LDP_TLV_ATM_SESSION_PARM:
529    case LDP_TLV_FR_SESSION_PARM:
530    case LDP_TLV_LABEL_REQUEST_MSG_ID:
531
532    default:
533        if (vflag <= 1)
534            print_unknown_data(tptr,"\n\t      ",tlv_tlen);
535        break;
536    }
537    return(tlv_len+4); /* Type & Length fields not included */
538 
539trunc:
540    printf("\n\t\t packet exceeded snapshot");
541    return 0;
542
543badtlv:
544    printf("\n\t\t TLV contents go past end of TLV");
545    return(tlv_len+4); /* Type & Length fields not included */
546}
547
548void
549ldp_print(register const u_char *pptr, register u_int len) {
550
551    int processed;
552    while (len > (sizeof(struct ldp_common_header) + sizeof(struct ldp_msg_header))) {
553        processed = ldp_msg_print(pptr);
554        if (processed == 0)
555            return;
556        len -= processed;
557        pptr += processed;
558    }
559}
560
561
562int
563ldp_msg_print(register const u_char *pptr) {
564
565    const struct ldp_common_header *ldp_com_header;
566    const struct ldp_msg_header *ldp_msg_header;
567    const u_char *tptr,*msg_tptr;
568    u_short tlen;
569    u_short pdu_len,msg_len,msg_type,msg_tlen;
570    int hexdump,processed;
571
572    tptr=pptr;
573    ldp_com_header = (const struct ldp_common_header *)pptr;
574    TCHECK(*ldp_com_header);
575
576    /*
577     * Sanity checking of the header.
578     */
579    if (EXTRACT_16BITS(&ldp_com_header->version) != LDP_VERSION) {
580        printf("%sLDP version %u packet not supported",
581               (vflag < 1) ? "" : "\n\t",
582               EXTRACT_16BITS(&ldp_com_header->version));
583        return 0;
584    }
585
586    /* print the LSR-ID, label-space & length */
587    pdu_len = EXTRACT_16BITS(&ldp_com_header->pdu_length);
588    printf("%sLDP, Label-Space-ID: %s:%u, pdu-length: %u",
589           (vflag < 1) ? "" : "\n\t",
590           ipaddr_string(&ldp_com_header->lsr_id),
591           EXTRACT_16BITS(&ldp_com_header->label_space),
592           pdu_len);
593
594    /* bail out if non-verbose */
595    if (vflag < 1)
596        return 0;
597
598    /* ok they seem to want to know everything - lets fully decode it */
599    tlen=pdu_len;
600
601    tptr += sizeof(const struct ldp_common_header);
602    tlen -= sizeof(const struct ldp_common_header)-4;   /* Type & Length fields not included */
603
604    while(tlen>0) {
605        /* did we capture enough for fully decoding the msg header ? */
606        TCHECK2(*tptr, sizeof(struct ldp_msg_header));
607
608        ldp_msg_header = (const struct ldp_msg_header *)tptr;
609        msg_len=EXTRACT_16BITS(ldp_msg_header->length);
610        msg_type=LDP_MASK_MSG_TYPE(EXTRACT_16BITS(ldp_msg_header->type));
611
612        /* FIXME vendor private / experimental check */
613        printf("\n\t  %s Message (0x%04x), length: %u, Message ID: 0x%08x, Flags: [%s if unknown]",
614               tok2str(ldp_msg_values,
615                       "Unknown",
616                       msg_type),
617               msg_type,
618               msg_len,
619               EXTRACT_32BITS(&ldp_msg_header->id),
620               LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_msg_header->type)) ? "continue processing" : "ignore");
621
622        if (msg_len == 0) /* infinite loop protection */
623            return 0;
624
625        msg_tptr=tptr+sizeof(struct ldp_msg_header);
626        msg_tlen=msg_len-sizeof(struct ldp_msg_header)+4; /* Type & Length fields not included */
627
628        /* did we capture enough for fully decoding the message ? */
629        TCHECK2(*tptr, msg_len);
630        hexdump=FALSE;
631
632        switch(msg_type) {
633 
634        case LDP_MSG_NOTIF:
635        case LDP_MSG_HELLO:
636        case LDP_MSG_INIT:
637        case LDP_MSG_KEEPALIVE:
638        case LDP_MSG_ADDRESS:
639        case LDP_MSG_LABEL_MAPPING:
640        case LDP_MSG_ADDRESS_WITHDRAW:
641        case LDP_MSG_LABEL_WITHDRAW:
642            while(msg_tlen >= 4) {
643                processed = ldp_tlv_print(msg_tptr);
644                if (processed == 0)
645                    break;
646                msg_tlen-=processed;
647                msg_tptr+=processed;
648            }
649            break;
650
651        /*
652         *  FIXME those are the defined messages that lack a decoder
653         *  you are welcome to contribute code ;-)
654         */
655
656        case LDP_MSG_LABEL_REQUEST:
657        case LDP_MSG_LABEL_RELEASE:
658        case LDP_MSG_LABEL_ABORT_REQUEST:
659
660        default:
661            if (vflag <= 1)
662                print_unknown_data(msg_tptr,"\n\t  ",msg_tlen);
663            break;
664        }
665        /* do we want to see an additionally hexdump ? */
666        if (vflag > 1 || hexdump==TRUE)
667            print_unknown_data(tptr+sizeof(struct ldp_msg_header),"\n\t  ",
668                               msg_len);
669
670        tptr += msg_len+4;
671        tlen -= msg_len+4;
672    }
673    return pdu_len+4;
674trunc:
675    printf("\n\t\t packet exceeded snapshot");
676    return 0;
677}
678
Note: See TracBrowser for help on using the repository browser.