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
29*ee67461eSJoseph Mingrone #include <config.h>
303c602fabSXin LI
31*ee67461eSJoseph Mingrone #include "netdissect-stdinc.h"
323c602fabSXin LI
33*ee67461eSJoseph Mingrone #define ND_LONGJMP_FROM_TCHECK
343340d773SGleb Smirnoff #include "netdissect.h"
353c602fabSXin LI #include "extract.h"
363c602fabSXin LI
373c602fabSXin LI
383c602fabSXin LI #define M3UA_REL_1_0 1
393c602fabSXin LI
403c602fabSXin LI struct m3ua_common_header {
41*ee67461eSJoseph Mingrone nd_uint8_t v;
42*ee67461eSJoseph Mingrone nd_uint8_t reserved;
43*ee67461eSJoseph Mingrone nd_uint8_t msg_class;
44*ee67461eSJoseph Mingrone nd_uint8_t msg_type;
45*ee67461eSJoseph Mingrone nd_uint32_t len;
463c602fabSXin LI };
473c602fabSXin LI
483c602fabSXin LI struct m3ua_param_header {
49*ee67461eSJoseph Mingrone nd_uint16_t tag;
50*ee67461eSJoseph Mingrone nd_uint16_t len;
513c602fabSXin LI };
523c602fabSXin LI
533c602fabSXin LI /* message classes */
543c602fabSXin LI #define M3UA_MSGC_MGMT 0
553c602fabSXin LI #define M3UA_MSGC_TRANSFER 1
563c602fabSXin LI #define M3UA_MSGC_SSNM 2
573c602fabSXin LI #define M3UA_MSGC_ASPSM 3
583c602fabSXin LI #define M3UA_MSGC_ASPTM 4
593c602fabSXin LI /* reserved values */
603c602fabSXin LI #define M3UA_MSGC_RKM 9
613c602fabSXin LI
623c602fabSXin LI static const struct tok MessageClasses[] = {
633c602fabSXin LI { M3UA_MSGC_MGMT, "Management" },
643c602fabSXin LI { M3UA_MSGC_TRANSFER, "Transfer" },
653c602fabSXin LI { M3UA_MSGC_SSNM, "SS7" },
663c602fabSXin LI { M3UA_MSGC_ASPSM, "ASP" },
673c602fabSXin LI { M3UA_MSGC_ASPTM, "ASP" },
680bff6a5aSEd Maste { M3UA_MSGC_RKM, "Routing Key Management"},
693c602fabSXin LI { 0, NULL }
703c602fabSXin LI };
713c602fabSXin LI
723c602fabSXin LI /* management messages */
733c602fabSXin LI #define M3UA_MGMT_ERROR 0
743c602fabSXin LI #define M3UA_MGMT_NOTIFY 1
753c602fabSXin LI
763c602fabSXin LI static const struct tok MgmtMessages[] = {
773c602fabSXin LI { M3UA_MGMT_ERROR, "Error" },
783c602fabSXin LI { M3UA_MGMT_NOTIFY, "Notify" },
793c602fabSXin LI { 0, NULL }
803c602fabSXin LI };
813c602fabSXin LI
823c602fabSXin LI /* transfer messages */
833c602fabSXin LI #define M3UA_TRANSFER_DATA 1
843c602fabSXin LI
853c602fabSXin LI static const struct tok TransferMessages[] = {
863c602fabSXin LI { M3UA_TRANSFER_DATA, "Data" },
873c602fabSXin LI { 0, NULL }
883c602fabSXin LI };
893c602fabSXin LI
903c602fabSXin LI /* SS7 Signaling Network Management messages */
913c602fabSXin LI #define M3UA_SSNM_DUNA 1
923c602fabSXin LI #define M3UA_SSNM_DAVA 2
933c602fabSXin LI #define M3UA_SSNM_DAUD 3
943c602fabSXin LI #define M3UA_SSNM_SCON 4
953c602fabSXin LI #define M3UA_SSNM_DUPU 5
963c602fabSXin LI #define M3UA_SSNM_DRST 6
973c602fabSXin LI
983c602fabSXin LI static const struct tok SS7Messages[] = {
993c602fabSXin LI { M3UA_SSNM_DUNA, "Destination Unavailable" },
1003c602fabSXin LI { M3UA_SSNM_DAVA, "Destination Available" },
1013c602fabSXin LI { M3UA_SSNM_DAUD, "Destination State Audit" },
1023c602fabSXin LI { M3UA_SSNM_SCON, "Signalling Congestion" },
1033c602fabSXin LI { M3UA_SSNM_DUPU, "Destination User Part Unavailable" },
1043c602fabSXin LI { M3UA_SSNM_DRST, "Destination Restricted" },
1053c602fabSXin LI { 0, NULL }
1063c602fabSXin LI };
1073c602fabSXin LI
1083c602fabSXin LI /* ASP State Maintenance messages */
1093c602fabSXin LI #define M3UA_ASP_UP 1
1103c602fabSXin LI #define M3UA_ASP_DN 2
1113c602fabSXin LI #define M3UA_ASP_BEAT 3
1123c602fabSXin LI #define M3UA_ASP_UP_ACK 4
1133c602fabSXin LI #define M3UA_ASP_DN_ACK 5
1143c602fabSXin LI #define M3UA_ASP_BEAT_ACK 6
1153c602fabSXin LI
1163c602fabSXin LI static const struct tok ASPStateMessages[] = {
1173c602fabSXin LI { M3UA_ASP_UP, "Up" },
1183c602fabSXin LI { M3UA_ASP_DN, "Down" },
1193c602fabSXin LI { M3UA_ASP_BEAT, "Heartbeat" },
1203c602fabSXin LI { M3UA_ASP_UP_ACK, "Up Acknowledgement" },
1213c602fabSXin LI { M3UA_ASP_DN_ACK, "Down Acknowledgement" },
1223c602fabSXin LI { M3UA_ASP_BEAT_ACK, "Heartbeat Acknowledgement" },
1233c602fabSXin LI { 0, NULL }
1243c602fabSXin LI };
1253c602fabSXin LI
1263c602fabSXin LI /* ASP Traffic Maintenance messages */
1273c602fabSXin LI #define M3UA_ASP_AC 1
1283c602fabSXin LI #define M3UA_ASP_IA 2
1293c602fabSXin LI #define M3UA_ASP_AC_ACK 3
1303c602fabSXin LI #define M3UA_ASP_IA_ACK 4
1313c602fabSXin LI
1323c602fabSXin LI static const struct tok ASPTrafficMessages[] = {
1333c602fabSXin LI { M3UA_ASP_AC, "Active" },
1343c602fabSXin LI { M3UA_ASP_IA, "Inactive" },
1353c602fabSXin LI { M3UA_ASP_AC_ACK, "Active Acknowledgement" },
1363c602fabSXin LI { M3UA_ASP_IA_ACK, "Inactive Acknowledgement" },
1373c602fabSXin LI { 0, NULL }
1383c602fabSXin LI };
1393c602fabSXin LI
1403c602fabSXin LI /* Routing Key Management messages */
1413c602fabSXin LI #define M3UA_RKM_REQ 1
1423c602fabSXin LI #define M3UA_RKM_RSP 2
1433c602fabSXin LI #define M3UA_RKM_DEREQ 3
1443c602fabSXin LI #define M3UA_RKM_DERSP 4
1453c602fabSXin LI
1463c602fabSXin LI static const struct tok RoutingKeyMgmtMessages[] = {
1473c602fabSXin LI { M3UA_RKM_REQ, "Registration Request" },
1483c602fabSXin LI { M3UA_RKM_RSP, "Registration Response" },
1493c602fabSXin LI { M3UA_RKM_DEREQ, "Deregistration Request" },
1503c602fabSXin LI { M3UA_RKM_DERSP, "Deregistration Response" },
1513c602fabSXin LI { 0, NULL }
1523c602fabSXin LI };
1533c602fabSXin LI
154*ee67461eSJoseph Mingrone static const struct uint_tokary m3ua_msgc2tokary[] = {
155*ee67461eSJoseph Mingrone { M3UA_MSGC_MGMT, MgmtMessages },
156*ee67461eSJoseph Mingrone { M3UA_MSGC_TRANSFER, TransferMessages },
157*ee67461eSJoseph Mingrone { M3UA_MSGC_SSNM, SS7Messages },
158*ee67461eSJoseph Mingrone { M3UA_MSGC_ASPSM, ASPStateMessages },
159*ee67461eSJoseph Mingrone { M3UA_MSGC_ASPTM, ASPTrafficMessages },
160*ee67461eSJoseph Mingrone { M3UA_MSGC_RKM, RoutingKeyMgmtMessages },
161*ee67461eSJoseph Mingrone /* uint2tokary() does not use array termination. */
162*ee67461eSJoseph Mingrone };
163*ee67461eSJoseph Mingrone
1643c602fabSXin LI /* M3UA Parameters */
1653c602fabSXin LI #define M3UA_PARAM_INFO 0x0004
1663c602fabSXin LI #define M3UA_PARAM_ROUTING_CTX 0x0006
1673c602fabSXin LI #define M3UA_PARAM_DIAGNOSTIC 0x0007
1683c602fabSXin LI #define M3UA_PARAM_HB_DATA 0x0009
1693c602fabSXin LI #define M3UA_PARAM_TRAFFIC_MODE_TYPE 0x000b
1703c602fabSXin LI #define M3UA_PARAM_ERROR_CODE 0x000c
1713c602fabSXin LI #define M3UA_PARAM_STATUS 0x000d
1723c602fabSXin LI #define M3UA_PARAM_ASP_ID 0x0011
1733c602fabSXin LI #define M3UA_PARAM_AFFECTED_POINT_CODE 0x0012
1743c602fabSXin LI #define M3UA_PARAM_CORR_ID 0x0013
1753c602fabSXin LI
1763c602fabSXin LI #define M3UA_PARAM_NETWORK_APPEARANCE 0x0200
1773c602fabSXin LI #define M3UA_PARAM_USER 0x0204
1783c602fabSXin LI #define M3UA_PARAM_CONGESTION_INDICATION 0x0205
1793c602fabSXin LI #define M3UA_PARAM_CONCERNED_DST 0x0206
1803c602fabSXin LI #define M3UA_PARAM_ROUTING_KEY 0x0207
1813c602fabSXin LI #define M3UA_PARAM_REG_RESULT 0x0208
1823c602fabSXin LI #define M3UA_PARAM_DEREG_RESULT 0x0209
1833c602fabSXin LI #define M3UA_PARAM_LOCAL_ROUTING_KEY_ID 0x020a
1843c602fabSXin LI #define M3UA_PARAM_DST_POINT_CODE 0x020b
1853c602fabSXin LI #define M3UA_PARAM_SI 0x020c
1863c602fabSXin LI #define M3UA_PARAM_ORIGIN_POINT_CODE_LIST 0x020e
1873c602fabSXin LI #define M3UA_PARAM_PROTO_DATA 0x0210
1883c602fabSXin LI #define M3UA_PARAM_REG_STATUS 0x0212
1893c602fabSXin LI #define M3UA_PARAM_DEREG_STATUS 0x0213
1903c602fabSXin LI
1913c602fabSXin LI static const struct tok ParamName[] = {
1923c602fabSXin LI { M3UA_PARAM_INFO, "INFO String" },
1933c602fabSXin LI { M3UA_PARAM_ROUTING_CTX, "Routing Context" },
1943c602fabSXin LI { M3UA_PARAM_DIAGNOSTIC, "Diagnostic Info" },
1953c602fabSXin LI { M3UA_PARAM_HB_DATA, "Heartbeat Data" },
1963c602fabSXin LI { M3UA_PARAM_TRAFFIC_MODE_TYPE, "Traffic Mode Type" },
1973c602fabSXin LI { M3UA_PARAM_ERROR_CODE, "Error Code" },
1983c602fabSXin LI { M3UA_PARAM_STATUS, "Status" },
1993c602fabSXin LI { M3UA_PARAM_ASP_ID, "ASP Identifier" },
2003c602fabSXin LI { M3UA_PARAM_AFFECTED_POINT_CODE, "Affected Point Code" },
2013c602fabSXin LI { M3UA_PARAM_CORR_ID, "Correlation ID" },
2023c602fabSXin LI { M3UA_PARAM_NETWORK_APPEARANCE, "Network Appearance" },
2033c602fabSXin LI { M3UA_PARAM_USER, "User/Cause" },
2043c602fabSXin LI { M3UA_PARAM_CONGESTION_INDICATION, "Congestion Indications" },
2053c602fabSXin LI { M3UA_PARAM_CONCERNED_DST, "Concerned Destination" },
2063c602fabSXin LI { M3UA_PARAM_ROUTING_KEY, "Routing Key" },
2073c602fabSXin LI { M3UA_PARAM_REG_RESULT, "Registration Result" },
2083c602fabSXin LI { M3UA_PARAM_DEREG_RESULT, "Deregistration Result" },
2093c602fabSXin LI { M3UA_PARAM_LOCAL_ROUTING_KEY_ID, "Local Routing Key Identifier" },
2103c602fabSXin LI { M3UA_PARAM_DST_POINT_CODE, "Destination Point Code" },
2113c602fabSXin LI { M3UA_PARAM_SI, "Service Indicators" },
2123c602fabSXin LI { M3UA_PARAM_ORIGIN_POINT_CODE_LIST, "Originating Point Code List" },
2133c602fabSXin LI { M3UA_PARAM_PROTO_DATA, "Protocol Data" },
2143c602fabSXin LI { M3UA_PARAM_REG_STATUS, "Registration Status" },
2153c602fabSXin LI { M3UA_PARAM_DEREG_STATUS, "Deregistration Status" },
2163c602fabSXin LI { 0, NULL }
2173c602fabSXin LI };
2183c602fabSXin LI
2193c602fabSXin LI static void
tag_value_print(netdissect_options * ndo,const u_char * buf,const uint16_t tag,const uint16_t size)2203c602fabSXin LI tag_value_print(netdissect_options *ndo,
2213c602fabSXin LI const u_char *buf, const uint16_t tag, const uint16_t size)
2223c602fabSXin LI {
2233c602fabSXin LI switch (tag) {
2243c602fabSXin LI case M3UA_PARAM_NETWORK_APPEARANCE:
2253c602fabSXin LI case M3UA_PARAM_ROUTING_CTX:
2263c602fabSXin LI case M3UA_PARAM_CORR_ID:
2273c602fabSXin LI /* buf and size don't include the header */
2283c602fabSXin LI if (size < 4)
2293340d773SGleb Smirnoff goto invalid;
230*ee67461eSJoseph Mingrone ND_PRINT("0x%08x", GET_BE_U_4(buf));
2313c602fabSXin LI break;
2323c602fabSXin LI /* ... */
2333c602fabSXin LI default:
234*ee67461eSJoseph Mingrone ND_PRINT("(length %zu)", size + sizeof(struct m3ua_param_header));
2353c602fabSXin LI }
236*ee67461eSJoseph Mingrone ND_TCHECK_LEN(buf, size);
2373c602fabSXin LI return;
2383c602fabSXin LI
2393340d773SGleb Smirnoff invalid:
240*ee67461eSJoseph Mingrone nd_print_invalid(ndo);
241*ee67461eSJoseph Mingrone ND_TCHECK_LEN(buf, size);
2423c602fabSXin LI }
2433c602fabSXin LI
2443c602fabSXin LI /*
2453c602fabSXin LI * 0 1 2 3
2463c602fabSXin 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
2473c602fabSXin LI * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2483c602fabSXin LI * | Parameter Tag | Parameter Length |
2493c602fabSXin LI * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2503c602fabSXin LI * \ \
2513c602fabSXin LI * / Parameter Value /
2523c602fabSXin LI * \ \
2533c602fabSXin LI * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2543c602fabSXin LI */
2553c602fabSXin LI static void
m3ua_tags_print(netdissect_options * ndo,const u_char * buf,const u_int size)2563c602fabSXin LI m3ua_tags_print(netdissect_options *ndo,
2573c602fabSXin LI const u_char *buf, const u_int size)
2583c602fabSXin LI {
2593c602fabSXin LI const u_char *p = buf;
2603c602fabSXin LI int align;
2613c602fabSXin LI uint16_t hdr_tag;
2623c602fabSXin LI uint16_t hdr_len;
2633c602fabSXin LI
2643c602fabSXin LI while (p < buf + size) {
2653c602fabSXin LI if (p + sizeof(struct m3ua_param_header) > buf + size)
2663340d773SGleb Smirnoff goto invalid;
2673c602fabSXin LI /* Parameter Tag */
268*ee67461eSJoseph Mingrone hdr_tag = GET_BE_U_2(p);
269*ee67461eSJoseph Mingrone ND_PRINT("\n\t\t\t%s: ", tok2str(ParamName, "Unknown Parameter (0x%04x)", hdr_tag));
2703c602fabSXin LI /* Parameter Length */
271*ee67461eSJoseph Mingrone hdr_len = GET_BE_U_2(p + 2);
2723c602fabSXin LI if (hdr_len < sizeof(struct m3ua_param_header))
2733340d773SGleb Smirnoff goto invalid;
2743c602fabSXin LI /* Parameter Value */
2753c602fabSXin LI align = (p + hdr_len - buf) % 4;
2763c602fabSXin LI align = align ? 4 - align : 0;
277*ee67461eSJoseph Mingrone ND_TCHECK_LEN(p, hdr_len + align);
2783c602fabSXin LI tag_value_print(ndo, p, hdr_tag, hdr_len - sizeof(struct m3ua_param_header));
2793c602fabSXin LI p += hdr_len + align;
2803c602fabSXin LI }
2813c602fabSXin LI return;
2823c602fabSXin LI
2833340d773SGleb Smirnoff invalid:
284*ee67461eSJoseph Mingrone nd_print_invalid(ndo);
285*ee67461eSJoseph Mingrone ND_TCHECK_LEN(buf, size);
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
m3ua_print(netdissect_options * ndo,const u_char * buf,const u_int size)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;
305*ee67461eSJoseph Mingrone uint8_t msg_class;
3063c602fabSXin LI
307*ee67461eSJoseph Mingrone ndo->ndo_protocol = "m3ua";
3083c602fabSXin LI /* size includes the header */
3093c602fabSXin LI if (size < sizeof(struct m3ua_common_header))
3103340d773SGleb Smirnoff goto invalid;
311*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(hdr);
312*ee67461eSJoseph Mingrone if (GET_U_1(hdr->v) != M3UA_REL_1_0)
3133c602fabSXin LI return;
3143c602fabSXin LI
315*ee67461eSJoseph Mingrone msg_class = GET_U_1(hdr->msg_class);
316*ee67461eSJoseph Mingrone dict = uint2tokary(m3ua_msgc2tokary, msg_class);
3173c602fabSXin LI
318*ee67461eSJoseph Mingrone ND_PRINT("\n\t\t%s", tok2str(MessageClasses, "Unknown message class %i", msg_class));
3193c602fabSXin LI if (dict != NULL)
320*ee67461eSJoseph Mingrone ND_PRINT(" %s Message",
321*ee67461eSJoseph Mingrone tok2str(dict, "Unknown (0x%02x)", GET_U_1(hdr->msg_type)));
3223c602fabSXin LI
323*ee67461eSJoseph Mingrone if (size != GET_BE_U_4(hdr->len))
324*ee67461eSJoseph Mingrone ND_PRINT("\n\t\t\t@@@@@@ Corrupted length %u of message @@@@@@",
325*ee67461eSJoseph Mingrone GET_BE_U_4(hdr->len));
3263c602fabSXin LI else
327*ee67461eSJoseph Mingrone m3ua_tags_print(ndo, buf + sizeof(struct m3ua_common_header),
328*ee67461eSJoseph Mingrone GET_BE_U_4(hdr->len) - sizeof(struct m3ua_common_header));
3293c602fabSXin LI return;
3303c602fabSXin LI
3313340d773SGleb Smirnoff invalid:
332*ee67461eSJoseph Mingrone nd_print_invalid(ndo);
333*ee67461eSJoseph Mingrone ND_TCHECK_LEN(buf, size);
3343c602fabSXin LI }
3353c602fabSXin LI
336