Home | History | Annotate | Download | only in tcpdump
      1 /* Copyright (c) 2013, The TCPDUMP project
      2  * All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are met:
      6  *
      7  * 1. Redistributions of source code must retain the above copyright notice, this
      8  *    list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright notice,
     10  *    this list of conditions and the following disclaimer in the documentation
     11  *    and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
     14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     16  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
     17  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     20  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     23  */
     24 
     25 /* \summary: Message Transfer Part 3 (MTP3) User Adaptation Layer (M3UA) printer */
     26 
     27 /* RFC 4666 */
     28 
     29 #ifdef HAVE_CONFIG_H
     30 #include "config.h"
     31 #endif
     32 
     33 #include <netdissect-stdinc.h>
     34 
     35 #include "netdissect.h"
     36 #include "extract.h"
     37 
     38 static const char tstr[] = " [|m3ua]";
     39 
     40 #define M3UA_REL_1_0 1
     41 
     42 struct m3ua_common_header {
     43   uint8_t  v;
     44   uint8_t  reserved;
     45   uint8_t  msg_class;
     46   uint8_t  msg_type;
     47   uint32_t len;
     48 };
     49 
     50 struct m3ua_param_header {
     51   uint16_t tag;
     52   uint16_t len;
     53 };
     54 
     55 /* message classes */
     56 #define M3UA_MSGC_MGMT 0
     57 #define M3UA_MSGC_TRANSFER 1
     58 #define M3UA_MSGC_SSNM 2
     59 #define M3UA_MSGC_ASPSM 3
     60 #define M3UA_MSGC_ASPTM 4
     61 /* reserved values */
     62 #define M3UA_MSGC_RKM 9
     63 
     64 static const struct tok MessageClasses[] = {
     65 	{ M3UA_MSGC_MGMT,     "Management"            },
     66 	{ M3UA_MSGC_TRANSFER, "Transfer"              },
     67 	{ M3UA_MSGC_SSNM,     "SS7"                   },
     68 	{ M3UA_MSGC_ASPSM,    "ASP"                   },
     69 	{ M3UA_MSGC_ASPTM,    "ASP"                   },
     70 	{ M3UA_MSGC_RKM,      "Routing Key Management"},
     71 	{ 0, NULL }
     72 };
     73 
     74 /* management messages */
     75 #define M3UA_MGMT_ERROR 0
     76 #define M3UA_MGMT_NOTIFY 1
     77 
     78 static const struct tok MgmtMessages[] = {
     79   { M3UA_MGMT_ERROR, "Error" },
     80   { M3UA_MGMT_NOTIFY, "Notify" },
     81   { 0, NULL }
     82 };
     83 
     84 /* transfer messages */
     85 #define M3UA_TRANSFER_DATA 1
     86 
     87 static const struct tok TransferMessages[] = {
     88   { M3UA_TRANSFER_DATA, "Data" },
     89   { 0, NULL }
     90 };
     91 
     92 /* SS7 Signaling Network Management messages */
     93 #define M3UA_SSNM_DUNA 1
     94 #define M3UA_SSNM_DAVA 2
     95 #define M3UA_SSNM_DAUD 3
     96 #define M3UA_SSNM_SCON 4
     97 #define M3UA_SSNM_DUPU 5
     98 #define M3UA_SSNM_DRST 6
     99 
    100 static const struct tok SS7Messages[] = {
    101   { M3UA_SSNM_DUNA, "Destination Unavailable" },
    102   { M3UA_SSNM_DAVA, "Destination Available" },
    103   { M3UA_SSNM_DAUD, "Destination State Audit" },
    104   { M3UA_SSNM_SCON, "Signalling Congestion" },
    105   { M3UA_SSNM_DUPU, "Destination User Part Unavailable" },
    106   { M3UA_SSNM_DRST, "Destination Restricted" },
    107   { 0, NULL }
    108 };
    109 
    110 /* ASP State Maintenance messages */
    111 #define M3UA_ASP_UP 1
    112 #define M3UA_ASP_DN 2
    113 #define M3UA_ASP_BEAT 3
    114 #define M3UA_ASP_UP_ACK 4
    115 #define M3UA_ASP_DN_ACK 5
    116 #define M3UA_ASP_BEAT_ACK 6
    117 
    118 static const struct tok ASPStateMessages[] = {
    119   { M3UA_ASP_UP, "Up" },
    120   { M3UA_ASP_DN, "Down" },
    121   { M3UA_ASP_BEAT, "Heartbeat" },
    122   { M3UA_ASP_UP_ACK, "Up Acknowledgement" },
    123   { M3UA_ASP_DN_ACK, "Down Acknowledgement" },
    124   { M3UA_ASP_BEAT_ACK, "Heartbeat Acknowledgement" },
    125   { 0, NULL }
    126 };
    127 
    128 /* ASP Traffic Maintenance messages */
    129 #define M3UA_ASP_AC 1
    130 #define M3UA_ASP_IA 2
    131 #define M3UA_ASP_AC_ACK 3
    132 #define M3UA_ASP_IA_ACK 4
    133 
    134 static const struct tok ASPTrafficMessages[] = {
    135   { M3UA_ASP_AC, "Active" },
    136   { M3UA_ASP_IA, "Inactive" },
    137   { M3UA_ASP_AC_ACK, "Active Acknowledgement" },
    138   { M3UA_ASP_IA_ACK, "Inactive Acknowledgement" },
    139   { 0, NULL }
    140 };
    141 
    142 /* Routing Key Management messages */
    143 #define M3UA_RKM_REQ 1
    144 #define M3UA_RKM_RSP 2
    145 #define M3UA_RKM_DEREQ 3
    146 #define M3UA_RKM_DERSP 4
    147 
    148 static const struct tok RoutingKeyMgmtMessages[] = {
    149   { M3UA_RKM_REQ, "Registration Request" },
    150   { M3UA_RKM_RSP, "Registration Response" },
    151   { M3UA_RKM_DEREQ, "Deregistration Request" },
    152   { M3UA_RKM_DERSP, "Deregistration Response" },
    153   { 0, NULL }
    154 };
    155 
    156 /* M3UA Parameters */
    157 #define M3UA_PARAM_INFO 0x0004
    158 #define M3UA_PARAM_ROUTING_CTX 0x0006
    159 #define M3UA_PARAM_DIAGNOSTIC 0x0007
    160 #define M3UA_PARAM_HB_DATA 0x0009
    161 #define M3UA_PARAM_TRAFFIC_MODE_TYPE 0x000b
    162 #define M3UA_PARAM_ERROR_CODE 0x000c
    163 #define M3UA_PARAM_STATUS 0x000d
    164 #define M3UA_PARAM_ASP_ID 0x0011
    165 #define M3UA_PARAM_AFFECTED_POINT_CODE 0x0012
    166 #define M3UA_PARAM_CORR_ID 0x0013
    167 
    168 #define M3UA_PARAM_NETWORK_APPEARANCE 0x0200
    169 #define M3UA_PARAM_USER 0x0204
    170 #define M3UA_PARAM_CONGESTION_INDICATION 0x0205
    171 #define M3UA_PARAM_CONCERNED_DST 0x0206
    172 #define M3UA_PARAM_ROUTING_KEY 0x0207
    173 #define M3UA_PARAM_REG_RESULT 0x0208
    174 #define M3UA_PARAM_DEREG_RESULT 0x0209
    175 #define M3UA_PARAM_LOCAL_ROUTING_KEY_ID 0x020a
    176 #define M3UA_PARAM_DST_POINT_CODE 0x020b
    177 #define M3UA_PARAM_SI 0x020c
    178 #define M3UA_PARAM_ORIGIN_POINT_CODE_LIST 0x020e
    179 #define M3UA_PARAM_PROTO_DATA 0x0210
    180 #define M3UA_PARAM_REG_STATUS 0x0212
    181 #define M3UA_PARAM_DEREG_STATUS 0x0213
    182 
    183 static const struct tok ParamName[] = {
    184   { M3UA_PARAM_INFO, "INFO String" },
    185   { M3UA_PARAM_ROUTING_CTX, "Routing Context" },
    186   { M3UA_PARAM_DIAGNOSTIC, "Diagnostic Info" },
    187   { M3UA_PARAM_HB_DATA, "Heartbeat Data" },
    188   { M3UA_PARAM_TRAFFIC_MODE_TYPE, "Traffic Mode Type" },
    189   { M3UA_PARAM_ERROR_CODE, "Error Code" },
    190   { M3UA_PARAM_STATUS, "Status" },
    191   { M3UA_PARAM_ASP_ID, "ASP Identifier" },
    192   { M3UA_PARAM_AFFECTED_POINT_CODE, "Affected Point Code" },
    193   { M3UA_PARAM_CORR_ID, "Correlation ID" },
    194   { M3UA_PARAM_NETWORK_APPEARANCE, "Network Appearance" },
    195   { M3UA_PARAM_USER, "User/Cause" },
    196   { M3UA_PARAM_CONGESTION_INDICATION, "Congestion Indications" },
    197   { M3UA_PARAM_CONCERNED_DST, "Concerned Destination" },
    198   { M3UA_PARAM_ROUTING_KEY, "Routing Key" },
    199   { M3UA_PARAM_REG_RESULT, "Registration Result" },
    200   { M3UA_PARAM_DEREG_RESULT, "Deregistration Result" },
    201   { M3UA_PARAM_LOCAL_ROUTING_KEY_ID, "Local Routing Key Identifier" },
    202   { M3UA_PARAM_DST_POINT_CODE, "Destination Point Code" },
    203   { M3UA_PARAM_SI, "Service Indicators" },
    204   { M3UA_PARAM_ORIGIN_POINT_CODE_LIST, "Originating Point Code List" },
    205   { M3UA_PARAM_PROTO_DATA, "Protocol Data" },
    206   { M3UA_PARAM_REG_STATUS, "Registration Status" },
    207   { M3UA_PARAM_DEREG_STATUS, "Deregistration Status" },
    208   { 0, NULL }
    209 };
    210 
    211 static void
    212 tag_value_print(netdissect_options *ndo,
    213                 const u_char *buf, const uint16_t tag, const uint16_t size)
    214 {
    215   switch (tag) {
    216   case M3UA_PARAM_NETWORK_APPEARANCE:
    217   case M3UA_PARAM_ROUTING_CTX:
    218   case M3UA_PARAM_CORR_ID:
    219     /* buf and size don't include the header */
    220     if (size < 4)
    221       goto invalid;
    222     ND_TCHECK2(*buf, size);
    223     ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(buf)));
    224     break;
    225   /* ... */
    226   default:
    227     ND_PRINT((ndo, "(length %u)", size + (u_int)sizeof(struct m3ua_param_header)));
    228     ND_TCHECK2(*buf, size);
    229   }
    230   return;
    231 
    232 invalid:
    233   ND_PRINT((ndo, "%s", istr));
    234   ND_TCHECK2(*buf, size);
    235   return;
    236 trunc:
    237   ND_PRINT((ndo, "%s", tstr));
    238 }
    239 
    240 /*
    241  *     0                   1                   2                   3
    242  *     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
    243  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    244  *    |          Parameter Tag        |       Parameter Length        |
    245  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    246  *    \                                                               \
    247  *    /                       Parameter Value                         /
    248  *    \                                                               \
    249  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    250  */
    251 static void
    252 m3ua_tags_print(netdissect_options *ndo,
    253                 const u_char *buf, const u_int size)
    254 {
    255   const u_char *p = buf;
    256   int align;
    257   uint16_t hdr_tag;
    258   uint16_t hdr_len;
    259 
    260   while (p < buf + size) {
    261     if (p + sizeof(struct m3ua_param_header) > buf + size)
    262       goto invalid;
    263     ND_TCHECK2(*p, sizeof(struct m3ua_param_header));
    264     /* Parameter Tag */
    265     hdr_tag = EXTRACT_16BITS(p);
    266     ND_PRINT((ndo, "\n\t\t\t%s: ", tok2str(ParamName, "Unknown Parameter (0x%04x)", hdr_tag)));
    267     /* Parameter Length */
    268     hdr_len = EXTRACT_16BITS(p + 2);
    269     if (hdr_len < sizeof(struct m3ua_param_header))
    270       goto invalid;
    271     /* Parameter Value */
    272     align = (p + hdr_len - buf) % 4;
    273     align = align ? 4 - align : 0;
    274     ND_TCHECK2(*p, hdr_len + align);
    275     tag_value_print(ndo, p, hdr_tag, hdr_len - sizeof(struct m3ua_param_header));
    276     p += hdr_len + align;
    277   }
    278   return;
    279 
    280 invalid:
    281   ND_PRINT((ndo, "%s", istr));
    282   ND_TCHECK2(*buf, size);
    283   return;
    284 trunc:
    285   ND_PRINT((ndo, "%s", tstr));
    286 }
    287 
    288 /*
    289  *     0                   1                   2                   3
    290  *     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
    291  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    292  *    |    Version    |   Reserved    | Message Class | Message Type  |
    293  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    294  *    |                        Message Length                         |
    295  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    296  *    \                                                               \
    297  *    /                                                               /
    298  */
    299 void
    300 m3ua_print(netdissect_options *ndo,
    301            const u_char *buf, const u_int size)
    302 {
    303   const struct m3ua_common_header *hdr = (const struct m3ua_common_header *) buf;
    304   const struct tok *dict;
    305 
    306   /* size includes the header */
    307   if (size < sizeof(struct m3ua_common_header))
    308     goto invalid;
    309   ND_TCHECK(*hdr);
    310   if (hdr->v != M3UA_REL_1_0)
    311     return;
    312 
    313   dict =
    314     hdr->msg_class == M3UA_MSGC_MGMT     ? MgmtMessages :
    315     hdr->msg_class == M3UA_MSGC_TRANSFER ? TransferMessages :
    316     hdr->msg_class == M3UA_MSGC_SSNM     ? SS7Messages :
    317     hdr->msg_class == M3UA_MSGC_ASPSM    ? ASPStateMessages :
    318     hdr->msg_class == M3UA_MSGC_ASPTM    ? ASPTrafficMessages :
    319     hdr->msg_class == M3UA_MSGC_RKM      ? RoutingKeyMgmtMessages :
    320     NULL;
    321 
    322   ND_PRINT((ndo, "\n\t\t%s", tok2str(MessageClasses, "Unknown message class %i", hdr->msg_class)));
    323   if (dict != NULL)
    324     ND_PRINT((ndo, " %s Message", tok2str(dict, "Unknown (0x%02x)", hdr->msg_type)));
    325 
    326   if (size != EXTRACT_32BITS(&hdr->len))
    327     ND_PRINT((ndo, "\n\t\t\t@@@@@@ Corrupted length %u of message @@@@@@", EXTRACT_32BITS(&hdr->len)));
    328   else
    329     m3ua_tags_print(ndo, buf + sizeof(struct m3ua_common_header), EXTRACT_32BITS(&hdr->len) - sizeof(struct m3ua_common_header));
    330   return;
    331 
    332 invalid:
    333   ND_PRINT((ndo, "%s", istr));
    334   ND_TCHECK2(*buf, size);
    335   return;
    336 trunc:
    337   ND_PRINT((ndo, "%s", tstr));
    338 }
    339 
    340