source: rtems-libbsd/freebsd/contrib/tcpdump/print-slow.c @ 8440506

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 8440506 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.5 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3/*
4 * Copyright (c) 1998-2006 The TCPDUMP project
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that: (1) source code
8 * distributions retain the above copyright notice and this paragraph
9 * in its entirety, and (2) distributions including binary code include
10 * the above copyright notice and this paragraph in its entirety in
11 * the documentation or other materials provided with the distribution.
12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
13 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
14 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
15 * FOR A PARTICULAR PURPOSE.
16 *
17 * support for the IEEE "slow protocols" LACP, MARKER as per 802.3ad
18 *                                       OAM as per 802.3ah
19 *
20 * Original code by Hannes Gredler (hannes@juniper.net)
21 */
22
23#ifndef lint
24static const char rcsid[] _U_ =
25    "@(#) $Header: /tcpdump/master/tcpdump/print-slow.c,v 1.8 2006-10-12 05:44:33 hannes Exp $";
26#endif
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <tcpdump-stdinc.h>
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37
38#include "interface.h"
39#include "extract.h"
40#include "addrtoname.h"
41#include "ether.h"
42#include "oui.h"
43
44struct slow_common_header_t {
45    u_int8_t proto_subtype;
46    u_int8_t version;
47};
48
49#define SLOW_PROTO_LACP                     1
50#define SLOW_PROTO_MARKER                   2
51#define SLOW_PROTO_OAM                      3
52
53#define LACP_VERSION                        1
54#define MARKER_VERSION                      1
55
56static const struct tok slow_proto_values[] = {
57    { SLOW_PROTO_LACP, "LACP" },
58    { SLOW_PROTO_MARKER, "MARKER" },
59    { SLOW_PROTO_OAM, "OAM" },
60    { 0, NULL}
61};
62
63static const struct tok slow_oam_flag_values[] = {
64    { 0x0001, "Link Fault" },
65    { 0x0002, "Dying Gasp" },
66    { 0x0004, "Critical Event" },
67    { 0x0008, "Local Evaluating" },
68    { 0x0010, "Local Stable" },
69    { 0x0020, "Remote Evaluating" },
70    { 0x0040, "Remote Stable" },
71    { 0, NULL}
72};
73
74#define SLOW_OAM_CODE_INFO          0x00
75#define SLOW_OAM_CODE_EVENT_NOTIF   0x01
76#define SLOW_OAM_CODE_VAR_REQUEST   0x02
77#define SLOW_OAM_CODE_VAR_RESPONSE  0x03
78#define SLOW_OAM_CODE_LOOPBACK_CTRL 0x04
79#define SLOW_OAM_CODE_PRIVATE       0xfe
80
81static const struct tok slow_oam_code_values[] = {
82    { SLOW_OAM_CODE_INFO, "Information" },
83    { SLOW_OAM_CODE_EVENT_NOTIF, "Event Notification" },
84    { SLOW_OAM_CODE_VAR_REQUEST, "Variable Request" },
85    { SLOW_OAM_CODE_VAR_RESPONSE, "Variable Response" },
86    { SLOW_OAM_CODE_LOOPBACK_CTRL, "Loopback Control" },
87    { SLOW_OAM_CODE_PRIVATE, "Vendor Private" },
88    { 0, NULL}
89};
90
91struct slow_oam_info_t {
92    u_int8_t info_type;
93    u_int8_t info_length;
94    u_int8_t oam_version;
95    u_int8_t revision[2];
96    u_int8_t state;
97    u_int8_t oam_config;
98    u_int8_t oam_pdu_config[2];
99    u_int8_t oui[3];
100    u_int8_t vendor_private[4];
101};
102
103#define SLOW_OAM_INFO_TYPE_END_OF_TLV 0x00
104#define SLOW_OAM_INFO_TYPE_LOCAL 0x01
105#define SLOW_OAM_INFO_TYPE_REMOTE 0x02
106#define SLOW_OAM_INFO_TYPE_ORG_SPECIFIC 0xfe
107
108static const struct tok slow_oam_info_type_values[] = {
109    { SLOW_OAM_INFO_TYPE_END_OF_TLV, "End of TLV marker" },
110    { SLOW_OAM_INFO_TYPE_LOCAL, "Local" },
111    { SLOW_OAM_INFO_TYPE_REMOTE, "Remote" },
112    { SLOW_OAM_INFO_TYPE_ORG_SPECIFIC, "Organization specific" },
113    { 0, NULL}
114};
115
116#define OAM_INFO_TYPE_PARSER_MASK 0x3
117static const struct tok slow_oam_info_type_state_parser_values[] = {
118    { 0x00, "forwarding" },
119    { 0x01, "looping back" },
120    { 0x02, "discarding" },
121    { 0x03, "reserved" },
122    { 0, NULL}
123};
124
125#define OAM_INFO_TYPE_MUX_MASK 0x4
126static const struct tok slow_oam_info_type_state_mux_values[] = {
127    { 0x00, "forwarding" },
128    { 0x04, "discarding" },
129    { 0, NULL}
130};
131
132static const struct tok slow_oam_info_type_oam_config_values[] = {
133    { 0x01, "Active" },
134    { 0x02, "Unidirectional" },
135    { 0x04, "Remote-Loopback" },
136    { 0x08, "Link-Events" },
137    { 0x10, "Variable-Retrieval" },
138    { 0, NULL}
139};
140
141/* 11 Bits */
142#define OAM_INFO_TYPE_PDU_SIZE_MASK 0x7ff
143
144#define SLOW_OAM_LINK_EVENT_END_OF_TLV 0x00
145#define SLOW_OAM_LINK_EVENT_ERR_SYM_PER 0x01
146#define SLOW_OAM_LINK_EVENT_ERR_FRM 0x02
147#define SLOW_OAM_LINK_EVENT_ERR_FRM_PER 0x03
148#define SLOW_OAM_LINK_EVENT_ERR_FRM_SUMM 0x04
149#define SLOW_OAM_LINK_EVENT_ORG_SPECIFIC 0xfe
150
151static const struct tok slow_oam_link_event_values[] = {
152    { SLOW_OAM_LINK_EVENT_END_OF_TLV, "End of TLV marker" },
153    { SLOW_OAM_LINK_EVENT_ERR_SYM_PER, "Errored Symbol Period Event" },
154    { SLOW_OAM_LINK_EVENT_ERR_FRM, "Errored Frame Event" },
155    { SLOW_OAM_LINK_EVENT_ERR_FRM_PER, "Errored Frame Period Event" },
156    { SLOW_OAM_LINK_EVENT_ERR_FRM_SUMM, "Errored Frame Seconds Summary Event" },
157    { SLOW_OAM_LINK_EVENT_ORG_SPECIFIC, "Organization specific" },
158    { 0, NULL}
159};
160
161struct slow_oam_link_event_t {
162    u_int8_t event_type;
163    u_int8_t event_length;
164    u_int8_t time_stamp[2];
165    u_int8_t window[8];
166    u_int8_t threshold[8];
167    u_int8_t errors[8];
168    u_int8_t errors_running_total[8];
169    u_int8_t event_running_total[4];
170};
171
172struct slow_oam_variablerequest_t {
173    u_int8_t branch;
174    u_int8_t leaf[2];
175};
176
177struct slow_oam_variableresponse_t {
178    u_int8_t branch;
179    u_int8_t leaf[2];
180    u_int8_t length;
181};
182
183struct slow_oam_loopbackctrl_t {
184    u_int8_t command;
185};
186
187static const struct tok slow_oam_loopbackctrl_cmd_values[] = {
188    { 0x01, "Enable OAM Remote Loopback" },
189    { 0x02, "Disable OAM Remote Loopback" },
190    { 0, NULL}
191};
192
193struct tlv_header_t {
194    u_int8_t type;
195    u_int8_t length;
196};
197
198#define LACP_TLV_TERMINATOR     0x00
199#define LACP_TLV_ACTOR_INFO     0x01
200#define LACP_TLV_PARTNER_INFO   0x02
201#define LACP_TLV_COLLECTOR_INFO 0x03
202
203#define MARKER_TLV_TERMINATOR   0x00
204#define MARKER_TLV_MARKER_INFO  0x01
205
206static const struct tok slow_tlv_values[] = {
207    { (SLOW_PROTO_LACP << 8) + LACP_TLV_TERMINATOR, "Terminator"},
208    { (SLOW_PROTO_LACP << 8) + LACP_TLV_ACTOR_INFO, "Actor Information"},
209    { (SLOW_PROTO_LACP << 8) + LACP_TLV_PARTNER_INFO, "Partner Information"},
210    { (SLOW_PROTO_LACP << 8) + LACP_TLV_COLLECTOR_INFO, "Collector Information"},
211
212    { (SLOW_PROTO_MARKER << 8) + MARKER_TLV_TERMINATOR, "Terminator"},
213    { (SLOW_PROTO_MARKER << 8) + MARKER_TLV_MARKER_INFO, "Marker Information"},
214    { 0, NULL}
215};
216
217struct lacp_tlv_actor_partner_info_t {
218    u_int8_t sys_pri[2];
219    u_int8_t sys[ETHER_ADDR_LEN];
220    u_int8_t key[2];
221    u_int8_t port_pri[2];
222    u_int8_t port[2];
223    u_int8_t state;
224    u_int8_t pad[3];
225};         
226
227static const struct tok lacp_tlv_actor_partner_info_state_values[] = {
228    { 0x01, "Activity"},
229    { 0x02, "Timeout"},
230    { 0x04, "Aggregation"},
231    { 0x08, "Synchronization"},
232    { 0x10, "Collecting"},
233    { 0x20, "Distributing"},
234    { 0x40, "Default"},
235    { 0x80, "Expired"},
236    { 0, NULL}
237};
238
239struct lacp_tlv_collector_info_t {
240    u_int8_t max_delay[2];
241    u_int8_t pad[12];
242};
243
244struct marker_tlv_marker_info_t {
245    u_int8_t req_port[2];
246    u_int8_t req_sys[ETHER_ADDR_LEN];
247    u_int8_t req_trans_id[4];
248    u_int8_t pad[2];
249};
250
251struct lacp_marker_tlv_terminator_t {
252    u_int8_t pad[50];
253};
254
255void slow_marker_lacp_print(register const u_char *, register u_int);
256void slow_oam_print(register const u_char *, register u_int);
257
258const struct slow_common_header_t *slow_com_header;
259
260void
261slow_print(register const u_char *pptr, register u_int len) {
262
263    int print_version;
264
265    slow_com_header = (const struct slow_common_header_t *)pptr;
266    TCHECK(*slow_com_header);
267
268    /*
269     * Sanity checking of the header.
270     */
271    switch (slow_com_header->proto_subtype) {
272    case SLOW_PROTO_LACP:
273        if (slow_com_header->version != LACP_VERSION) {
274            printf("LACP version %u packet not supported",slow_com_header->version);
275            return;
276        }
277        print_version = 1;
278        break;
279
280    case SLOW_PROTO_MARKER:
281        if (slow_com_header->version != MARKER_VERSION) {
282            printf("MARKER version %u packet not supported",slow_com_header->version);
283            return;
284        }
285        print_version = 1;
286        break;
287
288    case SLOW_PROTO_OAM: /* fall through */
289        print_version = 0;
290        break;
291
292    default:
293        /* print basic information and exit */
294        print_version = -1;
295        break;
296    }
297
298    if (print_version) {
299        printf("%sv%u, length %u",
300               tok2str(slow_proto_values, "unknown (%u)",slow_com_header->proto_subtype),
301               slow_com_header->version,
302               len);
303    } else {
304        /* some slow protos don't have a version number in the header */
305        printf("%s, length %u",
306               tok2str(slow_proto_values, "unknown (%u)",slow_com_header->proto_subtype),
307               len);
308    }
309
310    /* unrecognized subtype */
311    if (print_version == -1) {
312        print_unknown_data(pptr, "\n\t", len);
313        return;
314    }
315
316    if (!vflag)
317        return;
318
319    switch (slow_com_header->proto_subtype) {
320    default: /* should not happen */
321        break;
322
323    case SLOW_PROTO_OAM:
324        /* skip proto_subtype */
325        slow_oam_print(pptr+1, len-1);
326        break;
327
328    case SLOW_PROTO_LACP:   /* LACP and MARKER share the same semantics */
329    case SLOW_PROTO_MARKER:
330        /* skip slow_common_header */
331        len -= sizeof(const struct slow_common_header_t);
332        pptr += sizeof(const struct slow_common_header_t);
333        slow_marker_lacp_print(pptr, len);
334        break;
335    }
336    return;
337
338trunc:
339    printf("\n\t\t packet exceeded snapshot");
340}
341
342void slow_marker_lacp_print(register const u_char *tptr, register u_int tlen) {
343
344    const struct tlv_header_t *tlv_header;
345    const u_char *tlv_tptr;
346    u_int tlv_len, tlv_tlen;
347
348    union {
349        const struct lacp_marker_tlv_terminator_t *lacp_marker_tlv_terminator;
350        const struct lacp_tlv_actor_partner_info_t *lacp_tlv_actor_partner_info;
351        const struct lacp_tlv_collector_info_t *lacp_tlv_collector_info;
352        const struct marker_tlv_marker_info_t *marker_tlv_marker_info;
353    } tlv_ptr;
354   
355    while(tlen>0) {
356        /* did we capture enough for fully decoding the tlv header ? */
357        TCHECK2(*tptr, sizeof(struct tlv_header_t));
358        tlv_header = (const struct tlv_header_t *)tptr;
359        tlv_len = tlv_header->length;
360
361        printf("\n\t%s TLV (0x%02x), length %u",
362               tok2str(slow_tlv_values,
363                       "Unknown",
364                       (slow_com_header->proto_subtype << 8) + tlv_header->type),
365               tlv_header->type,
366               tlv_len);
367
368        if ((tlv_len < sizeof(struct tlv_header_t) ||
369            tlv_len > tlen) &&
370            tlv_header->type != LACP_TLV_TERMINATOR &&
371            tlv_header->type != MARKER_TLV_TERMINATOR) {
372            printf("\n\t-----trailing data-----");
373            print_unknown_data(tptr+sizeof(struct tlv_header_t),"\n\t  ",tlen);
374            return;
375        }
376
377        tlv_tptr=tptr+sizeof(struct tlv_header_t);
378        tlv_tlen=tlv_len-sizeof(struct tlv_header_t);
379
380        /* did we capture enough for fully decoding the tlv ? */
381        TCHECK2(*tptr, tlv_len);
382
383        switch((slow_com_header->proto_subtype << 8) + tlv_header->type) {
384
385            /* those two TLVs have the same structure -> fall through */
386        case ((SLOW_PROTO_LACP << 8) + LACP_TLV_ACTOR_INFO):
387        case ((SLOW_PROTO_LACP << 8) + LACP_TLV_PARTNER_INFO):
388            tlv_ptr.lacp_tlv_actor_partner_info = (const struct lacp_tlv_actor_partner_info_t *)tlv_tptr;
389
390            printf("\n\t  System %s, System Priority %u, Key %u" \
391                   ", Port %u, Port Priority %u\n\t  State Flags [%s]",
392                   etheraddr_string(tlv_ptr.lacp_tlv_actor_partner_info->sys),
393                   EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->sys_pri),
394                   EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->key),
395                   EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->port),
396                   EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->port_pri),
397                   bittok2str(lacp_tlv_actor_partner_info_state_values,
398                              "none",
399                              tlv_ptr.lacp_tlv_actor_partner_info->state));
400
401            break;
402
403        case ((SLOW_PROTO_LACP << 8) + LACP_TLV_COLLECTOR_INFO):
404            tlv_ptr.lacp_tlv_collector_info = (const struct lacp_tlv_collector_info_t *)tlv_tptr;
405
406            printf("\n\t  Max Delay %u",
407                   EXTRACT_16BITS(tlv_ptr.lacp_tlv_collector_info->max_delay));
408
409            break;
410
411        case ((SLOW_PROTO_MARKER << 8) + MARKER_TLV_MARKER_INFO):
412            tlv_ptr.marker_tlv_marker_info = (const struct marker_tlv_marker_info_t *)tlv_tptr;
413
414            printf("\n\t  Request System %s, Request Port %u, Request Transaction ID 0x%08x",
415                   etheraddr_string(tlv_ptr.marker_tlv_marker_info->req_sys),
416                   EXTRACT_16BITS(tlv_ptr.marker_tlv_marker_info->req_port),
417                   EXTRACT_32BITS(tlv_ptr.marker_tlv_marker_info->req_trans_id));
418
419            break;
420
421            /* those two TLVs have the same structure -> fall through */
422        case ((SLOW_PROTO_LACP << 8) + LACP_TLV_TERMINATOR):
423        case ((SLOW_PROTO_MARKER << 8) + LACP_TLV_TERMINATOR):
424            tlv_ptr.lacp_marker_tlv_terminator = (const struct lacp_marker_tlv_terminator_t *)tlv_tptr;
425            if (tlv_len == 0) {
426                tlv_len = sizeof(tlv_ptr.lacp_marker_tlv_terminator->pad) +
427                    sizeof(struct tlv_header_t);
428                /* tell the user that we modified the length field  */
429                if (vflag>1)
430                    printf(" (=%u)",tlv_len);
431                /* we have messed around with the length field - now we need to check
432                 * again if there are enough bytes on the wire for the hexdump */
433                TCHECK2(tlv_ptr.lacp_marker_tlv_terminator->pad[0],
434                        sizeof(tlv_ptr.lacp_marker_tlv_terminator->pad));
435            }
436
437            break;
438
439        default:
440            if (vflag <= 1)
441                print_unknown_data(tlv_tptr,"\n\t  ",tlv_tlen);
442            break;
443        }
444        /* do we want to see an additional hexdump ? */
445        if (vflag > 1) {
446            print_unknown_data(tptr+sizeof(struct tlv_header_t),"\n\t  ",
447                               tlv_len-sizeof(struct tlv_header_t));
448        }
449
450        tptr+=tlv_len;
451        tlen-=tlv_len;
452    }
453    return;
454trunc:
455    printf("\n\t\t packet exceeded snapshot");
456}
457
458void slow_oam_print(register const u_char *tptr, register u_int tlen) {
459
460    u_int hexdump;
461
462    struct slow_oam_common_header_t {
463        u_int8_t flags[2];
464        u_int8_t code;
465    };
466
467    struct slow_oam_tlv_header_t {
468        u_int8_t type;
469        u_int8_t length;
470    };
471
472    union {
473        const struct slow_oam_common_header_t *slow_oam_common_header;
474        const struct slow_oam_tlv_header_t *slow_oam_tlv_header;
475    } ptr;
476
477    union {
478        const struct slow_oam_info_t *slow_oam_info;
479        const struct slow_oam_link_event_t *slow_oam_link_event;
480        const struct slow_oam_variablerequest_t *slow_oam_variablerequest;
481        const struct slow_oam_variableresponse_t *slow_oam_variableresponse;
482        const struct slow_oam_loopbackctrl_t *slow_oam_loopbackctrl;
483    } tlv;
484   
485    ptr.slow_oam_common_header = (struct slow_oam_common_header_t *)tptr;
486    tptr += sizeof(struct slow_oam_common_header_t);
487    tlen -= sizeof(struct slow_oam_common_header_t);
488
489    printf("\n\tCode %s OAM PDU, Flags [%s]",
490           tok2str(slow_oam_code_values, "Unknown (%u)", ptr.slow_oam_common_header->code),
491           bittok2str(slow_oam_flag_values,
492                      "none",
493                      EXTRACT_16BITS(&ptr.slow_oam_common_header->flags)));
494
495    switch (ptr.slow_oam_common_header->code) {
496    case SLOW_OAM_CODE_INFO:
497        while (tlen > 0) {
498            ptr.slow_oam_tlv_header = (const struct slow_oam_tlv_header_t *)tptr;
499            printf("\n\t  %s Information Type (%u), length %u",
500                   tok2str(slow_oam_info_type_values, "Reserved",
501                           ptr.slow_oam_tlv_header->type),
502                   ptr.slow_oam_tlv_header->type,
503                   ptr.slow_oam_tlv_header->length);
504
505            hexdump = FALSE;
506            switch (ptr.slow_oam_tlv_header->type) {
507            case SLOW_OAM_INFO_TYPE_END_OF_TLV:
508                if (ptr.slow_oam_tlv_header->length != 0) {
509                    printf("\n\t    ERROR: illegal length - should be 0");
510                }
511                return;
512               
513            case SLOW_OAM_INFO_TYPE_LOCAL: /* identical format - fall through */
514            case SLOW_OAM_INFO_TYPE_REMOTE:
515                tlv.slow_oam_info = (const struct slow_oam_info_t *)tptr;
516               
517                if (tlv.slow_oam_info->info_length !=
518                    sizeof(struct slow_oam_info_t)) {
519                    printf("\n\t    ERROR: illegal length - should be %lu",
520                           (unsigned long) sizeof(struct slow_oam_info_t));
521                    return;
522                }
523
524                printf("\n\t    OAM-Version %u, Revision %u",
525                       tlv.slow_oam_info->oam_version,
526                       EXTRACT_16BITS(&tlv.slow_oam_info->revision));
527
528                printf("\n\t    State-Parser-Action %s, State-MUX-Action %s",
529                       tok2str(slow_oam_info_type_state_parser_values, "Reserved",
530                               tlv.slow_oam_info->state & OAM_INFO_TYPE_PARSER_MASK),
531                       tok2str(slow_oam_info_type_state_mux_values, "Reserved",
532                               tlv.slow_oam_info->state & OAM_INFO_TYPE_MUX_MASK));
533                printf("\n\t    OAM-Config Flags [%s], OAM-PDU-Config max-PDU size %u",
534                       bittok2str(slow_oam_info_type_oam_config_values, "none",
535                                  tlv.slow_oam_info->oam_config),
536                       EXTRACT_16BITS(&tlv.slow_oam_info->oam_pdu_config) &
537                       OAM_INFO_TYPE_PDU_SIZE_MASK);
538                printf("\n\t    OUI %s (0x%06x), Vendor-Private 0x%08x",
539                       tok2str(oui_values, "Unknown",
540                               EXTRACT_24BITS(&tlv.slow_oam_info->oui)),
541                       EXTRACT_24BITS(&tlv.slow_oam_info->oui),
542                       EXTRACT_32BITS(&tlv.slow_oam_info->vendor_private));
543                break;
544               
545            case SLOW_OAM_INFO_TYPE_ORG_SPECIFIC:
546                hexdump = TRUE;
547                break;
548               
549            default:
550                hexdump = TRUE;
551                break;
552            }
553
554            /* infinite loop check */
555            if (!ptr.slow_oam_tlv_header->length) {
556                return;
557            }
558
559            /* do we also want to see a hex dump ? */
560            if (vflag > 1 || hexdump==TRUE) {
561                print_unknown_data(tptr,"\n\t  ",
562                                   ptr.slow_oam_tlv_header->length);
563            }
564
565            tlen -= ptr.slow_oam_tlv_header->length;
566            tptr += ptr.slow_oam_tlv_header->length;
567        }
568        break;
569
570    case SLOW_OAM_CODE_EVENT_NOTIF:
571        while (tlen > 0) {
572            ptr.slow_oam_tlv_header = (const struct slow_oam_tlv_header_t *)tptr;
573            printf("\n\t  %s Link Event Type (%u), length %u",
574                   tok2str(slow_oam_link_event_values, "Reserved",
575                           ptr.slow_oam_tlv_header->type),
576                   ptr.slow_oam_tlv_header->type,
577                   ptr.slow_oam_tlv_header->length);
578
579            hexdump = FALSE;
580            switch (ptr.slow_oam_tlv_header->type) {
581            case SLOW_OAM_LINK_EVENT_END_OF_TLV:
582                if (ptr.slow_oam_tlv_header->length != 0) {
583                    printf("\n\t    ERROR: illegal length - should be 0");
584                }
585                return;
586               
587            case SLOW_OAM_LINK_EVENT_ERR_SYM_PER: /* identical format - fall through */
588            case SLOW_OAM_LINK_EVENT_ERR_FRM:
589            case SLOW_OAM_LINK_EVENT_ERR_FRM_PER:
590            case SLOW_OAM_LINK_EVENT_ERR_FRM_SUMM:
591                tlv.slow_oam_link_event = (const struct slow_oam_link_event_t *)tptr;
592               
593                if (tlv.slow_oam_link_event->event_length !=
594                    sizeof(struct slow_oam_link_event_t)) {
595                    printf("\n\t    ERROR: illegal length - should be %lu",
596                           (unsigned long) sizeof(struct slow_oam_link_event_t));
597                    return;
598                }
599
600                printf("\n\t    Timestamp %u ms, Errored Window %" PRIu64
601                       "\n\t    Errored Threshold %" PRIu64
602                       "\n\t    Errors %" PRIu64
603                       "\n\t    Error Running Total %" PRIu64
604                       "\n\t    Event Running Total %u",
605                       EXTRACT_16BITS(&tlv.slow_oam_link_event->time_stamp)*100,
606                       EXTRACT_64BITS(&tlv.slow_oam_link_event->window),
607                       EXTRACT_64BITS(&tlv.slow_oam_link_event->threshold),
608                       EXTRACT_64BITS(&tlv.slow_oam_link_event->errors),
609                       EXTRACT_64BITS(&tlv.slow_oam_link_event->errors_running_total),
610                       EXTRACT_32BITS(&tlv.slow_oam_link_event->event_running_total));
611                break;
612               
613            case SLOW_OAM_LINK_EVENT_ORG_SPECIFIC:
614                hexdump = TRUE;
615                break;
616               
617            default:
618                hexdump = TRUE;
619                break;
620            }
621
622            /* infinite loop check */
623            if (!ptr.slow_oam_tlv_header->length) {
624                return;
625            }
626
627            /* do we also want to see a hex dump ? */
628            if (vflag > 1 || hexdump==TRUE) {
629                print_unknown_data(tptr,"\n\t  ",
630                                   ptr.slow_oam_tlv_header->length);
631            }
632
633            tlen -= ptr.slow_oam_tlv_header->length;
634            tptr += ptr.slow_oam_tlv_header->length;
635        }
636        break;
637 
638    case SLOW_OAM_CODE_LOOPBACK_CTRL:
639        tlv.slow_oam_loopbackctrl = (const struct slow_oam_loopbackctrl_t *)tptr;
640        printf("\n\t  Command %s (%u)",
641               tok2str(slow_oam_loopbackctrl_cmd_values,
642                       "Unknown",
643                       tlv.slow_oam_loopbackctrl->command),
644               tlv.slow_oam_loopbackctrl->command);
645               tptr ++;
646               tlen --;
647        break;
648
649        /*
650         * FIXME those are the defined codes that lack a decoder
651         * you are welcome to contribute code ;-)
652         */
653    case SLOW_OAM_CODE_VAR_REQUEST:
654    case SLOW_OAM_CODE_VAR_RESPONSE:
655    case SLOW_OAM_CODE_PRIVATE:
656    default:
657        if (vflag <= 1) {
658            print_unknown_data(tptr,"\n\t  ", tlen);
659        }
660        break;
661    }
662    return;
663}
Note: See TracBrowser for help on using the repository browser.