Home | History | Annotate | Line # | Download | only in dist
      1   1.1  christos /*
      2   1.1  christos  * Copyright (c) 1998-2006 The TCPDUMP project
      3   1.1  christos  *
      4   1.1  christos  * Redistribution and use in source and binary forms, with or without
      5   1.1  christos  * modification, are permitted provided that: (1) source code
      6   1.1  christos  * distributions retain the above copyright notice and this paragraph
      7   1.1  christos  * in its entirety, and (2) distributions including binary code include
      8   1.1  christos  * the above copyright notice and this paragraph in its entirety in
      9   1.1  christos  * the documentation or other materials provided with the distribution.
     10   1.1  christos  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
     11   1.1  christos  * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
     12   1.1  christos  * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     13   1.1  christos  * FOR A PARTICULAR PURPOSE.
     14   1.1  christos  *
     15   1.8  christos  * Original code by Hannes Gredler (hannes (at) gredler.at)
     16   1.1  christos  */
     17   1.1  christos 
     18   1.7       spz /* \summary: IEEE 802.3ah Multi-Point Control Protocol (MPCP) printer */
     19   1.7       spz 
     20   1.2  christos #include <sys/cdefs.h>
     21   1.1  christos #ifndef lint
     22  1.10  christos __RCSID("$NetBSD: print-mpcp.c,v 1.10 2024/09/02 16:15:32 christos Exp $");
     23   1.1  christos #endif
     24   1.1  christos 
     25   1.9  christos #include <config.h>
     26   1.1  christos 
     27   1.9  christos #include "netdissect-stdinc.h"
     28   1.1  christos 
     29   1.6  christos #include "netdissect.h"
     30   1.1  christos #include "extract.h"
     31   1.1  christos 
     32   1.1  christos struct mpcp_common_header_t {
     33   1.9  christos     nd_uint16_t opcode;
     34   1.9  christos     nd_uint32_t timestamp;
     35   1.1  christos };
     36   1.1  christos 
     37   1.1  christos #define	MPCP_OPCODE_PAUSE   0x0001
     38   1.1  christos #define	MPCP_OPCODE_GATE    0x0002
     39   1.1  christos #define	MPCP_OPCODE_REPORT  0x0003
     40   1.1  christos #define	MPCP_OPCODE_REG_REQ 0x0004
     41   1.1  christos #define	MPCP_OPCODE_REG     0x0005
     42   1.1  christos #define	MPCP_OPCODE_REG_ACK 0x0006
     43   1.1  christos 
     44   1.1  christos static const struct tok mpcp_opcode_values[] = {
     45   1.1  christos     { MPCP_OPCODE_PAUSE, "Pause" },
     46   1.1  christos     { MPCP_OPCODE_GATE, "Gate" },
     47   1.1  christos     { MPCP_OPCODE_REPORT, "Report" },
     48   1.1  christos     { MPCP_OPCODE_REG_REQ, "Register Request" },
     49   1.1  christos     { MPCP_OPCODE_REG, "Register" },
     50   1.1  christos     { MPCP_OPCODE_REG_ACK, "Register ACK" },
     51   1.1  christos     { 0, NULL}
     52   1.1  christos };
     53   1.1  christos 
     54   1.1  christos #define MPCP_GRANT_NUMBER_LEN 1
     55   1.4  christos #define	MPCP_GRANT_NUMBER_MASK 0x7
     56   1.1  christos static const struct tok mpcp_grant_flag_values[] = {
     57   1.1  christos     { 0x08, "Discovery" },
     58   1.1  christos     { 0x10, "Force Grant #1" },
     59   1.1  christos     { 0x20, "Force Grant #2" },
     60   1.1  christos     { 0x40, "Force Grant #3" },
     61   1.1  christos     { 0x80, "Force Grant #4" },
     62   1.1  christos     { 0, NULL}
     63   1.1  christos };
     64   1.1  christos 
     65   1.1  christos struct mpcp_grant_t {
     66   1.9  christos     nd_uint32_t starttime;
     67   1.9  christos     nd_uint16_t duration;
     68   1.1  christos };
     69   1.1  christos 
     70   1.1  christos struct mpcp_reg_req_t {
     71   1.9  christos     nd_uint8_t flags;
     72   1.9  christos     nd_uint8_t pending_grants;
     73   1.1  christos };
     74   1.1  christos 
     75   1.1  christos 
     76   1.1  christos static const struct tok mpcp_reg_req_flag_values[] = {
     77   1.1  christos     { 1, "Register" },
     78   1.1  christos     { 3, "De-Register" },
     79   1.1  christos     { 0, NULL}
     80   1.1  christos };
     81   1.1  christos 
     82   1.1  christos struct mpcp_reg_t {
     83   1.9  christos     nd_uint16_t assigned_port;
     84   1.9  christos     nd_uint8_t  flags;
     85   1.9  christos     nd_uint16_t sync_time;
     86   1.9  christos     nd_uint8_t  echoed_pending_grants;
     87   1.1  christos };
     88   1.1  christos 
     89   1.1  christos static const struct tok mpcp_reg_flag_values[] = {
     90   1.1  christos     { 1, "Re-Register" },
     91   1.1  christos     { 2, "De-Register" },
     92   1.1  christos     { 3, "ACK" },
     93   1.1  christos     { 4, "NACK" },
     94   1.1  christos     { 0, NULL}
     95   1.1  christos };
     96   1.1  christos 
     97   1.1  christos #define MPCP_REPORT_QUEUESETS_LEN    1
     98   1.1  christos #define MPCP_REPORT_REPORTBITMAP_LEN 1
     99   1.1  christos static const struct tok mpcp_report_bitmap_values[] = {
    100   1.1  christos     { 0x01, "Q0" },
    101   1.1  christos     { 0x02, "Q1" },
    102   1.1  christos     { 0x04, "Q2" },
    103   1.1  christos     { 0x08, "Q3" },
    104   1.1  christos     { 0x10, "Q4" },
    105   1.1  christos     { 0x20, "Q5" },
    106   1.1  christos     { 0x40, "Q6" },
    107   1.1  christos     { 0x80, "Q7" },
    108   1.1  christos     { 0, NULL}
    109   1.1  christos };
    110   1.1  christos 
    111   1.1  christos struct mpcp_reg_ack_t {
    112   1.9  christos     nd_uint8_t  flags;
    113   1.9  christos     nd_uint16_t echoed_assigned_port;
    114   1.9  christos     nd_uint16_t echoed_sync_time;
    115   1.1  christos };
    116   1.1  christos 
    117   1.1  christos static const struct tok mpcp_reg_ack_flag_values[] = {
    118   1.1  christos     { 0, "NACK" },
    119   1.1  christos     { 1, "ACK" },
    120   1.1  christos     { 0, NULL}
    121   1.1  christos };
    122   1.1  christos 
    123   1.1  christos void
    124   1.9  christos mpcp_print(netdissect_options *ndo, const u_char *pptr, u_int length)
    125   1.5  christos {
    126   1.9  christos     const struct mpcp_common_header_t *mpcp_common_header;
    127   1.9  christos     const struct mpcp_reg_req_t *mpcp_reg_req;
    128   1.9  christos     const struct mpcp_reg_t *mpcp_reg;
    129   1.9  christos     const struct mpcp_reg_ack_t *mpcp_reg_ack;
    130   1.1  christos 
    131   1.1  christos 
    132   1.1  christos     const u_char *tptr;
    133   1.4  christos     uint16_t opcode;
    134   1.9  christos     uint32_t timestamp;
    135   1.4  christos     uint8_t grant_numbers, grant;
    136   1.4  christos     uint8_t queue_sets, queue_set, report_bitmap, report;
    137   1.1  christos 
    138   1.9  christos     ndo->ndo_protocol = "mpcp";
    139   1.1  christos     tptr=pptr;
    140   1.9  christos     mpcp_common_header = (const struct mpcp_common_header_t *)pptr;
    141   1.1  christos 
    142   1.9  christos     opcode = GET_BE_U_2(mpcp_common_header->opcode);
    143   1.9  christos     timestamp = GET_BE_U_4(mpcp_common_header->timestamp);
    144   1.9  christos     ND_PRINT("MPCP, Opcode %s", tok2str(mpcp_opcode_values, "Unknown (%u)", opcode));
    145   1.1  christos     if (opcode != MPCP_OPCODE_PAUSE) {
    146   1.9  christos         ND_PRINT(", Timestamp %u ticks", timestamp);
    147   1.1  christos     }
    148   1.9  christos     ND_PRINT(", length %u", length);
    149   1.1  christos 
    150   1.4  christos     if (!ndo->ndo_vflag)
    151   1.1  christos         return;
    152   1.1  christos 
    153   1.9  christos     tptr += sizeof(struct mpcp_common_header_t);
    154   1.1  christos 
    155   1.1  christos     switch (opcode) {
    156   1.1  christos     case MPCP_OPCODE_PAUSE:
    157   1.1  christos         break;
    158   1.1  christos 
    159   1.1  christos     case MPCP_OPCODE_GATE:
    160   1.9  christos         grant_numbers = GET_U_1(tptr) & MPCP_GRANT_NUMBER_MASK;
    161   1.9  christos         ND_PRINT("\n\tGrant Numbers %u, Flags [ %s ]",
    162   1.1  christos                grant_numbers,
    163   1.1  christos                bittok2str(mpcp_grant_flag_values,
    164   1.1  christos                           "?",
    165   1.9  christos                           GET_U_1(tptr) & ~MPCP_GRANT_NUMBER_MASK));
    166   1.1  christos         tptr++;
    167   1.1  christos 
    168   1.1  christos         for (grant = 1; grant <= grant_numbers; grant++) {
    169   1.9  christos             const struct mpcp_grant_t *mpcp_grant = (const struct mpcp_grant_t *)tptr;
    170   1.9  christos             ND_PRINT("\n\tGrant #%u, Start-Time %u ticks, duration %u ticks",
    171   1.1  christos                    grant,
    172   1.9  christos                    GET_BE_U_4(mpcp_grant->starttime),
    173   1.9  christos                    GET_BE_U_2(mpcp_grant->duration));
    174   1.9  christos             tptr += sizeof(struct mpcp_grant_t);
    175   1.1  christos         }
    176   1.1  christos 
    177   1.9  christos         ND_PRINT("\n\tSync-Time %u ticks", GET_BE_U_2(tptr));
    178   1.1  christos         break;
    179   1.1  christos 
    180   1.1  christos 
    181   1.1  christos     case MPCP_OPCODE_REPORT:
    182   1.9  christos         queue_sets = GET_U_1(tptr);
    183   1.1  christos         tptr+=MPCP_REPORT_QUEUESETS_LEN;
    184   1.9  christos         ND_PRINT("\n\tTotal Queue-Sets %u", queue_sets);
    185   1.1  christos 
    186   1.1  christos         for (queue_set = 1; queue_set < queue_sets; queue_set++) {
    187   1.9  christos             report_bitmap = GET_U_1(tptr);
    188   1.9  christos             ND_PRINT("\n\t  Queue-Set #%u, Report-Bitmap [ %s ]",
    189   1.1  christos                    queue_sets,
    190   1.9  christos                    bittok2str(mpcp_report_bitmap_values, "Unknown", report_bitmap));
    191   1.1  christos             tptr++;
    192   1.1  christos 
    193   1.1  christos             report=1;
    194   1.4  christos             while (report_bitmap != 0) {
    195   1.1  christos                 if (report_bitmap & 1) {
    196   1.9  christos                     ND_PRINT("\n\t    Q%u Report, Duration %u ticks",
    197   1.1  christos                            report,
    198   1.9  christos                            GET_BE_U_2(tptr));
    199   1.9  christos                     tptr += 2;
    200   1.1  christos                 }
    201   1.1  christos                 report++;
    202   1.1  christos                 report_bitmap = report_bitmap >> 1;
    203   1.1  christos             }
    204   1.1  christos         }
    205   1.1  christos         break;
    206   1.1  christos 
    207   1.1  christos     case MPCP_OPCODE_REG_REQ:
    208   1.9  christos         mpcp_reg_req = (const struct mpcp_reg_req_t *)tptr;
    209   1.9  christos         ND_PRINT("\n\tFlags [ %s ], Pending-Grants %u",
    210   1.9  christos                bittok2str(mpcp_reg_req_flag_values, "Reserved", GET_U_1(mpcp_reg_req->flags)),
    211   1.9  christos                GET_U_1(mpcp_reg_req->pending_grants));
    212   1.1  christos         break;
    213   1.1  christos 
    214   1.1  christos     case MPCP_OPCODE_REG:
    215   1.9  christos         mpcp_reg = (const struct mpcp_reg_t *)tptr;
    216   1.9  christos         ND_PRINT("\n\tAssigned-Port %u, Flags [ %s ]"
    217   1.1  christos                "\n\tSync-Time %u ticks, Echoed-Pending-Grants %u",
    218   1.9  christos                GET_BE_U_2(mpcp_reg->assigned_port),
    219   1.9  christos                bittok2str(mpcp_reg_flag_values, "Reserved", GET_U_1(mpcp_reg->flags)),
    220   1.9  christos                GET_BE_U_2(mpcp_reg->sync_time),
    221   1.9  christos                GET_U_1(mpcp_reg->echoed_pending_grants));
    222   1.1  christos         break;
    223   1.1  christos 
    224   1.1  christos     case MPCP_OPCODE_REG_ACK:
    225   1.9  christos         mpcp_reg_ack = (const struct mpcp_reg_ack_t *)tptr;
    226   1.9  christos         ND_PRINT("\n\tEchoed-Assigned-Port %u, Flags [ %s ]"
    227   1.1  christos                "\n\tEchoed-Sync-Time %u ticks",
    228   1.9  christos                GET_BE_U_2(mpcp_reg_ack->echoed_assigned_port),
    229   1.9  christos                bittok2str(mpcp_reg_ack_flag_values, "Reserved", GET_U_1(mpcp_reg_ack->flags)),
    230   1.9  christos                GET_BE_U_2(mpcp_reg_ack->echoed_sync_time));
    231   1.1  christos         break;
    232   1.1  christos 
    233   1.1  christos     default:
    234   1.1  christos         /* unknown opcode - hexdump for now */
    235   1.4  christos         print_unknown_data(ndo,pptr, "\n\t", length);
    236   1.1  christos         break;
    237   1.1  christos     }
    238   1.1  christos }
    239