aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2018-12-29 16:50:46 -0500
committerAnders Broman <a.broman58@gmail.com>2018-12-31 08:09:43 +0000
commit8d2b51410f3345ad263125647aeb5948b2143d77 (patch)
tree401eb39fc0bec9a77b3642b69b2fa5f9a6ec59be /epan
parent36981a653ea60b55f62efea4f1cb07e42687dd37 (diff)
SMPP: General improvements
1. Use proto_tree_add_item (and friends) instead of a protocol specific wrapper for integer types 2. Create #defines for command IDs and properly sort them in the their value_string 3. Improve heuristics for command specific parameters to reduce false positives 4. Use length value in TLV for strings 5. Remove "sub tvb" creation. The tvb passed into the pdu should be used. 6. Use proto_tree_add_bitmask_list and proto_tree_add_bitmask_list_value where applicable 7. Allow empty fields for vendor-specific TLVs. 8. Treat version fields as FT_UINT8 and use format with BASE_CUSTOM 9. Condense all command response codes to a single range_string. Bug: 5206 Bug: 15267 Change-Id: I49751d287af1ebb9e27ae7463c08f4724ee60c07 Reviewed-on: https://code.wireshark.org/review/31267 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-smpp.c1754
1 files changed, 841 insertions, 913 deletions
diff --git a/epan/dissectors/packet-smpp.c b/epan/dissectors/packet-smpp.c
index 6591781968..90697c8b18 100644
--- a/epan/dissectors/packet-smpp.c
+++ b/epan/dissectors/packet-smpp.c
@@ -47,28 +47,12 @@
#include "packet-tcp.h"
#include "packet-smpp.h"
-/* General-purpose debug logger.
- * Requires double parentheses because of variable arguments of printf().
- *
- * Enable debug logging for SMPP by defining AM_CFLAGS
- * so that it contains "-DDEBUG_smpp"
- */
-#ifdef DEBUG_smpp
-#define DebugLog(x) \
- g_print("%s:%u: ", __FILE__, __LINE__); \
- g_print x
-#else
-#define DebugLog(x) ;
-#endif
-
-#define SMPP_MIN_LENGTH 16
+#define SMPP_FIXED_HEADER_LENGTH 16
+#define SMPP_MIN_LENGTH SMPP_FIXED_HEADER_LENGTH
/* Forward declarations */
void proto_register_smpp(void);
void proto_reg_handoff_smpp(void);
-static int dissect_smpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data);
-static guint get_smpp_pdu_len(packet_info *pinfo, tvbuff_t *tvb, int offset, void *data);
-static int dissect_smpp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_);
/*
* Initialize the protocol and registered fields
@@ -260,6 +244,8 @@ static gint ett_dlist_resp = -1;
static gint ett_opt_params = -1;
static gint ett_opt_param = -1;
static gint ett_dcs = -1;
+static gint ett_dcs_gsm_sms = -1;
+static gint ett_dcs_gsm_cbs = -1;
static dissector_handle_t smpp_handle;
@@ -269,141 +255,159 @@ static gboolean reassemble_over_tcp = TRUE;
/* Tap */
static int smpp_tap = -1;
+#define SMPP_COMMAND_ID_GENERIC_NACK 0x00000000
+#define SMPP_COMMAND_ID_BIND_RECEIVER 0x00000001
+#define SMPP_COMMAND_ID_BIND_TRANSMITTER 0x00000002
+#define SMPP_COMMAND_ID_QUERY_SM 0x00000003
+#define SMPP_COMMAND_ID_SUBMIT_SM 0x00000004
+#define SMPP_COMMAND_ID_DELIVER_SM 0x00000005
+#define SMPP_COMMAND_ID_UNBIND 0x00000006
+#define SMPP_COMMAND_ID_REPLACE_SM 0x00000007
+#define SMPP_COMMAND_ID_CANCEL_SM 0x00000008
+#define SMPP_COMMAND_ID_BIND_TRANSCEIVER 0x00000009
+#define SMPP_COMMAND_ID_OUTBIND 0x0000000B
+#define SMPP_COMMAND_ID_ENQUIRE_LINK 0x00000015
+#define SMPP_COMMAND_ID_SUBMIT_MULTI 0x00000021
+#define SMPP_COMMAND_ID_ALERT_NOTIFICATION 0x00000102
+#define SMPP_COMMAND_ID_DATA_SM 0x00000103
+/* Introduced in SMPP 5.0 */
+#define SMPP_COMMAND_ID_BROADCAST_SM 0x00000111
+#define SMPP_COMMAND_ID_QUERY_BROADCAST_SM 0x00000112
+#define SMPP_COMMAND_ID_CANCEL_BROADCAST_SM 0x00000113
+/* Huawei SMPP+ extensions */
+#define SMPP_COMMAND_ID_HUAWEI_AUTH_ACC 0x01000001
+#define SMPP_COMMAND_ID_HUAWEI_SM_RESULT_NOTIFY 0X01000002
+
+
+#define SMPP_COMMAND_ID_RESPONSE_MASK 0x80000000
+
/*
* Value-arrays for field-contents
*/
static const value_string vals_command_id[] = { /* Operation */
- { 0x80000000, "Generic_nack" },
- { 0x00000001, "Bind_receiver" },
- { 0x80000001, "Bind_receiver - resp" },
- { 0x00000002, "Bind_transmitter" },
- { 0x80000002, "Bind_transmitter - resp" },
- { 0x00000003, "Query_sm" },
- { 0x80000003, "Query_sm - resp" },
- { 0x00000004, "Submit_sm" },
- { 0x80000004, "Submit_sm - resp" },
- { 0x00000005, "Deliver_sm" },
- { 0x80000005, "Deliver_sm - resp" },
- { 0x00000006, "Unbind" },
- { 0x80000006, "Unbind - resp" },
- { 0x00000007, "Replace_sm" },
- { 0x80000007, "Replace_sm - resp" },
- { 0x00000008, "Cancel_sm" },
- { 0x80000008, "Cancel_sm - resp" },
- { 0x00000009, "Bind_transceiver" },
- { 0x80000009, "Bind_transceiver - resp" },
- { 0x0000000B, "Outbind" },
- { 0x00000015, "Enquire_link" },
- { 0x80000015, "Enquire_link - resp" },
- { 0x00000021, "Submit_multi" },
- { 0x80000021, "Submit_multi - resp" },
- { 0x00000102, "Alert_notification" },
- { 0x00000103, "Data_sm" },
- { 0x80000103, "Data_sm - resp" },
- /* Introduced in SMPP 5.0 */
- { 0x00000111, "Broadcast_sm" },
- { 0x80000111, "Broadcast_sm - resp" },
- { 0x00000112, "Query_broadcast_sm" },
- { 0x80000112, "Query_broadcast_sm - resp" },
- { 0x00000113, "Cancel_broadcast_sm" },
- { 0x80000113, "Cancel_broadcast_sm - resp" },
- /* Huawei SMPP+ extensions */
- { 0x01000001, "Auth_acc" },
- { 0x81000001, "Auth_acc - resp" },
- { 0X01000002, "Sm_result_notify" },
- { 0X81000002, "Sm_result_notify - resp" },
- { 0, NULL }
-};
-
-static const value_string vals_command_status[] = { /* Status */
- { 0x00000000, "Ok" },
- { 0x00000001, "Message length is invalid" },
- { 0x00000002, "Command length is invalid" },
- { 0x00000003, "Invalid command ID" },
- { 0x00000004, "Incorrect BIND status for given command" },
- { 0x00000005, "ESME already in bound state" },
- { 0x00000006, "Invalid priority flag" },
- { 0x00000007, "Invalid registered delivery flag" },
- { 0x00000008, "System error" },
- { 0x00000009, "[Reserved]" },
- { 0x0000000A, "Invalid source address" },
- { 0x0000000B, "Invalid destination address" },
- { 0x0000000C, "Message ID is invalid" },
- { 0x0000000D, "Bind failed" },
- { 0x0000000E, "Invalid password" },
- { 0x0000000F, "Invalid system ID" },
- { 0x00000010, "[Reserved]" },
- { 0x00000011, "Cancel SM failed" },
- { 0x00000012, "[Reserved]" },
- { 0x00000013, "Replace SM failed" },
- { 0x00000014, "Message queue full" },
- { 0x00000015, "Invalid service type" },
- { 0x00000033, "Invalid number of destinations" },
- { 0x00000034, "Invalid distribution list name" },
- { 0x00000040, "Destination flag is invalid (submit_multi)" },
- { 0x00000041, "[Reserved]" },
- { 0x00000042, "Invalid 'submit with replace' request" },
- { 0x00000043, "Invalid esm_class field data" },
- { 0x00000044, "Cannot submit to distribution list" },
- { 0x00000045, "submit_sm or submit_multi failed" },
- { 0x00000046, "[Reserved]" },
- { 0x00000047, "[Reserved]" },
- { 0x00000048, "Invalid source address TON" },
- { 0x00000049, "Invalid source address NPI" },
- { 0x00000050, "Invalid destination address TON" },
- { 0x00000051, "Invalid destination address NPI" },
- { 0x00000052, "[Reserved]" },
- { 0x00000053, "Invalid system_type field" },
- { 0x00000054, "Invalid replace_if_present flag" },
- { 0x00000055, "Invalid number of messages" },
- { 0x00000056, "[Reserved]" },
- { 0x00000057, "[Reserved]" },
- { 0x00000058, "Throttling error (ESME exceeded allowed message limits)" },
- { 0x00000059, "[Reserved]" },
- { 0x00000060, "[Reserved]" },
- { 0x00000061, "Invalid scheduled delivery time" },
- { 0x00000062, "Invalid message validity period (expiry time)" },
- { 0x00000063, "Predefined message invalid or not found" },
- { 0x00000064, "ESME receiver temporary app error code" },
- { 0x00000065, "ESME receiver permanent app error code" },
- { 0x00000066, "ESME receiver reject message error code" },
- { 0x00000067, "query_sm request failed" },
- { 0x000000C0, "Error in the optional part of the PDU body" },
- { 0x000000C1, "Optional parameter not allowed" },
- { 0x000000C2, "Invalid parameter length" },
- { 0x000000C3, "Expected optional parameter missing" },
- { 0x000000C4, "Invalid optional parameter value" },
- { 0x000000FE, "(Transaction) Delivery failure (used for data_sm_resp)" },
- { 0x000000FF, "Unknown error" },
- /* Introduced in SMPP 5.0 */
- { 0x00000100, "ESME Not authorised to use specified service_type." },
- { 0x00000101, "ESME Prohibited from using specified operation."},
- { 0x00000102, "Specified service_type is unavailable." },
- { 0x00000103, "Specified service_type is denied." },
- { 0x00000104, "Invalid Data Coding Scheme." },
- { 0x00000105, "Source Address Sub unit is Invalid." },
- { 0x00000106, "Destination Address Sub unit is Invalid." },
- { 0x00000107, "Broadcast Frequency Interval is invalid." },
- { 0x00000108, "Broadcast Alias Name is invalid." },
- { 0x00000109, "Broadcast Area Format is invalid." },
- { 0x0000010A, "Number of Broadcast Areas is invalid." },
- { 0x0000010B, "Broadcast Content Type is invalid." },
- { 0x0000010C, "Broadcast Message Class is invalid." },
- { 0x0000010D, "broadcast_sm operation failed." },
- { 0x0000010E, "query_broadcast_sm operation failed." },
- { 0x0000010F, "cancel_broadcast_sm operation failed." },
- { 0x00000110, "Number of Repeated Broadcasts is invalid." },
- { 0x00000111, "Broadcast Service Group is invalid." },
- { 0x00000112, "Broadcast Channel Indicator is invalid." },
+ { SMPP_COMMAND_ID_BIND_RECEIVER, "Bind_receiver" },
+ { SMPP_COMMAND_ID_BIND_TRANSMITTER, "Bind_transmitter" },
+ { SMPP_COMMAND_ID_QUERY_SM, "Query_sm" },
+ { SMPP_COMMAND_ID_SUBMIT_SM, "Submit_sm" },
+ { SMPP_COMMAND_ID_DELIVER_SM, "Deliver_sm" },
+ { SMPP_COMMAND_ID_UNBIND, "Unbind" },
+ { SMPP_COMMAND_ID_REPLACE_SM, "Replace_sm" },
+ { SMPP_COMMAND_ID_CANCEL_SM, "Cancel_sm" },
+ { SMPP_COMMAND_ID_BIND_TRANSCEIVER, "Bind_transceiver" },
+ { SMPP_COMMAND_ID_OUTBIND, "Outbind" },
+ { SMPP_COMMAND_ID_ENQUIRE_LINK, "Enquire_link" },
+ { SMPP_COMMAND_ID_SUBMIT_MULTI, "Submit_multi" },
+ { SMPP_COMMAND_ID_ALERT_NOTIFICATION, "Alert_notification" },
+ { SMPP_COMMAND_ID_DATA_SM, "Data_sm" },
+ { SMPP_COMMAND_ID_BROADCAST_SM, "Broadcast_sm" },
+ { SMPP_COMMAND_ID_QUERY_BROADCAST_SM, "Query_broadcast_sm" },
+ { SMPP_COMMAND_ID_CANCEL_BROADCAST_SM, "Cancel_broadcast_sm" },
+ { SMPP_COMMAND_ID_HUAWEI_AUTH_ACC, "Auth_acc" },
+ { SMPP_COMMAND_ID_HUAWEI_SM_RESULT_NOTIFY, "Sm_result_notify" },
+
+ { SMPP_COMMAND_ID_RESPONSE_MASK|SMPP_COMMAND_ID_GENERIC_NACK, "Generic_nack" },
+ { SMPP_COMMAND_ID_RESPONSE_MASK|SMPP_COMMAND_ID_BIND_RECEIVER, "Bind_receiver - resp" },
+ { SMPP_COMMAND_ID_RESPONSE_MASK|SMPP_COMMAND_ID_BIND_TRANSMITTER, "Bind_transmitter - resp" },
+ { SMPP_COMMAND_ID_RESPONSE_MASK|SMPP_COMMAND_ID_QUERY_SM, "Query_sm - resp" },
+ { SMPP_COMMAND_ID_RESPONSE_MASK|SMPP_COMMAND_ID_SUBMIT_SM, "Submit_sm - resp" },
+ { SMPP_COMMAND_ID_RESPONSE_MASK|SMPP_COMMAND_ID_DELIVER_SM, "Deliver_sm - resp" },
+ { SMPP_COMMAND_ID_RESPONSE_MASK|SMPP_COMMAND_ID_UNBIND, "Unbind - resp" },
+ { SMPP_COMMAND_ID_RESPONSE_MASK|SMPP_COMMAND_ID_REPLACE_SM, "Replace_sm - resp" },
+ { SMPP_COMMAND_ID_RESPONSE_MASK|SMPP_COMMAND_ID_CANCEL_SM, "Cancel_sm - resp" },
+ { SMPP_COMMAND_ID_RESPONSE_MASK|SMPP_COMMAND_ID_BIND_TRANSCEIVER, "Bind_transceiver - resp" },
+ { SMPP_COMMAND_ID_RESPONSE_MASK|SMPP_COMMAND_ID_ENQUIRE_LINK, "Enquire_link - resp" },
+ { SMPP_COMMAND_ID_RESPONSE_MASK|SMPP_COMMAND_ID_SUBMIT_MULTI, "Submit_multi - resp" },
+ { SMPP_COMMAND_ID_RESPONSE_MASK|SMPP_COMMAND_ID_DATA_SM, "Data_sm - resp" },
+ { SMPP_COMMAND_ID_RESPONSE_MASK|SMPP_COMMAND_ID_BROADCAST_SM, "Broadcast_sm - resp" },
+ { SMPP_COMMAND_ID_RESPONSE_MASK|SMPP_COMMAND_ID_QUERY_BROADCAST_SM, "Query_broadcast_sm - resp" },
+ { SMPP_COMMAND_ID_RESPONSE_MASK|SMPP_COMMAND_ID_CANCEL_BROADCAST_SM, "Cancel_broadcast_sm - resp" },
+ { SMPP_COMMAND_ID_RESPONSE_MASK|SMPP_COMMAND_ID_HUAWEI_AUTH_ACC, "Auth_acc - resp" },
+ { SMPP_COMMAND_ID_RESPONSE_MASK|SMPP_COMMAND_ID_HUAWEI_SM_RESULT_NOTIFY, "Sm_result_notify - resp" },
{ 0, NULL }
};
-static const range_string reserved_command_status[] = { /* Reserved ranges */
+static const range_string rvals_command_status[] = { /* Status */
+ { 0x00000000, 0x00000000, "Ok" },
+ { 0x00000001, 0x00000001, "Message length is invalid" },
+ { 0x00000002, 0x00000002, "Command length is invalid" },
+ { 0x00000003, 0x00000003, "Invalid command ID" },
+ { 0x00000004, 0x00000004, "Incorrect BIND status for given command" },
+ { 0x00000005, 0x00000005, "ESME already in bound state" },
+ { 0x00000006, 0x00000006, "Invalid priority flag" },
+ { 0x00000007, 0x00000007, "Invalid registered delivery flag" },
+ { 0x00000008, 0x00000008, "System error" },
+ { 0x00000009, 0x00000009, "[Reserved]" },
+ { 0x0000000A, 0x0000000A, "Invalid source address" },
+ { 0x0000000B, 0x0000000B, "Invalid destination address" },
+ { 0x0000000C, 0x0000000C, "Message ID is invalid" },
+ { 0x0000000D, 0x0000000D, "Bind failed" },
+ { 0x0000000E, 0x0000000E, "Invalid password" },
+ { 0x0000000F, 0x0000000F, "Invalid system ID" },
+ { 0x00000010, 0x00000010, "[Reserved]" },
+ { 0x00000011, 0x00000011, "Cancel SM failed" },
+ { 0x00000012, 0x00000012, "[Reserved]" },
+ { 0x00000013, 0x00000013, "Replace SM failed" },
+ { 0x00000014, 0x00000014, "Message queue full" },
+ { 0x00000015, 0x00000015, "Invalid service type" },
{ 0x00000016, 0x00000032, "[Reserved]" },
+ { 0x00000033, 0x00000033, "Invalid number of destinations" },
+ { 0x00000034, 0x00000034, "Invalid distribution list name" },
{ 0x00000035, 0x0000003F, "[Reserved]" },
+ { 0x00000040, 0x00000040, "Destination flag is invalid (submit_multi)" },
+ { 0x00000041, 0x00000041, "[Reserved]" },
+ { 0x00000042, 0x00000042, "Invalid 'submit with replace' request" },
+ { 0x00000043, 0x00000043, "Invalid esm_class field data" },
+ { 0x00000044, 0x00000044, "Cannot submit to distribution list" },
+ { 0x00000045, 0x00000045, "submit_sm or submit_multi failed" },
+ { 0x00000046, 0x00000047, "[Reserved]" },
+ { 0x00000048, 0x00000048, "Invalid source address TON" },
+ { 0x00000049, 0x00000049, "Invalid source address NPI" },
+ { 0x00000050, 0x00000050, "Invalid destination address TON" },
+ { 0x00000051, 0x00000051, "Invalid destination address NPI" },
+ { 0x00000052, 0x00000052, "[Reserved]" },
+ { 0x00000053, 0x00000053, "Invalid system_type field" },
+ { 0x00000054, 0x00000054, "Invalid replace_if_present flag" },
+ { 0x00000055, 0x00000055, "Invalid number of messages" },
+ { 0x00000056, 0x00000057, "[Reserved]" },
+ { 0x00000058, 0x00000058, "Throttling error (ESME exceeded allowed message limits)" },
+ { 0x00000059, 0x00000060, "[Reserved]" },
+ { 0x00000061, 0x00000061, "Invalid scheduled delivery time" },
+ { 0x00000062, 0x00000062, "Invalid message validity period (expiry time)" },
+ { 0x00000063, 0x00000063, "Predefined message invalid or not found" },
+ { 0x00000064, 0x00000064, "ESME receiver temporary app error code" },
+ { 0x00000065, 0x00000065, "ESME receiver permanent app error code" },
+ { 0x00000066, 0x00000066, "ESME receiver reject message error code" },
+ { 0x00000067, 0x00000067, "query_sm request failed" },
{ 0x00000068, 0x000000BF, "[Reserved]" },
+ { 0x000000C0, 0x000000C0, "Error in the optional part of the PDU body" },
+ { 0x000000C1, 0x000000C1, "Optional parameter not allowed" },
+ { 0x000000C2, 0x000000C2, "Invalid parameter length" },
+ { 0x000000C3, 0x000000C3, "Expected optional parameter missing" },
+ { 0x000000C4, 0x000000C4, "Invalid optional parameter value" },
{ 0x000000C5, 0x000000FD, "[Reserved]" },
- { 0x00000400, 0x000004FF, "[Message center vendor-specific error code]" },
+ { 0x000000FE, 0x000000FE, "(Transaction) Delivery failure (used for data_sm_resp)" },
+ { 0x000000FF, 0x000000FF, "Unknown error" },
+ /* Introduced in SMPP 5.0 */
+ { 0x00000100, 0x00000100, "ESME Not authorised to use specified service_type." },
+ { 0x00000101, 0x00000101, "ESME Prohibited from using specified operation."},
+ { 0x00000102, 0x00000102, "Specified service_type is unavailable." },
+ { 0x00000103, 0x00000103, "Specified service_type is denied." },
+ { 0x00000104, 0x00000104, "Invalid Data Coding Scheme." },
+ { 0x00000105, 0x00000105, "Source Address Sub unit is Invalid." },
+ { 0x00000106, 0x00000106, "Destination Address Sub unit is Invalid." },
+ { 0x00000107, 0x00000107, "Broadcast Frequency Interval is invalid." },
+ { 0x00000108, 0x00000108, "Broadcast Alias Name is invalid." },
+ { 0x00000109, 0x00000109, "Broadcast Area Format is invalid." },
+ { 0x0000010A, 0x0000010A, "Number of Broadcast Areas is invalid." },
+ { 0x0000010B, 0x0000010B, "Broadcast Content Type is invalid." },
+ { 0x0000010C, 0x0000010C, "Broadcast Message Class is invalid." },
+ { 0x0000010D, 0x0000010D, "broadcast_sm operation failed." },
+ { 0x0000010E, 0x0000010E, "query_broadcast_sm operation failed." },
+ { 0x0000010F, 0x0000010F, "cancel_broadcast_sm operation failed." },
+ { 0x00000110, 0x00000110, "Number of Repeated Broadcasts is invalid." },
+ { 0x00000111, 0x00000111, "Broadcast Service Group is invalid." },
+ { 0x00000112, 0x00000112, "Broadcast Channel Indicator is invalid." },
+ { 0x00000400, 0x000004FF, "[Vendor-specific Error]" },
{ 0x00000500, 0xFFFFFFFF, "[Reserved]" },
{ 0, 0, NULL }
};
@@ -582,7 +586,8 @@ static const value_string vals_data_coding[] = {
{ 12, "reserved" },
{ 13, "Extended Kanji JIS(X 0212-1990)" },
{ 14, "KS C 5601" },
- /*! \TODO Rest to be defined (bitmask?) according GSM 03.38 */
+ { 15, "reserved" },
+/*! \TODO Rest to be defined (bitmask?) according GSM 03.38 */
{ 0, NULL }
};
@@ -1086,6 +1091,20 @@ static const value_string vals_msc_addr_npi [] = {
{ 0x00, NULL }
};
+static const gint *regdel_fields[] = {
+ &hf_smpp_regdel_receipt,
+ &hf_smpp_regdel_acks,
+ &hf_smpp_regdel_notif,
+ NULL
+};
+
+static const gint *submit_msg_fields[] = {
+ &hf_smpp_esm_submit_msg_mode,
+ &hf_smpp_esm_submit_msg_type,
+ &hf_smpp_esm_submit_features,
+ NULL
+};
+
static dissector_handle_t gsm_sms_handle;
/*
@@ -1111,13 +1130,13 @@ smpp_stats_tree_per_packet(stats_tree *st, /* st as it was passed to us */
tick_stat_node(st, "SMPP Operations", 0, TRUE);
- if ((tap_rec->command_id & 0x80000000) == 0x80000000) /* Response */
+ if ((tap_rec->command_id & SMPP_COMMAND_ID_RESPONSE_MASK) == SMPP_COMMAND_ID_RESPONSE_MASK) /* Response */
{
tick_stat_node(st, "SMPP Responses", st_smpp_ops, TRUE);
tick_stat_node(st, val_to_str(tap_rec->command_id, vals_command_id, "Unknown 0x%08x"), st_smpp_res, FALSE);
tick_stat_node(st, "SMPP Response Status", 0, TRUE);
- tick_stat_node(st, val_to_str(tap_rec->command_status, vals_command_status, "Unknown 0x%08x"), st_smpp_res_status, FALSE);
+ tick_stat_node(st, rval_to_str(tap_rec->command_status, rvals_command_status, "Unknown 0x%08x"), st_smpp_res_status, FALSE);
}
else /* Request */
@@ -1215,15 +1234,11 @@ static const char *
smpp_handle_string_return(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int field, int *offset)
{
gint len;
- const char *str;
+ const char* str = (const char *)tvb_get_stringz_enc(pinfo->pool, tvb, *offset, &len, ENC_ASCII);
- len = tvb_strsize(tvb, *offset);
- if (len > 1) {
- str = (char *)tvb_get_stringz_enc(pinfo->pool, tvb, *offset, &len, ENC_ASCII);
+ if (len > 0)
proto_tree_add_string(tree, field, tvb, *offset, len, str);
- } else {
- str = "";
- }
+
(*offset) += len;
return str;
}
@@ -1244,36 +1259,6 @@ smpp_handle_string_z(proto_tree *tree, tvbuff_t *tvb, int field, int *offset,
}
static void
-smpp_handle_int1(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
-{
- guint8 val;
-
- val = tvb_get_guint8(tvb, *offset);
- proto_tree_add_uint(tree, field, tvb, *offset, 1, val);
- (*offset)++;
-}
-
-static void
-smpp_handle_int2(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
-{
- guint val;
-
- val = tvb_get_ntohs(tvb, *offset);
- proto_tree_add_uint(tree, field, tvb, *offset, 2, val);
- (*offset) += 2;
-}
-
-static void
-smpp_handle_int4(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
-{
- guint val;
-
- val = tvb_get_ntohl(tvb, *offset);
- proto_tree_add_uint(tree, field, tvb, *offset, 4, val);
- (*offset) += 4;
-}
-
-static void
smpp_handle_time(proto_tree *tree, tvbuff_t *tvb,
int field, int field_R, int *offset)
{
@@ -1327,8 +1312,10 @@ smpp_handle_dlist(proto_tree *tree, tvbuff_t *tvb, int *offset)
dest_flag = tvb_get_guint8(tvb, tmpoff++);
if (dest_flag == 1) /* SME address */
{
- smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_ton, &tmpoff);
- smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_npi, &tmpoff);
+ proto_tree_add_item(sub_tree, hf_smpp_dest_addr_ton, tvb, tmpoff, 1, ENC_NA);
+ tmpoff += 1;
+ proto_tree_add_item(sub_tree, hf_smpp_dest_addr_npi, tvb, tmpoff, 1, ENC_NA);
+ tmpoff += 1;
smpp_handle_string(sub_tree,tvb,hf_smpp_destination_addr,&tmpoff);
}
else /* Distribution list */
@@ -1363,10 +1350,13 @@ smpp_handle_dlist_resp(proto_tree *tree, tvbuff_t *tvb, int *offset)
}
while (entries--)
{
- smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_ton, &tmpoff);
- smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_npi, &tmpoff);
+ proto_tree_add_item(sub_tree, hf_smpp_dest_addr_ton, tvb, tmpoff, 1, ENC_NA);
+ tmpoff += 1;
+ proto_tree_add_item(sub_tree, hf_smpp_dest_addr_npi, tvb, tmpoff, 1, ENC_NA);
+ tmpoff += 1;
smpp_handle_string(sub_tree,tvb,hf_smpp_destination_addr,&tmpoff);
- smpp_handle_int4(sub_tree, tvb, hf_smpp_error_status_code, &tmpoff);
+ proto_tree_add_item(sub_tree, hf_smpp_error_status_code, tvb, tmpoff, 4, ENC_BIG_ENDIAN);
+ tmpoff += 4;
}
*offset = tmpoff;
}
@@ -1399,11 +1389,6 @@ smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
guint16 tag;
guint16 length;
- guint8 field;
- guint16 field16;
- guint8 major, minor;
- char *strval=NULL;
-
tag = tvb_get_ntohs(tvb, *offset);
length = tvb_get_ntohs(tvb, (*offset+2));
@@ -1419,64 +1404,72 @@ smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
switch (tag) {
case 0x0005: /* dest_addr_subunit */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_dest_addr_subunit, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_dest_addr_subunit, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0006: /* dest_network_type */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_dest_network_type, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_dest_network_type, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0007: /* dest_bearer_type */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_dest_bearer_type, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_dest_bearer_type, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0008: /* dest_telematics_id */
- smpp_handle_int2(sub_tree, tvb,
- hf_smpp_dest_telematics_id, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_dest_telematics_id, tvb, *offset, 2, ENC_BIG_ENDIAN);
+ (*offset) += 2;
break;
case 0x000D: /* source_addr_subunit */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_source_addr_subunit, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_source_addr_subunit, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x000E: /* source_network_type */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_source_network_type, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_source_network_type, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x000F: /* source_bearer_type */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_source_bearer_type, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_source_bearer_type, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0010: /* source_telematics_id */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_source_telematics_id, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_source_telematics_id, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0017: /* qos_time_to_live */
- smpp_handle_int4(sub_tree, tvb,
- hf_smpp_qos_time_to_live, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_qos_time_to_live, tvb, *offset, 4, ENC_BIG_ENDIAN);
+ (*offset) += 4;
break;
case 0x0019: /* payload_type */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_payload_type, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_payload_type, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x001D: /* additional_status_info_text */
- smpp_handle_string(sub_tree, tvb,
- hf_smpp_additional_status_info_text, offset);
+ if (length)
+ proto_tree_add_item(sub_tree, hf_smpp_additional_status_info_text,
+ tvb, *offset, length, ENC_NA | ENC_ASCII);
+ (*offset) += length;
break;
case 0x001E: /* receipted_message_id */
- smpp_handle_string(sub_tree, tvb,
- hf_smpp_receipted_message_id, offset);
- break;
- case 0x0030: /* ms_msg_wait_facilities */
- field = tvb_get_guint8(tvb, *offset);
- proto_tree_add_uint(sub_tree, hf_smpp_msg_wait_ind,
- tvb, *offset, 1, field);
- proto_tree_add_uint(sub_tree, hf_smpp_msg_wait_type,
- tvb, *offset, 1, field);
+ if (length)
+ proto_tree_add_item(sub_tree, hf_smpp_receipted_message_id,
+ tvb, *offset, length, ENC_NA | ENC_ASCII);
+ (*offset) += length;
+ break;
+ case 0x0030: { /* ms_msg_wait_facilities */
+ const gint *fields[] = {
+ &hf_smpp_msg_wait_ind,
+ &hf_smpp_msg_wait_type,
+ NULL
+ };
+
+
+ proto_tree_add_bitmask_list(sub_tree, tvb, *offset, 1, fields, ENC_NA);
(*offset)++;
+ }
break;
case 0x0201: /* privacy_indicator */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_privacy_indicator, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_privacy_indicator, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0202: /* source_subaddress */
if (length) {
@@ -1493,53 +1486,52 @@ smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
}
break;
case 0x0204: /* user_message_reference */
- smpp_handle_int2(sub_tree, tvb,
- hf_smpp_user_message_reference, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_user_message_reference, tvb, *offset, 2, ENC_BIG_ENDIAN);
+ (*offset) += 2;
break;
case 0x0205: /* user_response_code */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_user_response_code, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_user_response_code, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x020A: /* source_port */
- smpp_handle_int2(sub_tree, tvb,
- hf_smpp_source_port, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_source_port, tvb, *offset, 2, ENC_BIG_ENDIAN);
+ (*offset) += 2;
break;
case 0x020B: /* destination_port */
- smpp_handle_int2(sub_tree, tvb,
- hf_smpp_destination_port, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_destination_port, tvb, *offset, 2, ENC_BIG_ENDIAN);
+ (*offset) += 2;
break;
case 0x020C: /* sar_msg_ref_num */
- smpp_handle_int2(sub_tree, tvb,
- hf_smpp_sar_msg_ref_num, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_sar_msg_ref_num, tvb, *offset, 2, ENC_BIG_ENDIAN);
+ (*offset) += 2;
break;
case 0x020D: /* language_indicator */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_language_indicator, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_language_indicator, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x020E: /* sar_total_segments */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_sar_total_segments, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_sar_total_segments, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x020F: /* sar_segment_seqnum */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_sar_segment_seqnum, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_sar_segment_seqnum, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0210: /* SC_interface_version */
- field = tvb_get_guint8(tvb, *offset);
- minor = field & 0x0F;
- major = (field & 0xF0) >> 4;
- strval=wmem_strdup_printf(wmem_packet_scope(), "%u.%u", major, minor);
- proto_tree_add_string(sub_tree, hf_smpp_SC_interface_version,
- tvb, *offset, 1, strval);
- (*offset)++;
+ proto_tree_add_item(sub_tree, hf_smpp_SC_interface_version, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
- case 0x0302: /* callback_num_pres_ind */
- field = tvb_get_guint8(tvb, *offset);
- proto_tree_add_uint(sub_tree, hf_smpp_callback_num_pres,
- tvb, *offset, 1, field);
- proto_tree_add_uint(sub_tree, hf_smpp_callback_num_scrn,
- tvb, *offset, 1, field);
+ case 0x0302: { /* callback_num_pres_ind */
+
+ const gint *fields[] = {
+ &hf_smpp_callback_num_pres,
+ &hf_smpp_callback_num_scrn,
+ NULL
+ };
+
+ proto_tree_add_bitmask_list(sub_tree, tvb, *offset, 1, fields, ENC_NA);
(*offset)++;
+ }
break;
case 0x0303: /* callback_num_atag */
if (length)
@@ -1548,8 +1540,8 @@ smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
(*offset) += length;
break;
case 0x0304: /* number_of_messages */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_number_of_messages, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_number_of_messages, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0381: /* callback_num */
if (length)
@@ -1558,22 +1550,22 @@ smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
(*offset) += length;
break;
case 0x0420: /* dpf_result */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_dpf_result, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_dpf_result, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0421: /* set_dpf */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_set_dpf, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_set_dpf, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0422: /* ms_availability_status */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_ms_availability_status, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_ms_availability_status, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0423: /* network_error_code */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_network_error_type, offset);
- smpp_handle_int2(sub_tree, tvb,
- hf_smpp_network_error_code, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_network_error_type, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
+ proto_tree_add_item(sub_tree, hf_smpp_network_error_code, tvb, *offset, 2, ENC_BIG_ENDIAN);
+ (*offset) += 2;
break;
case 0x0424: /* message_payload */
if (length)
@@ -1582,36 +1574,33 @@ smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
(*offset) += length;
break;
case 0x0425: /* delivery_failure_reason */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_delivery_failure_reason, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_delivery_failure_reason, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0426: /* more_messages_to_send */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_more_messages_to_send, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_more_messages_to_send, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0427: /* message_state */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_message_state, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_message_state, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0428: /* congestion_state */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_congestion_state, offset);
-
+ proto_tree_add_item(sub_tree, hf_smpp_congestion_state, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0501: /* ussd_service_op */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_ussd_service_op, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_ussd_service_op, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0600: /* broadcast_channel_indicator */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_broadcast_channel_indicator, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_broadcast_channel_indicator, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0601: /* broadcast_content_type */
- field = tvb_get_guint8(tvb, *offset);
- proto_tree_add_uint(sub_tree, hf_smpp_broadcast_content_type_nw, tvb, *offset, 1, field);
- (*offset)++;
- field16 = tvb_get_ntohs(tvb, *offset);
- proto_tree_add_uint(sub_tree, hf_smpp_broadcast_content_type_type, tvb, *offset, 2, field16);
+ proto_tree_add_item(sub_tree, hf_smpp_broadcast_content_type_nw, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
+ proto_tree_add_item(sub_tree, hf_smpp_broadcast_content_type_type, tvb, *offset, 2, ENC_BIG_ENDIAN);
(*offset) += 2;
break;
case 0x0602: /* broadcast_content_type_info */
@@ -1621,35 +1610,32 @@ smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
(*offset) += length;
break;
case 0x0603: /* broadcast_message_class */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_broadcast_message_class, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_broadcast_message_class, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0604: /* broadcast_rep_num */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_broadcast_rep_num, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_broadcast_rep_num, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0605: /* broadcast_frequency_interval */
- field = tvb_get_guint8(tvb, *offset);
- proto_tree_add_uint(sub_tree, hf_smpp_broadcast_frequency_interval_unit, tvb, *offset, 1, field);
- (*offset)++;
- field16 = tvb_get_ntohs(tvb, *offset);
- proto_tree_add_uint(sub_tree, hf_smpp_broadcast_frequency_interval_value, tvb, *offset, 2, field16);
+ proto_tree_add_item(sub_tree, hf_smpp_broadcast_frequency_interval_unit, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
+ proto_tree_add_item(sub_tree, hf_smpp_broadcast_frequency_interval_value, tvb, *offset, 2, ENC_BIG_ENDIAN);
(*offset) += 2;
break;
case 0x0606: /* broadcast_area_identifier */
- field = tvb_get_guint8(tvb, *offset);
- proto_tree_add_uint(sub_tree, hf_smpp_broadcast_area_identifier_format, tvb, *offset, 1, field);
+ proto_tree_add_item(sub_tree, hf_smpp_broadcast_area_identifier_format, tvb, *offset, 1, ENC_NA);
proto_tree_add_item(sub_tree, hf_smpp_broadcast_area_identifier,
tvb, *offset, length, ENC_NA);
(*offset) += length;
break;
case 0x0607: /* broadcast_error_status */
- smpp_handle_int4(sub_tree, tvb,
- hf_smpp_broadcast_error_status, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_broadcast_error_status, tvb, *offset, 4, ENC_BIG_ENDIAN);
+ (*offset) += 4;
break;
case 0x0608: /* broadcast_area_success */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_broadcast_area_success, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_broadcast_area_success, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0609: /* broadcast_end_time */
smpp_handle_time(sub_tree, tvb, hf_smpp_broadcast_end_time,
@@ -1669,12 +1655,16 @@ smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
break;
/* 0x060C is skipped in the specs for some reason :-? */
case 0x060D: /* source_network_id */
- smpp_handle_string_z(sub_tree, tvb, hf_smpp_source_network_id,
- offset, "Empty!");
+ if (length)
+ proto_tree_add_item(sub_tree, hf_smpp_source_network_id,
+ tvb, *offset, length, ENC_NA|ENC_ASCII);
+ (*offset) += length;
break;
case 0x060E: /* dest_network_id */
- smpp_handle_string_z(sub_tree, tvb, hf_smpp_dest_network_id,
- offset, "Empty!");
+ if (length)
+ proto_tree_add_item(sub_tree, hf_smpp_dest_network_id,
+ tvb, *offset, length, ENC_NA | ENC_ASCII);
+ (*offset) += length;
break;
case 0x060F: /* source_node_id */
if (length)
@@ -1689,8 +1679,8 @@ smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
(*offset) += length;
break;
case 0x0611: /* dest_addr_np_resolution */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_dest_addr_np_resolution, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_dest_addr_np_resolution, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x0612: /* dest_addr_np_information */
if (length)
@@ -1706,17 +1696,17 @@ smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
(*offset) += length;
break;
case 0x1201: /* display_time */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_display_time, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_display_time, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x1203: /* sms_signal */
- smpp_handle_int2(sub_tree, tvb,
- hf_smpp_sms_signal, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_sms_signal, tvb, *offset, 2, ENC_BIG_ENDIAN);
+ (*offset) += 2;
/*! \todo Fill as per TIA/EIA-136-710-A */
break;
case 0x1204: /* ms_validity */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_ms_validity, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_ms_validity, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
break;
case 0x130C: /* alert_on_message_delivery */
if (length == 0) {
@@ -1724,23 +1714,27 @@ smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
hf_smpp_alert_on_message_delivery_null,
tvb, *offset, length, ENC_NA);
} else {
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_alert_on_message_delivery_type, offset);
+ proto_tree_add_item(sub_tree, hf_smpp_alert_on_message_delivery_type, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
}
break;
case 0x1380: /* its_reply_type */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_its_reply_type, offset);
- break;
- case 0x1383: /* its_session_info */
- smpp_handle_int1(sub_tree, tvb,
- hf_smpp_its_session_number, offset);
- field = tvb_get_guint8(tvb, *offset);
- proto_tree_add_uint(sub_tree, hf_smpp_its_session_sequence,
- tvb, *offset, 1, field);
- proto_tree_add_uint(sub_tree, hf_smpp_its_session_ind,
- tvb, *offset, 1, field);
- (*offset)++;
+ proto_tree_add_item(sub_tree, hf_smpp_its_reply_type, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
+ break;
+ case 0x1383: { /* its_session_info */
+
+ const gint *fields[] = {
+ &hf_smpp_its_session_sequence,
+ &hf_smpp_its_session_ind,
+ NULL
+ };
+
+ proto_tree_add_item(sub_tree, hf_smpp_its_session_number, tvb, *offset, 1, ENC_NA);
+ (*offset) += 1;
+ proto_tree_add_bitmask_list(sub_tree, tvb, *offset, 1, fields, ENC_NA);
+ (*offset) += 1;
+ }
break;
default:
@@ -1754,7 +1748,9 @@ smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
*offset, length, ENC_NA);
}
- proto_item_append_text(sub_tree,": %s", tvb_bytes_to_str(wmem_packet_scope(), tvb,*offset,length));
+ if (length > 0)
+ proto_item_append_text(sub_tree,": %s", tvb_bytes_to_str(wmem_packet_scope(), tvb,*offset,length));
+
(*offset) += length;
break;
}
@@ -1764,72 +1760,107 @@ smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
void
smpp_handle_dcs(proto_tree *tree, tvbuff_t *tvb, int *offset)
{
- guint8 val;
+ guint32 val;
int off = *offset;
proto_tree *subtree, *code_tree;
proto_item *pi;
- val = tvb_get_guint8(tvb, off);
- pi = proto_tree_add_uint(tree, hf_smpp_data_coding, tvb, off, 1, val);
+ pi = proto_tree_add_item_ret_uint(tree, hf_smpp_data_coding, tvb, off, 1, ENC_NA, &val);
subtree = proto_item_add_subtree(pi, ett_dcs);
/* SMPP Data Coding Scheme */
proto_tree_add_uint(subtree, hf_smpp_dcs, tvb, off, 1, val);
- /* GSM SMS Data Coding Scheme */
- code_tree = proto_tree_add_subtree(subtree, tvb, off, 1, ett_dcs, NULL, "GSM SMS Data Coding");
-
- proto_tree_add_uint(code_tree,
- hf_smpp_dcs_sms_coding_group, tvb, off, 1, val);
- if (val>>6 == 2) { /* Reserved */
- ;
- } else if (val < 0xF0) {
- proto_tree_add_boolean(code_tree,
- hf_smpp_dcs_text_compression, tvb, off, 1, val);
- proto_tree_add_boolean(code_tree,
- hf_smpp_dcs_class_present, tvb, off, 1, val);
- proto_tree_add_uint(code_tree,
- hf_smpp_dcs_charset, tvb, off, 1, val);
- if (val & 0x10)
- proto_tree_add_uint(code_tree,
- hf_smpp_dcs_class, tvb, off, 1, val);
- } else {
- proto_tree_add_uint(code_tree, hf_smpp_dcs_reserved, tvb, off, 1, val);
- proto_tree_add_uint(code_tree, hf_smpp_dcs_charset, tvb, off, 1, val);
- proto_tree_add_uint(code_tree, hf_smpp_dcs_class, tvb, off, 1, val);
- }
- /* Cell Broadcast Service (CBS) Data Coding Scheme */
- code_tree = proto_tree_add_subtree(subtree, tvb, off, 1, ett_dcs, NULL,
- "GSM CBS Data Coding");
- proto_tree_add_uint(code_tree,
- hf_smpp_dcs_cbs_coding_group, tvb, off, 1, val);
- if (val < 0x40) { /* Language specified */
- proto_tree_add_uint(code_tree,
- hf_smpp_dcs_cbs_language, tvb, off, 1, val);
- } else if (val>>6 == 1) { /* General Data Coding indication */
- proto_tree_add_boolean(code_tree,
- hf_smpp_dcs_text_compression, tvb, off, 1, val);
- proto_tree_add_boolean(code_tree,
- hf_smpp_dcs_class_present, tvb, off, 1, val);
- proto_tree_add_uint(code_tree,
- hf_smpp_dcs_charset, tvb, off, 1, val);
- if (val & 0x10)
- proto_tree_add_uint(code_tree,
- hf_smpp_dcs_class, tvb, off, 1, val);
- } else if (val>>6 == 2) { /* Message with UDH structure */
- proto_tree_add_uint(code_tree,
- hf_smpp_dcs_charset, tvb, off, 1, val);
- proto_tree_add_uint(code_tree,
- hf_smpp_dcs_class, tvb, off, 1, val);
- } else if (val>>4 == 14) { /* WAP Forum */
- proto_tree_add_uint(code_tree,
- hf_smpp_dcs_wap_charset, tvb, off, 1, val);
- proto_tree_add_uint(code_tree,
- hf_smpp_dcs_wap_class, tvb, off, 1, val);
- } else if (val>>4 == 15) { /* Data coding / message handling */
- proto_tree_add_uint(code_tree, hf_smpp_dcs_reserved, tvb, off, 1, val);
- proto_tree_add_uint(code_tree, hf_smpp_dcs_charset, tvb, off, 1, val);
- proto_tree_add_uint(code_tree, hf_smpp_dcs_cbs_class, tvb, off, 1, val);
- }
+ if (val & 0xC0) {
+
+ /* GSM SMS Data Coding Scheme */
+ code_tree = proto_tree_add_subtree(subtree, tvb, off, 1, ett_dcs_gsm_sms, NULL, "GSM SMS Data Coding");
+ proto_tree_add_uint(code_tree, hf_smpp_dcs_sms_coding_group, tvb, off, 1, val);
+
+ if ((val & 0x80) == 0x80) {
+ /* Reserved */
+ } else if ((val & 0xF0) == 0xF0) {
+ const gint *gsm_msg_control_fields[] = {
+ &hf_smpp_dcs_reserved,
+ &hf_smpp_dcs_charset,
+ &hf_smpp_dcs_class,
+ NULL
+ };
+
+ proto_tree_add_bitmask_list_value(code_tree, tvb, off, 1, gsm_msg_control_fields, val);
+ } else if (val & 0x10) {
+ const gint *gsm_mwi_control_class_fields[] = {
+ &hf_smpp_dcs_text_compression,
+ &hf_smpp_dcs_class_present,
+ &hf_smpp_dcs_charset,
+ &hf_smpp_dcs_class,
+ NULL
+ };
+
+ proto_tree_add_bitmask_list_value(code_tree, tvb, off, 1, gsm_mwi_control_class_fields, val);
+ } else {
+ const gint *gsm_mwi_control_fields[] = {
+ &hf_smpp_dcs_text_compression,
+ &hf_smpp_dcs_class_present,
+ &hf_smpp_dcs_charset,
+ NULL
+ };
+
+ proto_tree_add_bitmask_list_value(code_tree, tvb, off, 1, gsm_mwi_control_fields, val);
+ }
+ /* Cell Broadcast Service (CBS) Data Coding Scheme */
+ code_tree = proto_tree_add_subtree(subtree, tvb, off, 1, ett_dcs_gsm_cbs, NULL, "GSM CBS Data Coding");
+ proto_tree_add_uint(code_tree, hf_smpp_dcs_cbs_coding_group, tvb, off, 1, val);
+
+ if (val < 0x40) { /* Language specified */
+ proto_tree_add_uint(code_tree, hf_smpp_dcs_cbs_language, tvb, off, 1, val);
+ } else if ((val & 0x40) == 0x40) { /* General Data Coding indication */
+ if (val & 0x10) {
+ const gint *gsm_cbs_gen_class_fields[] = {
+ &hf_smpp_dcs_text_compression,
+ &hf_smpp_dcs_class_present,
+ &hf_smpp_dcs_charset,
+ &hf_smpp_dcs_class,
+ NULL
+ };
+ proto_tree_add_bitmask_list_value(code_tree, tvb, off, 1, gsm_cbs_gen_class_fields, val);
+
+ } else {
+ const gint *gsm_cbs_gen_fields[] = {
+ &hf_smpp_dcs_text_compression,
+ &hf_smpp_dcs_class_present,
+ &hf_smpp_dcs_charset,
+ NULL
+ };
+
+ proto_tree_add_bitmask_list_value(code_tree, tvb, off, 1, gsm_cbs_gen_fields, val);
+ }
+ } else if ((val & 0x20) == 0x20) { /* Message with UDH structure */
+ const gint *gsm_cbs_udh_fields[] = {
+ &hf_smpp_dcs_charset,
+ &hf_smpp_dcs_class,
+ NULL
+ };
+
+ proto_tree_add_bitmask_list_value(code_tree, tvb, off, 1, gsm_cbs_udh_fields, val);
+ } else if ((val & 0xF0) == 0xE0) { /* WAP Forum */
+ const gint *gsm_cbs_wap_fields[] = {
+ &hf_smpp_dcs_wap_charset,
+ &hf_smpp_dcs_wap_class,
+ NULL
+ };
+
+ proto_tree_add_bitmask_list_value(code_tree, tvb, off, 1, gsm_cbs_wap_fields, val);
+ } else if ((val & 0xF0) == 0xF0) { /* Data coding / message handling */
+ const gint *gsm_cbs_dcs_fields[] = {
+ &hf_smpp_dcs_reserved,
+ &hf_smpp_dcs_charset,
+ &hf_smpp_dcs_cbs_class,
+ NULL
+ };
+
+ proto_tree_add_bitmask_list_value(code_tree, tvb, off, 1, gsm_cbs_dcs_fields, val);
+ }
+ }
(*offset)++;
}
@@ -1838,82 +1869,70 @@ smpp_handle_dcs(proto_tree *tree, tvbuff_t *tvb, int *offset)
* with SMPP.
*/
static void
-bind_receiver(proto_tree *tree, tvbuff_t *tvb)
+bind_receiver(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
- guint8 field;
- guint8 major, minor;
- char *strval;
-
smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
smpp_handle_string(tree, tvb, hf_smpp_password, &offset);
smpp_handle_string(tree, tvb, hf_smpp_system_type, &offset);
- field = tvb_get_guint8(tvb, offset++);
- minor = field & 0x0F;
- major = (field & 0xF0) >> 4;
- strval=wmem_strdup_printf(wmem_packet_scope(), "%u.%u", major, minor);
- proto_tree_add_string(tree, hf_smpp_interface_version, tvb,
- offset - 1, 1, strval);
- smpp_handle_int1(tree, tvb, hf_smpp_addr_ton, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_addr_npi, &offset);
+ proto_tree_add_item(tree, hf_smpp_interface_version, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_addr_ton, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_addr_npi, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_smpp_address_range, &offset);
}
-#define bind_transmitter(a, b) bind_receiver(a, b)
-
static void
-query_sm(proto_tree *tree, tvbuff_t *tvb)
+query_sm(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
-
smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
+ proto_tree_add_item(tree, hf_smpp_source_addr_ton, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_source_addr_npi, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
}
-#define bind_transceiver(a, b) bind_receiver(a, b)
-
static void
-outbind(proto_tree *tree, tvbuff_t *tvb)
+outbind(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
-
smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
smpp_handle_string(tree, tvb, hf_smpp_password, &offset);
}
static void
submit_sm(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
- proto_tree *top_tree)
+ proto_tree *top_tree, int offset)
{
tvbuff_t *tvb_msg;
- int offset = 0;
- guint8 flag, udhi;
- guint8 length;
+ guint8 udhi;
+ guint32 length;
const char *src_str = NULL;
const char *dst_str = NULL;
address save_src, save_dst;
nstime_t zero_time = NSTIME_INIT_ZERO;
smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
+ proto_tree_add_item(tree, hf_smpp_source_addr_ton, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_source_addr_npi, tvb, offset, 1, ENC_NA);
+ offset += 1;
src_str = smpp_handle_string_return(tree, tvb, pinfo, hf_smpp_source_addr, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
+ proto_tree_add_item(tree, hf_smpp_dest_addr_ton, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_dest_addr_npi, tvb, offset, 1, ENC_NA);
+ offset += 1;
dst_str = smpp_handle_string_return(tree, tvb, pinfo, hf_smpp_destination_addr, &offset);
- flag = tvb_get_guint8(tvb, offset);
- udhi = flag & 0x40;
- proto_tree_add_uint(tree, hf_smpp_esm_submit_msg_mode,
- tvb, offset, 1, flag);
- proto_tree_add_uint(tree, hf_smpp_esm_submit_msg_type,
- tvb, offset, 1, flag);
- proto_tree_add_uint(tree, hf_smpp_esm_submit_features,
- tvb, offset, 1, flag);
+
+ udhi = tvb_get_guint8(tvb, offset) & 0x40;
+ proto_tree_add_bitmask_list(tree, tvb, offset, 1, submit_msg_fields, ENC_NA);
offset++;
- smpp_handle_int1(tree, tvb, hf_smpp_protocol_id, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
+
+ proto_tree_add_item(tree, hf_smpp_protocol_id, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_priority_flag, tvb, offset, 1, ENC_NA);
+ offset += 1;
if (tvb_get_guint8(tvb,offset)) {
smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
hf_smpp_schedule_delivery_time_r, &offset);
@@ -1926,23 +1945,21 @@ submit_sm(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
} else { /* Time = NULL means SMSC default validity */
proto_tree_add_time_format_value(tree, hf_smpp_validity_period_r, tvb, offset++, 1, &zero_time, "SMSC default validity period");
}
- flag = tvb_get_guint8(tvb, offset);
- proto_tree_add_uint(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
- proto_tree_add_uint(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
- proto_tree_add_uint(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
+
+ proto_tree_add_bitmask_list(tree, tvb, offset, 1, regdel_fields, ENC_NA);
offset++;
- smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
- smpp_handle_dcs(tree, tvb, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
- length = tvb_get_guint8(tvb, offset);
- proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
+ proto_tree_add_item(tree, hf_smpp_replace_if_present_flag, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ smpp_handle_dcs(tree, tvb, &offset);
+ proto_tree_add_item(tree, hf_smpp_sm_default_msg_id, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item_ret_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, ENC_NA, &length);
if (length)
{
proto_tree_add_item(tree, hf_smpp_short_message,
tvb, offset, length, ENC_NA);
if (udhi) /* UDHI indicator present */
{
- DebugLog(("UDHI present - set addresses\n"));
/* Save original addresses */
copy_address_shallow(&save_src, &pinfo->src);
copy_address_shallow(&save_dst, &pinfo->dst);
@@ -1962,19 +1979,17 @@ submit_sm(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
smpp_handle_tlv(tree, tvb, &offset);
}
-#define deliver_sm(a, b, c, d) submit_sm(a, b, c, d)
-
static void
-replace_sm(proto_tree *tree, tvbuff_t *tvb)
+replace_sm(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
- guint8 flag;
- guint8 length;
+ guint32 length;
nstime_t zero_time = NSTIME_INIT_ZERO;
smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
+ proto_tree_add_item(tree, hf_smpp_source_addr_ton, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_source_addr_npi, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
if (tvb_get_guint8(tvb,offset)) {
smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
@@ -1988,59 +2003,54 @@ replace_sm(proto_tree *tree, tvbuff_t *tvb)
} else { /* Time = NULL */
proto_tree_add_time_format_value(tree, hf_smpp_validity_period_r, tvb, offset++, 1,&zero_time, "Keep initial validity period setting");
}
- flag = tvb_get_guint8(tvb, offset);
- proto_tree_add_uint(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
- proto_tree_add_uint(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
- proto_tree_add_uint(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
+ proto_tree_add_bitmask_list(tree, tvb, offset, 1, regdel_fields, ENC_NA);
offset++;
- smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
- length = tvb_get_guint8(tvb, offset);
- proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
+ proto_tree_add_item(tree, hf_smpp_sm_default_msg_id, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item_ret_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, ENC_NA, &length);
if (length)
proto_tree_add_item(tree, hf_smpp_short_message,
tvb, offset, length, ENC_NA);
}
static void
-cancel_sm(proto_tree *tree, tvbuff_t *tvb)
+cancel_sm(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
-
smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
+ proto_tree_add_item(tree, hf_smpp_source_addr_ton, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_source_addr_npi, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
+ proto_tree_add_item(tree, hf_smpp_dest_addr_ton, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_dest_addr_npi, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
}
static void
-submit_multi(proto_tree *tree, tvbuff_t *tvb)
+submit_multi(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
- guint8 flag;
- guint8 length;
+ guint32 length;
nstime_t zero_time = NSTIME_INIT_ZERO;
smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
+ proto_tree_add_item(tree, hf_smpp_source_addr_ton, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_source_addr_npi, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
smpp_handle_dlist(tree, tvb, &offset);
- flag = tvb_get_guint8(tvb, offset);
- proto_tree_add_uint(tree, hf_smpp_esm_submit_msg_mode,
- tvb, offset, 1, flag);
- proto_tree_add_uint(tree, hf_smpp_esm_submit_msg_type,
- tvb, offset, 1, flag);
- proto_tree_add_uint(tree, hf_smpp_esm_submit_features,
- tvb, offset, 1, flag);
+ proto_tree_add_bitmask_list(tree, tvb, offset, 1, submit_msg_fields, ENC_NA);
offset++;
- smpp_handle_int1(tree, tvb, hf_smpp_protocol_id, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
+ proto_tree_add_item(tree, hf_smpp_protocol_id, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_priority_flag, tvb, offset, 1, ENC_NA);
+ offset += 1;
if (tvb_get_guint8(tvb,offset)) {
smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
hf_smpp_schedule_delivery_time_r, &offset);
@@ -2052,16 +2062,14 @@ submit_multi(proto_tree *tree, tvbuff_t *tvb)
} else { /* Time = NULL means SMSC default validity */
proto_tree_add_time_format_value(tree, hf_smpp_schedule_delivery_time_r, tvb, offset++, 1, &zero_time, "SMSC default validity period");
}
- flag = tvb_get_guint8(tvb, offset);
- proto_tree_add_uint(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
- proto_tree_add_uint(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
- proto_tree_add_uint(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
+ proto_tree_add_bitmask_list(tree, tvb, offset, 1, regdel_fields, ENC_NA);
offset++;
- smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
+ proto_tree_add_item(tree, hf_smpp_replace_if_present_flag, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_dcs(tree, tvb, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
- length = tvb_get_guint8(tvb, offset);
- proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
+ proto_tree_add_item(tree, hf_smpp_sm_default_msg_id, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item_ret_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, ENC_NA, &length);
if (length)
proto_tree_add_item(tree, hf_smpp_short_message,
tvb, offset, length, ENC_NA);
@@ -2070,46 +2078,40 @@ submit_multi(proto_tree *tree, tvbuff_t *tvb)
}
static void
-alert_notification(proto_tree *tree, tvbuff_t *tvb)
+alert_notification(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
-
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
+ proto_tree_add_item(tree, hf_smpp_source_addr_ton, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_source_addr_npi, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_esme_addr_ton, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_esme_addr_npi, &offset);
+ proto_tree_add_item(tree, hf_smpp_esme_addr_ton, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_esme_addr_npi, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_smpp_esme_addr, &offset);
smpp_handle_tlv(tree, tvb, &offset);
}
static void
-data_sm(proto_tree *tree, tvbuff_t *tvb)
+data_sm(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
- guint8 flag;
-
smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
+ proto_tree_add_item(tree, hf_smpp_source_addr_ton, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_source_addr_npi, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
+ proto_tree_add_item(tree, hf_smpp_dest_addr_ton, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_dest_addr_npi, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
- flag = tvb_get_guint8(tvb, offset);
- proto_tree_add_uint(tree, hf_smpp_esm_submit_msg_mode,
- tvb, offset, 1, flag);
- proto_tree_add_uint(tree, hf_smpp_esm_submit_msg_type,
- tvb, offset, 1, flag);
- proto_tree_add_uint(tree, hf_smpp_esm_submit_features,
- tvb, offset, 1, flag);
+ proto_tree_add_bitmask_list(tree, tvb, offset, 1, submit_msg_fields, ENC_NA);
offset++;
- flag = tvb_get_guint8(tvb, offset);
- proto_tree_add_uint(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
- proto_tree_add_uint(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
- proto_tree_add_uint(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
+ proto_tree_add_bitmask_list(tree, tvb, offset, 1, regdel_fields, ENC_NA);
offset++;
- smpp_handle_dcs(tree, tvb, &offset);
+ smpp_handle_dcs(tree, tvb, &offset);
smpp_handle_tlv(tree, tvb, &offset);
}
@@ -2117,17 +2119,19 @@ data_sm(proto_tree *tree, tvbuff_t *tvb)
* Request operations introduced in the SMPP 5.0
*/
static void
-broadcast_sm(proto_tree *tree, tvbuff_t *tvb)
+broadcast_sm(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
nstime_t zero_time = NSTIME_INIT_ZERO;
smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
+ proto_tree_add_item(tree, hf_smpp_source_addr_ton, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_source_addr_npi, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
+ proto_tree_add_item(tree, hf_smpp_priority_flag, tvb, offset, 1, ENC_NA);
+ offset += 1;
if (tvb_get_guint8(tvb,offset)) {
smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
hf_smpp_schedule_delivery_time_r, &offset);
@@ -2139,33 +2143,35 @@ broadcast_sm(proto_tree *tree, tvbuff_t *tvb)
} else { /* Time = NULL means SMSC default validity */
proto_tree_add_time_format_value(tree, hf_smpp_validity_period_r, tvb, offset++, 1, &zero_time, "SMSC default validity period");
}
- smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
+ proto_tree_add_item(tree, hf_smpp_replace_if_present_flag, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_dcs(tree, tvb, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
+ proto_tree_add_item(tree, hf_smpp_sm_default_msg_id, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_tlv(tree, tvb, &offset);
}
static void
-query_broadcast_sm(proto_tree *tree, tvbuff_t *tvb)
+query_broadcast_sm(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
-
smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
+ proto_tree_add_item(tree, hf_smpp_source_addr_ton, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_source_addr_npi, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
smpp_handle_tlv(tree, tvb, &offset);
}
static void
-cancel_broadcast_sm(proto_tree *tree, tvbuff_t *tvb)
+cancel_broadcast_sm(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
-
smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
+ proto_tree_add_item(tree, hf_smpp_source_addr_ton, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_source_addr_npi, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
smpp_handle_tlv(tree, tvb, &offset);
}
@@ -2175,168 +2181,120 @@ cancel_broadcast_sm(proto_tree *tree, tvbuff_t *tvb)
* associated with SMPP.
*/
static void
-bind_receiver_resp(proto_tree *tree, tvbuff_t *tvb)
+bind_receiver_resp(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
-
smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
smpp_handle_tlv(tree, tvb, &offset);
}
-#define bind_transmitter_resp(a, b) bind_receiver_resp(a, b)
-
static void
-query_sm_resp(proto_tree *tree, tvbuff_t *tvb)
+query_sm_resp(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
-
smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
smpp_handle_time(tree, tvb, hf_smpp_final_date,
hf_smpp_final_date_r, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_message_state, &offset);
- smpp_handle_int1(tree, tvb, hf_smpp_error_code, &offset);
+ proto_tree_add_item(tree, hf_smpp_message_state, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_smpp_error_code, tvb, offset, 1, ENC_NA);
+ offset += 1;
}
-#define bind_transceiver_resp(a, b) bind_receiver_resp(a, b)
-
static void
-submit_sm_resp(proto_tree *tree, tvbuff_t *tvb)
+submit_sm_resp(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
-
smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
smpp_handle_tlv(tree, tvb, &offset);
}
-#define deliver_sm_resp(a, b) submit_sm_resp(a, b)
-
static void
-submit_multi_resp(proto_tree *tree, tvbuff_t *tvb)
+submit_multi_resp(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
-
smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
smpp_handle_dlist_resp(tree, tvb, &offset);
smpp_handle_tlv(tree, tvb, &offset);
}
static void
-data_sm_resp(proto_tree *tree, tvbuff_t *tvb)
+data_sm_resp(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
-
smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
smpp_handle_tlv(tree, tvb, &offset);
}
-#define broadcast_sm_resp(a, b) submit_sm_resp(a, b)
-
static void
-query_broadcast_sm_resp(proto_tree *tree, tvbuff_t *tvb)
+query_broadcast_sm_resp(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
-
smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
smpp_handle_tlv(tree, tvb, &offset);
}
/* Huawei SMPP+ extensions */
static void
-huawei_auth_acc(proto_tree *tree, tvbuff_t *tvb)
+huawei_auth_acc(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
- guint8 version = 0;
+ guint32 version;
- smpp_handle_int1(tree, tvb, hf_huawei_smpp_version, &offset);
- version = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item_ret_uint(tree, hf_smpp_error_code, tvb, offset, 1, ENC_NA, &version);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_huawei_smpp_smsc_addr, &offset);
if ( version == '3' ) {
- smpp_handle_int1(tree, tvb, hf_huawei_smpp_msc_addr_noa, &offset);
- smpp_handle_int1(tree, tvb, hf_huawei_smpp_msc_addr_npi, &offset);
+ proto_tree_add_item(tree, hf_huawei_smpp_msc_addr_noa, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_huawei_smpp_msc_addr_npi, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_huawei_smpp_msc_addr, &offset);
}
smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
- smpp_handle_int1(tree, tvb, hf_huawei_smpp_mo_mt_flag, &offset);
+ proto_tree_add_item(tree, hf_huawei_smpp_mo_mt_flag, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_huawei_smpp_sm_id, &offset);
- smpp_handle_int4(tree, tvb, hf_huawei_smpp_length_auth, &offset);
- smpp_handle_int4(tree, tvb, hf_huawei_smpp_service_id, &offset);
+ proto_tree_add_item(tree, hf_huawei_smpp_length_auth, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(tree, hf_huawei_smpp_service_id, tvb, offset, 4, ENC_BIG_ENDIAN);
}
static void
-huawei_auth_acc_resp(proto_tree *tree, tvbuff_t *tvb)
+huawei_auth_acc_resp(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
-
- smpp_handle_int4(tree, tvb, hf_huawei_smpp_operation_result, &offset);
- smpp_handle_int1(tree, tvb, hf_huawei_smpp_notify_mode, &offset);
+ proto_tree_add_item(tree, hf_huawei_smpp_operation_result, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(tree, hf_huawei_smpp_notify_mode, tvb, offset, 1, ENC_NA);
}
static void
-huawei_sm_result_notify(proto_tree *tree, tvbuff_t *tvb)
+huawei_sm_result_notify(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
- guint8 version = 0;
+ guint32 version;
- smpp_handle_int1(tree, tvb, hf_huawei_smpp_version, &offset);
- version = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item_ret_uint(tree, hf_smpp_error_code, tvb, offset, 1, ENC_NA, &version);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_huawei_smpp_smsc_addr, &offset);
if ( version == '3' ) {
- smpp_handle_int1(tree, tvb, hf_huawei_smpp_msc_addr_noa, &offset);
- smpp_handle_int1(tree, tvb, hf_huawei_smpp_msc_addr_npi, &offset);
+ proto_tree_add_item(tree, hf_huawei_smpp_msc_addr_noa, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_huawei_smpp_msc_addr_npi, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_huawei_smpp_msc_addr, &offset);
}
smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
- smpp_handle_int1(tree, tvb, hf_huawei_smpp_mo_mt_flag, &offset);
+ proto_tree_add_item(tree, hf_huawei_smpp_mo_mt_flag, tvb, offset, 1, ENC_NA);
+ offset += 1;
smpp_handle_string(tree, tvb, hf_huawei_smpp_sm_id, &offset);
- smpp_handle_int4(tree, tvb, hf_huawei_smpp_length_auth, &offset);
- smpp_handle_int4(tree, tvb, hf_huawei_smpp_delivery_result, &offset);
- smpp_handle_int4(tree, tvb, hf_huawei_smpp_service_id, &offset);
+ proto_tree_add_item(tree, hf_huawei_smpp_length_auth, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(tree, hf_huawei_smpp_delivery_result, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(tree, hf_huawei_smpp_service_id, tvb, offset, 4, ENC_BIG_ENDIAN);
}
static void
-huawei_sm_result_notify_resp(proto_tree *tree, tvbuff_t *tvb)
+huawei_sm_result_notify_resp(proto_tree *tree, tvbuff_t *tvb, int offset)
{
- int offset = 0;
-
- smpp_handle_int4(tree, tvb, hf_huawei_smpp_operation_result, &offset);
-}
-
-
-/*
- * A 'heuristic dissector' that attemtps to establish whether we have
- * a genuine SMPP PDU here.
- * Only works when:
- * at least the fixed header is there
- * it has a correct overall PDU length
- * it is a 'well-known' operation
- * has a 'well-known' or 'reserved' status
- */
-static gboolean
-dissect_smpp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
-{
- guint32 command_id; /* SMPP command */
- guint32 command_status; /* Status code */
- guint32 command_length; /* length of PDU */
-
- if (tvb_reported_length(tvb) < SMPP_MIN_LENGTH || /* Mandatory header */
- tvb_captured_length(tvb) < 12)
- return FALSE;
- command_length = tvb_get_ntohl(tvb, 0);
- if (command_length > 64 * 1024 || command_length < SMPP_MIN_LENGTH)
- return FALSE;
- command_id = tvb_get_ntohl(tvb, 4); /* Only known commands */
- if (try_val_to_str(command_id, vals_command_id) == NULL)
- return FALSE;
- command_status = tvb_get_ntohl(tvb, 8); /* ..with known status */
- if (try_val_to_str(command_status, vals_command_status) == NULL &&
- try_rval_to_str(command_status, reserved_command_status) == NULL)
- return FALSE;
- dissect_smpp(tvb, pinfo, tree, data);
- return TRUE;
+ proto_tree_add_item(tree, hf_huawei_smpp_delivery_result, tvb, offset, 4, ENC_BIG_ENDIAN);
}
static guint
@@ -2345,51 +2303,6 @@ get_smpp_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _
return tvb_get_ntohl(tvb, offset);
}
-/*
- * This global SMPP variable is used to determine whether the PDU to dissect
- * is the first SMPP PDU in the packet (or reassembled buffer), requiring
- * different column update code than subsequent SMPP PDUs within this packet
- * (or reassembled buffer).
- *
- * FIXME - This approach is NOT dissection multi-thread safe!
- */
-static gboolean first = TRUE;
-
-static int
-dissect_smpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
-{
- first = TRUE;
- if (pinfo->ptype == PT_TCP) { /* are we running on top of TCP */
- tcp_dissect_pdus(tvb, pinfo, tree,
- reassemble_over_tcp, /* Do we try to reassemble */
- 16, /* Length of fixed header */
- get_smpp_pdu_len, /* Function returning PDU len */
- dissect_smpp_pdu, data); /* PDU dissector */
- } else { /* no? probably X.25 */
- guint32 offset = 0;
- while (tvb_reported_length_remaining(tvb, offset) > 0) {
- guint16 pdu_len = tvb_get_ntohl(tvb, offset);
- gint pdu_real_len = tvb_captured_length_remaining(tvb, offset);
- tvbuff_t *pdu_tvb;
-
- if (pdu_len < 1)
- return offset;
-
- if (pdu_real_len <= 0)
- return offset;
- if (pdu_real_len > pdu_len)
- pdu_real_len = pdu_len;
- pdu_tvb = tvb_new_subset_length_caplen(tvb, offset, pdu_real_len, pdu_len);
- dissect_smpp_pdu(pdu_tvb, pinfo, tree, data);
- offset += pdu_len;
- first = FALSE;
- }
- }
-
- return tvb_captured_length(tvb);
-}
-
-
/* Dissect a single SMPP PDU contained within "tvb". */
static int
dissect_smpp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
@@ -2419,15 +2332,9 @@ dissect_smpp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data
"(Unknown SMPP Operation 0x%08X)");
offset += 4;
command_status = tvb_get_ntohl(tvb, offset);
- if (command_id & 0x80000000) {
+ if (command_id & SMPP_COMMAND_ID_RESPONSE_MASK) {
/* PDU is a response. */
- command_status_str = try_val_to_str(command_status, vals_command_status);
- if (command_status_str == NULL) {
- /* Check if the reserved value is in the vendor-specific range. */
- command_status_str = (command_status >= 0x400 && command_status <= 0x4FF ?
- wmem_strdup_printf(wmem_packet_scope(), "Vendor-specific Error (0x%08X)", command_status) :
- wmem_strdup_printf(wmem_packet_scope(), "(Reserved Error 0x%08X)", command_status));
- }
+ command_status_str = rval_to_str(command_status, rvals_command_status, "Unknown (0x%08x)");
}
offset += 4;
sequence_number = tvb_get_ntohl(tvb, offset);
@@ -2436,9 +2343,8 @@ dissect_smpp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data
/*
* Update the protocol column.
*/
- if (first == TRUE) {
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMPP");
- }
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMPP");
+ col_clear(pinfo->cinfo, COL_INFO);
/*
* Create display subtree for the protocol
@@ -2447,247 +2353,268 @@ dissect_smpp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data
smpp_tree = proto_item_add_subtree (ti, ett_smpp);
/*
- * Cycle over the encapsulated PDUs
+ * Make entries in the Info column on the summary display
*/
- {
- tvbuff_t *pdu_tvb;
+ col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", command_str);
- /*
- * Make entries in the Info column on the summary display
- */
- if (first == TRUE) {
- /*
- * First PDU - We already computed the fixed header
- */
- col_add_fstr(pinfo->cinfo, COL_INFO, "SMPP %s", command_str);
- first = FALSE;
- } else {
- /*
- * Subsequent PDUs
- */
- col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", command_str);
+ /*
+ * Display command status of responses in Info column
+ */
+ if (command_id & SMPP_COMMAND_ID_RESPONSE_MASK) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": \"%s\"", command_status_str);
+ }
+
+ /*
+ * Dissect the PDU
+ */
+
+ /*
+ * Create display subtree for the PDU
+ */
+ proto_tree_add_uint(smpp_tree, hf_smpp_command_length, tvb, 0, 4, command_length);
+ proto_tree_add_uint(smpp_tree, hf_smpp_command_id, tvb, 4, 4, command_id);
+ proto_item_append_text(ti, ", Command: %s", command_str);
+
+ /*
+ * Status is only meaningful with responses
+ */
+ if (command_id & SMPP_COMMAND_ID_RESPONSE_MASK) {
+ proto_tree_add_uint(smpp_tree, hf_smpp_command_status, tvb, 8, 4, command_status);
+ proto_item_append_text (ti, ", Status: \"%s\"", command_status_str);
+ }
+ proto_tree_add_uint(smpp_tree, hf_smpp_sequence_number, tvb, 12, 4, sequence_number);
+ proto_item_append_text(ti, ", Seq: %u, Len: %u", sequence_number, command_length);
+
+ if (command_length <= tvb_reported_length(tvb))
+ {
+ if (command_id & SMPP_COMMAND_ID_RESPONSE_MASK)
+ {
+ switch (command_id & (~SMPP_COMMAND_ID_RESPONSE_MASK)) {
+ /*
+ * All of these only have a fixed header
+ */
+ case SMPP_COMMAND_ID_GENERIC_NACK:
+ case SMPP_COMMAND_ID_UNBIND:
+ case SMPP_COMMAND_ID_REPLACE_SM:
+ case SMPP_COMMAND_ID_CANCEL_SM:
+ case SMPP_COMMAND_ID_ENQUIRE_LINK:
+ case SMPP_COMMAND_ID_CANCEL_BROADCAST_SM:
+ break;
+ /* FIXME: The body of the response PDUs are only
+ * only dissected if the request was successful.
+ * However, in SMPP 5.0 some responses might
+ * contain body to provide additional information
+ * about the error. This needs to be handled.
+ */
+ case SMPP_COMMAND_ID_BIND_RECEIVER:
+ case SMPP_COMMAND_ID_BIND_TRANSMITTER:
+ case SMPP_COMMAND_ID_BIND_TRANSCEIVER:
+ if (!command_status)
+ bind_receiver_resp(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_QUERY_SM:
+ if (!command_status)
+ query_sm_resp(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_SUBMIT_SM:
+ case SMPP_COMMAND_ID_DELIVER_SM:
+ case SMPP_COMMAND_ID_BROADCAST_SM:
+ if (!command_status)
+ submit_sm_resp(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_SUBMIT_MULTI:
+ if (!command_status)
+ submit_multi_resp(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_DATA_SM:
+ if (!command_status)
+ data_sm_resp(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_QUERY_BROADCAST_SM:
+ if (!command_status)
+ query_broadcast_sm_resp(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_HUAWEI_AUTH_ACC:
+ if (!command_status)
+ huawei_auth_acc_resp(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_HUAWEI_SM_RESULT_NOTIFY:
+ if (!command_status)
+ huawei_sm_result_notify_resp(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ default:
+ break;
+ } /* switch (command_id & 0x7FFFFFFF) */
}
- /*
- * Display command status of responses in Info column
- */
- if (command_id & 0x80000000) {
- col_append_fstr(pinfo->cinfo, COL_INFO, ": \"%s\"",
- command_status_str);
+ else
+ {
+ switch (command_id) {
+ case SMPP_COMMAND_ID_BIND_RECEIVER:
+ case SMPP_COMMAND_ID_BIND_TRANSMITTER:
+ case SMPP_COMMAND_ID_BIND_TRANSCEIVER:
+ bind_receiver(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_QUERY_SM:
+ query_sm(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_SUBMIT_SM:
+ case SMPP_COMMAND_ID_DELIVER_SM:
+ submit_sm(smpp_tree, tvb, pinfo, tree, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_UNBIND:
+ case SMPP_COMMAND_ID_ENQUIRE_LINK:
+ break;
+ case SMPP_COMMAND_ID_REPLACE_SM:
+ replace_sm(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_CANCEL_SM:
+ cancel_sm(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_OUTBIND:
+ outbind(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_SUBMIT_MULTI:
+ submit_multi(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_ALERT_NOTIFICATION:
+ alert_notification(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_DATA_SM:
+ data_sm(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_BROADCAST_SM:
+ broadcast_sm(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_QUERY_BROADCAST_SM:
+ query_broadcast_sm(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_CANCEL_BROADCAST_SM:
+ cancel_broadcast_sm(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_HUAWEI_AUTH_ACC:
+ huawei_auth_acc(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ case SMPP_COMMAND_ID_HUAWEI_SM_RESULT_NOTIFY:
+ huawei_sm_result_notify(smpp_tree, tvb, SMPP_FIXED_HEADER_LENGTH);
+ break;
+ default:
+ break;
+ } /* switch (command_id) */
}
- /*
- * Create a tvb for the current PDU.
- * Physical length: at most command_length
- * Reported length: command_length
- */
- if (tvb_captured_length_remaining(tvb, offset - 16 + command_length) > 0) {
- pdu_tvb = tvb_new_subset_length_caplen(tvb, offset - 16,
- command_length, /* Physical length */
- command_length); /* Length reported by the protocol */
- } else {
- pdu_tvb = tvb_new_subset_length_caplen(tvb, offset - 16,
- tvb_captured_length_remaining(tvb, offset - 16),/* Physical length */
- command_length); /* Length reported by the protocol */
- }
+ }
- /*
- * Dissect the PDU
- *
- * If "tree" is NULL, Wireshark is only interested in creation
- * of conversations, reassembly and subdissection but not in
- * the detailed protocol tree.
- * In the interest of speed, skip the generation of protocol tree
- * items when "tree" is NULL.
- *
- * The only PDU which requires subdissection currently is the
- * sm_submit PDU (command ID = 0x00000004).
- */
- if (tree || (command_id == 4))
- {
- /*
- * Create display subtree for the PDU
- */
- if (tree) {
- proto_tree_add_uint(smpp_tree, hf_smpp_command_length,
- pdu_tvb, 0, 4, command_length);
- proto_tree_add_uint(smpp_tree, hf_smpp_command_id,
- pdu_tvb, 4, 4, command_id);
- proto_item_append_text(ti, ", Command: %s", command_str);
+ /* Queue packet for Tap */
+ tap_rec = wmem_new0(wmem_packet_scope(), smpp_tap_rec_t);
+ tap_rec->command_id = command_id;
+ tap_rec->command_status = command_status;
+ tap_queue_packet(smpp_tap, pinfo, tap_rec);
- /*
- * Status is only meaningful with responses
- */
- if (command_id & 0x80000000) {
- proto_tree_add_uint(smpp_tree, hf_smpp_command_status,
- pdu_tvb, 8, 4, command_status);
- proto_item_append_text (ti, ", Status: \"%s\"",
- command_status_str);
- }
- proto_tree_add_uint(smpp_tree, hf_smpp_sequence_number,
- pdu_tvb, 12, 4, sequence_number);
- proto_item_append_text(ti, ", Seq: %u, Len: %u",
- sequence_number, command_length);
- }
-
- /*
- * End of fixed header.
- * Don't dissect variable part if it is shortened.
- *
- * FIXME - We then do not report a Short Frame or Malformed Packet
- */
- if (command_length <= tvb_reported_length(pdu_tvb))
- {
- tvbuff_t *tmp_tvb = tvb_new_subset_length_caplen(pdu_tvb, 16,
- -1, command_length - 16);
- if (command_id & 0x80000000)
- {
- switch (command_id & 0x7FFFFFFF) {
- /*
- * All of these only have a fixed header
- */
- case 0: /* Generic nack */
- case 6: /* Unbind resp */
- case 7: /* Replace SM resp */
- case 8: /* Cancel SM resp */
- case 21: /* Enquire link resp */
- case 275: /* Cancel Broadcast SM resp */
- break;
- /* FIXME: The body of the response PDUs are only
- * only dissected if the request was successful.
- * However, in SMPP 5.0 some responses might
- * contain body to provide additional information
- * about the error. This needs to be handled.
- */
- case 1:
- if (!command_status)
- bind_receiver_resp(smpp_tree, tmp_tvb);
- break;
- case 2:
- if (!command_status)
- bind_transmitter_resp(smpp_tree, tmp_tvb);
- break;
- case 3:
- if (!command_status)
- query_sm_resp(smpp_tree, tmp_tvb);
- break;
- case 4:
- if (!command_status)
- submit_sm_resp(smpp_tree, tmp_tvb);
- break;
- case 5:
- if (!command_status)
- deliver_sm_resp(smpp_tree, tmp_tvb);
- break;
- case 9:
- if (!command_status)
- bind_transceiver_resp(smpp_tree, tmp_tvb);
- break;
- case 33:
- if (!command_status)
- submit_multi_resp(smpp_tree, tmp_tvb);
- break;
- case 259:
- if (!command_status)
- data_sm_resp(smpp_tree, tmp_tvb);
- break;
- case 273:
- if (!command_status)
- broadcast_sm_resp(smpp_tree, tmp_tvb);
- break;
- case 274:
- if (!command_status)
- query_broadcast_sm_resp(smpp_tree, tmp_tvb);
- break;
- case 16777217:
- if (!command_status)
- huawei_auth_acc_resp(smpp_tree, tmp_tvb);
- break;
- case 16777218:
- if (!command_status)
- huawei_sm_result_notify_resp(smpp_tree, tmp_tvb);
- break;
- default:
- break;
- } /* switch (command_id & 0x7FFFFFFF) */
- }
- else
- {
- switch (command_id) {
- case 1:
- bind_receiver(smpp_tree, tmp_tvb);
- break;
- case 2:
- bind_transmitter(smpp_tree, tmp_tvb);
- break;
- case 3:
- query_sm(smpp_tree, tmp_tvb);
- break;
- case 4:
- submit_sm(smpp_tree, tmp_tvb, pinfo, tree);
- break;
- case 5:
- deliver_sm(smpp_tree, tmp_tvb, pinfo, tree);
- break;
- case 6: /* Unbind */
- case 21: /* Enquire link */
- break;
- case 7:
- replace_sm(smpp_tree, tmp_tvb);
- break;
- case 8:
- cancel_sm(smpp_tree, tmp_tvb);
- break;
- case 9:
- bind_transceiver(smpp_tree, tmp_tvb);
- break;
- case 11:
- outbind(smpp_tree, tmp_tvb);
- break;
- case 33:
- submit_multi(smpp_tree, tmp_tvb);
- break;
- case 258:
- alert_notification(smpp_tree, tmp_tvb);
- break;
- case 259:
- data_sm(smpp_tree, tmp_tvb);
- break;
- case 273:
- broadcast_sm(smpp_tree, tmp_tvb);
- break;
- case 274:
- query_broadcast_sm(smpp_tree, tmp_tvb);
- break;
- case 275:
- cancel_broadcast_sm(smpp_tree, tmp_tvb);
- break;
- case 16777217:
- huawei_auth_acc(smpp_tree, tmp_tvb);
- break;
- case 16777218:
- huawei_sm_result_notify(smpp_tree, tmp_tvb);
- break;
- default:
- break;
- } /* switch (command_id) */
- } /* if (command_id & 0x80000000) */
-
- } /* if (command_length <= tvb_reported_length(pdu_tvb)) */
- /*offset += command_length;*/
- } /* if (tree || (command_id == 4)) */
-
- /* Queue packet for Tap */
- tap_rec = wmem_new0(wmem_packet_scope(), smpp_tap_rec_t);
- tap_rec->command_id = command_id;
- tap_rec->command_status = command_status;
- tap_queue_packet(smpp_tap, pinfo, tap_rec);
-
- first = FALSE;
+ col_set_fence(pinfo->cinfo, COL_INFO);
+
+ return tvb_captured_length(tvb);
+}
+
+static int
+dissect_smpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ if (pinfo->ptype == PT_TCP) { /* are we running on top of TCP */
+ tcp_dissect_pdus(tvb, pinfo, tree,
+ reassemble_over_tcp, /* Do we try to reassemble */
+ 16, /* Length of fixed header */
+ get_smpp_pdu_len, /* Function returning PDU len */
+ dissect_smpp_pdu, data); /* PDU dissector */
+ }
+ else { /* no? probably X.25 */
+ guint32 offset = 0;
+ while (tvb_reported_length_remaining(tvb, offset) > 0) {
+ guint16 pdu_len = tvb_get_ntohl(tvb, offset);
+ gint pdu_real_len = tvb_captured_length_remaining(tvb, offset);
+ tvbuff_t *pdu_tvb;
+
+ if (pdu_len < 1)
+ return offset;
+
+ if (pdu_real_len <= 0)
+ return offset;
+ if (pdu_real_len > pdu_len)
+ pdu_real_len = pdu_len;
+ pdu_tvb = tvb_new_subset_length_caplen(tvb, offset, pdu_real_len, pdu_len);
+ dissect_smpp_pdu(pdu_tvb, pinfo, tree, data);
+ offset += pdu_len;
+ }
}
return tvb_captured_length(tvb);
}
+/*
+* A 'heuristic dissector' that attemtps to establish whether we have
+* a genuine SMPP PDU here.
+* Only works when:
+* at least the fixed header is there
+* it has a correct overall PDU length
+* it is a 'well-known' operation
+* has a 'well-known' or 'reserved' status
+*/
+static gboolean
+dissect_smpp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
+{
+ guint32 command_id; /* SMPP command */
+ guint32 command_status; /* Status code */
+ guint32 command_length; /* length of PDU */
+
+ if (tvb_reported_length(tvb) < SMPP_MIN_LENGTH || /* Mandatory header */
+ tvb_captured_length(tvb) < 12)
+ return FALSE;
+ command_length = tvb_get_ntohl(tvb, 0);
+ if (command_length > 64 * 1024 || command_length < SMPP_MIN_LENGTH)
+ return FALSE;
+ command_id = tvb_get_ntohl(tvb, 4); /* Only known commands */
+ if (try_val_to_str(command_id, vals_command_id) == NULL)
+ return FALSE;
+ command_status = tvb_get_ntohl(tvb, 8); /* ..with known status */
+ if (try_rval_to_str(command_status, rvals_command_status) == NULL)
+ return FALSE;
+
+ //Check for specific values in commands (to avoid false positives)
+ switch (command_id)
+ {
+ case SMPP_COMMAND_ID_ALERT_NOTIFICATION:
+ {
+ guint8 ton, npi;
+
+ if (tvb_reported_length(tvb) < 19)
+ return FALSE;
+ ton = tvb_get_guint8(tvb, 16);
+ if (try_val_to_str(ton, vals_addr_ton) == NULL)
+ return FALSE;
+
+ npi = tvb_get_guint8(tvb, 17);
+ if (try_val_to_str(npi, vals_addr_npi) == NULL)
+ return FALSE;
+
+ //address must be NULL-terminated string of up to 65 ascii characters
+ int end = tvb_find_guint8(tvb, 18, -1, 0);
+ if ((end <= 0) || (end > 65))
+ return FALSE;
+
+ if (!tvb_ascii_isprint(tvb, 18, end - 18))
+ return FALSE;
+ }
+ break;
+ }
+
+
+ dissect_smpp(tvb, pinfo, tree, data);
+ return TRUE;
+}
+
+static void
+smpp_fmt_version(gchar *result, guint32 revision)
+{
+ g_snprintf(result, ITEM_LABEL_LENGTH, "%u.%u", (guint8)((revision & 0xF0) >> 4), (guint8)(revision & 0x0F));
+}
/* Register the protocol with Wireshark */
void
@@ -2713,7 +2640,7 @@ proto_register_smpp(void)
},
{ &hf_smpp_command_status,
{ "Result", "smpp.command_status",
- FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
+ FT_UINT32, BASE_HEX | BASE_RANGE_STRING, RVALS(rvals_command_status), 0x00,
"Indicates success or failure of the SMPP request.",
HFILL
}
@@ -2748,7 +2675,7 @@ proto_register_smpp(void)
},
{ &hf_smpp_interface_version,
{ "Version (if)", "smpp.interface_version",
- FT_STRING, BASE_NONE, NULL, 0x00,
+ FT_UINT8, BASE_CUSTOM, CF_FUNC(smpp_fmt_version), 0x00,
"Version of SMPP interface supported.",
HFILL
}
@@ -3001,7 +2928,7 @@ proto_register_smpp(void)
},
{ &hf_smpp_error_status_code,
{ "Status", "smpp.error_status_code",
- FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
+ FT_UINT32, BASE_HEX | BASE_RANGE_STRING, RVALS(rvals_command_status), 0x00,
"Indicates success/failure of request for this address.",
HFILL
}
@@ -3267,14 +3194,14 @@ proto_register_smpp(void)
},
{ &hf_smpp_vendor_op,
{ "Value", "smpp.vendor_op",
- FT_BYTES, BASE_NONE, NULL, 0x00,
+ FT_BYTES, BASE_NONE|BASE_ALLOW_ZERO, NULL, 0x00,
"A supplied optional parameter specific to an SMSC-vendor.",
HFILL
}
},
{ &hf_smpp_reserved_op,
{ "Value", "smpp.reserved_op",
- FT_BYTES, BASE_NONE, NULL, 0x00,
+ FT_BYTES, BASE_NONE|BASE_ALLOW_ZERO, NULL, 0x00,
"An optional parameter that is reserved in this version.",
HFILL
}
@@ -3295,7 +3222,7 @@ proto_register_smpp(void)
},
{ &hf_smpp_SC_interface_version,
{ "SMSC-supported version", "smpp.SC_interface_version",
- FT_STRING, BASE_NONE, NULL, 0x00,
+ FT_UINT8, BASE_CUSTOM, CF_FUNC(smpp_fmt_version), 0x00,
"Version of SMPP interface supported by the SMSC.",
HFILL
}
@@ -3609,7 +3536,7 @@ proto_register_smpp(void)
},
{ &hf_smpp_broadcast_error_status,
{ "Broadcast Message - Error Status", "smpp.broadcast_error_status",
- FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
+ FT_UINT32, BASE_HEX | BASE_RANGE_STRING, RVALS(rvals_command_status), 0x00,
"Cell Broadcast Message - Error Status", HFILL
}
},
@@ -3720,8 +3647,10 @@ proto_register_smpp(void)
&ett_opt_params,
&ett_opt_param,
&ett_dcs,
+ &ett_dcs_gsm_sms,
+ &ett_dcs_gsm_cbs,
};
- DebugLog(("Registering SMPP dissector\n"));
+
/* Register the protocol name and description */
proto_smpp = proto_register_protocol("Short Message Peer to Peer",
"SMPP", "smpp");
@@ -3764,7 +3693,6 @@ proto_reg_handoff_smpp(void)
heur_dissector_add("x.25", dissect_smpp_heur, "SMPP over X.25", "smpp_x25", proto_smpp, HEURISTIC_ENABLE);
/* Required for call_dissector() */
- DebugLog(("Finding gsm_sms_ud subdissector\n"));
gsm_sms_handle = find_dissector_add_dependency("gsm_sms_ud", proto_smpp);
DISSECTOR_ASSERT(gsm_sms_handle);