summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-cimd.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-cimd.c')
-rw-r--r--epan/dissectors/packet-cimd.c1103
1 files changed, 1103 insertions, 0 deletions
diff --git a/epan/dissectors/packet-cimd.c b/epan/dissectors/packet-cimd.c
new file mode 100644
index 00000000..6ef145f8
--- /dev/null
+++ b/epan/dissectors/packet-cimd.c
@@ -0,0 +1,1103 @@
+/* packet-cimd.c
+ *
+ * Routines for Computer Interface to Message Distribution (CIMD) version 2 dissection
+ *
+ * Copyright : 2005 Viorel Suman <vsuman[AT]avmob.ro>, Lucian Piros <lpiros[AT]avmob.ro>
+ * In association with Avalanche Mobile BV, http://www.avmob.com
+ *
+ * Updates :
+ * Sub routines for further dissection of Status and Error codes added by Vineeth <vineethvijaysv@gmail.com>
+ *
+ * Refer to the AUTHORS file or the AUTHORS section in the man page
+ * for contacting the author(s) of this file.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "config.h"
+
+#include <stdlib.h>
+
+#include <epan/packet.h>
+#include <epan/charsets.h>
+#define CIMD_STX 0x02 /* Start of CIMD PDU */
+#define CIMD_ETX 0x03 /* End of CIMD PDU */
+#define CIMD_COLON 0x3A /* CIMD colon */
+#define CIMD_DELIM 0x09 /* CIMD Delimiter */
+
+#define CIMD_OC_OFFSET 1 /* CIMD Operation Code Offset */
+#define CIMD_OC_LENGTH 2 /* CIMD Operation Code Length */
+#define CIMD_PN_OFFSET 4 /* CIMD Packet Number Offset */
+#define CIMD_PN_LENGTH 3 /* CIMD Packet Number Length */
+#define CIMD_PC_LENGTH 3 /* CIMD Parameter Code Length */
+#define CIMD_MIN_LENGTH 9 /* CIMD Minimal packet length : STX(1) + OC(2) + COLON(1) + PN(3) + DELIM(1) + ETX(1)*/
+
+/* define CIMD2 operation code */
+
+#define CIMD_Login 1
+#define CIMD_LoginResp 51
+#define CIMD_Logout 2
+#define CIMD_LogoutResp 52
+#define CIMD_SubmitMessage 3
+#define CIMD_SubmitMessageResp 53
+#define CIMD_EnqMessageStatus 4
+#define CIMD_EnqMessageStatusResp 54
+#define CIMD_DeliveryRequest 5
+#define CIMD_DeliveryRequestResp 55
+#define CIMD_CancelMessage 6
+#define CIMD_CancelMessageResp 56
+#define CIMD_SetMessage 8
+#define CIMD_SetMessageResp 58
+#define CIMD_GetMessage 9
+#define CIMD_GetMessageResp 59
+#define CIMD_Alive 40
+#define CIMD_AliveResp 90
+#define CIMD_GeneralErrorResp 98
+#define CIMD_NACK 99
+ /* SC2App */
+#define CIMD_DeliveryMessage 20
+#define CIMD_DeliveryMessageResp 70
+#define CIMD_DeliveryStatusReport 23
+#define CIMD_DeliveryStatusReportResp 73
+
+/* define CIMD2 operation's parameter codes */
+
+#define CIMD_UserIdentity 10
+#define CIMD_Password 11
+#define CIMD_Subaddress 12
+#define CIMD_WindowSize 19
+#define CIMD_DestinationAddress 21
+#define CIMD_OriginatingAddress 23
+#define CIMD_OriginatingImsi 26
+#define CIMD_AlphaOriginatingAddr 27
+#define CIMD_OriginatedVisitedMSCAd 28
+#define CIMD_DataCodingScheme 30
+#define CIMD_UserDataHeader 32
+#define CIMD_UserData 33
+#define CIMD_UserDataBinary 34
+#define CIMD_MoreMessagesToSend 44
+#define CIMD_ValidityPeriodRelative 50
+#define CIMD_ValidityPeriodAbsolute 51
+#define CIMD_ProtocolIdentifier 52
+#define CIMD_FirstDeliveryTimeRel 53
+#define CIMD_FirstDeliveryTimeAbs 54
+#define CIMD_ReplyPath 55
+#define CIMD_StatusReportRequest 56
+#define CIMD_CancelEnabled 58
+#define CIMD_CancelMode 59
+#define CIMD_SCTimeStamp 60
+#define CIMD_StatusCode 61
+#define CIMD_StatusErrorCode 62
+#define CIMD_DischargeTime 63
+#define CIMD_TariffClass 64
+#define CIMD_ServiceDescription 65
+#define CIMD_MessageCount 66
+#define CIMD_Priority 67
+#define CIMD_DeliveryRequestMode 68
+#define CIMD_SCAddress 69
+#define CIMD_GetParameter 500
+#define CIMD_SMSCTime 501
+#define CIMD_ErrorCode 900
+#define CIMD_ErrorText 901
+
+#define MAXPARAMSCOUNT 37
+
+typedef struct cimd_parameter_t cimd_parameter_t;
+
+typedef void (*cimd_pdissect)(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset);
+
+struct cimd_parameter_t {
+ cimd_pdissect diss;
+ gint *ett_p;
+ gint *hf_p;
+};
+
+void proto_register_cimd(void);
+void proto_reg_handoff_cimd(void);
+static void dissect_cimd_parameter(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset);
+static void dissect_cimd_ud(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset);
+static void dissect_cimd_dcs(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset);
+static void dissect_cimd_error_code(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset);
+
+static dissector_handle_t cimd_handle;
+
+static int proto_cimd = -1;
+/* Initialize the subtree pointers */
+static gint ett_cimd = -1;
+
+/* Initialize the protocol and registered fields */
+static int hf_cimd_opcode_indicator = -1;
+static int hf_cimd_packet_number_indicator = -1;
+static int hf_cimd_checksum_indicator = -1;
+static int hf_cimd_pcode_indicator = -1;
+
+static int hf_cimd_dcs_coding_group_indicatorC0 = -1;
+static int hf_cimd_dcs_coding_group_indicatorF0 = -1;
+static int hf_cimd_dcs_compressed_indicator = -1;
+static int hf_cimd_dcs_message_class_meaning_indicator = -1;
+static int hf_cimd_dcs_message_class_indicator = -1;
+static int hf_cimd_dcs_character_set_indicator0C = -1;
+static int hf_cimd_dcs_character_set_indicator04 = -1;
+static int hf_cimd_dcs_indication_sense = -1;
+static int hf_cimd_dcs_indication_type = -1;
+
+static const value_string vals_hdr_OC[] = {
+ /* operation codes array */
+ {CIMD_Login, "Login"},
+ {CIMD_LoginResp, "Login Resp"},
+ {CIMD_Logout, "Logout"},
+ {CIMD_LogoutResp, "Logout Resp"},
+ {CIMD_SubmitMessage, "Submit message"},
+ {CIMD_SubmitMessageResp, "Submit message Resp"},
+ {CIMD_EnqMessageStatus, "Enquire message status"},
+ {CIMD_EnqMessageStatusResp, "Enquire message status Resp"},
+ {CIMD_DeliveryRequest, "Delivery request"},
+ {CIMD_DeliveryRequestResp, "Delivery request Resp"},
+ {CIMD_CancelMessage, "Cancel message"},
+ {CIMD_CancelMessageResp, "Cancel message Resp"},
+ {CIMD_SetMessage, "Set message"},
+ {CIMD_SetMessageResp, "Set message Resp"},
+ {CIMD_GetMessage, "Get message"},
+ {CIMD_GetMessageResp, "Get message Resp"},
+ {CIMD_Alive, "Alive"},
+ {CIMD_AliveResp, "Alive Resp"},
+ {CIMD_GeneralErrorResp, "General error Resp"},
+ {CIMD_NACK, "Nack"},
+ /* SC2App */
+ {CIMD_DeliveryMessage, "Deliver message"},
+ {CIMD_DeliveryMessageResp, "Deliver message Resp"},
+ {CIMD_DeliveryStatusReport, "Deliver status report"},
+ {CIMD_DeliveryStatusReportResp, "Deliver status report Resp"},
+ {0, NULL}
+};
+
+static const value_string cimd_vals_PC[] = {
+ /* parameter codes array */
+ {CIMD_UserIdentity, "User Identity"},
+ {CIMD_Password, "Password"},
+ {CIMD_Subaddress, "Subaddr"},
+ {CIMD_WindowSize, "Window Size"},
+ {CIMD_DestinationAddress, "Destination Address"},
+ {CIMD_OriginatingAddress, "Originating Address"},
+ {CIMD_OriginatingImsi, "Originating IMSI"},
+ {CIMD_AlphaOriginatingAddr, "Alphanumeric Originating Address"},
+ {CIMD_OriginatedVisitedMSCAd, "Originated Visited MSC Address"},
+ {CIMD_DataCodingScheme, "Data Coding Scheme"},
+ {CIMD_UserDataHeader, "User Data Header"},
+ {CIMD_UserData, "User Data"},
+ {CIMD_UserDataBinary, "User Data Binary"},
+ {CIMD_MoreMessagesToSend, "More Messages To Send"},
+ {CIMD_ValidityPeriodRelative, "Validity Period Relative"},
+ {CIMD_ValidityPeriodAbsolute, "Validity Period Absolute"},
+ {CIMD_ProtocolIdentifier, "Protocol Identifier"},
+ {CIMD_FirstDeliveryTimeRel, "First Delivery Time Relative"},
+ {CIMD_FirstDeliveryTimeAbs, "First Delivery Time Absolute"},
+ {CIMD_ReplyPath, "Reply Path"},
+ {CIMD_StatusReportRequest, "Status Report Request"},
+ {CIMD_CancelEnabled, "Cancel Enabled"},
+ {CIMD_CancelMode, "Cancel Mode"},
+ {CIMD_SCTimeStamp, "Service Centre Time Stamp"},
+ {CIMD_StatusCode, "Status Code"},
+ {CIMD_StatusErrorCode, "Status Error Code"},
+ {CIMD_DischargeTime, "Discharge Time"},
+ {CIMD_TariffClass, "Tariff Class"},
+ {CIMD_ServiceDescription, "Service Description"},
+ {CIMD_MessageCount, "Message Count"},
+ {CIMD_Priority, "Priority"},
+ {CIMD_DeliveryRequestMode, "Delivery Request Mode"},
+ {CIMD_SCAddress, "Service Center Address"},
+ {CIMD_GetParameter, "Get Parameter"},
+ {CIMD_SMSCTime, "SMS Center Time"},
+ {CIMD_ErrorCode, "Error Code"},
+ {CIMD_ErrorText, "Error Text"},
+ {0, NULL}
+};
+
+static const value_string cimd_dcs_coding_groups[] = {
+ {0x00, "General Data Coding indication"},
+ {0x01, "General Data Coding indication"},
+ {0x02, "General Data Coding indication"},
+ {0x03, "General Data Coding indication"},
+ {0x04, "Message Marked for Automatic Deletion Group"},
+ {0x05, "Message Marked for Automatic Deletion Group"},
+ {0x06, "Message Marked for Automatic Deletion Group"},
+ {0x07, "Message Marked for Automatic Deletion Group"},
+ {0x08, "Reserved coding group"},
+ {0x09, "Reserved coding group"},
+ {0x0A, "Reserved coding group"},
+ {0x0B, "Reserved coding group"},
+ {0x0C, "Message Waiting Indication Group: Discard Message (7-bit encoded)"},
+ {0x0D, "Message Waiting Indication Group: Store Message (7-bit encoded)"},
+ {0x0E, "Message Waiting Indication Group: Store Message (uncompressed UCS2 encoded)"},
+ {0x0F, "Data coding/message class"},
+ {0, NULL}
+};
+
+static const value_string cimd_dcs_compressed[] = {
+ {0x00, "Text is uncompressed"},
+ {0x01, "Text is compressed"},
+ {0, NULL}
+};
+
+static const value_string cimd_dcs_message_class_meaning[] = {
+ {0x00, "Reserved, bits 1 to 0 have no message class meaning"},
+ {0x01, "Bits 1 to 0 have message class meaning"},
+ {0, NULL}
+};
+
+static const value_string cimd_dcs_message_class[] = {
+ {0x00, "Class 0"},
+ {0x01, "Class 1 Default meaning: ME-specific"},
+ {0x02, "Class 2 (U)SIM specific message"},
+ {0x03, "Class 3 Default meaning: TE-specific"},
+ {0, NULL}
+};
+
+static const value_string cimd_dcs_character_set[] = {
+ {0x00, "GSM 7 bit default alphabet"},
+ {0x01, "8 bit data"},
+ {0x02, "UCS2 (16bit)"},
+ {0x03, "Reserved"},
+ {0, NULL}
+};
+
+static const value_string cimd_dcs_indication_sense[] = {
+ {0x00, "Set Indication Inactive"},
+ {0x01, "Set Indication Active"},
+ {0, NULL}
+};
+
+static const value_string cimd_dcs_indication_type[] = {
+ {0x00, "Voicemail Message Waiting"},
+ {0x01, "Fax Message Waiting"},
+ {0x02, "Electronic Mail Message Waiting"},
+ {0x03, "Other Message Waiting"},
+ {0, NULL}
+};
+
+static const value_string cimd_error_vals[] = {
+ {1, "Unexpected operation"},
+ {2, "Syntax error"},
+ {3, "Unsupported parameter error"},
+ {4, "Connection to SMS Center lost"},
+ {5, "No response from SMS Center"},
+ {6, "General system error"},
+ {7, "Cannot find information"},
+ {8, "Parameter formatting error"},
+ {9, "Requested operation failed"},
+ {10, "Temporary congestion error"},
+ {100, "Invalid login"},
+ {101, "Incorrect access type"},
+ {102, "Too many users with this login ID"},
+ {103, "Login refused by SMS Center"},
+ {104, "Invalid window size"},
+ {105, "Windowing disabled"},
+ {106, "Virtual SMS Center-based barring"},
+ {107, "Invalid subaddr"},
+ {108, "Alias account, login refused"},
+ {300, "Incorrect destination address"},
+ {301, "Incorrect number of destination addresses"},
+ {302, "Syntax error in user data parameter"},
+ {303, "Incorrect bin/head/normal user data parameter combination"},
+ {304, "Incorrect dcs parameter usage"},
+ {305, "Incorrect validity period parameters usage"},
+ {306, "Incorrect originator address usage"},
+ {307, "Incorrect PID parameter usage"},
+ {308, "Incorrect first delivery parameter usage"},
+ {309, "Incorrect reply path usage"},
+ {310, "Incorrect status report request parameter usage"},
+ {311, "Incorrect cancel enabled parameter usage"},
+ {312, "Incorrect priority parameter usage"},
+ {313, "Incorrect tariff class parameter usage"},
+ {314, "Incorrect service description parameter usage"},
+ {315, "Incorrect transport type parameter usage"},
+ {316, "Incorrect message type parameter usage"},
+ {318, "Incorrect MMs parameter usage"},
+ {319, "Incorrect operation timer parameter usage"},
+ {320, "Incorrect dialogue ID parameter usage"},
+ {321, "Incorrect alpha originator address usage"},
+ {322, "Invalid data for alpha numeric originator"},
+ {400, "Incorrect address parameter usage"},
+ {401, "Incorrect scts parameter usage"},
+ {500, "Incorrect scts parameter usage"},
+ {501, "Incorrect mode parameter usage"},
+ {502, "Incorrect parameter combination"},
+ {600, "Incorrect scts parameter usage"},
+ {601, "Incorrect address parameter usage"},
+ {602, "Incorrect mode parameter usage"},
+ {603, "Incorrect parameter combination"},
+ {800, "Changing password failed"},
+ {801, "Changing password not allowed"},
+ {900, "Unsupported item requested"},
+ {0, NULL}
+};
+
+static value_string_ext cimd_error_vals_ext = VALUE_STRING_EXT_INIT(cimd_error_vals);
+
+static const value_string cimd_status_code_vals[] = {
+ {1, " in process"},
+ {2, " validity period expired"},
+ {3, " delivery failed"},
+ {4, " delivery successful"},
+ {5, " no response"},
+ {6, " last no response"},
+ {7, " message cancelled"},
+ {8, " message deleted"},
+ {9, " message deleted by cancel"},
+ {0, NULL}
+};
+
+static const value_string cimd_status_error_vals[] = {
+ {1, "Unknown subscriber"},
+ {9, "Illegal subscriber"},
+ {11, "Teleservice not provisioned"},
+ {13, "Call barred"},
+ {15, "CUG reject"},
+ {19, "No SMS support in MS"},
+ {20, "Error in MS"},
+ {21, "Facility not supported"},
+ {22, "Memory capacity exceeded"},
+ {29, "Absent subscriber"},
+ {30, "MS busy for MT SMS"},
+ {36, "Network/Protocol failure"},
+ {44, "Illegal equipment"},
+ {60, "No paging response"},
+ {61, "GMSC congestion"},
+ {63, "HLR timeout"},
+ {64, "MSC/SGSN_timeout"},
+ {70, "SMRSE/TCP error"},
+ {72, "MT congestion"},
+ {75, "GPRS suspended"},
+ {80, "No paging response via MSC"},
+ {81, "IMSI detached"},
+ {82, "Roaming restriction"},
+ {83, "Deregistered in HLR for GSM"},
+ {84, "Purged for GSM"},
+ {85, "No paging response via SGSN"},
+ {86, "GPRS detached"},
+ {87, "Deregistered in HLR for GPRS"},
+ {88, "The MS purged for GPRS"},
+ {89, "Unidentified subscriber via MSC"},
+ {90, "Unidentified subscriber via SGSN"},
+ {112, "Originator missing credit on prepaid account"},
+ {113, "Destination missing credit on prepaid account"},
+ {114, "Error in prepaid system"},
+ {0, NULL}
+};
+
+static value_string_ext cimd_status_error_vals_ext = VALUE_STRING_EXT_INIT(cimd_status_error_vals);
+
+static const cimd_pdissect cimd_pc_handles[] = {
+ /* function handles for parsing cimd parameters */
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_dcs,
+ dissect_cimd_parameter,
+ dissect_cimd_ud,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_error_code,
+ dissect_cimd_error_code,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_parameter,
+ dissect_cimd_error_code,
+ dissect_cimd_parameter
+};
+
+/* Parameters */
+static cimd_parameter_t vals_hdr_PC[MAXPARAMSCOUNT + 1];
+static gint ett_index[MAXPARAMSCOUNT];
+static gint hf_index[MAXPARAMSCOUNT];
+
+static void dissect_cimd_parameter(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset)
+{
+ /* Set up structures needed to add the param subtree and manage it */
+ proto_tree *param_tree;
+
+ param_tree = proto_tree_add_subtree(tree, tvb, startOffset + 1, endOffset - (startOffset + 1),
+ (*vals_hdr_PC[pindex].ett_p), NULL, cimd_vals_PC[pindex].strptr);
+
+ proto_tree_add_item(param_tree, hf_cimd_pcode_indicator, tvb,
+ startOffset + 1, CIMD_PC_LENGTH, ENC_ASCII);
+ proto_tree_add_item(param_tree, (*vals_hdr_PC[pindex].hf_p), tvb,
+ startOffset + 1 + CIMD_PC_LENGTH + 1, endOffset - (startOffset + 1 + CIMD_PC_LENGTH + 1), ENC_ASCII|ENC_NA);
+}
+
+static void dissect_cimd_ud(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset)
+{
+ /* Set up structures needed to add the param subtree and manage it */
+ proto_tree *param_tree;
+
+ guint8 *tmpBuffer1;
+ const guint8* payloadText;
+ wmem_strbuf_t *tmpBuffer;
+ int loop;
+ gint g_offset, g_size;
+ gchar token[4];
+
+ /* The user data (33) parameter is used when the data coding scheme (30)
+ * indicates that the default GSM character set is being used.
+ * It is not transmitted directly as the 23.038 GSM encoding (packed
+ * or unpacked), but rather each character is converted to ASCII
+ * or Latin-1 (ISO-8859-1).
+ *
+ * (XXX: It is possible that the UDH indicates that a national
+ * language shift table is to be used, but we don't implement that.
+ * It is also theoretically possible for some encoding other than
+ * Latin-1 to be used.)
+ *
+ * It is simplest to first convert back to the GSM 7 bit encoding (unpacked),
+ * and then convert that to UTF-8, since the GSM extension table characters
+ * require a second level of escape handling. We will use '\xff' as a
+ * placeholder for illegal characters that will be replaced with Unicode
+ * REPLACEMENT CHARACTERS upon final conversion.
+ */
+ static const value_string combining_mapping[] = {
+ { 0, "_Oa"},
+ { 1, "_L-"},
+ { 3, "_Y-"},
+ { 4, "_e`"},
+ { 5, "_e'"},
+ { 6, "_u`"},
+ { 7, "_i`"},
+ { 8, "_o`"},
+ { 9, "_C,"},
+ { 11, "_O/"},
+ { 12, "_o/"},
+ { 14, "_A*"},
+ { 15, "_a*"},
+ { 16, "_gd"},
+ { 17, "_--"},
+ { 18, "_gf"},
+ { 19, "_gg"},
+ { 20, "_gl"},
+ { 21, "_go"},
+ { 22, "_gp"},
+ { 23, "_gi"},
+ { 24, "_gs"},
+ { 25, "_gt"},
+ { 26, "_gx"},
+ { 27, "_XX"},
+ { 28, "_AE"},
+ { 29, "_ae"},
+ { 30, "_ss"},
+ { 31, "_E'"},
+ { 34, "_qq"},
+ { 36, "_ox"},
+ { 40, "_!!"},
+ { 91, "_A\""},
+ { 92, "_O\""},
+ { 93, "_N~"},
+ { 94, "_U\""},
+ { 95, "_so"},
+ { 96, "_??"},
+ {123, "_a\""},
+ {124, "_o\""},
+ {125, "_n~"},
+ {126, "_n\""},
+ {127, "_a`"},
+ { 0, NULL }
+ };
+
+ static const char latin_mapping[256] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x00 - */
+ 0xff, 0xff, 0x0a, 0xff, 0xff, 0x0d, 0xff, 0xff, /* - 0x0F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x10 - */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* - 0x1F */
+ 0x20, 0x21, 0x22, 0x23, 0x02, 0x25, 0x26, 0x27, /* 0x20 - */
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* - 0x2F */
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 - */
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* - 0x3F */
+ 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 - */
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* - 0x4F */
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 - */
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x0e, 0x5e, 0xff, /* - 0x5F */
+ 0xff, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 - */
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* - 0x6F */
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 - */
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x0f, 0x7e, 0xff, /* - 0x7F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x80 - */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* - 0x8F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x90 - */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* - 0x9F */
+ 0xff, 0x40, 0xff, 0x01, 0x24, 0x03, 0xff, 0x5f, /* 0xA0 - */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* - 0xAF */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xB0 - */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, /* - 0xBF */
+ 0xff, 0xff, 0xff, 0xff, 0x5b, 0x0e, 0x1c, 0x09, /* 0xC0 - */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* - 0xCF */
+ };
+
+ param_tree = proto_tree_add_subtree(tree, tvb,
+ startOffset + 1, endOffset - (startOffset + 1),
+ (*vals_hdr_PC[pindex].ett_p), NULL, cimd_vals_PC[pindex].strptr
+ );
+ proto_tree_add_item(param_tree, hf_cimd_pcode_indicator, tvb,
+ startOffset + 1, CIMD_PC_LENGTH, ENC_ASCII);
+
+ g_offset = startOffset + 1 + CIMD_PC_LENGTH + 1;
+ g_size = endOffset - g_offset;
+
+ payloadText = tvb_get_ptr(tvb, g_offset, g_size);
+ tmpBuffer = wmem_strbuf_new_sized(wmem_packet_scope(), g_size+1);
+ for (loop = 0; loop < g_size; loop++)
+ {
+ if (payloadText[loop] == '_')
+ {
+ if (loop < g_size - 2)
+ {
+ token[0] = payloadText[loop++];
+ token[1] = payloadText[loop++];
+ token[2] = payloadText[loop];
+ token[3] = '\0';
+ wmem_strbuf_append_c(tmpBuffer, str_to_val(token, combining_mapping, 0xff));
+ }
+ else
+ {
+ /* Not enough room for a combining sequence. */
+ wmem_strbuf_append_c(tmpBuffer, 0xff);
+ }
+ }
+ else
+ {
+ wmem_strbuf_append_c(tmpBuffer, latin_mapping[payloadText[loop]]);
+ }
+ }
+
+ tmpBuffer1 = get_ts_23_038_7bits_string_unpacked(wmem_packet_scope(), wmem_strbuf_get_str(tmpBuffer), (int)wmem_strbuf_get_len(tmpBuffer));
+ wmem_strbuf_destroy(tmpBuffer);
+ proto_tree_add_string(param_tree, (*vals_hdr_PC[pindex].hf_p), tvb, g_offset, g_size, tmpBuffer1);
+}
+
+static void dissect_cimd_dcs(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset)
+{
+ /* Set up structures needed to add the param subtree and manage it */
+ proto_tree *param_tree;
+ gint offset;
+ guint32 dcs;
+ guint32 dcs_cg; /* coding group */
+
+ param_tree = proto_tree_add_subtree(tree, tvb,
+ startOffset + 1, endOffset - (startOffset + 1),
+ (*vals_hdr_PC[pindex].ett_p), NULL, cimd_vals_PC[pindex].strptr
+ );
+
+ proto_tree_add_item(param_tree, hf_cimd_pcode_indicator, tvb,
+ startOffset + 1, CIMD_PC_LENGTH, ENC_ASCII);
+
+ offset = startOffset + 1 + CIMD_PC_LENGTH + 1;
+ dcs = (guint32) strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, offset, endOffset - offset, ENC_ASCII), NULL, 10);
+ proto_tree_add_uint(param_tree, (*vals_hdr_PC[pindex].hf_p), tvb, offset, endOffset - offset, dcs);
+
+ dcs_cg = (dcs & 0xF0) >> 4;
+ if (dcs_cg <= 0x07)
+ {
+ proto_tree_add_uint(param_tree, hf_cimd_dcs_coding_group_indicatorC0, tvb, offset, 1, dcs);
+ }
+ else
+ {
+ proto_tree_add_uint(param_tree, hf_cimd_dcs_coding_group_indicatorF0, tvb, offset, 1, dcs);
+ }
+
+ if (dcs_cg <= 0x07)
+ {
+ proto_tree_add_uint(param_tree, hf_cimd_dcs_compressed_indicator, tvb, offset, 1, dcs);
+ proto_tree_add_uint(param_tree, hf_cimd_dcs_message_class_meaning_indicator, tvb, offset, 1, dcs);
+ proto_tree_add_uint(param_tree, hf_cimd_dcs_character_set_indicator0C, tvb, offset, 1, dcs);
+
+ if (dcs & 0x10)
+ {
+ proto_tree_add_uint(param_tree, hf_cimd_dcs_message_class_indicator, tvb, offset, 1, dcs);
+ }
+ }
+ else if (dcs_cg >= 0x0C && dcs_cg <= 0x0E)
+ {
+ proto_tree_add_uint(param_tree, hf_cimd_dcs_indication_sense, tvb, offset, 1, dcs);
+ proto_tree_add_uint(param_tree, hf_cimd_dcs_indication_type, tvb, offset, 1, dcs);
+ }
+ else if (dcs_cg == 0x0F)
+ {
+ proto_tree_add_uint(param_tree, hf_cimd_dcs_character_set_indicator04, tvb, offset, 1, dcs);
+ proto_tree_add_uint(param_tree, hf_cimd_dcs_message_class_indicator, tvb, offset, 1, dcs);
+ }
+}
+
+static void dissect_cimd_error_code( tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset )
+{
+ /* Same routine can be used to dissect CIMD Error,Status and Status Error Codes */
+ proto_tree *param_tree;
+ guint32 err_code;
+
+ param_tree = proto_tree_add_subtree(tree, tvb, startOffset + 1, endOffset - (startOffset + 1),
+ (*vals_hdr_PC[pindex].ett_p), NULL, cimd_vals_PC[pindex].strptr);
+
+ proto_tree_add_item(param_tree, hf_cimd_pcode_indicator, tvb, startOffset + 1, CIMD_PC_LENGTH, ENC_ASCII);
+
+ err_code = (guint32) strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb,
+ startOffset + 1 + CIMD_PC_LENGTH + 1, endOffset - (startOffset + 1 + CIMD_PC_LENGTH + 1), ENC_ASCII),
+ NULL, 10);
+ proto_tree_add_uint(param_tree, (*vals_hdr_PC[pindex].hf_p), tvb, startOffset + 1 + CIMD_PC_LENGTH + 1, endOffset - (startOffset + 1 + CIMD_PC_LENGTH + 1), err_code);
+}
+
+static void
+dissect_cimd_operation(tvbuff_t *tvb, proto_tree *tree, gint etxp, guint16 checksum, guint8 last1,guint8 OC, guint8 PN)
+{
+ guint32 PC = 0; /* Parameter code */
+ gint idx;
+ gint offset = 0;
+ gint endOffset = 0;
+ proto_item *cimd_item;
+ proto_tree *cimd_tree;
+
+ /* create display subtree for the protocol */
+ cimd_item = proto_tree_add_item(tree, proto_cimd, tvb, 0, etxp + 1, ENC_NA);
+ cimd_tree = proto_item_add_subtree(cimd_item, ett_cimd);
+ proto_tree_add_uint(cimd_tree, hf_cimd_opcode_indicator, tvb, CIMD_OC_OFFSET, CIMD_OC_LENGTH, OC);
+ proto_tree_add_uint(cimd_tree, hf_cimd_packet_number_indicator, tvb, CIMD_PN_OFFSET, CIMD_PN_LENGTH, PN);
+
+ offset = CIMD_PN_OFFSET + CIMD_PN_LENGTH;
+ while (offset < etxp && tvb_get_guint8(tvb, offset) == CIMD_DELIM)
+ {
+ endOffset = tvb_find_guint8(tvb, offset + 1, etxp, CIMD_DELIM);
+ if (endOffset == -1)
+ break;
+
+ PC = (guint32) strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + 1, CIMD_PC_LENGTH, ENC_ASCII), NULL, 10);
+ try_val_to_str_idx(PC, cimd_vals_PC, &idx);
+ if (idx != -1 && tree)
+ {
+ (vals_hdr_PC[idx].diss)(tvb, cimd_tree, idx, offset, endOffset);
+ }
+ offset = endOffset;
+ }
+
+ if (last1 != CIMD_DELIM)
+ {
+ /* Checksum is present */
+ proto_tree_add_uint(cimd_tree, hf_cimd_checksum_indicator, tvb, etxp - 2, 2, checksum);
+ }
+}
+
+static int
+dissect_cimd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ guint8 OC; /* Operation Code */
+ guint8 PN; /* Packet number */
+ guint16 checksum = 0; /* Checksum */
+ guint16 pkt_check = 0;
+ gint etxp = 0; /* ETX position */
+ gint offset = 0;
+ gboolean checksumIsValid = TRUE;
+ guint8 last1, last2, last3;
+
+ etxp = tvb_find_guint8(tvb, CIMD_PN_OFFSET + CIMD_PN_LENGTH, -1, CIMD_ETX);
+ if (etxp == -1) return 0;
+
+ OC = (guint8)strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, CIMD_OC_OFFSET, CIMD_OC_LENGTH, ENC_ASCII), NULL, 10);
+ PN = (guint8)strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, CIMD_PN_OFFSET, CIMD_PN_LENGTH, ENC_ASCII), NULL, 10);
+
+ last1 = tvb_get_guint8(tvb, etxp - 1);
+ last2 = tvb_get_guint8(tvb, etxp - 2);
+ last3 = tvb_get_guint8(tvb, etxp - 3);
+
+ if (last1 == CIMD_DELIM) {
+ /* valid packet, CC is missing */
+ } else if (last1 != CIMD_DELIM && last2 != CIMD_DELIM && last3 == CIMD_DELIM) {
+ /* looks valid, it would be nice to check that last1 and last2 are HEXA */
+ /* CC is present */
+ checksum = (guint16)strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, etxp - 2, 2, ENC_ASCII), NULL, 16);
+ for (; offset < (etxp - 2); offset++)
+ {
+ pkt_check += tvb_get_guint8(tvb, offset);
+ pkt_check &= 0xFF;
+ }
+ checksumIsValid = (checksum == pkt_check);
+ } else {
+ checksumIsValid = FALSE;
+ }
+
+ /* Make entries in Protocol column on summary display */
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "CIMD");
+
+ if (checksumIsValid)
+ col_add_str(pinfo->cinfo, COL_INFO, val_to_str(OC, vals_hdr_OC, "Unknown (%d)"));
+ else
+ col_add_fstr(pinfo->cinfo, COL_INFO, "%s - %s", val_to_str(OC, vals_hdr_OC, "Unknown (%d)"), "invalid checksum");
+
+ dissect_cimd_operation(tvb, tree, etxp, checksum, last1, OC, PN);
+ return tvb_captured_length(tvb);
+}
+
+/**
+ * A 'heuristic dissector' that attemtps to establish whether we have
+ * a CIMD MSU here.
+ */
+static gboolean
+dissect_cimd_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
+{
+ int etxp;
+ guint8 opcode = 0; /* Operation code */
+
+ if (tvb_captured_length(tvb) < CIMD_MIN_LENGTH)
+ return FALSE;
+
+ if (tvb_get_guint8(tvb, 0) != CIMD_STX)
+ return FALSE;
+
+ etxp = tvb_find_guint8(tvb, CIMD_OC_OFFSET, -1, CIMD_ETX);
+ if (etxp == -1)
+ { /* XXX - should we have an option to request reassembly? */
+ return FALSE;
+ }
+
+ /* Try getting the operation-code */
+ opcode = (guint8)strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, CIMD_OC_OFFSET, CIMD_OC_LENGTH, ENC_ASCII), NULL, 10);
+ if (try_val_to_str(opcode, vals_hdr_OC) == NULL)
+ return FALSE;
+
+ if (tvb_get_guint8(tvb, CIMD_OC_OFFSET + CIMD_OC_LENGTH) != CIMD_COLON)
+ return FALSE;
+
+ if (tvb_get_guint8(tvb, CIMD_PN_OFFSET + CIMD_PN_LENGTH) != CIMD_DELIM)
+ return FALSE;
+
+ /* Ok, looks like a valid packet, go dissect. */
+ dissect_cimd(tvb, pinfo, tree, data);
+ return TRUE;
+}
+
+void
+proto_register_cimd(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_cimd_opcode_indicator,
+ { "Operation Code", "cimd.opcode",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_cimd_packet_number_indicator,
+ { "Packet Number", "cimd.pnumber",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_cimd_pcode_indicator,
+ { "Parameter Code", "cimd.pcode",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_cimd_checksum_indicator,
+ { "Checksum", "cimd.chksum",
+ FT_UINT8, BASE_HEX, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_cimd_dcs_coding_group_indicatorC0,
+ { "DCS Coding Group", "cimd.dcs.cg",
+ FT_UINT8, BASE_DEC, VALS(cimd_dcs_coding_groups), 0xC0,
+ NULL, HFILL }
+ },
+ { &hf_cimd_dcs_coding_group_indicatorF0,
+ { "DCS Coding Group", "cimd.dcs.cg",
+ FT_UINT8, BASE_DEC, VALS(cimd_dcs_coding_groups), 0xF0,
+ NULL, HFILL }
+ },
+ { &hf_cimd_dcs_compressed_indicator,
+ { "DCS Compressed Flag", "cimd.dcs.cf",
+ FT_UINT8, BASE_DEC, VALS(cimd_dcs_compressed), 0x20,
+ NULL, HFILL }
+ },
+ { &hf_cimd_dcs_message_class_meaning_indicator,
+ { "DCS Message Class Meaning", "cimd.dcs.mcm",
+ FT_UINT8, BASE_DEC, VALS(cimd_dcs_message_class_meaning), 0x10,
+ NULL, HFILL }
+ },
+ { &hf_cimd_dcs_message_class_indicator,
+ { "DCS Message Class", "cimd.dcs.mc",
+ FT_UINT8, BASE_DEC, VALS(cimd_dcs_message_class), 0x03,
+ NULL, HFILL }
+ },
+ { &hf_cimd_dcs_character_set_indicator0C,
+ { "DCS Character Set", "cimd.dcs.chs",
+ FT_UINT8, BASE_DEC, VALS(cimd_dcs_character_set), 0x0C,
+ NULL, HFILL }
+ },
+ { &hf_cimd_dcs_character_set_indicator04,
+ { "DCS Character Set", "cimd.dcs.chs",
+ FT_UINT8, BASE_DEC, VALS(cimd_dcs_character_set), 0x04,
+ NULL, HFILL }
+ },
+ { &hf_cimd_dcs_indication_sense,
+ { "DCS Indication Sense", "cimd.dcs.is",
+ FT_UINT8, BASE_DEC, VALS(cimd_dcs_indication_sense), 0x04,
+ NULL, HFILL }
+ },
+ { &hf_cimd_dcs_indication_type,
+ { "DCS Indication Type", "cimd.dcs.it",
+ FT_UINT8, BASE_DEC, VALS(cimd_dcs_indication_type), 0x03,
+ NULL, HFILL }
+ },
+ { &hf_index[0],
+ { "User Identity", "cimd.ui",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[1],
+ { "Password", "cimd.passwd",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[2],
+ { "Subaddress", "cimd.saddr",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[3],
+ { "Window Size", "cimd.ws",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[4],
+ { "Destination Address", "cimd.da",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[5],
+ { "Originating Address", "cimd.oa",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[6],
+ { "Originating IMSI", "cimd.oimsi",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[7],
+ { "Alphanumeric Originating Address", "cimd.aoi",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[8],
+ { "Originated Visited MSC Address", "cimd.ovma",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[9],
+ { "Data Coding Scheme", "cimd.dcs",
+ FT_UINT8, BASE_HEX, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[10],
+ { "User Data Header", "cimd.udh",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[11],
+ { "User Data", "cimd.ud",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[12],
+ { "User Data Binary", "cimd.udb",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[13],
+ { "More Messages To Send", "cimd.mms",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[14],
+ { "Validity Period Relative", "cimd.vpr",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[15],
+ { "Validity Period Absolute", "cimd.vpa",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[16],
+ { "Protocol Identifier", "cimd.pi",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[17],
+ { "First Delivery Time Relative", "cimd.fdtr",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[18],
+ { "First Delivery Time Absolute", "cimd.fdta",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[19],
+ { "Reply Path", "cimd.rpath",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[20],
+ { "Status Report Request", "cimd.srr",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[21],
+ { "Cancel Enabled", "cimd.ce",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[22],
+ { "Cancel Mode", "cimd.cm",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[23],
+ { "Service Center Time Stamp", "cimd.scts",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[24],
+ { "Status Code", "cimd.stcode",
+ FT_UINT8, BASE_DEC, VALS(cimd_status_code_vals), 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[25],
+ { "Status Error Code", "cimd.sterrcode",
+ FT_UINT16, BASE_DEC|BASE_EXT_STRING, &cimd_status_error_vals_ext, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[26],
+ { "Discharge Time", "cimd.dt",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[27],
+ { "Tariff Class", "cimd.tclass",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[28],
+ { "Service Description", "cimd.sdes",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[29],
+ { "Message Count", "cimd.mcount",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[30],
+ { "Priority", "cimd.priority",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[31],
+ { "Delivery Request Mode", "cimd.drmode",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[32],
+ { "Service Center Address", "cimd.scaddr",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[33],
+ { "Get Parameter", "cimd.gpar",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[34],
+ { "SMS Center Time", "cimd.smsct",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[35],
+ { "Error Code Description", "cimd.errcode",
+ FT_UINT16, BASE_DEC|BASE_EXT_STRING, &cimd_error_vals_ext, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_index[36],
+ { "Error Text", "cimd.errtext",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ }
+ };
+
+ /* Setup protocol subtree array */
+ gint *ett[MAXPARAMSCOUNT + 1];
+ int i;
+
+ ett[0] = &ett_cimd;
+
+ for(i=0;i<MAXPARAMSCOUNT;i++)
+ {
+ ett_index[i] = -1;
+ ett[i + 1] = &(ett_index[i]);
+ vals_hdr_PC[i].ett_p = &(ett_index[i]);
+ vals_hdr_PC[i].hf_p = &(hf_index[i]);
+ vals_hdr_PC[i].diss = cimd_pc_handles[i];
+ };
+
+ /* Register the protocol name and description */
+ proto_cimd = proto_register_protocol("Computer Interface to Message Distribution", "CIMD", "cimd");
+ /* Required function calls to register the header fields and subtrees used */
+ proto_register_field_array(proto_cimd, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+
+ /* Register the dissector */
+ cimd_handle = register_dissector("cimd", dissect_cimd, proto_cimd);
+}
+
+void
+proto_reg_handoff_cimd(void)
+{
+ /**
+ * CIMD can be spoken on any port so, when not on a specific port, try this
+ * one whenever TCP is spoken.
+ */
+ heur_dissector_add("tcp", dissect_cimd_heur, "CIMD over TCP", "cimd_tcp", proto_cimd, HEURISTIC_ENABLE);
+
+ /**
+ * Also register as one that can be selected by a TCP port number.
+ */
+ dissector_add_for_decode_as_with_preference("tcp.port", cimd_handle);
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local Variables:
+ * c-basic-offset: 2
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=2 tabstop=8 expandtab:
+ * :indentSize=2:tabSize=8:noTabs=true:
+ */