2001-12-03 20:18:29 +00:00
|
|
|
/* packet-smpp.c
|
|
|
|
* Routines for Short Message Peer to Peer dissection
|
2004-03-08 22:03:59 +00:00
|
|
|
* Copyright 2001, Tom Uijldert.
|
2001-12-03 20:18:29 +00:00
|
|
|
*
|
2003-09-04 18:59:21 +00:00
|
|
|
* Data Coding Scheme decoding for GSM (SMS and CBS),
|
2003-07-02 21:10:50 +00:00
|
|
|
* provided by Olivier Biot.
|
|
|
|
*
|
2004-01-18 00:07:03 +00:00
|
|
|
* Dissection of multiple SMPP PDUs within one packet
|
|
|
|
* provided by Chris Wilson.
|
|
|
|
*
|
2004-07-18 00:24:25 +00:00
|
|
|
* $Id$
|
2003-07-02 21:10:50 +00:00
|
|
|
*
|
2004-03-08 22:03:59 +00:00
|
|
|
* Refer to the AUTHORS file or the AUTHORS section in the man page
|
|
|
|
* for contacting the author(s) of this file.
|
2001-12-03 20:18:29 +00:00
|
|
|
*
|
|
|
|
* Ethereal - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@ethereal.com>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
* ----------
|
|
|
|
*
|
|
|
|
* Dissector of an SMPP (Short Message Peer to Peer) PDU, as defined by the
|
|
|
|
* SMS forum (www.smsforum.net) in "SMPP protocol specification v3.4"
|
|
|
|
* (document version: 12-Oct-1999 Issue 1.2)
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
#include <glib.h>
|
|
|
|
|
2002-01-21 07:37:49 +00:00
|
|
|
#include <epan/packet.h>
|
2001-12-03 20:18:29 +00:00
|
|
|
|
2004-09-27 22:55:15 +00:00
|
|
|
#include <epan/prefs.h>
|
2004-01-20 17:58:37 +00:00
|
|
|
#include "packet-tcp.h"
|
2003-07-02 21:10:50 +00:00
|
|
|
|
2003-12-23 12:07:14 +00:00
|
|
|
/* 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) \
|
|
|
|
printf("%s:%u: ", __FILE__, __LINE__); \
|
|
|
|
printf x; \
|
|
|
|
fflush(stdout)
|
|
|
|
#else
|
|
|
|
#define DebugLog(x) ;
|
|
|
|
#endif
|
|
|
|
|
2001-12-03 20:18:29 +00:00
|
|
|
/* Forward declarations */
|
2004-01-20 17:58:37 +00:00
|
|
|
static void dissect_smpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
|
|
|
|
static guint get_smpp_pdu_len(tvbuff_t *tvb, int offset);
|
|
|
|
static void dissect_smpp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
|
|
|
|
|
2001-12-03 20:18:29 +00:00
|
|
|
/*
|
|
|
|
* Initialize the protocol and registered fields
|
|
|
|
*
|
|
|
|
* Fixed header section
|
|
|
|
*/
|
|
|
|
static int proto_smpp = -1;
|
|
|
|
|
|
|
|
static int hf_smpp_command_id = -1;
|
|
|
|
static int hf_smpp_command_length = -1;
|
|
|
|
static int hf_smpp_command_status = -1;
|
|
|
|
static int hf_smpp_sequence_number = -1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Fixed body section
|
|
|
|
*/
|
|
|
|
static int hf_smpp_system_id = -1;
|
|
|
|
static int hf_smpp_password = -1;
|
|
|
|
static int hf_smpp_system_type = -1;
|
|
|
|
static int hf_smpp_interface_version = -1;
|
|
|
|
static int hf_smpp_addr_ton = -1;
|
|
|
|
static int hf_smpp_addr_npi = -1;
|
|
|
|
static int hf_smpp_address_range = -1;
|
|
|
|
static int hf_smpp_service_type = -1;
|
|
|
|
static int hf_smpp_source_addr_ton = -1;
|
|
|
|
static int hf_smpp_source_addr_npi = -1;
|
|
|
|
static int hf_smpp_source_addr = -1;
|
|
|
|
static int hf_smpp_dest_addr_ton = -1;
|
|
|
|
static int hf_smpp_dest_addr_npi = -1;
|
|
|
|
static int hf_smpp_destination_addr = -1;
|
|
|
|
static int hf_smpp_esm_submit_msg_mode = -1;
|
|
|
|
static int hf_smpp_esm_submit_msg_type = -1;
|
|
|
|
static int hf_smpp_esm_submit_features = -1;
|
|
|
|
static int hf_smpp_protocol_id = -1;
|
|
|
|
static int hf_smpp_priority_flag = -1;
|
|
|
|
static int hf_smpp_schedule_delivery_time = -1;
|
|
|
|
static int hf_smpp_schedule_delivery_time_r = -1;
|
|
|
|
static int hf_smpp_validity_period = -1;
|
|
|
|
static int hf_smpp_validity_period_r = -1;
|
|
|
|
static int hf_smpp_regdel_receipt = -1;
|
|
|
|
static int hf_smpp_regdel_acks = -1;
|
|
|
|
static int hf_smpp_regdel_notif = -1;
|
|
|
|
static int hf_smpp_replace_if_present_flag = -1;
|
|
|
|
static int hf_smpp_data_coding = -1;
|
|
|
|
static int hf_smpp_sm_default_msg_id = -1;
|
|
|
|
static int hf_smpp_sm_length = -1;
|
|
|
|
static int hf_smpp_short_message = -1;
|
|
|
|
static int hf_smpp_message_id = -1;
|
|
|
|
static int hf_smpp_dlist = -1;
|
|
|
|
static int hf_smpp_dlist_resp = -1;
|
|
|
|
static int hf_smpp_dl_name = -1;
|
|
|
|
static int hf_smpp_final_date = -1;
|
|
|
|
static int hf_smpp_final_date_r = -1;
|
|
|
|
static int hf_smpp_message_state = -1;
|
|
|
|
static int hf_smpp_error_code = -1;
|
|
|
|
static int hf_smpp_error_status_code = -1;
|
|
|
|
static int hf_smpp_esme_addr_ton = -1;
|
|
|
|
static int hf_smpp_esme_addr_npi = -1;
|
|
|
|
static int hf_smpp_esme_addr = -1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Optional parameter section
|
|
|
|
*/
|
|
|
|
static int hf_smpp_opt_param = -1;
|
|
|
|
static int hf_smpp_vendor_op = -1;
|
|
|
|
static int hf_smpp_reserved_op = -1;
|
|
|
|
|
|
|
|
static int hf_smpp_dest_addr_subunit = -1;
|
|
|
|
static int hf_smpp_dest_network_type = -1;
|
|
|
|
static int hf_smpp_dest_bearer_type = -1;
|
|
|
|
static int hf_smpp_dest_telematics_id = -1;
|
|
|
|
static int hf_smpp_source_addr_subunit = -1;
|
|
|
|
static int hf_smpp_source_network_type = -1;
|
|
|
|
static int hf_smpp_source_bearer_type = -1;
|
|
|
|
static int hf_smpp_source_telematics_id = -1;
|
|
|
|
static int hf_smpp_qos_time_to_live = -1;
|
|
|
|
static int hf_smpp_payload_type = -1;
|
|
|
|
static int hf_smpp_additional_status_info_text = -1;
|
|
|
|
static int hf_smpp_receipted_message_id = -1;
|
|
|
|
static int hf_smpp_msg_wait_ind = -1;
|
|
|
|
static int hf_smpp_msg_wait_type = -1;
|
|
|
|
static int hf_smpp_privacy_indicator = -1;
|
|
|
|
static int hf_smpp_source_subaddress = -1;
|
|
|
|
static int hf_smpp_dest_subaddress = -1;
|
|
|
|
static int hf_smpp_user_message_reference = -1;
|
|
|
|
static int hf_smpp_user_response_code = -1;
|
|
|
|
static int hf_smpp_source_port = -1;
|
|
|
|
static int hf_smpp_destination_port = -1;
|
|
|
|
static int hf_smpp_sar_msg_ref_num = -1;
|
|
|
|
static int hf_smpp_language_indicator = -1;
|
|
|
|
static int hf_smpp_sar_total_segments = -1;
|
|
|
|
static int hf_smpp_sar_segment_seqnum = -1;
|
|
|
|
static int hf_smpp_SC_interface_version = -1;
|
|
|
|
static int hf_smpp_callback_num_pres = -1;
|
|
|
|
static int hf_smpp_callback_num_scrn = -1;
|
|
|
|
static int hf_smpp_callback_num_atag = -1;
|
|
|
|
static int hf_smpp_number_of_messages = -1;
|
|
|
|
static int hf_smpp_callback_num = -1;
|
|
|
|
static int hf_smpp_dpf_result = -1;
|
|
|
|
static int hf_smpp_set_dpf = -1;
|
|
|
|
static int hf_smpp_ms_availability_status = -1;
|
|
|
|
static int hf_smpp_network_error_type = -1;
|
|
|
|
static int hf_smpp_network_error_code = -1;
|
|
|
|
static int hf_smpp_message_payload = -1;
|
|
|
|
static int hf_smpp_delivery_failure_reason = -1;
|
|
|
|
static int hf_smpp_more_messages_to_send = -1;
|
|
|
|
static int hf_smpp_ussd_service_op = -1;
|
|
|
|
static int hf_smpp_display_time = -1;
|
|
|
|
static int hf_smpp_sms_signal = -1;
|
|
|
|
static int hf_smpp_ms_validity = -1;
|
|
|
|
static int hf_smpp_alert_on_message_delivery = -1;
|
|
|
|
static int hf_smpp_its_reply_type = -1;
|
|
|
|
static int hf_smpp_its_session_number = -1;
|
|
|
|
static int hf_smpp_its_session_sequence = -1;
|
|
|
|
static int hf_smpp_its_session_ind = -1;
|
|
|
|
|
2003-08-23 02:15:53 +00:00
|
|
|
/*
|
|
|
|
* Data Coding Scheme section
|
|
|
|
*/
|
|
|
|
static int hf_smpp_dcs = -1;
|
|
|
|
static int hf_smpp_dcs_sms_coding_group = -1;
|
|
|
|
static int hf_smpp_dcs_text_compression = -1;
|
|
|
|
static int hf_smpp_dcs_class_present = -1;
|
|
|
|
static int hf_smpp_dcs_charset = -1;
|
|
|
|
static int hf_smpp_dcs_class = -1;
|
|
|
|
static int hf_smpp_dcs_cbs_coding_group = -1;
|
|
|
|
static int hf_smpp_dcs_cbs_language = -1;
|
|
|
|
static int hf_smpp_dcs_wap_charset = -1;
|
|
|
|
static int hf_smpp_dcs_wap_class = -1;
|
|
|
|
static int hf_smpp_dcs_cbs_class = -1;
|
|
|
|
|
2001-12-03 20:18:29 +00:00
|
|
|
/* Initialize the subtree pointers */
|
|
|
|
static gint ett_smpp = -1;
|
|
|
|
static gint ett_dlist = -1;
|
|
|
|
static gint ett_dlist_resp = -1;
|
|
|
|
static gint ett_opt_param = -1;
|
2004-01-18 00:07:03 +00:00
|
|
|
static gint ett_dcs = -1;
|
2003-07-02 21:10:50 +00:00
|
|
|
|
2004-01-20 17:58:37 +00:00
|
|
|
/* Reassemble SMPP TCP segments */
|
|
|
|
static gboolean reassemble_over_tcp = FALSE;
|
2003-07-02 21:10:50 +00:00
|
|
|
|
2001-12-03 20:18:29 +00:00
|
|
|
/*
|
|
|
|
* 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" },
|
|
|
|
{ 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 (expirey 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, "Delivery failure (used for data_sm_resp)" },
|
|
|
|
{ 0x000000FF, "Unknown error" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_addr_ton[] = {
|
|
|
|
{ 0, "Unknown" },
|
|
|
|
{ 1, "International" },
|
|
|
|
{ 2, "National" },
|
|
|
|
{ 3, "Network specific" },
|
|
|
|
{ 4, "Subscriber number" },
|
|
|
|
{ 5, "Alphanumeric" },
|
|
|
|
{ 6, "Abbreviated" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_addr_npi[] = {
|
|
|
|
{ 0, "Unknown" },
|
|
|
|
{ 1, "ISDN (E163/E164)" },
|
|
|
|
{ 3, "Data (X.121)" },
|
|
|
|
{ 4, "Telex (F.69)" },
|
|
|
|
{ 6, "Land mobile (E.212)" },
|
|
|
|
{ 8, "National" },
|
|
|
|
{ 9, "Private" },
|
|
|
|
{ 10, "ERMES" },
|
|
|
|
{ 14, "Internet (IP)" },
|
|
|
|
{ 18, "WAP client Id" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_esm_submit_msg_mode[] = {
|
|
|
|
{ 0x0, "Default SMSC mode" },
|
|
|
|
{ 0x1, "Datagram mode" },
|
|
|
|
{ 0x2, "Forward mode" },
|
|
|
|
{ 0x3, "Store and forward mode" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_esm_submit_msg_type[] = {
|
|
|
|
{ 0x0, "Default message type" },
|
|
|
|
{ 0x1, "Short message contains SMSC Delivery Receipt" },
|
|
|
|
{ 0x2, "Short message contains (E)SME delivery acknowledgement" },
|
|
|
|
{ 0x3, "Reserved" },
|
|
|
|
{ 0x4, "Short message contains (E)SME manual/user acknowledgement" },
|
|
|
|
{ 0x5, "Reserved" },
|
|
|
|
{ 0x6, "Short message contains conversation abort" },
|
|
|
|
{ 0x7, "Reserved" },
|
|
|
|
{ 0x8, "Short message contains intermediate delivery notification" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_esm_submit_features[] = {
|
|
|
|
{ 0x0, "No specific features selected" },
|
|
|
|
{ 0x1, "UDHI indicator" },
|
|
|
|
{ 0x2, "Reply path" },
|
|
|
|
{ 0x3, "UDHI and reply path" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_priority_flag[] = {
|
|
|
|
{ 0, "GSM: None ANSI-136: Bulk IS-95: Normal" },
|
|
|
|
{ 1, "GSM: priority ANSI-136: Normal IS-95: Interactive" },
|
|
|
|
{ 2, "GSM: priority ANSI-136: Urgent IS-95: Urgent" },
|
|
|
|
{ 3, "GSM: priority ANSI-136: Very Urgent IS-95: Emergency" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_regdel_receipt[] = {
|
|
|
|
{ 0x0, "No SMSC delivery receipt requested" },
|
|
|
|
{ 0x1, "Delivery receipt requested (for success or failure)" },
|
|
|
|
{ 0x2, "Delivery receipt requested (for failure)" },
|
|
|
|
{ 0x3, "Reserved" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_regdel_acks[] = {
|
|
|
|
{ 0x0, "No recipient SME acknowledgement requested" },
|
|
|
|
{ 0x1, "SME delivery acknowledgement requested" },
|
|
|
|
{ 0x2, "SME manual/user acknowledgement requested" },
|
|
|
|
{ 0x3, "Both delivery and manual/user acknowledgement requested" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_regdel_notif[] = {
|
|
|
|
{ 0x0, "No intermediate notification requested" },
|
|
|
|
{ 0x1, "Intermediate notification requested" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_replace_if_present_flag[] = {
|
|
|
|
{ 0x0, "Don't replace" },
|
|
|
|
{ 0x1, "Replace" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_data_coding[] = {
|
|
|
|
{ 0, "SMSC default alphabet" },
|
|
|
|
{ 1, "IA5 (CCITT T.50/ASCII (ANSI X3.4)" },
|
|
|
|
{ 2, "Octet unspecified (8-bit binary)" },
|
|
|
|
{ 3, "Latin 1 (ISO-8859-1)" },
|
|
|
|
{ 4, "Octet unspecified (8-bit binary)" },
|
|
|
|
{ 5, "JIS (X 0208-1990)" },
|
|
|
|
{ 6, "Cyrillic (ISO-8859-5)" },
|
|
|
|
{ 7, "Latin/Hebrew (ISO-8859-8)" },
|
|
|
|
{ 8, "UCS2 (ISO/IEC-10646)" },
|
|
|
|
{ 9, "Pictogram encoding" },
|
|
|
|
{ 10, "ISO-2022-JP (Music codes)" },
|
|
|
|
{ 11, "reserved" },
|
|
|
|
{ 12, "reserved" },
|
|
|
|
{ 13, "Extended Kanji JIS(X 0212-1990)" },
|
|
|
|
{ 14, "KS C 5601" },
|
|
|
|
/*! \todo Rest to be defined (bitmask?) according GSM 03.38 */
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_message_state[] = {
|
|
|
|
{ 1, "ENROUTE" },
|
|
|
|
{ 2, "DELIVERED" },
|
|
|
|
{ 3, "EXPIRED" },
|
|
|
|
{ 4, "DELETED" },
|
|
|
|
{ 5, "UNDELIVERABLE" },
|
|
|
|
{ 6, "ACCEPTED" },
|
|
|
|
{ 7, "UNKNOWN" },
|
|
|
|
{ 8, "REJECTED" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_addr_subunit[] = {
|
|
|
|
{ 0, "Unknown -default-" },
|
|
|
|
{ 1, "MS Display" },
|
|
|
|
{ 2, "Mobile equipment" },
|
|
|
|
{ 3, "Smart card 1" },
|
|
|
|
{ 4, "External unit 1" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_network_type[] = {
|
|
|
|
{ 0, "Unknown" },
|
|
|
|
{ 1, "GSM" },
|
|
|
|
{ 2, "ANSI-136/TDMA" },
|
|
|
|
{ 3, "IS-95/CDMA" },
|
|
|
|
{ 4, "PDC" },
|
|
|
|
{ 5, "PHS" },
|
|
|
|
{ 6, "iDEN" },
|
|
|
|
{ 7, "AMPS" },
|
|
|
|
{ 8, "Paging network" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_bearer_type[] = {
|
|
|
|
{ 0, "Unknown" },
|
|
|
|
{ 1, "SMS" },
|
|
|
|
{ 2, "Circuit Switched Data (CSD)" },
|
|
|
|
{ 3, "Packet data" },
|
|
|
|
{ 4, "USSD" },
|
|
|
|
{ 5, "CDPD" },
|
|
|
|
{ 6, "DataTAC" },
|
|
|
|
{ 7, "FLEX/ReFLEX" },
|
|
|
|
{ 8, "Cell Broadcast" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_payload_type[] = {
|
|
|
|
{ 0, "Default" },
|
|
|
|
{ 1, "WCMP message" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_privacy_indicator[] = {
|
|
|
|
{ 0, "Not restricted -default-" },
|
|
|
|
{ 1, "Restricted" },
|
|
|
|
{ 2, "Confidential" },
|
|
|
|
{ 3, "Secret" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_language_indicator[] = {
|
|
|
|
{ 0, "Unspecified -default-" },
|
|
|
|
{ 1, "english" },
|
|
|
|
{ 2, "french" },
|
|
|
|
{ 3, "spanish" },
|
|
|
|
{ 4, "german" },
|
|
|
|
{ 5, "portuguese" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_display_time[] = {
|
|
|
|
{ 0, "Temporary" },
|
|
|
|
{ 1, "Default -default-" },
|
|
|
|
{ 2, "Invoke" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_ms_validity[] = {
|
|
|
|
{ 0, "Store indefinitely -default-" },
|
|
|
|
{ 1, "Power down" },
|
|
|
|
{ 2, "SID based registration area" },
|
|
|
|
{ 3, "Display only" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_dpf_result[] = {
|
|
|
|
{ 0, "DPF not set" },
|
|
|
|
{ 1, "DPF set" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_set_dpf[] = {
|
|
|
|
{ 0, "Not requested (Set DPF for delivery failure)" },
|
|
|
|
{ 1, "Requested (Set DPF for delivery failure)" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_ms_availability_status[] = {
|
|
|
|
{ 0, "Available -default-" },
|
|
|
|
{ 1, "Denied" },
|
|
|
|
{ 2, "Unavailable" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_delivery_failure_reason[] = {
|
|
|
|
{ 0, "Destination unavailable" },
|
|
|
|
{ 1, "Destination address invalid" },
|
|
|
|
{ 2, "Permanent network error" },
|
|
|
|
{ 3, "Temporary network error" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_more_messages_to_send[] = {
|
|
|
|
{ 0, "No more messages" },
|
|
|
|
{ 1, "More messages -default-" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_its_reply_type[] = {
|
|
|
|
{ 0, "Digit" },
|
|
|
|
{ 1, "Number" },
|
|
|
|
{ 2, "Telephone no." },
|
|
|
|
{ 3, "Password" },
|
|
|
|
{ 4, "Character line" },
|
|
|
|
{ 5, "Menu" },
|
|
|
|
{ 6, "Date" },
|
|
|
|
{ 7, "Time" },
|
|
|
|
{ 8, "Continue" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_ussd_service_op[] = {
|
|
|
|
{ 0, "PSSD indication" },
|
|
|
|
{ 1, "PSSR indication" },
|
|
|
|
{ 2, "USSR request" },
|
|
|
|
{ 3, "USSN request" },
|
|
|
|
{ 16, "PSSD response" },
|
|
|
|
{ 17, "PSSR response" },
|
|
|
|
{ 18, "USSR confirm" },
|
|
|
|
{ 19, "USSN confirm" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_msg_wait_ind[] = {
|
|
|
|
{ 0, "Set indication inactive" },
|
|
|
|
{ 1, "Set indication active" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_msg_wait_type[] = {
|
|
|
|
{ 0, "Voicemail message waiting" },
|
|
|
|
{ 1, "Fax message waiting" },
|
|
|
|
{ 2, "Electronic mail message waiting" },
|
|
|
|
{ 3, "Other message waiting" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_callback_num_pres[] = {
|
|
|
|
{ 0, "Presentation allowed" },
|
|
|
|
{ 1, "Presentation restricted" },
|
|
|
|
{ 2, "Number not available" },
|
|
|
|
{ 3, "[Reserved]" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_callback_num_scrn[] = {
|
|
|
|
{ 0, "User provided, not screened" },
|
|
|
|
{ 1, "User provided, verified and passed" },
|
|
|
|
{ 2, "User provided, verified and failed" },
|
|
|
|
{ 3, "Network provided" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_network_error_type[] = {
|
|
|
|
{ 1, "ANSI-136" },
|
|
|
|
{ 2, "IS-95" },
|
|
|
|
{ 3, "GSM" },
|
|
|
|
{ 4, "[Reserved]" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_its_session_ind[] = {
|
|
|
|
{ 0, "End of session indicator inactive" },
|
|
|
|
{ 1, "End of session indicator active" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
2003-08-23 02:15:53 +00:00
|
|
|
/* Data Coding Scheme: see 3GPP TS 23.040 and 3GPP TS 23.038 */
|
|
|
|
static const value_string vals_dcs_sms_coding_group[] = {
|
|
|
|
{ 0x00, "SMS DCS: General Data Coding indication - Uncompressed text, no message class" },
|
|
|
|
{ 0x01, "SMS DCS: General Data Coding indication - Uncompressed text" },
|
|
|
|
{ 0x02, "SMS DCS: General Data Coding indication - Compressed text, no message class" },
|
|
|
|
{ 0x03, "SMS DCS: General Data Coding indication - Compressed text" },
|
|
|
|
{ 0x04, "SMS DCS: Message Marked for Automatic Deletion - Uncompressed text, no message class" },
|
|
|
|
{ 0x05, "SMS DCS: Message Marked for Automatic Deletion - Uncompressed text" },
|
|
|
|
{ 0x06, "SMS DCS: Message Marked for Automatic Deletion - Compressed text, no message class" },
|
|
|
|
{ 0x07, "SMS DCS: Message Marked for Automatic Deletion - Compressed text" },
|
|
|
|
{ 0x08, "SMS DCS: Reserved" },
|
|
|
|
{ 0x09, "SMS DCS: Reserved" },
|
|
|
|
{ 0x0A, "SMS DCS: Reserved" },
|
|
|
|
{ 0x0B, "SMS DCS: Reserved" },
|
|
|
|
{ 0x0C, "SMS DCS: Message Waiting Indication - Discard Message" },
|
|
|
|
{ 0x0D, "SMS DCS: Message Waiting Indication - Store Message (GSM 7-bit default alphabet)" },
|
|
|
|
{ 0x0E, "SMS DCS: Message Waiting Indication - Store Message (UCS-2 character set)" },
|
|
|
|
{ 0x0F, "SMS DCS: Data coding / message class" },
|
|
|
|
{ 0x00, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string tfs_dcs_text_compression = {
|
|
|
|
"Compressed text",
|
|
|
|
"Uncompressed text"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string tfs_dcs_class_present = {
|
|
|
|
"Message class is present",
|
|
|
|
"No message class"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_dcs_charset[] = {
|
|
|
|
{ 0x00, "GSM 7-bit default alphabet" },
|
|
|
|
{ 0x01, "8-bit data" },
|
|
|
|
{ 0x02, "UCS-2 (16-bit) data" },
|
|
|
|
{ 0x03, "Reserved" },
|
|
|
|
{ 0x00, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_dcs_class[] = {
|
|
|
|
{ 0x00, "Class 0" },
|
|
|
|
{ 0x01, "Class 1 - ME specific" },
|
|
|
|
{ 0x02, "Class 2 - (U)SIM specific" },
|
|
|
|
{ 0x03, "Class 3 - TE specific" },
|
|
|
|
{ 0x00, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_dcs_cbs_coding_group[] = {
|
|
|
|
{ 0x00, "CBS DCS: Language using the GSM 7-bit default alphabet" },
|
|
|
|
{ 0x01, "CBS DCS: Language indication at beginning of message" },
|
|
|
|
{ 0x02, "CBS DCS: Language using the GSM 7-bit default alphabet" },
|
|
|
|
{ 0x03, "CBS DCS: Reserved" },
|
|
|
|
{ 0x04, "CBS DCS: General Data Coding indication - Uncompressed text, no message class" },
|
|
|
|
{ 0x05, "CBS DCS: General Data Coding indication - Uncompressed text" },
|
|
|
|
{ 0x06, "CBS DCS: General Data Coding indication - Compressed text, no message class" },
|
|
|
|
{ 0x07, "CBS DCS: General Data Coding indication - Compressed text" },
|
|
|
|
{ 0x08, "CBS DCS: Reserved" },
|
|
|
|
{ 0x09, "CBS DCS: Message with User Data Header structure" },
|
|
|
|
{ 0x0A, "CBS DCS: Reserved" },
|
|
|
|
{ 0x0B, "CBS DCS: Reserved" },
|
|
|
|
{ 0x0C, "CBS DCS: Reserved" },
|
|
|
|
{ 0x0D, "CBS DCS: Reserved" },
|
|
|
|
{ 0x0E, "CBS DCS: Defined by the WAP Forum" },
|
|
|
|
{ 0x0F, "SMS DCS: Data coding / message class" },
|
|
|
|
{ 0x00, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_dcs_cbs_language[] = {
|
|
|
|
{ 0x00, "German" },
|
|
|
|
{ 0x01, "English" },
|
|
|
|
{ 0x02, "Italian" },
|
|
|
|
{ 0x03, "French" },
|
|
|
|
{ 0x04, "Spanish" },
|
|
|
|
{ 0x05, "Dutch" },
|
|
|
|
{ 0x06, "Swedish" },
|
|
|
|
{ 0x07, "Danish" },
|
|
|
|
{ 0x08, "Portuguese" },
|
|
|
|
{ 0x09, "Finnish" },
|
|
|
|
{ 0x0A, "Norwegian" },
|
|
|
|
{ 0x0B, "Greek" },
|
|
|
|
{ 0x0C, "Turkish" },
|
|
|
|
{ 0x0D, "Hungarian" },
|
|
|
|
{ 0x0E, "Polish" },
|
|
|
|
{ 0x0F, "Language not specified" },
|
|
|
|
{ 0x10, "GSM 7-bit default alphabet - message preceeded by language indication" },
|
|
|
|
{ 0x11, "UCS-2 (16-bit) - message preceeded by language indication" },
|
|
|
|
{ 0x20, "Czech" },
|
|
|
|
{ 0x21, "Hebrew" },
|
|
|
|
{ 0x22, "Arabic" },
|
|
|
|
{ 0x23, "Russian" },
|
|
|
|
{ 0x24, "Icelandic" },
|
|
|
|
{ 0x00, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_dcs_cbs_class[] = {
|
|
|
|
{ 0x00, "No message class" },
|
|
|
|
{ 0x01, "Class 1 - User defined" },
|
|
|
|
{ 0x02, "Class 2 - User defined" },
|
|
|
|
{ 0x03, "Class 3 - TE specific" },
|
|
|
|
{ 0x00, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_dcs_wap_class[] = {
|
|
|
|
{ 0x00, "No message class" },
|
|
|
|
{ 0x01, "Class 1 - ME specific" },
|
|
|
|
{ 0x02, "Class 2 - (U)SIM specific" },
|
|
|
|
{ 0x03, "Class 3 - TE specific" },
|
|
|
|
{ 0x00, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string vals_dcs_wap_charset[] = {
|
|
|
|
{ 0x00, "Reserved" },
|
|
|
|
{ 0x01, "8-bit data" },
|
|
|
|
{ 0x02, "Reserved" },
|
|
|
|
{ 0x03, "Reserved" },
|
|
|
|
{ 0x00, NULL }
|
|
|
|
};
|
|
|
|
|
2004-01-27 00:20:37 +00:00
|
|
|
static dissector_handle_t gsm_sms_handle;
|
2003-08-23 02:15:53 +00:00
|
|
|
|
2001-12-03 20:18:29 +00:00
|
|
|
/*!
|
|
|
|
* SMPP equivalent of mktime() (3). Convert date to standard 'time_t' format
|
|
|
|
*
|
|
|
|
* \param datestr The SMPP-formatted date to convert
|
|
|
|
* \param secs Returns the 'time_t' equivalent
|
|
|
|
* \param nsecs Returns the additional nano-seconds
|
|
|
|
*
|
|
|
|
* \return Whether time is specified relative or absolute
|
|
|
|
* \retval TRUE Relative time
|
|
|
|
* \retval FALSE Absolute time
|
|
|
|
*/
|
|
|
|
static gboolean
|
Add new routines:
tvb_get_string() - takes a tvbuff, an offset, and a length as
arguments, allocates a buffer big enough to hold a string with
the specified number of bytes plus an added null terminator
(i.e., length+1), copies the specified number of bytes from the
tvbuff, at the specified offset, to that buffer and puts in a
null terminator, and returns a pointer to that buffer (or throws
an exception before allocating the buffer if that many bytes
aren't available in the tvbuff);
tvb_get_stringz() - takes a tvbuff, an offset, and a pointer to
a "gint" as arguments, gets the size of the null-terminated
string starting at the specified offset in the tvbuff (throwing
an exception if the null terminator isn't found), allocates a
buffer big enough to hold that string, copies the string to that
buffer, and returns a pointer to that buffer and stores the
length of the string (including the terminating null) in the
variable pointed to by the "gint" pointer.
Replace many pieces of code allocating a buffer and copying a string
with calls to "tvb_get_string()" (for one thing, "tvb_get_string()"
doesn't require you to remember that the argument to
"tvb_get_nstringz0()" is the size of the buffer into which you're
copying the string, which might be the length of the string to be copied
*plus 1*).
Don't use fixed-length buffers for null-terminated strings (even if the
code that generates those packets has a #define to limit the length of
the string). Use "tvb_get_stringz()", instead.
In some cases where a value is fetched but is only used to pass an
argument to a "proto_tree_add_XXX" routine, use "proto_tree_add_item()"
instead.
svn path=/trunk/; revision=7859
2003-06-12 08:33:32 +00:00
|
|
|
smpp_mktime(const char *datestr, time_t *secs, int *nsecs)
|
2001-12-03 20:18:29 +00:00
|
|
|
{
|
|
|
|
struct tm r_time;
|
|
|
|
time_t t_diff;
|
|
|
|
gboolean relative = FALSE;
|
|
|
|
|
|
|
|
r_time.tm_year = 10 * (datestr[0] - '0') + (datestr[1] - '0');
|
|
|
|
/*
|
|
|
|
* Y2K rollover date as recommended in appendix C
|
|
|
|
*/
|
|
|
|
if (r_time.tm_year < 38)
|
|
|
|
r_time.tm_year += 100;
|
|
|
|
r_time.tm_mon = 10 * (datestr[2] - '0') + (datestr[3] - '0');
|
|
|
|
r_time.tm_mon--;
|
|
|
|
r_time.tm_mday = 10 * (datestr[4] - '0') + (datestr[5] - '0');
|
|
|
|
r_time.tm_hour = 10 * (datestr[6] - '0') + (datestr[7] - '0');
|
|
|
|
r_time.tm_min = 10 * (datestr[8] - '0') + (datestr[9] - '0');
|
|
|
|
r_time.tm_sec = 10 * (datestr[10] - '0') + (datestr[11] - '0');
|
2002-03-10 01:02:06 +00:00
|
|
|
r_time.tm_isdst = -1;
|
2001-12-03 20:18:29 +00:00
|
|
|
*secs = mktime(&r_time);
|
|
|
|
*nsecs = (datestr[12] - '0') * 100000000;
|
|
|
|
t_diff = (10 * (datestr[13] - '0') + (datestr[14] - '0')) * 900;
|
|
|
|
if (datestr[15] == '+')
|
|
|
|
*secs += t_diff;
|
|
|
|
else if (datestr[15] == '-')
|
|
|
|
*secs -= t_diff;
|
|
|
|
else /* Must be relative ('R') */
|
|
|
|
relative = TRUE;
|
|
|
|
return relative;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* Scanning routines to add standard types (byte, int, string...) to the
|
|
|
|
* protocol tree.
|
|
|
|
*
|
|
|
|
* \param tree The protocol tree to add to
|
|
|
|
* \param tvb Buffer containing the data
|
|
|
|
* \param field Actual field whose value needs displaying
|
|
|
|
* \param offset Location of field in buffer, returns location of
|
|
|
|
* next field
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
smpp_handle_string(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
|
|
|
|
{
|
Add new routines:
tvb_get_string() - takes a tvbuff, an offset, and a length as
arguments, allocates a buffer big enough to hold a string with
the specified number of bytes plus an added null terminator
(i.e., length+1), copies the specified number of bytes from the
tvbuff, at the specified offset, to that buffer and puts in a
null terminator, and returns a pointer to that buffer (or throws
an exception before allocating the buffer if that many bytes
aren't available in the tvbuff);
tvb_get_stringz() - takes a tvbuff, an offset, and a pointer to
a "gint" as arguments, gets the size of the null-terminated
string starting at the specified offset in the tvbuff (throwing
an exception if the null terminator isn't found), allocates a
buffer big enough to hold that string, copies the string to that
buffer, and returns a pointer to that buffer and stores the
length of the string (including the terminating null) in the
variable pointed to by the "gint" pointer.
Replace many pieces of code allocating a buffer and copying a string
with calls to "tvb_get_string()" (for one thing, "tvb_get_string()"
doesn't require you to remember that the argument to
"tvb_get_nstringz0()" is the size of the buffer into which you're
copying the string, which might be the length of the string to be copied
*plus 1*).
Don't use fixed-length buffers for null-terminated strings (even if the
code that generates those packets has a #define to limit the length of
the string). Use "tvb_get_stringz()", instead.
In some cases where a value is fetched but is only used to pass an
argument to a "proto_tree_add_XXX" routine, use "proto_tree_add_item()"
instead.
svn path=/trunk/; revision=7859
2003-06-12 08:33:32 +00:00
|
|
|
guint len;
|
2001-12-03 20:18:29 +00:00
|
|
|
|
2003-06-06 01:56:39 +00:00
|
|
|
len = tvb_strsize(tvb, *offset);
|
|
|
|
if (len > 1) {
|
|
|
|
proto_tree_add_string(tree, field, tvb, *offset, len,
|
2004-01-18 00:07:03 +00:00
|
|
|
(const char *) tvb_get_ptr(tvb, *offset, len));
|
2003-06-06 01:56:39 +00:00
|
|
|
}
|
2001-12-03 20:18:29 +00:00
|
|
|
(*offset) += len;
|
|
|
|
}
|
|
|
|
|
2003-12-23 12:07:14 +00:00
|
|
|
/* NOTE - caller must free the returned string! */
|
|
|
|
static char *
|
|
|
|
smpp_handle_string_return(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
|
|
|
|
{
|
2004-01-18 00:07:03 +00:00
|
|
|
gint len;
|
|
|
|
char *str;
|
2003-12-23 12:07:14 +00:00
|
|
|
|
|
|
|
len = tvb_strsize(tvb, *offset);
|
|
|
|
if (len > 1) {
|
2005-08-11 07:44:38 +00:00
|
|
|
str = (char *)tvb_get_ephemeral_stringz(tvb, *offset, &len);
|
2004-01-18 00:07:03 +00:00
|
|
|
proto_tree_add_string(tree, field, tvb, *offset, len, str);
|
2003-12-23 12:07:14 +00:00
|
|
|
} else {
|
2005-08-11 07:44:38 +00:00
|
|
|
str = "";
|
2004-01-18 00:07:03 +00:00
|
|
|
}
|
2003-12-23 12:07:14 +00:00
|
|
|
(*offset) += len;
|
2004-01-18 00:07:03 +00:00
|
|
|
return str;
|
2003-12-23 12:07:14 +00:00
|
|
|
}
|
|
|
|
|
2003-08-23 02:15:53 +00:00
|
|
|
static void
|
|
|
|
smpp_handle_string_z(proto_tree *tree, tvbuff_t *tvb, int field, int *offset,
|
|
|
|
const char *null_string)
|
|
|
|
{
|
2004-01-18 00:07:03 +00:00
|
|
|
gint len;
|
2003-08-23 02:15:53 +00:00
|
|
|
|
|
|
|
len = tvb_strsize(tvb, *offset);
|
|
|
|
if (len > 1) {
|
2004-01-18 00:07:03 +00:00
|
|
|
proto_tree_add_string(tree, field, tvb, *offset, len,
|
|
|
|
(const char *)tvb_get_ptr(tvb, *offset, len));
|
2003-08-23 02:15:53 +00:00
|
|
|
} else {
|
2004-01-18 00:07:03 +00:00
|
|
|
proto_tree_add_string(tree, field, tvb, *offset, len, null_string);
|
|
|
|
}
|
2003-08-23 02:15:53 +00:00
|
|
|
(*offset) += len;
|
|
|
|
}
|
|
|
|
|
2001-12-03 20:18:29 +00:00
|
|
|
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)
|
|
|
|
{
|
Add new routines:
tvb_get_string() - takes a tvbuff, an offset, and a length as
arguments, allocates a buffer big enough to hold a string with
the specified number of bytes plus an added null terminator
(i.e., length+1), copies the specified number of bytes from the
tvbuff, at the specified offset, to that buffer and puts in a
null terminator, and returns a pointer to that buffer (or throws
an exception before allocating the buffer if that many bytes
aren't available in the tvbuff);
tvb_get_stringz() - takes a tvbuff, an offset, and a pointer to
a "gint" as arguments, gets the size of the null-terminated
string starting at the specified offset in the tvbuff (throwing
an exception if the null terminator isn't found), allocates a
buffer big enough to hold that string, copies the string to that
buffer, and returns a pointer to that buffer and stores the
length of the string (including the terminating null) in the
variable pointed to by the "gint" pointer.
Replace many pieces of code allocating a buffer and copying a string
with calls to "tvb_get_string()" (for one thing, "tvb_get_string()"
doesn't require you to remember that the argument to
"tvb_get_nstringz0()" is the size of the buffer into which you're
copying the string, which might be the length of the string to be copied
*plus 1*).
Don't use fixed-length buffers for null-terminated strings (even if the
code that generates those packets has a #define to limit the length of
the string). Use "tvb_get_stringz()", instead.
In some cases where a value is fetched but is only used to pass an
argument to a "proto_tree_add_XXX" routine, use "proto_tree_add_item()"
instead.
svn path=/trunk/; revision=7859
2003-06-12 08:33:32 +00:00
|
|
|
char *strval;
|
2001-12-03 20:18:29 +00:00
|
|
|
gint len;
|
|
|
|
nstime_t tmptime;
|
|
|
|
|
2005-08-11 07:44:38 +00:00
|
|
|
strval = (char *) tvb_get_ephemeral_stringz(tvb, *offset, &len);
|
2001-12-03 20:18:29 +00:00
|
|
|
if (*strval)
|
|
|
|
{
|
|
|
|
if (smpp_mktime(strval, &tmptime.secs, &tmptime.nsecs))
|
|
|
|
proto_tree_add_time(tree, field_R, tvb, *offset, len, &tmptime);
|
|
|
|
else
|
|
|
|
proto_tree_add_time(tree, field, tvb, *offset, len, &tmptime);
|
|
|
|
}
|
|
|
|
*offset += len;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* Scanning routine to handle the destination-list of 'submit_multi'
|
|
|
|
*
|
|
|
|
* \param tree The protocol tree to add to
|
|
|
|
* \param tvb Buffer containing the data
|
|
|
|
* \param offset Location of field in buffer, returns location of
|
|
|
|
* next field
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
smpp_handle_dlist(proto_tree *tree, tvbuff_t *tvb, int *offset)
|
|
|
|
{
|
|
|
|
guint8 entries;
|
|
|
|
int tmpoff = *offset;
|
|
|
|
proto_item *sub_tree = NULL;
|
|
|
|
guint8 dest_flag;
|
|
|
|
|
|
|
|
if ((entries = tvb_get_guint8(tvb, tmpoff++)))
|
|
|
|
{
|
|
|
|
sub_tree = proto_tree_add_item(tree, hf_smpp_dlist,
|
|
|
|
tvb, *offset, 1, FALSE);
|
|
|
|
proto_item_add_subtree(sub_tree, ett_dlist);
|
|
|
|
}
|
|
|
|
while (entries--)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
smpp_handle_string(sub_tree,tvb,hf_smpp_destination_addr,&tmpoff);
|
|
|
|
}
|
|
|
|
else /* Distribution list */
|
|
|
|
{
|
|
|
|
smpp_handle_string(sub_tree, tvb, hf_smpp_dl_name, &tmpoff);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*offset = tmpoff;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* Scanning routine to handle the destination result list
|
|
|
|
* of 'submit_multi_resp'
|
|
|
|
*
|
|
|
|
* \param tree The protocol tree to add to
|
|
|
|
* \param tvb Buffer containing the data
|
|
|
|
* \param offset Location of field in buffer, returns location of
|
|
|
|
* next field
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
smpp_handle_dlist_resp(proto_tree *tree, tvbuff_t *tvb, int *offset)
|
|
|
|
{
|
|
|
|
guint8 entries;
|
|
|
|
int tmpoff = *offset;
|
|
|
|
proto_item *sub_tree = NULL;
|
|
|
|
|
|
|
|
if ((entries = tvb_get_guint8(tvb, tmpoff++)))
|
|
|
|
{
|
|
|
|
sub_tree = proto_tree_add_item(tree, hf_smpp_dlist_resp,
|
|
|
|
tvb, *offset, 1, FALSE);
|
|
|
|
proto_item_add_subtree(sub_tree, ett_dlist_resp);
|
|
|
|
}
|
|
|
|
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);
|
|
|
|
smpp_handle_string(sub_tree,tvb,hf_smpp_destination_addr,&tmpoff);
|
|
|
|
smpp_handle_int4(sub_tree, tvb, hf_smpp_error_status_code, &tmpoff);
|
|
|
|
}
|
|
|
|
*offset = tmpoff;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* Scanning routine to handle all optional parameters of SMPP-operations.
|
|
|
|
* The parameters have the format Tag Length Value (TLV), with a 2-byte tag
|
|
|
|
* and 2-byte length.
|
|
|
|
*
|
|
|
|
* \param tree The protocol tree to add to
|
|
|
|
* \param tvb Buffer containing the data
|
|
|
|
* \param offset Location of field in buffer, returns location of
|
|
|
|
* next field
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
|
|
|
|
{
|
|
|
|
proto_item *sub_tree = NULL;
|
|
|
|
guint tag;
|
|
|
|
guint length;
|
|
|
|
guint8 field;
|
|
|
|
guint8 major, minor;
|
|
|
|
char strval[BUFSIZ];
|
|
|
|
|
|
|
|
if (tvb_reported_length_remaining(tvb, *offset) >= 4)
|
|
|
|
{
|
|
|
|
sub_tree = proto_tree_add_item(tree, hf_smpp_opt_param,
|
|
|
|
tvb, *offset, 0, FALSE);
|
|
|
|
proto_item_add_subtree(sub_tree, ett_opt_param);
|
|
|
|
}
|
|
|
|
|
|
|
|
while (tvb_reported_length_remaining(tvb, *offset) >= 4)
|
|
|
|
{
|
|
|
|
tag = tvb_get_ntohs(tvb, *offset);
|
|
|
|
*offset += 2;
|
|
|
|
length = tvb_get_ntohs(tvb, *offset);
|
|
|
|
*offset += 2;
|
|
|
|
switch (tag) {
|
|
|
|
case 0x0005: /* dest_addr_subunit */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_dest_addr_subunit, offset);
|
|
|
|
break;
|
|
|
|
case 0x0006: /* dest_network_type */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_dest_network_type, offset);
|
|
|
|
break;
|
|
|
|
case 0x0007: /* dest_bearer_type */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_dest_bearer_type, offset);
|
|
|
|
break;
|
|
|
|
case 0x0008: /* dest_telematics_id */
|
|
|
|
smpp_handle_int2(sub_tree, tvb,
|
|
|
|
hf_smpp_dest_telematics_id, offset);
|
|
|
|
break;
|
|
|
|
case 0x000D: /* source_addr_subunit */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_source_addr_subunit, offset);
|
|
|
|
break;
|
|
|
|
case 0x000E: /* source_network_type */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_source_network_type, offset);
|
|
|
|
break;
|
|
|
|
case 0x000F: /* source_bearer_type */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_source_bearer_type, offset);
|
|
|
|
break;
|
|
|
|
case 0x0010: /* source_telematics_id */
|
|
|
|
smpp_handle_int2(sub_tree, tvb,
|
|
|
|
hf_smpp_source_telematics_id, offset);
|
|
|
|
break;
|
|
|
|
case 0x0017: /* qos_time_to_live */
|
|
|
|
smpp_handle_int4(sub_tree, tvb,
|
|
|
|
hf_smpp_qos_time_to_live, offset);
|
|
|
|
break;
|
|
|
|
case 0x0019: /* payload_type */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_payload_type, offset);
|
|
|
|
break;
|
|
|
|
case 0x001D: /* additional_status_info_text */
|
|
|
|
smpp_handle_string(sub_tree, tvb,
|
|
|
|
hf_smpp_additional_status_info_text, offset);
|
|
|
|
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_item(sub_tree, hf_smpp_msg_wait_ind,
|
|
|
|
tvb, *offset, 1, field);
|
|
|
|
proto_tree_add_item(sub_tree, hf_smpp_msg_wait_type,
|
|
|
|
tvb, *offset, 1, field);
|
|
|
|
(*offset)++;
|
|
|
|
break;
|
|
|
|
case 0x0201: /* privacy_indicator */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_privacy_indicator, offset);
|
|
|
|
break;
|
|
|
|
case 0x0202: /* source_subaddress */
|
|
|
|
smpp_handle_string(sub_tree, tvb,
|
|
|
|
hf_smpp_source_subaddress, offset);
|
|
|
|
break;
|
|
|
|
case 0x0203: /* dest_subaddress */
|
|
|
|
smpp_handle_string(sub_tree, tvb,
|
|
|
|
hf_smpp_dest_subaddress, offset);
|
|
|
|
break;
|
|
|
|
case 0x0204: /* user_message_reference */
|
|
|
|
smpp_handle_int2(sub_tree, tvb,
|
|
|
|
hf_smpp_user_message_reference, offset);
|
|
|
|
break;
|
|
|
|
case 0x0205: /* user_response_code */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_user_response_code, offset);
|
|
|
|
break;
|
|
|
|
case 0x020A: /* source_port */
|
|
|
|
smpp_handle_int2(sub_tree, tvb,
|
|
|
|
hf_smpp_source_port, offset);
|
|
|
|
break;
|
|
|
|
case 0x020B: /* destination_port */
|
|
|
|
smpp_handle_int2(sub_tree, tvb,
|
|
|
|
hf_smpp_destination_port, offset);
|
|
|
|
break;
|
|
|
|
case 0x020C: /* sar_msg_ref_num */
|
|
|
|
smpp_handle_int2(sub_tree, tvb,
|
|
|
|
hf_smpp_sar_msg_ref_num, offset);
|
|
|
|
break;
|
|
|
|
case 0x020D: /* language_indicator */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_language_indicator, offset);
|
|
|
|
break;
|
|
|
|
case 0x020E: /* sar_total_segments */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_sar_total_segments, offset);
|
|
|
|
break;
|
|
|
|
case 0x020F: /* sar_segment_seqnum */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_sar_segment_seqnum, offset);
|
|
|
|
break;
|
|
|
|
case 0x0210: /* SC_interface_version */
|
|
|
|
field = tvb_get_guint8(tvb, *offset);
|
|
|
|
minor = field & 0x0F;
|
|
|
|
major = (field & 0xF0) >> 4;
|
2003-07-02 21:10:50 +00:00
|
|
|
sprintf(strval, "%u.%u", major, minor);
|
2001-12-03 20:18:29 +00:00
|
|
|
proto_tree_add_string(sub_tree, hf_smpp_SC_interface_version,
|
|
|
|
tvb, *offset, 1, strval);
|
|
|
|
(*offset)++;
|
|
|
|
break;
|
|
|
|
case 0x0302: /* callback_num_pres_ind */
|
|
|
|
field = tvb_get_guint8(tvb, *offset);
|
|
|
|
proto_tree_add_item(sub_tree, hf_smpp_callback_num_pres,
|
|
|
|
tvb, *offset, 1, field);
|
|
|
|
proto_tree_add_item(sub_tree, hf_smpp_callback_num_scrn,
|
|
|
|
tvb, *offset, 1, field);
|
|
|
|
(*offset)++;
|
|
|
|
break;
|
|
|
|
case 0x0303: /* callback_num_atag */
|
|
|
|
if (length)
|
|
|
|
proto_tree_add_item(sub_tree, hf_smpp_callback_num_atag,
|
|
|
|
tvb, *offset, length, FALSE);
|
|
|
|
(*offset) += length;
|
|
|
|
break;
|
|
|
|
case 0x0304: /* number_of_messages */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_number_of_messages, offset);
|
|
|
|
break;
|
|
|
|
case 0x0381: /* callback_num */
|
|
|
|
if (length)
|
|
|
|
proto_tree_add_item(sub_tree, hf_smpp_callback_num,
|
|
|
|
tvb, *offset, length, FALSE);
|
|
|
|
(*offset) += length;
|
|
|
|
break;
|
|
|
|
case 0x0420: /* dpf_result */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_dpf_result, offset);
|
|
|
|
break;
|
|
|
|
case 0x0421: /* set_dpf */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_set_dpf, offset);
|
|
|
|
break;
|
|
|
|
case 0x0422: /* ms_availability_status */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_ms_availability_status, offset);
|
|
|
|
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);
|
|
|
|
(*offset) += length;
|
|
|
|
break;
|
|
|
|
case 0x0424: /* message_payload */
|
|
|
|
if (length)
|
|
|
|
proto_tree_add_item(sub_tree, hf_smpp_message_payload,
|
|
|
|
tvb, *offset, length, FALSE);
|
|
|
|
(*offset) += length;
|
|
|
|
break;
|
|
|
|
case 0x0425: /* delivery_failure_reason */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_delivery_failure_reason, offset);
|
|
|
|
break;
|
|
|
|
case 0x0426: /* more_messages_to_send */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_more_messages_to_send, offset);
|
|
|
|
break;
|
|
|
|
case 0x0427: /* message_state */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_message_state, offset);
|
|
|
|
break;
|
|
|
|
case 0x0501: /* ussd_service_op */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_ussd_service_op, offset);
|
|
|
|
break;
|
|
|
|
case 0x1201: /* display_time */
|
|
|
|
smpp_handle_int1(sub_tree, tvb,
|
|
|
|
hf_smpp_display_time, offset);
|
|
|
|
break;
|
|
|
|
case 0x1203: /* sms_signal */
|
|
|
|
smpp_handle_int2(sub_tree, tvb,
|
|
|
|
hf_smpp_sms_signal, offset);
|
|
|
|
/*! \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);
|
|
|
|
break;
|
|
|
|
case 0x130C: /* alert_on_message_delivery */
|
|
|
|
proto_tree_add_item(sub_tree,
|
|
|
|
hf_smpp_alert_on_message_delivery,
|
|
|
|
tvb, *offset, length, FALSE);
|
|
|
|
(*offset) += length;
|
|
|
|
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_item(sub_tree, hf_smpp_its_session_sequence,
|
|
|
|
tvb, *offset, 1, field);
|
|
|
|
proto_tree_add_item(sub_tree, hf_smpp_its_session_ind,
|
|
|
|
tvb, *offset, 1, field);
|
|
|
|
(*offset)++;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if ((tag >= 0x1400) && (tag <= 0x3FFF))
|
|
|
|
proto_tree_add_item(sub_tree, hf_smpp_vendor_op, tvb,
|
|
|
|
*offset, length, FALSE);
|
|
|
|
else
|
|
|
|
proto_tree_add_item(sub_tree, hf_smpp_reserved_op, tvb,
|
|
|
|
*offset, length, FALSE);
|
|
|
|
(*offset) += length;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-08-23 02:15:53 +00:00
|
|
|
static void
|
|
|
|
smpp_handle_dcs(proto_tree *tree, tvbuff_t *tvb, int *offset)
|
|
|
|
{
|
|
|
|
guint8 val;
|
|
|
|
int off = *offset;
|
|
|
|
proto_item *subtree = NULL;
|
|
|
|
|
|
|
|
val = tvb_get_guint8(tvb, off);
|
|
|
|
subtree = proto_tree_add_uint(tree,
|
|
|
|
hf_smpp_data_coding, tvb, off, 1, val);
|
|
|
|
proto_item_add_subtree(subtree, ett_dcs);
|
|
|
|
/* SMPP Data Coding Scheme */
|
|
|
|
proto_tree_add_uint(subtree, hf_smpp_dcs, tvb, off, 1, val);
|
|
|
|
/* GSM SMS Data Coding Scheme */
|
|
|
|
proto_tree_add_text(subtree, tvb, off, 1,
|
|
|
|
"GSM SMS Data Coding");
|
|
|
|
proto_tree_add_uint(subtree,
|
|
|
|
hf_smpp_dcs_sms_coding_group, tvb, off, 1, val);
|
|
|
|
if (val>>6 == 2) { /* Reserved */
|
|
|
|
;
|
|
|
|
} else if (val < 0xF0) {
|
|
|
|
proto_tree_add_boolean(subtree,
|
|
|
|
hf_smpp_dcs_text_compression, tvb, off, 1, val);
|
|
|
|
proto_tree_add_boolean(subtree,
|
|
|
|
hf_smpp_dcs_class_present, tvb, off, 1, val);
|
|
|
|
proto_tree_add_uint(subtree,
|
|
|
|
hf_smpp_dcs_charset, tvb, off, 1, val);
|
|
|
|
if (val & 0x10)
|
|
|
|
proto_tree_add_uint(subtree,
|
|
|
|
hf_smpp_dcs_class, tvb, off, 1, val);
|
|
|
|
} else {
|
|
|
|
if (val & 0x08)
|
|
|
|
proto_tree_add_text(subtree, tvb, off, 1,
|
|
|
|
"SMPP: Bit .... 1... should be 0 (reserved)");
|
|
|
|
proto_tree_add_uint(subtree,
|
|
|
|
hf_smpp_dcs_charset, tvb, off, 1, val);
|
|
|
|
proto_tree_add_uint(subtree,
|
|
|
|
hf_smpp_dcs_class, tvb, off, 1, val);
|
|
|
|
}
|
|
|
|
/* Cell Broadcast Service (CBS) Data Coding Scheme */
|
|
|
|
proto_tree_add_text(subtree, tvb, off, 1,
|
|
|
|
"GSM CBS Data Coding");
|
|
|
|
proto_tree_add_uint(subtree,
|
|
|
|
hf_smpp_dcs_cbs_coding_group, tvb, off, 1, val);
|
|
|
|
if (val < 0x40) { /* Language specified */
|
|
|
|
proto_tree_add_uint(subtree,
|
|
|
|
hf_smpp_dcs_cbs_language, tvb, off, 1, val);
|
|
|
|
} else if (val>>6 == 1) { /* General Data Coding indication */
|
|
|
|
proto_tree_add_boolean(subtree,
|
|
|
|
hf_smpp_dcs_text_compression, tvb, off, 1, val);
|
|
|
|
proto_tree_add_boolean(subtree,
|
|
|
|
hf_smpp_dcs_class_present, tvb, off, 1, val);
|
|
|
|
proto_tree_add_uint(subtree,
|
|
|
|
hf_smpp_dcs_charset, tvb, off, 1, val);
|
|
|
|
if (val & 0x10)
|
|
|
|
proto_tree_add_uint(subtree,
|
|
|
|
hf_smpp_dcs_class, tvb, off, 1, val);
|
|
|
|
} else if (val>>6 == 2) { /* Message with UDH structure */
|
|
|
|
proto_tree_add_uint(subtree,
|
|
|
|
hf_smpp_dcs_charset, tvb, off, 1, val);
|
|
|
|
proto_tree_add_uint(subtree,
|
|
|
|
hf_smpp_dcs_class, tvb, off, 1, val);
|
|
|
|
} else if (val>>4 == 14) { /* WAP Forum */
|
|
|
|
proto_tree_add_uint(subtree,
|
|
|
|
hf_smpp_dcs_wap_charset, tvb, off, 1, val);
|
|
|
|
proto_tree_add_uint(subtree,
|
|
|
|
hf_smpp_dcs_wap_class, tvb, off, 1, val);
|
|
|
|
} else if (val>>4 == 15) { /* Data coding / message handling */
|
|
|
|
if (val & 0x08)
|
|
|
|
proto_tree_add_text(subtree, tvb, off, 1,
|
|
|
|
"SMPP: Bit .... 1... should be 0 (reserved)");
|
|
|
|
proto_tree_add_uint(subtree,
|
|
|
|
hf_smpp_dcs_charset, tvb, off, 1, val);
|
|
|
|
proto_tree_add_uint(subtree,
|
|
|
|
hf_smpp_dcs_cbs_class, tvb, off, 1, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
(*offset)++;
|
|
|
|
}
|
|
|
|
|
2001-12-03 20:18:29 +00:00
|
|
|
/*!
|
|
|
|
* The next set of routines handle the different operations, associated
|
|
|
|
* with SMPP.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
bind_receiver(proto_tree *tree, tvbuff_t *tvb)
|
|
|
|
{
|
|
|
|
int offset = 0;
|
|
|
|
guint8 field;
|
|
|
|
guint8 major, minor;
|
|
|
|
char strval[BUFSIZ];
|
|
|
|
|
|
|
|
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;
|
2003-07-02 21:10:50 +00:00
|
|
|
sprintf(strval, "%u.%u", major, minor);
|
2001-12-03 20:18:29 +00:00
|
|
|
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);
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
int offset = 0;
|
|
|
|
|
|
|
|
smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
|
|
|
|
smpp_handle_string(tree, tvb, hf_smpp_password, &offset);
|
|
|
|
}
|
|
|
|
|
2003-06-30 23:24:39 +00:00
|
|
|
static void
|
2003-12-23 12:07:14 +00:00
|
|
|
submit_sm(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
|
|
|
|
proto_tree *top_tree)
|
2003-06-30 23:24:39 +00:00
|
|
|
{
|
|
|
|
tvbuff_t *tvb_msg;
|
2001-12-03 20:18:29 +00:00
|
|
|
int offset = 0;
|
2003-06-30 23:24:39 +00:00
|
|
|
guint8 flag, udhi;
|
2001-12-03 20:18:29 +00:00
|
|
|
guint8 length;
|
2005-01-07 10:39:51 +00:00
|
|
|
char *src_str = NULL;
|
|
|
|
char *dst_str = NULL;
|
|
|
|
address save_src, save_dst;
|
2001-12-03 20:18:29 +00:00
|
|
|
|
2003-08-23 02:15:53 +00:00
|
|
|
smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
|
2001-12-03 20:18:29 +00:00
|
|
|
smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
|
|
|
|
smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
|
2003-12-23 12:07:14 +00:00
|
|
|
src_str = smpp_handle_string_return(tree, tvb, hf_smpp_source_addr, &offset);
|
2001-12-03 20:18:29 +00:00
|
|
|
smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
|
|
|
|
smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
|
2003-12-23 12:07:14 +00:00
|
|
|
dst_str = smpp_handle_string_return(tree, tvb, hf_smpp_destination_addr, &offset);
|
2001-12-03 20:18:29 +00:00
|
|
|
flag = tvb_get_guint8(tvb, offset);
|
2003-06-30 23:24:39 +00:00
|
|
|
udhi = flag & 0x40;
|
2001-12-03 20:18:29 +00:00
|
|
|
proto_tree_add_item(tree, hf_smpp_esm_submit_msg_mode,
|
|
|
|
tvb, offset, 1, flag);
|
|
|
|
proto_tree_add_item(tree, hf_smpp_esm_submit_msg_type,
|
|
|
|
tvb, offset, 1, flag);
|
|
|
|
proto_tree_add_item(tree, hf_smpp_esm_submit_features,
|
|
|
|
tvb, offset, 1, flag);
|
|
|
|
offset++;
|
|
|
|
smpp_handle_int1(tree, tvb, hf_smpp_protocol_id, &offset);
|
|
|
|
smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
|
2005-01-07 10:39:51 +00:00
|
|
|
if (tvb_get_guint8(tvb,offset)) {
|
|
|
|
smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
|
|
|
|
hf_smpp_schedule_delivery_time_r, &offset);
|
|
|
|
} else { /* Time = NULL means Immediate delivery */
|
|
|
|
proto_tree_add_text(tree, tvb, offset++, 1,
|
|
|
|
"Scheduled delivery time: Immediate delivery");
|
|
|
|
}
|
|
|
|
if (tvb_get_guint8(tvb,offset)) {
|
|
|
|
smpp_handle_time(tree, tvb, hf_smpp_validity_period,
|
|
|
|
hf_smpp_validity_period_r, &offset);
|
|
|
|
} else { /* Time = NULL means SMSC default validity */
|
|
|
|
proto_tree_add_text(tree, tvb, offset++, 1,
|
|
|
|
"Validity period: SMSC default validity period");
|
|
|
|
}
|
2001-12-03 20:18:29 +00:00
|
|
|
flag = tvb_get_guint8(tvb, offset);
|
|
|
|
proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
|
|
|
|
proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
|
|
|
|
proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
|
|
|
|
offset++;
|
|
|
|
smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
|
2003-08-23 02:15:53 +00:00
|
|
|
smpp_handle_dcs(tree, tvb, &offset);
|
2001-12-03 20:18:29 +00:00
|
|
|
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);
|
|
|
|
if (length)
|
2003-06-30 23:24:39 +00:00
|
|
|
{
|
2001-12-03 20:18:29 +00:00
|
|
|
proto_tree_add_item(tree, hf_smpp_short_message,
|
|
|
|
tvb, offset, length, FALSE);
|
2003-06-30 23:24:39 +00:00
|
|
|
if (udhi) /* UDHI indicator present */
|
|
|
|
{
|
2004-01-18 00:07:03 +00:00
|
|
|
DebugLog(("UDHI present - set addresses\n"));
|
|
|
|
/* Save original addresses */
|
|
|
|
COPY_ADDRESS(&save_src, &(pinfo->src));
|
|
|
|
COPY_ADDRESS(&save_dst, &(pinfo->dst));
|
|
|
|
/* Set SMPP source and destination address */
|
|
|
|
SET_ADDRESS(&(pinfo->src), AT_STRINGZ, 1+strlen(src_str), src_str);
|
|
|
|
SET_ADDRESS(&(pinfo->dst), AT_STRINGZ, 1+strlen(dst_str), dst_str);
|
2003-06-30 23:24:39 +00:00
|
|
|
tvb_msg = tvb_new_subset (tvb, offset,
|
2004-01-18 00:07:03 +00:00
|
|
|
MIN(length, tvb_reported_length(tvb) - offset), length);
|
|
|
|
call_dissector (gsm_sms_handle, tvb_msg, pinfo, top_tree);
|
|
|
|
/* Restore original addresses */
|
|
|
|
COPY_ADDRESS(&(pinfo->src), &save_src);
|
|
|
|
COPY_ADDRESS(&(pinfo->dst), &save_dst);
|
2003-06-30 23:24:39 +00:00
|
|
|
}
|
|
|
|
offset += length;
|
|
|
|
}
|
2005-01-07 10:39:51 +00:00
|
|
|
/* Get rid of SMPP text string addresses */
|
2001-12-03 20:18:29 +00:00
|
|
|
smpp_handle_tlv(tree, tvb, &offset);
|
|
|
|
}
|
|
|
|
|
2003-12-23 12:07:14 +00:00
|
|
|
#define deliver_sm(a, b, c, d) submit_sm(a, b, c, d)
|
2001-12-03 20:18:29 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
replace_sm(proto_tree *tree, tvbuff_t *tvb)
|
|
|
|
{
|
|
|
|
int offset = 0;
|
|
|
|
guint8 flag;
|
|
|
|
guint8 length;
|
|
|
|
|
|
|
|
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);
|
|
|
|
smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
|
2003-08-23 02:15:53 +00:00
|
|
|
if (tvb_get_guint8(tvb,offset)) {
|
2001-12-03 20:18:29 +00:00
|
|
|
smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
|
|
|
|
hf_smpp_schedule_delivery_time_r, &offset);
|
2003-08-23 02:15:53 +00:00
|
|
|
} else { /* Time = NULL */
|
|
|
|
proto_tree_add_text(tree, tvb, offset++, 1,
|
|
|
|
"Scheduled delivery time: Keep initial delivery time setting");
|
|
|
|
}
|
|
|
|
if (tvb_get_guint8(tvb,offset)) {
|
2001-12-03 20:18:29 +00:00
|
|
|
smpp_handle_time(tree, tvb, hf_smpp_validity_period,
|
|
|
|
hf_smpp_validity_period_r, &offset);
|
2003-08-23 02:15:53 +00:00
|
|
|
} else { /* Time = NULL */
|
|
|
|
proto_tree_add_text(tree, tvb, offset++, 1,
|
|
|
|
"Validity period: Keep initial validity period setting");
|
|
|
|
}
|
2001-12-03 20:18:29 +00:00
|
|
|
flag = tvb_get_guint8(tvb, offset);
|
|
|
|
proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
|
|
|
|
proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
|
|
|
|
proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
|
|
|
|
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);
|
|
|
|
if (length)
|
|
|
|
proto_tree_add_item(tree, hf_smpp_short_message,
|
|
|
|
tvb, offset, length, FALSE);
|
|
|
|
offset += length;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
cancel_sm(proto_tree *tree, tvbuff_t *tvb)
|
|
|
|
{
|
|
|
|
int offset = 0;
|
|
|
|
|
2003-08-23 02:15:53 +00:00
|
|
|
smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
|
2001-12-03 20:18:29 +00:00
|
|
|
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);
|
|
|
|
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);
|
|
|
|
smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
submit_multi(proto_tree *tree, tvbuff_t *tvb)
|
|
|
|
{
|
|
|
|
int offset = 0;
|
|
|
|
guint8 flag;
|
|
|
|
guint8 length;
|
|
|
|
|
2003-08-23 02:15:53 +00:00
|
|
|
smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
|
2001-12-03 20:18:29 +00:00
|
|
|
smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
|
|
|
|
smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
|
|
|
|
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_item(tree, hf_smpp_esm_submit_msg_mode,
|
2004-01-18 00:07:03 +00:00
|
|
|
tvb, offset, 1, flag);
|
2001-12-03 20:18:29 +00:00
|
|
|
proto_tree_add_item(tree, hf_smpp_esm_submit_msg_type,
|
2004-01-18 00:07:03 +00:00
|
|
|
tvb, offset, 1, flag);
|
2001-12-03 20:18:29 +00:00
|
|
|
proto_tree_add_item(tree, hf_smpp_esm_submit_features,
|
2004-01-18 00:07:03 +00:00
|
|
|
tvb, offset, 1, flag);
|
2001-12-03 20:18:29 +00:00
|
|
|
offset++;
|
|
|
|
smpp_handle_int1(tree, tvb, hf_smpp_protocol_id, &offset);
|
|
|
|
smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
|
2004-01-18 00:07:03 +00:00
|
|
|
if (tvb_get_guint8(tvb,offset)) {
|
|
|
|
smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
|
|
|
|
hf_smpp_schedule_delivery_time_r, &offset);
|
|
|
|
} else { /* Time = NULL means Immediate delivery */
|
|
|
|
proto_tree_add_text(tree, tvb, offset++, 1,
|
|
|
|
"Scheduled delivery time: Immediate delivery");
|
|
|
|
}
|
|
|
|
if (tvb_get_guint8(tvb,offset)) {
|
|
|
|
smpp_handle_time(tree, tvb, hf_smpp_validity_period,
|
|
|
|
hf_smpp_validity_period_r, &offset);
|
|
|
|
} else { /* Time = NULL means SMSC default validity */
|
|
|
|
proto_tree_add_text(tree, tvb, offset++, 1,
|
|
|
|
"Validity period: SMSC default validity period");
|
|
|
|
}
|
2001-12-03 20:18:29 +00:00
|
|
|
flag = tvb_get_guint8(tvb, offset);
|
|
|
|
proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
|
|
|
|
proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
|
|
|
|
proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
|
|
|
|
offset++;
|
|
|
|
smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
|
2004-01-18 00:07:03 +00:00
|
|
|
smpp_handle_dcs(tree, tvb, &offset);
|
2001-12-03 20:18:29 +00:00
|
|
|
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);
|
|
|
|
if (length)
|
|
|
|
proto_tree_add_item(tree, hf_smpp_short_message,
|
2004-01-18 00:07:03 +00:00
|
|
|
tvb, offset, length, FALSE);
|
2001-12-03 20:18:29 +00:00
|
|
|
offset += length;
|
|
|
|
smpp_handle_tlv(tree, tvb, &offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
alert_notification(proto_tree *tree, tvbuff_t *tvb)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
int offset = 0;
|
|
|
|
guint8 flag;
|
|
|
|
|
2003-08-23 02:15:53 +00:00
|
|
|
smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
|
2001-12-03 20:18:29 +00:00
|
|
|
smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
|
|
|
|
smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
|
|
|
|
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);
|
|
|
|
smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
|
|
|
|
flag = tvb_get_guint8(tvb, offset);
|
|
|
|
proto_tree_add_item(tree, hf_smpp_esm_submit_msg_mode,
|
|
|
|
tvb, offset, 1, flag);
|
|
|
|
proto_tree_add_item(tree, hf_smpp_esm_submit_msg_type,
|
|
|
|
tvb, offset, 1, flag);
|
|
|
|
proto_tree_add_item(tree, hf_smpp_esm_submit_features,
|
|
|
|
tvb, offset, 1, flag);
|
|
|
|
offset++;
|
|
|
|
flag = tvb_get_guint8(tvb, offset);
|
|
|
|
proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
|
|
|
|
proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
|
|
|
|
proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
|
|
|
|
offset++;
|
2003-08-23 02:15:53 +00:00
|
|
|
smpp_handle_dcs(tree, tvb, &offset);
|
2001-12-03 20:18:29 +00:00
|
|
|
smpp_handle_tlv(tree, tvb, &offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* The next set of routines handle the different operation-responses,
|
|
|
|
* associated with SMPP.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
bind_receiver_resp(proto_tree *tree, tvbuff_t *tvb)
|
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define bind_transceiver_resp(a, b) bind_receiver_resp(a, b)
|
|
|
|
|
|
|
|
static void
|
|
|
|
submit_sm_resp(proto_tree *tree, tvbuff_t *tvb)
|
|
|
|
{
|
|
|
|
int offset = 0;
|
|
|
|
|
|
|
|
smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define deliver_sm_resp(a, b) submit_sm_resp(a, b)
|
|
|
|
|
|
|
|
static void
|
|
|
|
submit_multi_resp(proto_tree *tree, tvbuff_t *tvb)
|
|
|
|
{
|
|
|
|
int offset = 0;
|
|
|
|
|
|
|
|
smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
|
|
|
|
smpp_handle_dlist_resp(tree, tvb, &offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
data_sm_resp(proto_tree *tree, tvbuff_t *tvb)
|
|
|
|
{
|
|
|
|
int offset = 0;
|
|
|
|
|
|
|
|
smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
|
|
|
|
smpp_handle_tlv(tree, tvb, &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
|
2003-03-08 14:21:15 +00:00
|
|
|
* it has a correct overall PDU length
|
2001-12-03 20:18:29 +00:00
|
|
|
* it is a 'well-known' operation
|
|
|
|
* has a 'well-known' status
|
|
|
|
*/
|
|
|
|
static gboolean
|
|
|
|
dissect_smpp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|
|
|
{
|
|
|
|
guint command_id; /* SMPP command */
|
|
|
|
guint command_status; /* Status code */
|
2003-03-08 14:21:15 +00:00
|
|
|
guint command_length; /* length of PDU */
|
2001-12-03 20:18:29 +00:00
|
|
|
|
|
|
|
if (tvb_reported_length(tvb) < 4 * 4) /* Mandatory header */
|
|
|
|
return FALSE;
|
2003-03-08 14:21:15 +00:00
|
|
|
command_length = tvb_get_ntohl(tvb, 0);
|
|
|
|
if (command_length > 64 * 1024)
|
|
|
|
return FALSE;
|
2001-12-03 20:18:29 +00:00
|
|
|
command_id = tvb_get_ntohl(tvb, 4); /* Only known commands */
|
|
|
|
if (match_strval(command_id, vals_command_id) == NULL)
|
|
|
|
return FALSE;
|
|
|
|
command_status = tvb_get_ntohl(tvb, 8); /* ..with known status */
|
|
|
|
if (match_strval(command_status, vals_command_status) == NULL)
|
|
|
|
return FALSE;
|
|
|
|
dissect_smpp(tvb, pinfo, tree);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2004-01-20 17:58:37 +00:00
|
|
|
static guint
|
|
|
|
get_smpp_pdu_len(tvbuff_t *tvb, int offset)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
2001-12-03 20:18:29 +00:00
|
|
|
static void
|
|
|
|
dissect_smpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
2004-01-20 17:58:37 +00:00
|
|
|
{
|
|
|
|
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); /* 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_length_remaining(tvb, offset);
|
|
|
|
tvbuff_t *pdu_tvb;
|
|
|
|
|
2005-06-16 19:51:14 +00:00
|
|
|
if (pdu_len < 1)
|
|
|
|
THROW(ReportedBoundsError);
|
|
|
|
|
2004-01-20 17:58:37 +00:00
|
|
|
if (pdu_real_len <= 0)
|
|
|
|
return;
|
|
|
|
if (pdu_real_len > pdu_len)
|
|
|
|
pdu_real_len = pdu_len;
|
|
|
|
pdu_tvb = tvb_new_subset(tvb, offset, pdu_real_len, pdu_len);
|
|
|
|
dissect_smpp_pdu(pdu_tvb, pinfo, tree);
|
|
|
|
offset += pdu_len;
|
|
|
|
first = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Dissect a single SMPP PDU contained within "tvb". */
|
|
|
|
static void
|
|
|
|
dissect_smpp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
2001-12-03 20:18:29 +00:00
|
|
|
{
|
|
|
|
int offset = 0; /* Offset within tvbuff */
|
|
|
|
guint command_length; /* length of PDU */
|
|
|
|
guint command_id; /* SMPP command */
|
|
|
|
guint command_status; /* Status code */
|
|
|
|
guint sequence_number; /* ...of command */
|
2005-06-26 19:56:52 +00:00
|
|
|
const gchar *command_str;
|
|
|
|
const gchar *command_status_str = NULL;
|
2001-12-03 20:18:29 +00:00
|
|
|
/* Set up structures needed to add the protocol subtree and manage it */
|
2004-01-18 00:07:03 +00:00
|
|
|
proto_item *ti = NULL;
|
|
|
|
proto_tree *smpp_tree = NULL;
|
2001-12-03 20:18:29 +00:00
|
|
|
|
|
|
|
/*
|
2004-01-20 17:58:37 +00:00
|
|
|
* Safety: don't even try to dissect the PDU
|
|
|
|
* when the mandatory header isn't present.
|
2001-12-03 20:18:29 +00:00
|
|
|
*/
|
|
|
|
if (tvb_reported_length(tvb) < 4 * 4)
|
|
|
|
return;
|
|
|
|
command_length = tvb_get_ntohl(tvb, offset);
|
|
|
|
offset += 4;
|
|
|
|
command_id = tvb_get_ntohl(tvb, offset);
|
2004-01-20 17:58:37 +00:00
|
|
|
command_str = val_to_str(command_id, vals_command_id,
|
|
|
|
"(Unknown SMPP Operation 0x%08X)");
|
2001-12-03 20:18:29 +00:00
|
|
|
offset += 4;
|
|
|
|
command_status = tvb_get_ntohl(tvb, offset);
|
2004-01-20 17:58:37 +00:00
|
|
|
if (command_id & 0x80000000) {
|
|
|
|
command_status_str = val_to_str(command_status, vals_command_status,
|
|
|
|
"(Reserved Error 0x%08X)");
|
|
|
|
}
|
|
|
|
offset += 4;
|
2001-12-03 20:18:29 +00:00
|
|
|
sequence_number = tvb_get_ntohl(tvb, offset);
|
|
|
|
offset += 4;
|
2004-01-18 00:07:03 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Update the protocol column.
|
|
|
|
*/
|
2004-01-20 17:58:37 +00:00
|
|
|
if (first == TRUE) {
|
|
|
|
if (check_col(pinfo->cinfo, COL_PROTOCOL))
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMPP");
|
|
|
|
}
|
2001-12-03 20:18:29 +00:00
|
|
|
|
2004-01-18 00:07:03 +00:00
|
|
|
/*
|
|
|
|
* Create display subtree for the protocol
|
|
|
|
*/
|
|
|
|
if (tree) {
|
|
|
|
ti = proto_tree_add_item (tree, proto_smpp, tvb, 0, tvb->length, FALSE);
|
|
|
|
smpp_tree = proto_item_add_subtree (ti, ett_smpp);
|
2001-12-03 20:18:29 +00:00
|
|
|
}
|
|
|
|
|
2004-01-18 00:07:03 +00:00
|
|
|
/*
|
|
|
|
* Cycle over the encapsulated PDUs
|
2001-12-03 20:18:29 +00:00
|
|
|
*/
|
2004-01-20 17:58:37 +00:00
|
|
|
{
|
2004-01-18 00:07:03 +00:00
|
|
|
tvbuff_t *pdu_tvb;
|
|
|
|
|
|
|
|
/*
|
2004-01-20 17:58:37 +00:00
|
|
|
* Make entries in the Info column on the summary display
|
2004-01-18 00:07:03 +00:00
|
|
|
*/
|
2004-01-20 17:58:37 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_INFO)) {
|
|
|
|
if (first == TRUE) {
|
|
|
|
/*
|
|
|
|
* First PDU - We already computed the fixed header
|
|
|
|
*/
|
2004-01-18 00:07:03 +00:00
|
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "SMPP %s", command_str);
|
2004-01-20 17:58:37 +00:00
|
|
|
first = FALSE;
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Subsequent PDUs
|
|
|
|
*/
|
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", command_str);
|
2004-01-18 00:07:03 +00:00
|
|
|
}
|
|
|
|
/*
|
2004-01-20 17:58:37 +00:00
|
|
|
* Display command status of responses in Info column
|
2004-01-18 00:07:03 +00:00
|
|
|
*/
|
2004-01-20 17:58:37 +00:00
|
|
|
if (command_id & 0x80000000) {
|
2004-01-18 00:07:03 +00:00
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, ": \"%s\"",
|
|
|
|
command_status_str);
|
|
|
|
}
|
2003-09-17 20:24:45 +00:00
|
|
|
}
|
2004-01-18 00:07:03 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Create a tvb for the current PDU.
|
|
|
|
* Physical length: at most command_length
|
|
|
|
* Reported length: command_length
|
|
|
|
*/
|
|
|
|
if (tvb_length_remaining(tvb, offset - 16 + command_length) > 0) {
|
|
|
|
pdu_tvb = tvb_new_subset(tvb, offset - 16,
|
|
|
|
command_length, /* Physical length */
|
|
|
|
command_length); /* Length reported by the protocol */
|
|
|
|
} else {
|
|
|
|
pdu_tvb = tvb_new_subset(tvb, offset - 16,
|
|
|
|
tvb_length_remaining(tvb, offset - 16),/* Physical length */
|
|
|
|
command_length); /* Length reported by the protocol */
|
|
|
|
}
|
|
|
|
|
2001-12-03 20:18:29 +00:00
|
|
|
/*
|
2004-01-18 00:07:03 +00:00
|
|
|
* Dissect the PDU
|
|
|
|
*
|
|
|
|
* If "tree" is NULL, Ethereal 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).
|
2001-12-03 20:18:29 +00:00
|
|
|
*/
|
2004-01-18 00:07:03 +00:00
|
|
|
if (tree || (command_id == 4))
|
2001-12-03 20:18:29 +00:00
|
|
|
{
|
2004-01-18 00:07:03 +00:00
|
|
|
/*
|
|
|
|
* Create display subtree for the PDU
|
|
|
|
*/
|
|
|
|
if (tree) {
|
2004-01-20 17:58:37 +00:00
|
|
|
proto_tree_add_uint(smpp_tree, hf_smpp_command_length,
|
2004-01-18 00:07:03 +00:00
|
|
|
pdu_tvb, 0, 4, command_length);
|
2004-01-20 17:58:37 +00:00
|
|
|
proto_tree_add_uint(smpp_tree, hf_smpp_command_id,
|
2004-01-18 00:07:03 +00:00
|
|
|
pdu_tvb, 4, 4, command_id);
|
2004-01-20 17:58:37 +00:00
|
|
|
proto_item_append_text(ti, ", Command: %s", command_str);
|
2004-01-18 00:07:03 +00:00
|
|
|
|
2001-12-03 20:18:29 +00:00
|
|
|
/*
|
2004-01-18 00:07:03 +00:00
|
|
|
* Status is only meaningful with responses
|
2001-12-03 20:18:29 +00:00
|
|
|
*/
|
2004-01-18 00:07:03 +00:00
|
|
|
if (command_id & 0x80000000) {
|
2004-01-20 17:58:37 +00:00
|
|
|
proto_tree_add_uint(smpp_tree, hf_smpp_command_status,
|
2004-01-18 00:07:03 +00:00
|
|
|
pdu_tvb, 8, 4, command_status);
|
2004-01-20 17:58:37 +00:00
|
|
|
proto_item_append_text (ti, ", Status: \"%s\"",
|
2004-01-18 00:07:03 +00:00
|
|
|
command_status_str);
|
|
|
|
}
|
2004-01-20 17:58:37 +00:00
|
|
|
proto_tree_add_uint(smpp_tree, hf_smpp_sequence_number,
|
2004-01-18 00:07:03 +00:00
|
|
|
pdu_tvb, 12, 4, sequence_number);
|
2004-01-20 17:58:37 +00:00
|
|
|
proto_item_append_text(ti, ", Seq: %u, Len: %u",
|
2004-01-18 00:07:03 +00:00
|
|
|
sequence_number, command_length);
|
2001-12-03 20:18:29 +00:00
|
|
|
}
|
2004-01-18 00:07:03 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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(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 */
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if (!command_status)
|
2004-01-20 17:58:37 +00:00
|
|
|
bind_receiver_resp(smpp_tree, tmp_tvb);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
if (!command_status)
|
2004-01-20 17:58:37 +00:00
|
|
|
bind_transmitter_resp(smpp_tree, tmp_tvb);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
if (!command_status)
|
2004-01-20 17:58:37 +00:00
|
|
|
query_sm_resp(smpp_tree, tmp_tvb);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
if (!command_status)
|
2004-01-20 17:58:37 +00:00
|
|
|
submit_sm_resp(smpp_tree, tmp_tvb);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
if (!command_status)
|
2004-01-20 17:58:37 +00:00
|
|
|
deliver_sm_resp(smpp_tree, tmp_tvb);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
case 9:
|
|
|
|
if (!command_status)
|
2004-01-20 17:58:37 +00:00
|
|
|
bind_transceiver_resp(smpp_tree, tmp_tvb);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
case 33:
|
|
|
|
if (!command_status)
|
2004-01-20 17:58:37 +00:00
|
|
|
submit_multi_resp(smpp_tree, tmp_tvb);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
case 259:
|
|
|
|
if (!command_status)
|
2004-01-20 17:58:37 +00:00
|
|
|
data_sm_resp(smpp_tree, tmp_tvb);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
} /* switch (command_id & 0x7FFFFFFF) */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (command_id) {
|
|
|
|
case 1:
|
2004-01-20 17:58:37 +00:00
|
|
|
bind_receiver(smpp_tree, tmp_tvb);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
2004-01-20 17:58:37 +00:00
|
|
|
bind_transmitter(smpp_tree, tmp_tvb);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
case 3:
|
2004-01-20 17:58:37 +00:00
|
|
|
query_sm(smpp_tree, tmp_tvb);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
case 4:
|
2004-01-20 17:58:37 +00:00
|
|
|
submit_sm(smpp_tree, tmp_tvb, pinfo, tree);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
case 5:
|
2004-01-20 17:58:37 +00:00
|
|
|
deliver_sm(smpp_tree, tmp_tvb, pinfo, tree);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
case 6: /* Unbind */
|
|
|
|
case 21: /* Enquire link */
|
|
|
|
break;
|
|
|
|
case 7:
|
2004-01-20 17:58:37 +00:00
|
|
|
replace_sm(smpp_tree, tmp_tvb);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
case 8:
|
2004-01-20 17:58:37 +00:00
|
|
|
cancel_sm(smpp_tree, tmp_tvb);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
case 9:
|
2004-01-20 17:58:37 +00:00
|
|
|
bind_transceiver(smpp_tree, tmp_tvb);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
case 11:
|
2004-01-20 17:58:37 +00:00
|
|
|
outbind(smpp_tree, tmp_tvb);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
case 33:
|
2004-01-20 17:58:37 +00:00
|
|
|
submit_multi(smpp_tree, tmp_tvb);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
case 258:
|
2004-01-20 17:58:37 +00:00
|
|
|
alert_notification(smpp_tree, tmp_tvb);
|
2004-01-18 00:07:03 +00:00
|
|
|
break;
|
|
|
|
case 259:
|
2004-01-20 17:58:37 +00:00
|
|
|
data_sm(smpp_tree, tmp_tvb);
|
2004-01-18 00:07:03 +00:00
|
|
|
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)) */
|
|
|
|
first = FALSE;
|
2004-01-20 17:58:37 +00:00
|
|
|
}
|
2004-01-18 00:07:03 +00:00
|
|
|
|
2001-12-03 20:18:29 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-12-23 12:07:14 +00:00
|
|
|
|
|
|
|
/* Register the protocol with Ethereal */
|
|
|
|
void
|
|
|
|
proto_register_smpp(void)
|
|
|
|
{
|
2004-01-20 17:58:37 +00:00
|
|
|
module_t *smpp_module; /* Preferences for SMPP */
|
|
|
|
|
2001-12-03 20:18:29 +00:00
|
|
|
/* Setup list of header fields */
|
|
|
|
static hf_register_info hf[] = {
|
|
|
|
{ &hf_smpp_command_length,
|
|
|
|
{ "Length ", "smpp.command_length",
|
|
|
|
FT_UINT32, BASE_DEC, NULL, 0x00,
|
|
|
|
"Total length of the SMPP PDU.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_command_id,
|
|
|
|
{ "Operation ", "smpp.command_id",
|
|
|
|
FT_UINT32, BASE_HEX, VALS(vals_command_id), 0x00,
|
|
|
|
"Defines the SMPP PDU.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_command_status,
|
|
|
|
{ "Result ", "smpp.command_status",
|
|
|
|
FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
|
|
|
|
"Indicates success or failure of the SMPP request.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_sequence_number,
|
|
|
|
{ "Sequence #", "smpp.sequence_number",
|
|
|
|
FT_UINT32, BASE_DEC, NULL, 0x00,
|
|
|
|
"A number to correlate requests with responses.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_system_id,
|
|
|
|
{ "System ID", "smpp.system_id",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x00,
|
|
|
|
"Identifies a system.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_password,
|
|
|
|
{ "Password", "smpp.password",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x00,
|
|
|
|
"Password used for authentication.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_system_type,
|
|
|
|
{ "System type", "smpp.system_type",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x00,
|
|
|
|
"Categorises the system.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_interface_version,
|
|
|
|
{ "Version (if)", "smpp.interface_version",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x00,
|
|
|
|
"Version of SMPP interface supported.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_service_type,
|
|
|
|
{ "Service type", "smpp.service_type",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x00,
|
|
|
|
"SMS application service associated with the message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_addr_ton,
|
|
|
|
{ "Type of number", "smpp.addr_ton",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
|
|
|
|
"Indicates the type of number, given in the address.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_source_addr_ton,
|
|
|
|
{ "Type of number (originator)", "smpp.source_addr_ton",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
|
|
|
|
"Indicates originator type of number, given in the address.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dest_addr_ton,
|
|
|
|
{ "Type of number (recipient)", "smpp.dest_addr_ton",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
|
|
|
|
"Indicates recipient type of number, given in the address.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_addr_npi,
|
|
|
|
{ "Numbering plan indicator", "smpp.addr_npi",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
|
|
|
|
"Gives the numbering plan this address belongs to.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_source_addr_npi,
|
|
|
|
{ "Numbering plan indicator (originator)", "smpp.source_addr_npi",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
|
|
|
|
"Gives originator numbering plan this address belongs to.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dest_addr_npi,
|
|
|
|
{ "Numbering plan indicator (recipient)", "smpp.dest_addr_npi",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
|
|
|
|
"Gives recipient numbering plan this address belongs to.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_address_range,
|
|
|
|
{ "Address", "smpp.address_range",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x00,
|
|
|
|
"Given address or address range.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_source_addr,
|
|
|
|
{ "Originator address", "smpp.source_addr",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x00,
|
|
|
|
"Address of SME originating this message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_destination_addr,
|
|
|
|
{ "Recipient address", "smpp.destination_addr",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x00,
|
|
|
|
"Address of SME receiving this message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_esm_submit_msg_mode,
|
|
|
|
{ "Messaging mode", "smpp.esm.submit.msg_mode",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_esm_submit_msg_mode), 0x03,
|
|
|
|
"Mode attribute for this message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_esm_submit_msg_type,
|
|
|
|
{ "Message type ", "smpp.esm.submit.msg_type",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_esm_submit_msg_type), 0x3C,
|
|
|
|
"Type attribute for this message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_esm_submit_features,
|
|
|
|
{ "GSM features ", "smpp.esm.submit.features",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_esm_submit_features), 0xC0,
|
|
|
|
"GSM network specific features.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/*! \todo Get proper values from GSM-spec. */
|
|
|
|
{ &hf_smpp_protocol_id,
|
|
|
|
{ "Protocol id.", "smpp.protocol_id",
|
|
|
|
FT_UINT8, BASE_HEX, NULL, 0x00,
|
|
|
|
"Protocol identifier according GSM 03.40.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_priority_flag,
|
|
|
|
{ "Priority level", "smpp.priority_flag",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_priority_flag), 0x00,
|
|
|
|
"The priority level of the short message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_schedule_delivery_time,
|
|
|
|
{ "Scheduled delivery time", "smpp.schedule_delivery_time",
|
|
|
|
FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
|
|
|
|
"Scheduled time for delivery of short message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_schedule_delivery_time_r,
|
|
|
|
{ "Scheduled delivery time", "smpp.schedule_delivery_time_r",
|
|
|
|
FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
|
|
|
|
"Scheduled time for delivery of short message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_validity_period,
|
|
|
|
{ "Validity period", "smpp.validity_period",
|
|
|
|
FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
|
|
|
|
"Validity period of this message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_validity_period_r,
|
|
|
|
{ "Validity period", "smpp.validity_period_r",
|
|
|
|
FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
|
|
|
|
"Validity period of this message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_regdel_receipt,
|
|
|
|
{ "Delivery receipt ", "smpp.regdel.receipt",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_regdel_receipt), 0x03,
|
|
|
|
"SMSC delivery receipt request.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_regdel_acks,
|
|
|
|
{ "Message type ", "smpp.regdel.acks",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_regdel_acks), 0x0C,
|
|
|
|
"SME acknowledgement request.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_regdel_notif,
|
|
|
|
{ "Intermediate notif", "smpp.regdel.notif",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_regdel_notif), 0x10,
|
|
|
|
"Intermediate notification request.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_replace_if_present_flag,
|
|
|
|
{ "Replace ", "smpp.replace_if_present_flag",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_replace_if_present_flag), 0x01,
|
|
|
|
"Replace the short message with this one or not.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_data_coding,
|
|
|
|
{ "Data coding", "smpp.data_coding",
|
2003-08-23 02:15:53 +00:00
|
|
|
FT_UINT8, BASE_HEX, NULL, 0x00,
|
2001-12-03 20:18:29 +00:00
|
|
|
"Defines the encoding scheme of the message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_sm_default_msg_id,
|
|
|
|
{ "Predefined message", "smpp.sm_default_msg_id",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x00,
|
|
|
|
"Index of a predefined ('canned') short message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_sm_length,
|
|
|
|
{ "Message length", "smpp.sm_length",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x00,
|
|
|
|
"Length of the message content.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_short_message,
|
|
|
|
{ "Message", "smpp.message",
|
|
|
|
FT_NONE, BASE_NONE, NULL, 0x00,
|
|
|
|
"The actual message or data.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_message_id,
|
|
|
|
{ "Message id.", "smpp.message_id",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x00,
|
|
|
|
"Identifier of the submitted short message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dlist,
|
|
|
|
{ "Destination list", "smpp.dlist",
|
|
|
|
FT_NONE, BASE_NONE, NULL, 0x00,
|
|
|
|
"The list of destinations for a short message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dlist_resp,
|
|
|
|
{ "Unsuccesfull delivery list", "smpp.dlist_resp",
|
|
|
|
FT_NONE, BASE_NONE, NULL, 0x00,
|
|
|
|
"The list of unsuccesfull deliveries to destinations.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dl_name,
|
|
|
|
{ "Distr. list name", "smpp.dl_name",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x00,
|
|
|
|
"The name of the distribution list.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_final_date,
|
|
|
|
{ "Final date", "smpp.final_date",
|
|
|
|
FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
|
|
|
|
"Date-time when the queried message reached a final state.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_final_date_r,
|
|
|
|
{ "Final date", "smpp.final_date_r",
|
|
|
|
FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
|
|
|
|
"Date-time when the queried message reached a final state.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_message_state,
|
|
|
|
{ "Message state", "smpp.message_state",
|
|
|
|
FT_UINT8, BASE_DEC, VALS(vals_message_state), 0x00,
|
|
|
|
"Specifies the status of the queried short message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_error_code,
|
|
|
|
{ "Error code", "smpp.error_code",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x00,
|
|
|
|
"Network specific error code defining reason for failure.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_error_status_code,
|
|
|
|
{ "Status", "smpp.error_status_code",
|
|
|
|
FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
|
|
|
|
"Indicates success/failure of request for this address.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_esme_addr_ton,
|
|
|
|
{ "Type of number (ESME)", "smpp.esme_addr_ton",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
|
|
|
|
"Indicates recipient type of number, given in the address.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_esme_addr_npi,
|
|
|
|
{ "Numbering plan indicator (ESME)", "smpp.esme_addr_npi",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
|
|
|
|
"Gives the numbering plan this address belongs to.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_esme_addr,
|
|
|
|
{ "ESME address", "smpp.esme_addr",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x00,
|
|
|
|
"Address of ESME originating this message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dest_addr_subunit,
|
|
|
|
{ "Subunit destination", "smpp.dest_addr_subunit",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_addr_subunit), 0x00,
|
|
|
|
"Subunit address within mobile to route message to.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_source_addr_subunit,
|
|
|
|
{ "Subunit origin", "smpp.source_addr_subunit",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_addr_subunit), 0x00,
|
|
|
|
"Subunit address within mobile that generated the message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dest_network_type,
|
|
|
|
{ "Destination network", "smpp.dest_network_type",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_network_type), 0x00,
|
|
|
|
"Network associated with the destination address.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_source_network_type,
|
|
|
|
{ "Originator network", "smpp.source_network_type",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_network_type), 0x00,
|
|
|
|
"Network associated with the originator address.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dest_bearer_type,
|
|
|
|
{ "Destination bearer", "smpp.dest_bearer_type",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_bearer_type), 0x00,
|
|
|
|
"Desired bearer for delivery of message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_source_bearer_type,
|
|
|
|
{ "Originator bearer", "smpp.source_bearer_type",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_bearer_type), 0x00,
|
|
|
|
"Bearer over which the message originated.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dest_telematics_id,
|
|
|
|
{ "Telematic interworking (dest)", "smpp.dest_telematics_id",
|
|
|
|
FT_UINT16, BASE_HEX, NULL, 0x00,
|
|
|
|
"Telematic interworking to be used for message delivery.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_source_telematics_id,
|
|
|
|
{ "Telematic interworking (orig)", "smpp.source_telematics_id",
|
|
|
|
FT_UINT16, BASE_HEX, NULL, 0x00,
|
|
|
|
"Telematic interworking used for message submission.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_qos_time_to_live,
|
|
|
|
{ "Validity period", "smpp.qos_time_to_live",
|
|
|
|
FT_UINT32, BASE_DEC, NULL, 0x00,
|
|
|
|
"Number of seconds to retain message before expiry.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_payload_type,
|
|
|
|
{ "Payload", "smpp.payload_type",
|
|
|
|
FT_UINT8, BASE_DEC, VALS(vals_payload_type), 0x00,
|
|
|
|
"PDU type contained in the message payload.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_additional_status_info_text,
|
|
|
|
{ "Information", "smpp.additional_status_info_text",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x00,
|
|
|
|
"Description of the meaning of a response PDU.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_receipted_message_id,
|
|
|
|
{ "SMSC identifier", "smpp.receipted_message_id",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x00,
|
|
|
|
"SMSC handle of the message being received.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_privacy_indicator,
|
|
|
|
{ "Privacy indicator", "smpp.privacy_indicator",
|
|
|
|
FT_UINT8, BASE_DEC, VALS(vals_privacy_indicator), 0x00,
|
|
|
|
"Indicates the privacy level of the message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
2005-07-01 21:04:13 +00:00
|
|
|
{ &hf_smpp_source_subaddress,
|
|
|
|
{ "Source Subaddress", "smpp.source_subaddress",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x00,
|
|
|
|
"Source Subaddress",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dest_subaddress,
|
|
|
|
{ "Destination Subaddress", "smpp.dest_subaddress",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x00,
|
|
|
|
"Destination Subaddress",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_user_message_reference,
|
2001-12-03 20:18:29 +00:00
|
|
|
{ "Message reference", "smpp.user_message_reference",
|
|
|
|
FT_UINT16, BASE_HEX, NULL, 0x00,
|
|
|
|
"Reference to the message, assigned by the user.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_user_response_code,
|
|
|
|
{ "Application response code", "smpp.user_response_code",
|
|
|
|
FT_UINT8, BASE_HEX, NULL, 0x00,
|
|
|
|
"A response code set by the user.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_language_indicator,
|
|
|
|
{ "Language", "smpp.language_indicator",
|
|
|
|
FT_UINT8, BASE_DEC, VALS(vals_language_indicator), 0x00,
|
|
|
|
"Indicates the language of the short message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_source_port,
|
|
|
|
{ "Source port", "smpp.source_port",
|
|
|
|
FT_UINT16, BASE_HEX, NULL, 0x00,
|
|
|
|
"Application port associated with the source of the message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_destination_port,
|
|
|
|
{ "Destination port", "smpp.destination_port",
|
|
|
|
FT_UINT16, BASE_HEX, NULL, 0x00,
|
|
|
|
"Application port associated with the destination of the message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_sar_msg_ref_num,
|
|
|
|
{ "SAR reference number", "smpp.sar_msg_ref_num",
|
|
|
|
FT_UINT16, BASE_DEC, NULL, 0x00,
|
|
|
|
"Reference number for a concatenated short message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_sar_total_segments,
|
|
|
|
{ "SAR size", "smpp.sar_total_segments",
|
|
|
|
FT_UINT16, BASE_DEC, NULL, 0x00,
|
|
|
|
"Number of segments of a concatenated short message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_sar_segment_seqnum,
|
|
|
|
{ "SAR sequence number", "smpp.sar_segment_seqnum",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x00,
|
|
|
|
"Segment number within a concatenated short message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_display_time,
|
|
|
|
{ "Display time", "smpp.display_time",
|
|
|
|
FT_UINT8, BASE_DEC, VALS(vals_display_time), 0x00,
|
|
|
|
"Associates a display time with the message on the handset.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_ms_validity,
|
|
|
|
{ "Validity info", "smpp.ms_validity",
|
|
|
|
FT_UINT8, BASE_DEC, VALS(vals_ms_validity), 0x00,
|
|
|
|
"Associates validity info with the message on the handset.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dpf_result,
|
|
|
|
{ "Delivery pending set?", "smpp.dpf_result",
|
|
|
|
FT_UINT8, BASE_DEC, VALS(vals_dpf_result), 0x00,
|
|
|
|
"Indicates whether Delivery Pending Flag was set.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_set_dpf,
|
|
|
|
{ "Request DPF set", "smpp.set_dpf",
|
|
|
|
FT_UINT8, BASE_DEC, VALS(vals_set_dpf), 0x00,
|
|
|
|
"Request to set the DPF for certain failure scenario's.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_ms_availability_status,
|
|
|
|
{ "Availability status", "smpp.ms_availability_status",
|
|
|
|
FT_UINT8, BASE_DEC, VALS(vals_ms_availability_status), 0x00,
|
|
|
|
"Indicates the availability state of the handset.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_delivery_failure_reason,
|
|
|
|
{ "Delivery failure reason", "smpp.delivery_failure_reason",
|
|
|
|
FT_UINT8, BASE_DEC, VALS(vals_delivery_failure_reason), 0x00,
|
|
|
|
"Indicates the reason for a failed delivery attempt.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_more_messages_to_send,
|
|
|
|
{ "More messages?", "smpp.more_messages_to_send",
|
|
|
|
FT_UINT8, BASE_DEC, VALS(vals_more_messages_to_send), 0x00,
|
|
|
|
"Indicates more messages pending for the same destination.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_number_of_messages,
|
|
|
|
{ "Number of messages", "smpp.number_of_messages",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x00,
|
|
|
|
"Indicates number of messages stored in a mailbox.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_its_reply_type,
|
|
|
|
{ "Reply method", "smpp.its_reply_type",
|
|
|
|
FT_UINT8, BASE_DEC, VALS(vals_its_reply_type), 0x00,
|
|
|
|
"Indicates the handset reply method on message receipt.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_ussd_service_op,
|
|
|
|
{ "USSD service operation", "smpp.ussd_service_op",
|
|
|
|
FT_UINT8, BASE_DEC, VALS(vals_ussd_service_op), 0x00,
|
|
|
|
"Indicates the USSD service operation.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_vendor_op,
|
|
|
|
{ "Optional parameter - Vendor-specific", "smpp.vendor_op",
|
|
|
|
FT_NONE, BASE_NONE, NULL, 0x00,
|
|
|
|
"A supplied optional parameter specific to an SMSC-vendor.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_reserved_op,
|
|
|
|
{ "Optional parameter - Reserved", "smpp.reserved_op",
|
|
|
|
FT_NONE, BASE_NONE, NULL, 0x00,
|
|
|
|
"An optional parameter that is reserved in this version.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_msg_wait_ind,
|
|
|
|
{ "Indication", "smpp.msg_wait.ind",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_msg_wait_ind), 0x80,
|
|
|
|
"Indicates to the handset that a message is waiting.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_msg_wait_type,
|
|
|
|
{ "Type ", "smpp.msg_wait.type",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_msg_wait_type), 0x03,
|
|
|
|
"Indicates type of message that is waiting.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_SC_interface_version,
|
|
|
|
{ "SMSC-supported version", "smpp.SC_interface_version",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x00,
|
|
|
|
"Version of SMPP interface supported by the SMSC.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_callback_num_pres,
|
|
|
|
{ "Presentation", "smpp.callback_num.pres",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_callback_num_pres), 0x0C,
|
|
|
|
"Controls the presentation indication.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_callback_num_scrn,
|
|
|
|
{ "Screening ", "smpp.callback_num.scrn",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_callback_num_scrn), 0x03,
|
|
|
|
"Controls screening of the callback-number.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_callback_num_atag,
|
|
|
|
{ "Callback number - alphanumeric display tag",
|
|
|
|
"smpp.callback_num_atag",
|
|
|
|
FT_NONE, BASE_NONE, NULL, 0x00,
|
|
|
|
"Associates an alphanumeric display with call back number.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_callback_num,
|
|
|
|
{ "Callback number", "smpp.callback_num",
|
|
|
|
FT_NONE, BASE_NONE, NULL, 0x00,
|
|
|
|
"Associates a call back number with the message.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_network_error_type,
|
|
|
|
{ "Error type", "smpp.network_error.type",
|
|
|
|
FT_UINT8, BASE_DEC, VALS(vals_network_error_type), 0x00,
|
|
|
|
"Indicates the network type.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_network_error_code,
|
|
|
|
{ "Error code", "smpp.network_error.code",
|
|
|
|
FT_UINT16, BASE_HEX, NULL, 0x00,
|
|
|
|
"Gives the actual network error code.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_message_payload,
|
|
|
|
{ "Payload", "smpp.message_payload",
|
|
|
|
FT_NONE, BASE_NONE, NULL, 0x00,
|
|
|
|
"Short message user data.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_alert_on_message_delivery,
|
|
|
|
{ "Alert on delivery", "smpp.alert_on_message_delivery",
|
|
|
|
FT_NONE, BASE_NONE, NULL, 0x00,
|
|
|
|
"Instructs the handset to alert user on message delivery.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_its_session_number,
|
|
|
|
{ "Session number", "smpp.its_session.number",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x00,
|
|
|
|
"Session number of interactive teleservice.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_its_session_sequence,
|
|
|
|
{ "Sequence number ", "smpp.its_session.sequence",
|
|
|
|
FT_UINT8, BASE_HEX, NULL, 0xFE,
|
|
|
|
"Sequence number of the dialogue unit.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_its_session_ind,
|
|
|
|
{ "Session indicator", "smpp.its_session.ind",
|
2003-06-26 08:55:27 +00:00
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_its_session_ind), 0x01,
|
2001-12-03 20:18:29 +00:00
|
|
|
"Indicates whether this message is end of conversation.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_opt_param,
|
|
|
|
{ "Optional parameters", "smpp.opt_param",
|
|
|
|
FT_NONE, BASE_NONE, NULL, 0x00,
|
|
|
|
"The list of optional parameters in this operation.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
2003-12-23 12:07:14 +00:00
|
|
|
/*
|
|
|
|
* Data Coding Scheme
|
|
|
|
*/
|
2003-08-23 02:15:53 +00:00
|
|
|
{ &hf_smpp_dcs,
|
|
|
|
{ "SMPP Data Coding Scheme", "smpp.dcs",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_data_coding), 0x00,
|
|
|
|
"Data Coding Scheme according to SMPP.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dcs_sms_coding_group,
|
|
|
|
{ "DCS Coding Group for SMS", "smpp.dcs.sms_coding_group",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_dcs_sms_coding_group), 0xF0,
|
|
|
|
"Data Coding Scheme coding group for GSM Short Message Service.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dcs_text_compression,
|
|
|
|
{ "DCS Text compression", "smpp.dcs.text_compression",
|
|
|
|
FT_BOOLEAN, 8, TFS(&tfs_dcs_text_compression), 0x20,
|
|
|
|
"Indicates if text compression is used.", HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dcs_class_present,
|
|
|
|
{ "DCS Class present", "smpp.dcs.class_present",
|
|
|
|
FT_BOOLEAN, 8, TFS(&tfs_dcs_class_present), 0x10,
|
|
|
|
"Indicates if the message class is present (defined).", HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dcs_charset,
|
|
|
|
{ "DCS Character set", "smpp.dcs.charset",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_dcs_charset), 0x0C,
|
|
|
|
"Specifies the character set used in the message.", HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dcs_class,
|
|
|
|
{ "DCS Message class", "smpp.dcs.class",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_dcs_class), 0x03,
|
|
|
|
"Specifies the message class.", HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dcs_cbs_coding_group,
|
|
|
|
{ "DCS Coding Group for CBS", "smpp.dcs.cbs_coding_group",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_dcs_cbs_coding_group), 0xF0,
|
|
|
|
"Data Coding Scheme coding group for GSM Cell Broadcast Service.",
|
|
|
|
HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dcs_cbs_language,
|
|
|
|
{ "DCS CBS Message language", "smpp.dcs.cbs_language",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_dcs_cbs_language), 0x3F,
|
|
|
|
"Language of the GSM Cell Broadcast Service message.", HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dcs_cbs_class,
|
|
|
|
{ "DCS CBS Message class", "smpp.dcs.cbs_class",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_dcs_cbs_class), 0x03,
|
|
|
|
"Specifies the message class for GSM Cell Broadcast Service, "
|
|
|
|
"for the Data coding / message handling code group.", HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dcs_wap_charset,
|
|
|
|
{ "DCS Message coding", "smpp.dcs.wap_coding",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_dcs_wap_charset), 0x0C,
|
|
|
|
"Specifies the used message encoding, "
|
|
|
|
"as specified by the WAP Forum (WAP over GSM USSD).", HFILL
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ &hf_smpp_dcs_wap_class,
|
|
|
|
{ "DCS CBS Message class", "smpp.dcs.wap_class",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(vals_dcs_wap_class), 0x03,
|
|
|
|
"Specifies the message class for GSM Cell Broadcast Service, "
|
|
|
|
"as specified by the WAP Forum (WAP over GSM USSD).", HFILL
|
|
|
|
}
|
|
|
|
},
|
2001-12-03 20:18:29 +00:00
|
|
|
};
|
|
|
|
/* Setup protocol subtree array */
|
|
|
|
static gint *ett[] = {
|
2004-01-18 00:07:03 +00:00
|
|
|
&ett_smpp,
|
|
|
|
&ett_dlist,
|
|
|
|
&ett_dlist_resp,
|
|
|
|
&ett_opt_param,
|
|
|
|
&ett_dcs,
|
2001-12-03 20:18:29 +00:00
|
|
|
};
|
2004-01-20 17:58:37 +00:00
|
|
|
DebugLog(("Registering SMPP dissector\n"));
|
2001-12-03 20:18:29 +00:00
|
|
|
/* Register the protocol name and description */
|
|
|
|
proto_smpp = proto_register_protocol("Short Message Peer to Peer",
|
|
|
|
"SMPP", "smpp");
|
|
|
|
|
|
|
|
/* Required function calls to register header fields and subtrees used */
|
|
|
|
proto_register_field_array(proto_smpp, hf, array_length(hf));
|
|
|
|
proto_register_subtree_array(ett, array_length(ett));
|
2004-01-20 17:58:37 +00:00
|
|
|
|
|
|
|
/* Preferences */
|
|
|
|
smpp_module = prefs_register_protocol (proto_smpp, NULL);
|
|
|
|
prefs_register_bool_preference (smpp_module,
|
|
|
|
"reassemble_smpp_over_tcp",
|
2004-08-21 09:02:52 +00:00
|
|
|
"Reassemble SMPP over TCP messages spanning multiple TCP segments",
|
|
|
|
"Whether the SMPP dissector should reassemble messages spanning multiple TCP segments."
|
|
|
|
" To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
|
2004-01-20 17:58:37 +00:00
|
|
|
&reassemble_over_tcp);
|
2001-12-03 20:18:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If dissector uses sub-dissector registration add a registration routine.
|
|
|
|
* This format is required because a script is used to find these routines and
|
|
|
|
* create the code that calls these routines.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
proto_reg_handoff_smpp(void)
|
|
|
|
{
|
|
|
|
dissector_handle_t smpp_handle;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SMPP can be spoken on any port under TCP or X.25
|
2002-03-10 03:08:31 +00:00
|
|
|
* ...how *do* we do that under X.25?
|
|
|
|
*
|
|
|
|
* We can register the heuristic SMPP dissector with X.25, for one
|
|
|
|
* thing. We don't currently have any mechanism to allow the user
|
|
|
|
* to specify that a given X.25 circuit is to be dissected as SMPP,
|
|
|
|
* however.
|
2001-12-03 20:18:29 +00:00
|
|
|
*/
|
|
|
|
smpp_handle = create_dissector_handle(dissect_smpp, proto_smpp);
|
|
|
|
dissector_add_handle("tcp.port", smpp_handle);
|
|
|
|
heur_dissector_add("tcp", dissect_smpp_heur, proto_smpp);
|
2002-03-10 03:08:31 +00:00
|
|
|
heur_dissector_add("x.25", dissect_smpp_heur, proto_smpp);
|
2003-07-02 21:10:50 +00:00
|
|
|
|
|
|
|
/* Required for call_dissector() */
|
2004-01-27 00:20:37 +00:00
|
|
|
DebugLog(("Finding gsm-sms-ud subdissector\n"));
|
|
|
|
gsm_sms_handle = find_dissector("gsm-sms-ud");
|
2005-06-10 18:28:22 +00:00
|
|
|
DISSECTOR_ASSERT(gsm_sms_handle);
|
2001-12-03 20:18:29 +00:00
|
|
|
}
|