13c602fabSXin LI /* Copyright (c) 2013, The TCPDUMP project 23c602fabSXin LI * All rights reserved. 33c602fabSXin LI * 43c602fabSXin LI * Redistribution and use in source and binary forms, with or without 53c602fabSXin LI * modification, are permitted provided that the following conditions are met: 63c602fabSXin LI * 73c602fabSXin LI * 1. Redistributions of source code must retain the above copyright notice, this 83c602fabSXin LI * list of conditions and the following disclaimer. 93c602fabSXin LI * 2. Redistributions in binary form must reproduce the above copyright notice, 103c602fabSXin LI * this list of conditions and the following disclaimer in the documentation 113c602fabSXin LI * and/or other materials provided with the distribution. 123c602fabSXin LI * 133c602fabSXin LI * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 143c602fabSXin LI * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 153c602fabSXin LI * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 163c602fabSXin LI * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 173c602fabSXin LI * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 183c602fabSXin LI * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 193c602fabSXin LI * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 203c602fabSXin LI * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 213c602fabSXin LI * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 223c602fabSXin LI * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 233c602fabSXin LI */ 243c602fabSXin LI 253340d773SGleb Smirnoff /* \summary: Message Transfer Part 3 (MTP3) User Adaptation Layer (M3UA) printer */ 263340d773SGleb Smirnoff 273340d773SGleb Smirnoff /* RFC 4666 */ 283340d773SGleb Smirnoff 293c602fabSXin LI #ifdef HAVE_CONFIG_H 303c602fabSXin LI #include "config.h" 313c602fabSXin LI #endif 323c602fabSXin LI 333340d773SGleb Smirnoff #include <netdissect-stdinc.h> 343c602fabSXin LI 353340d773SGleb Smirnoff #include "netdissect.h" 363c602fabSXin LI #include "extract.h" 373c602fabSXin LI 383c602fabSXin LI static const char tstr[] = " [|m3ua]"; 393c602fabSXin LI 403c602fabSXin LI #define M3UA_REL_1_0 1 413c602fabSXin LI 423c602fabSXin LI struct m3ua_common_header { 433c602fabSXin LI uint8_t v; 443c602fabSXin LI uint8_t reserved; 453c602fabSXin LI uint8_t msg_class; 463c602fabSXin LI uint8_t msg_type; 473c602fabSXin LI uint32_t len; 483c602fabSXin LI }; 493c602fabSXin LI 503c602fabSXin LI struct m3ua_param_header { 513c602fabSXin LI uint16_t tag; 523c602fabSXin LI uint16_t len; 533c602fabSXin LI }; 543c602fabSXin LI 553c602fabSXin LI /* message classes */ 563c602fabSXin LI #define M3UA_MSGC_MGMT 0 573c602fabSXin LI #define M3UA_MSGC_TRANSFER 1 583c602fabSXin LI #define M3UA_MSGC_SSNM 2 593c602fabSXin LI #define M3UA_MSGC_ASPSM 3 603c602fabSXin LI #define M3UA_MSGC_ASPTM 4 613c602fabSXin LI /* reserved values */ 623c602fabSXin LI #define M3UA_MSGC_RKM 9 633c602fabSXin LI 643c602fabSXin LI static const struct tok MessageClasses[] = { 653c602fabSXin LI { M3UA_MSGC_MGMT, "Management" }, 663c602fabSXin LI { M3UA_MSGC_TRANSFER, "Transfer" }, 673c602fabSXin LI { M3UA_MSGC_SSNM, "SS7" }, 683c602fabSXin LI { M3UA_MSGC_ASPSM, "ASP" }, 693c602fabSXin LI { M3UA_MSGC_ASPTM, "ASP" }, 70*0bff6a5aSEd Maste { M3UA_MSGC_RKM, "Routing Key Management"}, 713c602fabSXin LI { 0, NULL } 723c602fabSXin LI }; 733c602fabSXin LI 743c602fabSXin LI /* management messages */ 753c602fabSXin LI #define M3UA_MGMT_ERROR 0 763c602fabSXin LI #define M3UA_MGMT_NOTIFY 1 773c602fabSXin LI 783c602fabSXin LI static const struct tok MgmtMessages[] = { 793c602fabSXin LI { M3UA_MGMT_ERROR, "Error" }, 803c602fabSXin LI { M3UA_MGMT_NOTIFY, "Notify" }, 813c602fabSXin LI { 0, NULL } 823c602fabSXin LI }; 833c602fabSXin LI 843c602fabSXin LI /* transfer messages */ 853c602fabSXin LI #define M3UA_TRANSFER_DATA 1 863c602fabSXin LI 873c602fabSXin LI static const struct tok TransferMessages[] = { 883c602fabSXin LI { M3UA_TRANSFER_DATA, "Data" }, 893c602fabSXin LI { 0, NULL } 903c602fabSXin LI }; 913c602fabSXin LI 923c602fabSXin LI /* SS7 Signaling Network Management messages */ 933c602fabSXin LI #define M3UA_SSNM_DUNA 1 943c602fabSXin LI #define M3UA_SSNM_DAVA 2 953c602fabSXin LI #define M3UA_SSNM_DAUD 3 963c602fabSXin LI #define M3UA_SSNM_SCON 4 973c602fabSXin LI #define M3UA_SSNM_DUPU 5 983c602fabSXin LI #define M3UA_SSNM_DRST 6 993c602fabSXin LI 1003c602fabSXin LI static const struct tok SS7Messages[] = { 1013c602fabSXin LI { M3UA_SSNM_DUNA, "Destination Unavailable" }, 1023c602fabSXin LI { M3UA_SSNM_DAVA, "Destination Available" }, 1033c602fabSXin LI { M3UA_SSNM_DAUD, "Destination State Audit" }, 1043c602fabSXin LI { M3UA_SSNM_SCON, "Signalling Congestion" }, 1053c602fabSXin LI { M3UA_SSNM_DUPU, "Destination User Part Unavailable" }, 1063c602fabSXin LI { M3UA_SSNM_DRST, "Destination Restricted" }, 1073c602fabSXin LI { 0, NULL } 1083c602fabSXin LI }; 1093c602fabSXin LI 1103c602fabSXin LI /* ASP State Maintenance messages */ 1113c602fabSXin LI #define M3UA_ASP_UP 1 1123c602fabSXin LI #define M3UA_ASP_DN 2 1133c602fabSXin LI #define M3UA_ASP_BEAT 3 1143c602fabSXin LI #define M3UA_ASP_UP_ACK 4 1153c602fabSXin LI #define M3UA_ASP_DN_ACK 5 1163c602fabSXin LI #define M3UA_ASP_BEAT_ACK 6 1173c602fabSXin LI 1183c602fabSXin LI static const struct tok ASPStateMessages[] = { 1193c602fabSXin LI { M3UA_ASP_UP, "Up" }, 1203c602fabSXin LI { M3UA_ASP_DN, "Down" }, 1213c602fabSXin LI { M3UA_ASP_BEAT, "Heartbeat" }, 1223c602fabSXin LI { M3UA_ASP_UP_ACK, "Up Acknowledgement" }, 1233c602fabSXin LI { M3UA_ASP_DN_ACK, "Down Acknowledgement" }, 1243c602fabSXin LI { M3UA_ASP_BEAT_ACK, "Heartbeat Acknowledgement" }, 1253c602fabSXin LI { 0, NULL } 1263c602fabSXin LI }; 1273c602fabSXin LI 1283c602fabSXin LI /* ASP Traffic Maintenance messages */ 1293c602fabSXin LI #define M3UA_ASP_AC 1 1303c602fabSXin LI #define M3UA_ASP_IA 2 1313c602fabSXin LI #define M3UA_ASP_AC_ACK 3 1323c602fabSXin LI #define M3UA_ASP_IA_ACK 4 1333c602fabSXin LI 1343c602fabSXin LI static const struct tok ASPTrafficMessages[] = { 1353c602fabSXin LI { M3UA_ASP_AC, "Active" }, 1363c602fabSXin LI { M3UA_ASP_IA, "Inactive" }, 1373c602fabSXin LI { M3UA_ASP_AC_ACK, "Active Acknowledgement" }, 1383c602fabSXin LI { M3UA_ASP_IA_ACK, "Inactive Acknowledgement" }, 1393c602fabSXin LI { 0, NULL } 1403c602fabSXin LI }; 1413c602fabSXin LI 1423c602fabSXin LI /* Routing Key Management messages */ 1433c602fabSXin LI #define M3UA_RKM_REQ 1 1443c602fabSXin LI #define M3UA_RKM_RSP 2 1453c602fabSXin LI #define M3UA_RKM_DEREQ 3 1463c602fabSXin LI #define M3UA_RKM_DERSP 4 1473c602fabSXin LI 1483c602fabSXin LI static const struct tok RoutingKeyMgmtMessages[] = { 1493c602fabSXin LI { M3UA_RKM_REQ, "Registration Request" }, 1503c602fabSXin LI { M3UA_RKM_RSP, "Registration Response" }, 1513c602fabSXin LI { M3UA_RKM_DEREQ, "Deregistration Request" }, 1523c602fabSXin LI { M3UA_RKM_DERSP, "Deregistration Response" }, 1533c602fabSXin LI { 0, NULL } 1543c602fabSXin LI }; 1553c602fabSXin LI 1563c602fabSXin LI /* M3UA Parameters */ 1573c602fabSXin LI #define M3UA_PARAM_INFO 0x0004 1583c602fabSXin LI #define M3UA_PARAM_ROUTING_CTX 0x0006 1593c602fabSXin LI #define M3UA_PARAM_DIAGNOSTIC 0x0007 1603c602fabSXin LI #define M3UA_PARAM_HB_DATA 0x0009 1613c602fabSXin LI #define M3UA_PARAM_TRAFFIC_MODE_TYPE 0x000b 1623c602fabSXin LI #define M3UA_PARAM_ERROR_CODE 0x000c 1633c602fabSXin LI #define M3UA_PARAM_STATUS 0x000d 1643c602fabSXin LI #define M3UA_PARAM_ASP_ID 0x0011 1653c602fabSXin LI #define M3UA_PARAM_AFFECTED_POINT_CODE 0x0012 1663c602fabSXin LI #define M3UA_PARAM_CORR_ID 0x0013 1673c602fabSXin LI 1683c602fabSXin LI #define M3UA_PARAM_NETWORK_APPEARANCE 0x0200 1693c602fabSXin LI #define M3UA_PARAM_USER 0x0204 1703c602fabSXin LI #define M3UA_PARAM_CONGESTION_INDICATION 0x0205 1713c602fabSXin LI #define M3UA_PARAM_CONCERNED_DST 0x0206 1723c602fabSXin LI #define M3UA_PARAM_ROUTING_KEY 0x0207 1733c602fabSXin LI #define M3UA_PARAM_REG_RESULT 0x0208 1743c602fabSXin LI #define M3UA_PARAM_DEREG_RESULT 0x0209 1753c602fabSXin LI #define M3UA_PARAM_LOCAL_ROUTING_KEY_ID 0x020a 1763c602fabSXin LI #define M3UA_PARAM_DST_POINT_CODE 0x020b 1773c602fabSXin LI #define M3UA_PARAM_SI 0x020c 1783c602fabSXin LI #define M3UA_PARAM_ORIGIN_POINT_CODE_LIST 0x020e 1793c602fabSXin LI #define M3UA_PARAM_PROTO_DATA 0x0210 1803c602fabSXin LI #define M3UA_PARAM_REG_STATUS 0x0212 1813c602fabSXin LI #define M3UA_PARAM_DEREG_STATUS 0x0213 1823c602fabSXin LI 1833c602fabSXin LI static const struct tok ParamName[] = { 1843c602fabSXin LI { M3UA_PARAM_INFO, "INFO String" }, 1853c602fabSXin LI { M3UA_PARAM_ROUTING_CTX, "Routing Context" }, 1863c602fabSXin LI { M3UA_PARAM_DIAGNOSTIC, "Diagnostic Info" }, 1873c602fabSXin LI { M3UA_PARAM_HB_DATA, "Heartbeat Data" }, 1883c602fabSXin LI { M3UA_PARAM_TRAFFIC_MODE_TYPE, "Traffic Mode Type" }, 1893c602fabSXin LI { M3UA_PARAM_ERROR_CODE, "Error Code" }, 1903c602fabSXin LI { M3UA_PARAM_STATUS, "Status" }, 1913c602fabSXin LI { M3UA_PARAM_ASP_ID, "ASP Identifier" }, 1923c602fabSXin LI { M3UA_PARAM_AFFECTED_POINT_CODE, "Affected Point Code" }, 1933c602fabSXin LI { M3UA_PARAM_CORR_ID, "Correlation ID" }, 1943c602fabSXin LI { M3UA_PARAM_NETWORK_APPEARANCE, "Network Appearance" }, 1953c602fabSXin LI { M3UA_PARAM_USER, "User/Cause" }, 1963c602fabSXin LI { M3UA_PARAM_CONGESTION_INDICATION, "Congestion Indications" }, 1973c602fabSXin LI { M3UA_PARAM_CONCERNED_DST, "Concerned Destination" }, 1983c602fabSXin LI { M3UA_PARAM_ROUTING_KEY, "Routing Key" }, 1993c602fabSXin LI { M3UA_PARAM_REG_RESULT, "Registration Result" }, 2003c602fabSXin LI { M3UA_PARAM_DEREG_RESULT, "Deregistration Result" }, 2013c602fabSXin LI { M3UA_PARAM_LOCAL_ROUTING_KEY_ID, "Local Routing Key Identifier" }, 2023c602fabSXin LI { M3UA_PARAM_DST_POINT_CODE, "Destination Point Code" }, 2033c602fabSXin LI { M3UA_PARAM_SI, "Service Indicators" }, 2043c602fabSXin LI { M3UA_PARAM_ORIGIN_POINT_CODE_LIST, "Originating Point Code List" }, 2053c602fabSXin LI { M3UA_PARAM_PROTO_DATA, "Protocol Data" }, 2063c602fabSXin LI { M3UA_PARAM_REG_STATUS, "Registration Status" }, 2073c602fabSXin LI { M3UA_PARAM_DEREG_STATUS, "Deregistration Status" }, 2083c602fabSXin LI { 0, NULL } 2093c602fabSXin LI }; 2103c602fabSXin LI 2113c602fabSXin LI static void 2123c602fabSXin LI tag_value_print(netdissect_options *ndo, 2133c602fabSXin LI const u_char *buf, const uint16_t tag, const uint16_t size) 2143c602fabSXin LI { 2153c602fabSXin LI switch (tag) { 2163c602fabSXin LI case M3UA_PARAM_NETWORK_APPEARANCE: 2173c602fabSXin LI case M3UA_PARAM_ROUTING_CTX: 2183c602fabSXin LI case M3UA_PARAM_CORR_ID: 2193c602fabSXin LI /* buf and size don't include the header */ 2203c602fabSXin LI if (size < 4) 2213340d773SGleb Smirnoff goto invalid; 2223c602fabSXin LI ND_TCHECK2(*buf, size); 2233c602fabSXin LI ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(buf))); 2243c602fabSXin LI break; 2253c602fabSXin LI /* ... */ 2263c602fabSXin LI default: 2273c602fabSXin LI ND_PRINT((ndo, "(length %u)", size + (u_int)sizeof(struct m3ua_param_header))); 2283c602fabSXin LI ND_TCHECK2(*buf, size); 2293c602fabSXin LI } 2303c602fabSXin LI return; 2313c602fabSXin LI 2323340d773SGleb Smirnoff invalid: 2333340d773SGleb Smirnoff ND_PRINT((ndo, "%s", istr)); 2343c602fabSXin LI ND_TCHECK2(*buf, size); 2353c602fabSXin LI return; 2363c602fabSXin LI trunc: 2373c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 2383c602fabSXin LI } 2393c602fabSXin LI 2403c602fabSXin LI /* 2413c602fabSXin LI * 0 1 2 3 2423c602fabSXin LI * 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 2433c602fabSXin LI * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2443c602fabSXin LI * | Parameter Tag | Parameter Length | 2453c602fabSXin LI * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2463c602fabSXin LI * \ \ 2473c602fabSXin LI * / Parameter Value / 2483c602fabSXin LI * \ \ 2493c602fabSXin LI * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2503c602fabSXin LI */ 2513c602fabSXin LI static void 2523c602fabSXin LI m3ua_tags_print(netdissect_options *ndo, 2533c602fabSXin LI const u_char *buf, const u_int size) 2543c602fabSXin LI { 2553c602fabSXin LI const u_char *p = buf; 2563c602fabSXin LI int align; 2573c602fabSXin LI uint16_t hdr_tag; 2583c602fabSXin LI uint16_t hdr_len; 2593c602fabSXin LI 2603c602fabSXin LI while (p < buf + size) { 2613c602fabSXin LI if (p + sizeof(struct m3ua_param_header) > buf + size) 2623340d773SGleb Smirnoff goto invalid; 2633c602fabSXin LI ND_TCHECK2(*p, sizeof(struct m3ua_param_header)); 2643c602fabSXin LI /* Parameter Tag */ 2653c602fabSXin LI hdr_tag = EXTRACT_16BITS(p); 2663c602fabSXin LI ND_PRINT((ndo, "\n\t\t\t%s: ", tok2str(ParamName, "Unknown Parameter (0x%04x)", hdr_tag))); 2673c602fabSXin LI /* Parameter Length */ 2683c602fabSXin LI hdr_len = EXTRACT_16BITS(p + 2); 2693c602fabSXin LI if (hdr_len < sizeof(struct m3ua_param_header)) 2703340d773SGleb Smirnoff goto invalid; 2713c602fabSXin LI /* Parameter Value */ 2723c602fabSXin LI align = (p + hdr_len - buf) % 4; 2733c602fabSXin LI align = align ? 4 - align : 0; 2743c602fabSXin LI ND_TCHECK2(*p, hdr_len + align); 2753c602fabSXin LI tag_value_print(ndo, p, hdr_tag, hdr_len - sizeof(struct m3ua_param_header)); 2763c602fabSXin LI p += hdr_len + align; 2773c602fabSXin LI } 2783c602fabSXin LI return; 2793c602fabSXin LI 2803340d773SGleb Smirnoff invalid: 2813340d773SGleb Smirnoff ND_PRINT((ndo, "%s", istr)); 2823c602fabSXin LI ND_TCHECK2(*buf, size); 2833c602fabSXin LI return; 2843c602fabSXin LI trunc: 2853c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 2863c602fabSXin LI } 2873c602fabSXin LI 2883c602fabSXin LI /* 2893c602fabSXin LI * 0 1 2 3 2903c602fabSXin LI * 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 2913c602fabSXin LI * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2923c602fabSXin LI * | Version | Reserved | Message Class | Message Type | 2933c602fabSXin LI * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2943c602fabSXin LI * | Message Length | 2953c602fabSXin LI * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2963c602fabSXin LI * \ \ 2973c602fabSXin LI * / / 2983c602fabSXin LI */ 2993c602fabSXin LI void 3003c602fabSXin LI m3ua_print(netdissect_options *ndo, 3013c602fabSXin LI const u_char *buf, const u_int size) 3023c602fabSXin LI { 3033c602fabSXin LI const struct m3ua_common_header *hdr = (const struct m3ua_common_header *) buf; 3043c602fabSXin LI const struct tok *dict; 3053c602fabSXin LI 3063c602fabSXin LI /* size includes the header */ 3073c602fabSXin LI if (size < sizeof(struct m3ua_common_header)) 3083340d773SGleb Smirnoff goto invalid; 3093c602fabSXin LI ND_TCHECK(*hdr); 3103c602fabSXin LI if (hdr->v != M3UA_REL_1_0) 3113c602fabSXin LI return; 3123c602fabSXin LI 3133c602fabSXin LI dict = 3143c602fabSXin LI hdr->msg_class == M3UA_MSGC_MGMT ? MgmtMessages : 3153c602fabSXin LI hdr->msg_class == M3UA_MSGC_TRANSFER ? TransferMessages : 3163c602fabSXin LI hdr->msg_class == M3UA_MSGC_SSNM ? SS7Messages : 3173c602fabSXin LI hdr->msg_class == M3UA_MSGC_ASPSM ? ASPStateMessages : 3183c602fabSXin LI hdr->msg_class == M3UA_MSGC_ASPTM ? ASPTrafficMessages : 3193c602fabSXin LI hdr->msg_class == M3UA_MSGC_RKM ? RoutingKeyMgmtMessages : 3203c602fabSXin LI NULL; 3213c602fabSXin LI 3223c602fabSXin LI ND_PRINT((ndo, "\n\t\t%s", tok2str(MessageClasses, "Unknown message class %i", hdr->msg_class))); 3233c602fabSXin LI if (dict != NULL) 3243c602fabSXin LI ND_PRINT((ndo, " %s Message", tok2str(dict, "Unknown (0x%02x)", hdr->msg_type))); 3253c602fabSXin LI 3263c602fabSXin LI if (size != EXTRACT_32BITS(&hdr->len)) 3273c602fabSXin LI ND_PRINT((ndo, "\n\t\t\t@@@@@@ Corrupted length %u of message @@@@@@", EXTRACT_32BITS(&hdr->len))); 3283c602fabSXin LI else 3293c602fabSXin LI m3ua_tags_print(ndo, buf + sizeof(struct m3ua_common_header), EXTRACT_32BITS(&hdr->len) - sizeof(struct m3ua_common_header)); 3303c602fabSXin LI return; 3313c602fabSXin LI 3323340d773SGleb Smirnoff invalid: 3333340d773SGleb Smirnoff ND_PRINT((ndo, "%s", istr)); 3343c602fabSXin LI ND_TCHECK2(*buf, size); 3353c602fabSXin LI return; 3363c602fabSXin LI trunc: 3373c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 3383c602fabSXin LI } 3393c602fabSXin LI 340