Treat TVBs as opaque: use the accessor functions instead of accessing the fields
[obnox/wireshark/wip.git] / epan / dissectors / packet-smpp.c
1 /* packet-smpp.c
2  * Routines for Short Message Peer to Peer dissection
3  * Copyright 2001, Tom Uijldert.
4  *
5  * Data Coding Scheme decoding for GSM (SMS and CBS),
6  * provided by Olivier Biot.
7  *
8  * Dissection of multiple SMPP PDUs within one packet
9  * provided by Chris Wilson.
10  *
11  * Statistics support using Stats Tree API
12  * provided by Abhik Sarkar
13  *
14  * Support for SMPP 5.0
15  * introduced by Abhik Sarkar
16  *
17  * $Id$
18  *
19  * Refer to the AUTHORS file or the AUTHORS section in the man page
20  * for contacting the author(s) of this file.
21  *
22  * Wireshark - Network traffic analyzer
23  * By Gerald Combs <gerald@wireshark.org>
24  * Copyright 1998 Gerald Combs
25  *
26  * This program is free software; you can redistribute it and/or
27  * modify it under the terms of the GNU General Public License
28  * as published by the Free Software Foundation; either version 2
29  * of the License, or (at your option) any later version.
30  *
31  * This program is distributed in the hope that it will be useful,
32  * but WITHOUT ANY WARRANTY; without even the implied warranty of
33  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34  * GNU General Public License for more details.
35  *
36  * You should have received a copy of the GNU General Public License
37  * along with this program; if not, write to the Free Software
38  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
39  * ----------
40  *
41  * Dissector of an SMPP (Short Message Peer to Peer) PDU, as defined by the
42  * SMS forum (www.smsforum.net) in "SMPP protocol specification v3.4"
43  * (document version: 12-Oct-1999 Issue 1.2)
44  */
45
46 #ifdef HAVE_CONFIG_H
47 # include "config.h"
48 #endif
49
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <string.h>
53 #include <time.h>
54
55 #include <glib.h>
56
57 #include <epan/packet.h>
58 #include <epan/tap.h>
59 #include <epan/stats_tree.h>
60
61 #include <epan/prefs.h>
62 #include <epan/emem.h>
63 #include "packet-tcp.h"
64 #include "packet-smpp.h"
65
66 /* General-purpose debug logger.
67  * Requires double parentheses because of variable arguments of printf().
68  *
69  * Enable debug logging for SMPP by defining AM_CFLAGS
70  * so that it contains "-DDEBUG_smpp"
71  */
72 #ifdef DEBUG_smpp
73 #define DebugLog(x) \
74     g_print("%s:%u: ", __FILE__, __LINE__);     \
75     g_print x
76 #else
77 #define DebugLog(x) ;
78 #endif
79
80 #define SMPP_MIN_LENGTH 16
81
82 /* Forward declarations         */
83 static void dissect_smpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
84 static guint get_smpp_pdu_len(packet_info *pinfo, tvbuff_t *tvb, int offset);
85 static void dissect_smpp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
86
87 /*
88  * Initialize the protocol and registered fields
89  *
90  * Fixed header section
91  */
92 static int proto_smpp                           = -1;
93
94 static int st_smpp_ops                          = -1;
95 static int st_smpp_req                          = -1;
96 static int st_smpp_res                          = -1;
97 static int st_smpp_res_status                   = -1;
98
99 static int hf_smpp_command_id                   = -1;
100 static int hf_smpp_command_length               = -1;
101 static int hf_smpp_command_status               = -1;
102 static int hf_smpp_sequence_number              = -1;
103
104 /*
105  * Fixed body section
106  */
107 static int hf_smpp_system_id                    = -1;
108 static int hf_smpp_password                     = -1;
109 static int hf_smpp_system_type                  = -1;
110 static int hf_smpp_interface_version            = -1;
111 static int hf_smpp_addr_ton                     = -1;
112 static int hf_smpp_addr_npi                     = -1;
113 static int hf_smpp_address_range                = -1;
114 static int hf_smpp_service_type                 = -1;
115 static int hf_smpp_source_addr_ton              = -1;
116 static int hf_smpp_source_addr_npi              = -1;
117 static int hf_smpp_source_addr                  = -1;
118 static int hf_smpp_dest_addr_ton                = -1;
119 static int hf_smpp_dest_addr_npi                = -1;
120 static int hf_smpp_destination_addr             = -1;
121 static int hf_smpp_esm_submit_msg_mode          = -1;
122 static int hf_smpp_esm_submit_msg_type          = -1;
123 static int hf_smpp_esm_submit_features          = -1;
124 static int hf_smpp_protocol_id                  = -1;
125 static int hf_smpp_priority_flag                = -1;
126 static int hf_smpp_schedule_delivery_time       = -1;
127 static int hf_smpp_schedule_delivery_time_r     = -1;
128 static int hf_smpp_validity_period              = -1;
129 static int hf_smpp_validity_period_r            = -1;
130 static int hf_smpp_regdel_receipt               = -1;
131 static int hf_smpp_regdel_acks                  = -1;
132 static int hf_smpp_regdel_notif                 = -1;
133 static int hf_smpp_replace_if_present_flag      = -1;
134 static int hf_smpp_data_coding                  = -1;
135 static int hf_smpp_sm_default_msg_id            = -1;
136 static int hf_smpp_sm_length                    = -1;
137 static int hf_smpp_short_message                = -1;
138 static int hf_smpp_message_id                   = -1;
139 static int hf_smpp_dlist                        = -1;
140 static int hf_smpp_dlist_resp                   = -1;
141 static int hf_smpp_dl_name                      = -1;
142 static int hf_smpp_final_date                   = -1;
143 static int hf_smpp_final_date_r                 = -1;
144 static int hf_smpp_message_state                = -1;
145 static int hf_smpp_error_code                   = -1;
146 static int hf_smpp_error_status_code            = -1;
147 static int hf_smpp_esme_addr_ton                = -1;
148 static int hf_smpp_esme_addr_npi                = -1;
149 static int hf_smpp_esme_addr                    = -1;
150
151 /*
152  * Optional parameter section
153  */
154 static int hf_smpp_opt_params                   = -1;
155 static int hf_smpp_opt_param                    = -1;
156 static int hf_smpp_opt_param_tag                = -1;
157 static int hf_smpp_opt_param_len                = -1;
158 static int hf_smpp_vendor_op                    = -1;
159 static int hf_smpp_reserved_op                  = -1;
160
161 static int hf_smpp_dest_addr_subunit            = -1;
162 static int hf_smpp_dest_network_type            = -1;
163 static int hf_smpp_dest_bearer_type             = -1;
164 static int hf_smpp_dest_telematics_id           = -1;
165 static int hf_smpp_source_addr_subunit          = -1;
166 static int hf_smpp_source_network_type          = -1;
167 static int hf_smpp_source_bearer_type           = -1;
168 static int hf_smpp_source_telematics_id         = -1;
169 static int hf_smpp_qos_time_to_live             = -1;
170 static int hf_smpp_payload_type                 = -1;
171 static int hf_smpp_additional_status_info_text  = -1;
172 static int hf_smpp_receipted_message_id         = -1;
173 static int hf_smpp_msg_wait_ind                 = -1;
174 static int hf_smpp_msg_wait_type                = -1;
175 static int hf_smpp_privacy_indicator            = -1;
176 static int hf_smpp_source_subaddress            = -1;
177 static int hf_smpp_dest_subaddress              = -1;
178 static int hf_smpp_user_message_reference       = -1;
179 static int hf_smpp_user_response_code           = -1;
180 static int hf_smpp_source_port                  = -1;
181 static int hf_smpp_destination_port             = -1;
182 static int hf_smpp_sar_msg_ref_num              = -1;
183 static int hf_smpp_language_indicator           = -1;
184 static int hf_smpp_sar_total_segments           = -1;
185 static int hf_smpp_sar_segment_seqnum           = -1;
186 static int hf_smpp_SC_interface_version         = -1;
187 static int hf_smpp_callback_num_pres            = -1;
188 static int hf_smpp_callback_num_scrn            = -1;
189 static int hf_smpp_callback_num_atag            = -1;
190 static int hf_smpp_number_of_messages           = -1;
191 static int hf_smpp_callback_num                 = -1;
192 static int hf_smpp_dpf_result                   = -1;
193 static int hf_smpp_set_dpf                      = -1;
194 static int hf_smpp_ms_availability_status       = -1;
195 static int hf_smpp_network_error_type           = -1;
196 static int hf_smpp_network_error_code           = -1;
197 static int hf_smpp_message_payload              = -1;
198 static int hf_smpp_delivery_failure_reason      = -1;
199 static int hf_smpp_more_messages_to_send        = -1;
200 static int hf_smpp_ussd_service_op              = -1;
201 static int hf_smpp_display_time                 = -1;
202 static int hf_smpp_sms_signal                   = -1;
203 static int hf_smpp_ms_validity                  = -1;
204 static int hf_smpp_alert_on_message_delivery_null       = -1;
205 static int hf_smpp_alert_on_message_delivery    = -1;
206 static int hf_smpp_its_reply_type               = -1;
207 static int hf_smpp_its_session_number           = -1;
208 static int hf_smpp_its_session_sequence         = -1;
209 static int hf_smpp_its_session_ind              = -1;
210
211 /* Optional Parameters introduced in SMPP 5.0   */
212 static int hf_smpp_congestion_state             = -1;
213 static int hf_smpp_billing_identification       = -1;
214 static int hf_smpp_dest_addr_np_country         = -1;
215 static int hf_smpp_dest_addr_np_information     = -1;
216 static int hf_smpp_dest_addr_np_resolution      = -1;
217 static int hf_smpp_source_network_id            = -1;
218 static int hf_smpp_source_node_id               = -1;
219 static int hf_smpp_dest_network_id              = -1;
220 static int hf_smpp_dest_node_id                 = -1;
221 /* Optional Parameters for Cell Broadcast Operations */
222 static int hf_smpp_broadcast_channel_indicator  = -1;
223 static int hf_smpp_broadcast_content_type_nw    = -1;
224 static int hf_smpp_broadcast_content_type_type  = -1;
225 static int hf_smpp_broadcast_content_type_info  = -1;
226 static int hf_smpp_broadcast_message_class      = -1;
227 static int hf_smpp_broadcast_rep_num            = -1;
228 static int hf_smpp_broadcast_frequency_interval_unit    = -1;
229 static int hf_smpp_broadcast_frequency_interval_value   = -1;
230 static int hf_smpp_broadcast_area_identifier    = -1;
231 static int hf_smpp_broadcast_area_identifier_format     = -1;
232 static int hf_smpp_broadcast_error_status       = -1;
233 static int hf_smpp_broadcast_area_success       = -1;
234 static int hf_smpp_broadcast_end_time           = -1;
235 static int hf_smpp_broadcast_end_time_r         = -1;
236 static int hf_smpp_broadcast_service_group      = -1;
237
238 /*
239  * Data Coding Scheme section
240  */
241 static int hf_smpp_dcs = -1;
242 static int hf_smpp_dcs_sms_coding_group = -1;
243 static int hf_smpp_dcs_text_compression = -1;
244 static int hf_smpp_dcs_class_present = -1;
245 static int hf_smpp_dcs_charset = -1;
246 static int hf_smpp_dcs_class = -1;
247 static int hf_smpp_dcs_cbs_coding_group = -1;
248 static int hf_smpp_dcs_cbs_language = -1;
249 static int hf_smpp_dcs_wap_charset = -1;
250 static int hf_smpp_dcs_wap_class = -1;
251 static int hf_smpp_dcs_cbs_class = -1;
252
253 /* Initialize the subtree pointers */
254 static gint ett_smpp            = -1;
255 static gint ett_dlist           = -1;
256 static gint ett_dlist_resp      = -1;
257 static gint ett_opt_params      = -1;
258 static gint ett_opt_param       = -1;
259 static gint ett_dcs             = -1;
260
261 /* Reassemble SMPP TCP segments */
262 static gboolean reassemble_over_tcp = TRUE;
263
264 /* Tap */
265 static int smpp_tap             = -1;
266
267 /*
268  * Value-arrays for field-contents
269  */
270 static const value_string vals_command_id[] = {         /* Operation    */
271     { 0x80000000, "Generic_nack" },
272     { 0x00000001, "Bind_receiver" },
273     { 0x80000001, "Bind_receiver - resp" },
274     { 0x00000002, "Bind_transmitter" },
275     { 0x80000002, "Bind_transmitter - resp" },
276     { 0x00000003, "Query_sm" },
277     { 0x80000003, "Query_sm - resp" },
278     { 0x00000004, "Submit_sm" },
279     { 0x80000004, "Submit_sm - resp" },
280     { 0x00000005, "Deliver_sm" },
281     { 0x80000005, "Deliver_sm - resp" },
282     { 0x00000006, "Unbind" },
283     { 0x80000006, "Unbind - resp" },
284     { 0x00000007, "Replace_sm" },
285     { 0x80000007, "Replace_sm - resp" },
286     { 0x00000008, "Cancel_sm" },
287     { 0x80000008, "Cancel_sm - resp" },
288     { 0x00000009, "Bind_transceiver" },
289     { 0x80000009, "Bind_transceiver - resp" },
290     { 0x0000000B, "Outbind" },
291     { 0x00000015, "Enquire_link" },
292     { 0x80000015, "Enquire_link - resp" },
293     { 0x00000021, "Submit_multi" },
294     { 0x80000021, "Submit_multi - resp" },
295     { 0x00000102, "Alert_notification" },
296     { 0x00000103, "Data_sm" },
297     { 0x80000103, "Data_sm - resp" },
298     /* Introduced in SMPP 5.0 */
299     { 0x00000111, "Broadcast_sm" },
300     { 0x80000111, "Broadcast_sm - resp" },
301     { 0x00000112, "Query_broadcast_sm" },
302     { 0x80000112, "Query_broadcast_sm - resp" },
303     { 0x00000113, "Cancel_broadcast_sm" },
304     { 0x80000113, "Cancel_broadcast_sm - resp" },
305     { 0, NULL }
306 };
307
308 static const value_string vals_command_status[] = {     /* Status       */
309     { 0x00000000, "Ok" },
310     { 0x00000001, "Message length is invalid" },
311     { 0x00000002, "Command length is invalid" },
312     { 0x00000003, "Invalid command ID" },
313     { 0x00000004, "Incorrect BIND status for given command" },
314     { 0x00000005, "ESME already in bound state" },
315     { 0x00000006, "Invalid priority flag" },
316     { 0x00000007, "Invalid registered delivery flag" },
317     { 0x00000008, "System error" },
318     { 0x00000009, "[Reserved]" },
319     { 0x0000000A, "Invalid source address" },
320     { 0x0000000B, "Invalid destination address" },
321     { 0x0000000C, "Message ID is invalid" },
322     { 0x0000000D, "Bind failed" },
323     { 0x0000000E, "Invalid password" },
324     { 0x0000000F, "Invalid system ID" },
325     { 0x00000010, "[Reserved]" },
326     { 0x00000011, "Cancel SM failed" },
327     { 0x00000012, "[Reserved]" },
328     { 0x00000013, "Replace SM failed" },
329     { 0x00000014, "Message queue full" },
330     { 0x00000015, "Invalid service type" },
331     { 0x00000033, "Invalid number of destinations" },
332     { 0x00000034, "Invalid distribution list name" },
333     { 0x00000040, "Destination flag is invalid (submit_multi)" },
334     { 0x00000041, "[Reserved]" },
335     { 0x00000042, "Invalid 'submit with replace' request" },
336     { 0x00000043, "Invalid esm_class field data" },
337     { 0x00000044, "Cannot submit to distribution list" },
338     { 0x00000045, "submit_sm or submit_multi failed" },
339     { 0x00000046, "[Reserved]" },
340     { 0x00000047, "[Reserved]" },
341     { 0x00000048, "Invalid source address TON" },
342     { 0x00000049, "Invalid source address NPI" },
343     { 0x00000050, "Invalid destination address TON" },
344     { 0x00000051, "Invalid destination address NPI" },
345     { 0x00000052, "[Reserved]" },
346     { 0x00000053, "Invalid system_type field" },
347     { 0x00000054, "Invalid replace_if_present flag" },
348     { 0x00000055, "Invalid number of messages" },
349     { 0x00000056, "[Reserved]" },
350     { 0x00000057, "[Reserved]" },
351     { 0x00000058, "Throttling error (ESME exceeded allowed message limits)" },
352     { 0x00000059, "[Reserved]" },
353     { 0x00000060, "[Reserved]" },
354     { 0x00000061, "Invalid scheduled delivery time" },
355     { 0x00000062, "Invalid message validity period (expiry time)" },
356     { 0x00000063, "Predefined message invalid or not found" },
357     { 0x00000064, "ESME receiver temporary app error code" },
358     { 0x00000065, "ESME receiver permanent app error code" },
359     { 0x00000066, "ESME receiver reject message error code" },
360     { 0x00000067, "query_sm request failed" },
361     { 0x000000C0, "Error in the optional part of the PDU body" },
362     { 0x000000C1, "Optional parameter not allowed" },
363     { 0x000000C2, "Invalid parameter length" },
364     { 0x000000C3, "Expected optional parameter missing" },
365     { 0x000000C4, "Invalid optional parameter  value" },
366     { 0x000000FE, "(Transaction) Delivery failure (used for data_sm_resp)" },
367     { 0x000000FF, "Unknown error" },
368     /* Introduced in SMPP 5.0 */
369     { 0x00000100, "ESME Not authorised to use specified service_type." },
370     { 0x00000101, "ESME Prohibited from using specified operation."},
371     { 0x00000102, "Specified service_type is unavailable." },
372     { 0x00000103, "Specified service_type is denied." },
373     { 0x00000104, "Invalid Data Coding Scheme." },
374     { 0x00000105, "Source Address Sub unit is Invalid." },
375     { 0x00000106, "Destination Address Sub unit is Invalid." },
376     { 0x00000107, "Broadcast Frequency Interval is invalid." },
377     { 0x00000108, "Broadcast Alias Name is invalid." },
378     { 0x00000109, "Broadcast Area Format is invalid." },
379     { 0x0000010A, "Number of Broadcast Areas is invalid." },
380     { 0x0000010B, "Broadcast Content Type is invalid." },
381     { 0x0000010C, "Broadcast Message Class is invalid." },
382     { 0x0000010D, "broadcast_sm operation failed." },
383     { 0x0000010E, "query_broadcast_sm operation failed." },
384     { 0x0000010F, "cancel_broadcast_sm operation failed." },
385     { 0x00000110, "Number of Repeated Broadcasts is invalid." },
386     { 0x00000111, "Broadcast Service Group is invalid." },
387     { 0x00000112, "Broadcast Channel Indicator is invalid." },
388     { 0, NULL }
389 };
390
391 static const value_string vals_tlv_tags[] = {
392     { 0x0005, "dest_addr_subunit" },
393     { 0x0006, "dest_network_type" },
394     { 0x0007, "dest_bearer_type" },
395     { 0x0008, "dest_telematics_id" },
396     { 0x000D, "source_addr_subunit" },
397     { 0x000E, "source_network_type" },
398     { 0x000F, "source_bearer_type" },
399     { 0x0010, "source_telematics_id" },
400     { 0x0017, "qos_time_to_live" },
401     { 0x0019, "payload_type" },
402     { 0x001D, "additional_status_info_text" },
403     { 0x001E, "receipted_message_id" },
404     { 0x0030, "ms_msg_wait_facilities" },
405     { 0x0201, "privacy_indicator" },
406     { 0x0202, "source_subaddress" },
407     { 0x0203, "dest_subaddress" },
408     { 0x0204, "user_message_reference" },
409     { 0x0205, "user_response_code" },
410     { 0x020A, "source_port" },
411     { 0x020B, "dest_port" },
412     { 0x020C, "sar_msg_ref_num" },
413     { 0x020D, "language_indicator" },
414     { 0x020E, "sar_total_segments" },
415     { 0x020F, "sar_segment_seqnum" },
416     { 0x0210, "sc_interface_version" },
417     { 0x0302, "callback_num_pres_ind" },
418     { 0x0303, "callback_num_atag" },
419     { 0x0304, "number_of_messages" },
420     { 0x0381, "callback_num" },
421     { 0x0420, "dpf_result" },
422     { 0x0421, "set_dpf" },
423     { 0x0422, "ms_availability_status" },
424     { 0x0423, "network_error_code" },
425     { 0x0424, "message_payload" },
426     { 0x0425, "delivery_failure_reason" },
427     { 0x0426, "more_messages_to_send" },
428     { 0x0427, "message_state" },
429     { 0x0428, "congestion_state" },
430     { 0x0501, "ussd_service_op" },
431     { 0x0600, "broadcast_channel_indicator" },
432     { 0x0601, "broadcast_content_type" },
433     { 0x0602, "broadcast_content_type_info" },
434     { 0x0603, "broadcast_message_class" },
435     { 0x0604, "broadcast_rep_num" },
436     { 0x0605, "broadcast_frequency_interval" },
437     { 0x0606, "broadcast_area_identifier" },
438     { 0x0607, "broadcast_error_status" },
439     { 0x0608, "broadcast_area_success" },
440     { 0x0609, "broadcast_end_time" },
441     { 0x060A, "broadcast_service_group" },
442     { 0x060B, "billing_identification" },
443     { 0x060D, "source_network_id" },
444     { 0x060E, "dest_network_id" },
445     { 0x060F, "source_node_id" },
446     { 0x0610, "dest_node_id" },
447     { 0x0611, "dest_addr_np_resolution" },
448     { 0x0612, "dest_addr_np_information" },
449     { 0x0613, "dest_addr_np_country" },
450     { 0x1201, "display_time" },
451     { 0x1203, "sms_signal" },
452     { 0x1204, "ms_validity" },
453     { 0x130C, "alert_on_message_delivery" },
454     { 0x1380, "its_reply_type" },
455     { 0x1383, "its_session_info" },
456     { 0, NULL }
457 };
458
459 static const value_string vals_addr_ton[] = {
460     { 0, "Unknown" },
461     { 1, "International" },
462     { 2, "National" },
463     { 3, "Network specific" },
464     { 4, "Subscriber number" },
465     { 5, "Alphanumeric" },
466     { 6, "Abbreviated" },
467     { 0, NULL }
468 };
469
470 static const value_string vals_addr_npi[] = {
471     {  0, "Unknown" },
472     {  1, "ISDN (E163/E164)" },
473     {  3, "Data (X.121)" },
474     {  4, "Telex (F.69)" },
475     {  6, "Land mobile (E.212)" },
476     {  8, "National" },
477     {  9, "Private" },
478     { 10, "ERMES" },
479     { 14, "Internet (IP)" },
480     { 18, "WAP client Id" },
481     {  0, NULL }
482 };
483
484 static const value_string vals_esm_submit_msg_mode[] = {
485     {  0x0, "Default SMSC mode" },
486     {  0x1, "Datagram mode" },
487     {  0x2, "Forward mode" },
488     {  0x3, "Store and forward mode" },
489     {  0, NULL }
490 };
491
492 static const value_string vals_esm_submit_msg_type[] = {
493     {  0x0, "Default message type" },
494     {  0x1, "Short message contains SMSC Delivery Receipt" },
495     {  0x2, "Short message contains (E)SME delivery acknowledgement" },
496     {  0x3, "Reserved" },
497     {  0x4, "Short message contains (E)SME manual/user acknowledgement" },
498     {  0x5, "Reserved" },
499     {  0x6, "Short message contains conversation abort" },
500     {  0x7, "Reserved" },
501     {  0x8, "Short message contains intermediate delivery notification" },
502     {  0, NULL }
503 };
504
505 static const value_string vals_esm_submit_features[] = {
506     {  0x0, "No specific features selected" },
507     {  0x1, "UDHI indicator" },
508     {  0x2, "Reply path" },
509     {  0x3, "UDHI and reply path" },
510     {  0, NULL }
511 };
512
513 static const value_string vals_priority_flag[] = {
514     {  0, "GSM: None      ANSI-136: Bulk         IS-95: Normal" },
515     {  1, "GSM: priority  ANSI-136: Normal       IS-95: Interactive" },
516     {  2, "GSM: priority  ANSI-136: Urgent       IS-95: Urgent" },
517     {  3, "GSM: priority  ANSI-136: Very Urgent  IS-95: Emergency" },
518     {  0, NULL }
519 };
520
521 static const value_string vals_regdel_receipt[] = {
522     {  0x0, "No SMSC delivery receipt requested" },
523     {  0x1, "Delivery receipt requested (for success or failure)" },
524     {  0x2, "Delivery receipt requested (for failure)" },
525     {  0x3, "Reserved in version <= 3.4; Delivery receipt requested (for success) in 5.0" },
526     {  0, NULL }
527 };
528
529 static const value_string vals_regdel_acks[] = {
530     {  0x0, "No recipient SME acknowledgement requested" },
531     {  0x1, "SME delivery acknowledgement requested" },
532     {  0x2, "SME manual/user acknowledgement requested" },
533     {  0x3, "Both delivery and manual/user acknowledgement requested" },
534     {  0, NULL }
535 };
536
537 static const value_string vals_regdel_notif[] = {
538     {  0x0, "No intermediate notification requested" },
539     {  0x1, "Intermediate notification requested" },
540     {  0, NULL }
541 };
542
543 static const value_string vals_replace_if_present_flag[] = {
544     {  0x0, "Don't replace" },
545     {  0x1, "Replace" },
546     {  0, NULL }
547 };
548
549 static const value_string vals_data_coding[] = {
550     {  0, "SMSC default alphabet" },
551     {  1, "IA5 (CCITT T.50/ASCII (ANSI X3.4)" },
552     {  2, "Octet unspecified (8-bit binary)" },
553     {  3, "Latin 1 (ISO-8859-1)" },
554     {  4, "Octet unspecified (8-bit binary)" },
555     {  5, "JIS (X 0208-1990)" },
556     {  6, "Cyrillic (ISO-8859-5)" },
557     {  7, "Latin/Hebrew (ISO-8859-8)" },
558     {  8, "UCS2 (ISO/IEC-10646)" },
559     {  9, "Pictogram encoding" },
560     {  10, "ISO-2022-JP (Music codes)" },
561     {  11, "reserved" },
562     {  12, "reserved" },
563     {  13, "Extended Kanji JIS(X 0212-1990)" },
564     {  14, "KS C 5601" },
565     /*! \TODO Rest to be defined (bitmask?) according GSM 03.38 */
566     {  0, NULL }
567 };
568
569 static const value_string vals_message_state[] = {
570     {  1, "ENROUTE" },
571     {  2, "DELIVERED" },
572     {  3, "EXPIRED" },
573     {  4, "DELETED" },
574     {  5, "UNDELIVERABLE" },
575     {  6, "ACCEPTED" },
576     {  7, "UNKNOWN" },
577     {  8, "REJECTED" },
578     {  0, NULL }
579 };
580
581 static const value_string vals_addr_subunit[] = {
582     {  0, "Unknown -default-" },
583     {  1, "MS Display" },
584     {  2, "Mobile equipment" },
585     {  3, "Smart card 1" },
586     {  4, "External unit 1" },
587     {  0, NULL }
588 };
589
590 static const value_string vals_network_type[] = {
591     {  0, "Unknown" },
592     {  1, "GSM" },
593     {  2, "ANSI-136/TDMA" },
594     {  3, "IS-95/CDMA" },
595     {  4, "PDC" },
596     {  5, "PHS" },
597     {  6, "iDEN" },
598     {  7, "AMPS" },
599     {  8, "Paging network" },
600     {  0, NULL }
601 };
602
603 static const value_string vals_bearer_type[] = {
604     {  0, "Unknown" },
605     {  1, "SMS" },
606     {  2, "Circuit Switched Data (CSD)" },
607     {  3, "Packet data" },
608     {  4, "USSD" },
609     {  5, "CDPD" },
610     {  6, "DataTAC" },
611     {  7, "FLEX/ReFLEX" },
612     {  8, "Cell Broadcast" },
613     {  0, NULL }
614 };
615
616 static const value_string vals_payload_type[] = {
617     {  0, "Default" },
618     {  1, "WCMP message" },
619     {  0, NULL }
620 };
621
622 static const value_string vals_privacy_indicator[] = {
623     {  0, "Not restricted -default-" },
624     {  1, "Restricted" },
625     {  2, "Confidential" },
626     {  3, "Secret" },
627     {  0, NULL }
628 };
629
630 static const value_string vals_language_indicator[] = {
631     {  0, "Unspecified -default-" },
632     {  1, "english" },
633     {  2, "french" },
634     {  3, "spanish" },
635     {  4, "german" },
636     {  5, "portuguese" },
637     {  0, NULL }
638 };
639
640 static const value_string vals_display_time[] = {
641     {  0, "Temporary" },
642     {  1, "Default -default-" },
643     {  2, "Invoke" },
644     {  0, NULL }
645 };
646
647 static const value_string vals_ms_validity[] = {
648     {  0, "Store indefinitely -default-" },
649     {  1, "Power down" },
650     {  2, "SID based registration area" },
651     {  3, "Display only" },
652     {  0, NULL }
653 };
654
655 static const value_string vals_dpf_result[] = {
656     {  0, "DPF not set" },
657     {  1, "DPF set" },
658     {  0, NULL }
659 };
660
661 static const value_string vals_set_dpf[] = {
662     {  0, "Not requested (Set DPF for delivery failure)" },
663     {  1, "Requested (Set DPF for delivery failure)" },
664     {  0, NULL }
665 };
666
667 static const value_string vals_ms_availability_status[] = {
668     {  0, "Available -default-" },
669     {  1, "Denied" },
670     {  2, "Unavailable" },
671     {  0, NULL }
672 };
673
674 static const value_string vals_delivery_failure_reason[] = {
675     {  0, "Destination unavailable" },
676     {  1, "Destination address invalid" },
677     {  2, "Permanent network error" },
678     {  3, "Temporary network error" },
679     {  0, NULL }
680 };
681
682 static const value_string vals_more_messages_to_send[] = {
683     {  0, "No more messages" },
684     {  1, "More messages -default-" },
685     {  0, NULL }
686 };
687
688 static const value_string vals_its_reply_type[] = {
689     {  0, "Digit" },
690     {  1, "Number" },
691     {  2, "Telephone no." },
692     {  3, "Password" },
693     {  4, "Character line" },
694     {  5, "Menu" },
695     {  6, "Date" },
696     {  7, "Time" },
697     {  8, "Continue" },
698     {  0, NULL }
699 };
700
701 static const value_string vals_ussd_service_op[] = {
702     {  0, "PSSD indication" },
703     {  1, "PSSR indication" },
704     {  2, "USSR request" },
705     {  3, "USSN request" },
706     { 16, "PSSD response" },
707     { 17, "PSSR response" },
708     { 18, "USSR confirm" },
709     { 19, "USSN confirm" },
710     {  0, NULL }
711 };
712
713 static const value_string vals_msg_wait_ind[] = {
714     {  0, "Set indication inactive" },
715     {  1, "Set indication active" },
716     {  0, NULL }
717 };
718
719 static const value_string vals_msg_wait_type[] = {
720     {  0, "Voicemail message waiting" },
721     {  1, "Fax message waiting" },
722     {  2, "Electronic mail message waiting" },
723     {  3, "Other message waiting" },
724     {  0, NULL }
725 };
726
727 static const value_string vals_callback_num_pres[] = {
728     {  0, "Presentation allowed" },
729     {  1, "Presentation restricted" },
730     {  2, "Number not available" },
731     {  3, "[Reserved]" },
732     {  0, NULL }
733 };
734
735 static const value_string vals_callback_num_scrn[] = {
736     {  0, "User provided, not screened" },
737     {  1, "User provided, verified and passed" },
738     {  2, "User provided, verified and failed" },
739     {  3, "Network provided" },
740     {  0, NULL }
741 };
742
743 static const value_string vals_network_error_type[] = {
744     {  1, "ANSI-136 (Access Denied Reason)" },
745     {  2, "IS-95 (Access Denied Reason)" },
746     {  3, "GSM" },
747     {  4, "[Reserved] in <= 3.4; ANSI 136 Cause Code in 5.0" },
748     {  5, "[Reserved] in <= 3.4; IS 95 Cause Code in 5.0" },
749     {  6, "[Reserved] in <= 3.4; ANSI-41 Error in 5.0" },
750     {  7, "[Reserved] in <= 3.4; SMPP Error in 5.0" },
751     {  8, "[Reserved] in <= 3.4; Message Center Specific in 5.0" },
752     {  0, NULL }
753 };
754
755 static const value_string vals_its_session_ind[] = {
756     {  0, "End of session indicator inactive" },
757     {  1, "End of session indicator active" },
758     {  0, NULL }
759 };
760
761 /* Data Coding Scheme: see 3GPP TS 23.040 and 3GPP TS 23.038 */
762 static const value_string vals_dcs_sms_coding_group[] = {
763     { 0x00, "SMS DCS: General Data Coding indication - Uncompressed text, no message class" },
764     { 0x01, "SMS DCS: General Data Coding indication - Uncompressed text" },
765     { 0x02, "SMS DCS: General Data Coding indication - Compressed text, no message class" },
766     { 0x03, "SMS DCS: General Data Coding indication - Compressed text" },
767     { 0x04, "SMS DCS: Message Marked for Automatic Deletion - Uncompressed text, no message class" },
768     { 0x05, "SMS DCS: Message Marked for Automatic Deletion - Uncompressed text" },
769     { 0x06, "SMS DCS: Message Marked for Automatic Deletion - Compressed text, no message class" },
770     { 0x07, "SMS DCS: Message Marked for Automatic Deletion - Compressed text" },
771     { 0x08, "SMS DCS: Reserved" },
772     { 0x09, "SMS DCS: Reserved" },
773     { 0x0A, "SMS DCS: Reserved" },
774     { 0x0B, "SMS DCS: Reserved" },
775     { 0x0C, "SMS DCS: Message Waiting Indication - Discard Message" },
776     { 0x0D, "SMS DCS: Message Waiting Indication - Store Message (GSM 7-bit default alphabet)" },
777     { 0x0E, "SMS DCS: Message Waiting Indication - Store Message (UCS-2 character set)" },
778     { 0x0F, "SMS DCS: Data coding / message class" },
779     { 0x00, NULL }
780 };
781
782 static const true_false_string tfs_dcs_text_compression = {
783     "Compressed text",
784     "Uncompressed text"
785 };
786
787 static const true_false_string tfs_dcs_class_present = {
788     "Message class is present",
789     "No message class"
790 };
791
792 static const value_string vals_dcs_charset[] = {
793     { 0x00, "GSM 7-bit default alphabet" },
794     { 0x01, "8-bit data" },
795     { 0x02, "UCS-2 (16-bit) data" },
796     { 0x03, "Reserved" },
797     { 0x00, NULL }
798 };
799
800 static const value_string vals_dcs_class[] = {
801     { 0x00, "Class 0" },
802     { 0x01, "Class 1 - ME specific" },
803     { 0x02, "Class 2 - (U)SIM specific" },
804     { 0x03, "Class 3 - TE specific" },
805     { 0x00, NULL }
806 };
807
808 static const value_string vals_dcs_cbs_coding_group[] = {
809     { 0x00, "CBS DCS: Language using the GSM 7-bit default alphabet" },
810     { 0x01, "CBS DCS: Language indication at beginning of message" },
811     { 0x02, "CBS DCS: Language using the GSM 7-bit default alphabet" },
812     { 0x03, "CBS DCS: Reserved" },
813     { 0x04, "CBS DCS: General Data Coding indication - Uncompressed text, no message class" },
814     { 0x05, "CBS DCS: General Data Coding indication - Uncompressed text" },
815     { 0x06, "CBS DCS: General Data Coding indication - Compressed text, no message class" },
816     { 0x07, "CBS DCS: General Data Coding indication - Compressed text" },
817     { 0x08, "CBS DCS: Reserved" },
818     { 0x09, "CBS DCS: Message with User Data Header structure" },
819     { 0x0A, "CBS DCS: Reserved" },
820     { 0x0B, "CBS DCS: Reserved" },
821     { 0x0C, "CBS DCS: Reserved" },
822     { 0x0D, "CBS DCS: Reserved" },
823     { 0x0E, "CBS DCS: Defined by the WAP Forum" },
824     { 0x0F, "SMS DCS: Data coding / message class" },
825     { 0x00, NULL }
826 };
827
828 static const value_string vals_dcs_cbs_language[] = {
829     { 0x00, "German" },
830     { 0x01, "English" },
831     { 0x02, "Italian" },
832     { 0x03, "French" },
833     { 0x04, "Spanish" },
834     { 0x05, "Dutch" },
835     { 0x06, "Swedish" },
836     { 0x07, "Danish" },
837     { 0x08, "Portuguese" },
838     { 0x09, "Finnish" },
839     { 0x0A, "Norwegian" },
840     { 0x0B, "Greek" },
841     { 0x0C, "Turkish" },
842     { 0x0D, "Hungarian" },
843     { 0x0E, "Polish" },
844     { 0x0F, "Language not specified" },
845     { 0x10, "GSM 7-bit default alphabet - message preceded by language indication" },
846     { 0x11, "UCS-2 (16-bit) - message preceded by language indication" },
847     { 0x20, "Czech" },
848     { 0x21, "Hebrew" },
849     { 0x22, "Arabic" },
850     { 0x23, "Russian" },
851     { 0x24, "Icelandic" },
852     { 0x00, NULL }
853 };
854
855 static const value_string vals_dcs_cbs_class[] = {
856     { 0x00, "No message class" },
857     { 0x01, "Class 1 - User defined" },
858     { 0x02, "Class 2 - User defined" },
859     { 0x03, "Class 3 - TE specific" },
860     { 0x00, NULL }
861 };
862
863 static const value_string vals_dcs_wap_class[] = {
864     { 0x00, "No message class" },
865     { 0x01, "Class 1 - ME specific" },
866     { 0x02, "Class 2 - (U)SIM specific" },
867     { 0x03, "Class 3 - TE specific" },
868     { 0x00, NULL }
869 };
870
871 static const value_string vals_dcs_wap_charset[] = {
872     { 0x00, "Reserved" },
873     { 0x01, "8-bit data" },
874     { 0x02, "Reserved" },
875     { 0x03, "Reserved" },
876     { 0x00, NULL }
877 };
878
879 static const value_string vals_alert_on_message_delivery[] = {
880     { 0x00, "Use mobile default alert (Default)" },
881     { 0x01, "Use low-priority alert" },
882     { 0x02, "Use medium-priority alert" },
883     { 0x03, "Use high-priority alert" },
884     { 0x00, NULL }
885 };
886
887 static const range_string vals_congestion_state[] = {
888     {0,     0,      "Idle"},
889     {1,     29,     "Low Load"},
890     {30,    49,     "Medium Load"},
891     {50,    79,     "High Load"},
892     {80,    89,     "Optimum Load"}, /*Specs says 80-90, but that is probably a mistake */
893     {90,    99,     "Nearing Congestion"},
894     {100,   100,    "Congested / Maximum Load"},
895     { 0,    0,      NULL }
896 };
897
898 static const range_string vals_broadcast_channel_indicator[] = {
899     {0,     0,      "Basic Broadcast Channel (Default)"},
900     {1,     1,      "Extended Broadcast Channel"},
901     {2,     255,    "[Reserved]"},
902     { 0,    0,      NULL }
903 };
904
905 static const value_string vals_broadcast_message_class[] = {
906     {0, "No Class Specified (default)"},
907     {1, "Class 1 (User Defined)"},
908     {2, "Class 2 (User Defined)"},
909     {3, "Class 3 (Terminal Equipment)"},
910     {0, NULL }
911 };
912
913 static const range_string vals_broadcast_area_success[] = {
914     {0,     100,    "%"},
915     {101,   254,    "[Reserved]"},
916     {255,   255,    "Information not available"},
917     { 0,    0,      NULL }
918 };
919
920 static const value_string vals_broadcast_content_type_nw[] = {
921     {0,     "Generic"},
922     {1,     "GSM [23041]"},
923     {2,     "TDMA [IS824][ANSI-41]"},
924     {3,     "CDMA [IS824][IS637]"},
925     {0,     NULL }
926 };
927
928 static const value_string vals_broadcast_content_type_type[] = {
929     {0x0000,        "[System Service] Index"},
930     {0x0001,        "[System Service] Emergency Broadcasts"},
931     {0x0002,        "[System Service] IRDB Download"},
932     {0x0010,        "[News Service] News Flashes"},
933     {0x0011,        "[News Service] General News (Local)"},
934     {0x0012,        "[News Service] General News (Regional)"},
935     {0x0013,        "[News Service] General News (National)"},
936     {0x0014,        "[News Service] General News (Internationa)"},
937     {0x0015,        "[News Service] Business/Financial News (Local)"},
938     {0x0016,        "[News Service] Business/Financial News (Regional)"},
939     {0x0017,        "[News Service] Business/Financial News (National)"},
940     {0x0018,        "[News Service] Business/Financial News (International)"},
941     {0x0019,        "[News Service] Sports News (Local)"},
942     {0x001A,        "[News Service] Sports News (Regional)"},
943     {0x001B,        "[News Service] Sports News (National)"},
944     {0x001C,        "[News Service] Sports News (International)"},
945     {0x001D,        "[News Service] Entertainment News (Local)"},
946     {0x001E,        "[News Service] Entertainment News (Regional)"},
947     {0x001F,        "[News Service] Entertainment News (National)"},
948     {0x0020,        "[News Service] Entertainment News (International)"},
949     {0x0021,        "[Subscriber Information Services] Medical/Health/Hospitals"},
950     {0x0022,        "[Subscriber Information Services] Doctors"},
951     {0x0023,        "[Subscriber Information Services] Pharmacy"},
952     {0x0030,        "[Subscriber Information Services] Local Traffic/Road Reports"},
953     {0x0031,        "[Subscriber Information Services] Long Distance Traffic/Road Reports"},
954     {0x0032,        "[Subscriber Information Services] Taxis"},
955     {0x0033,        "[Subscriber Information Services] Weather"},
956     {0x0034,        "[Subscriber Information Services] Local Airport Flight Schedules"},
957     {0x0035,        "[Subscriber Information Services] Restaurants"},
958     {0x0036,        "[Subscriber Information Services] Lodgings"},
959     {0x0037,        "[Subscriber Information Services] Retail Directory"},
960     {0x0038,        "[Subscriber Information Services] Advertisements"},
961     {0x0039,        "[Subscriber Information Services] Stock Quotes"},
962     {0x0040,        "[Subscriber Information Services] Employment Opportunities"},
963     {0x0041,        "[Subscriber Information Services] Technology News"},
964     {0x0070,        "[Carrier Information Services] District (Base Station Info)"},
965     {0x0071,        "[Carrier Information Services] Network Information"},
966     {0x0080,        "[Subscriber Care Services] Operator Services"},
967     {0x0081,        "[Subscriber Care Services] Directory Enquiries (National)"},
968     {0x0082,        "[Subscriber Care Services] Directory Enquiries (International)"},
969     {0x0083,        "[Subscriber Care Services] Customer Care (National)"},
970     {0x0084,        "[Subscriber Care Services] Customer Care (International)"},
971     {0x0085,        "[Subscriber Care Services] Local Date/Time/Time Zone"},
972     {0x0100,        "[Multi Category Services] Multi Category Services"},
973     {0x0000,        NULL }
974 };
975
976 static const value_string vals_broadcast_frequency_interval_unit[] = {
977     {0x00,  "As frequently as possible"},
978     {0x08,  "seconds"},
979     {0x09,  "minutes"},
980     {0x0A,  "hours"},
981     {0x0B,  "days"},
982     {0x0C,  "weeks"},
983     {0x0D,  "months"},
984     {0x0E,  "years"},
985     {0x00,  NULL }
986 };
987
988 static const value_string vals_dest_addr_np_resolution[] = {
989     {0x00,  "query has not been performed (default)"},
990     {0x01,  "query has been performed, number not ported"},
991     {0x02,  "query has been performed, number ported"},
992     {0x00,  NULL }
993 };
994
995 static const range_string vals_broadcast_area_identifier_format[] = {
996     {0, 0, "Alias / Name"},
997     {1, 1, "Ellipsoid Arc"},
998     {2, 2, "Polygon"},
999     {3, 255, "[Reserved]"},
1000     {0, 0,  NULL }
1001 };
1002
1003 static dissector_handle_t gsm_sms_handle;
1004
1005 /*
1006  * For Stats Tree
1007  */
1008 void
1009 smpp_stats_tree_init(stats_tree* st)
1010 {
1011     st_smpp_ops = stats_tree_create_node(st, "SMPP Operations", 0, TRUE);
1012     st_smpp_req = stats_tree_create_node(st, "SMPP Requests", st_smpp_ops, TRUE);
1013     st_smpp_res = stats_tree_create_node(st, "SMPP Responses", st_smpp_ops, TRUE);
1014     st_smpp_res_status = stats_tree_create_node(st, "SMPP Response Status", 0, TRUE);
1015
1016 }
1017
1018 int
1019 smpp_stats_tree_per_packet(stats_tree *st, /* st as it was passed to us */
1020                            packet_info *pinfo _U_,
1021                            epan_dissect_t *edt _U_,
1022                            const void *p) /* Used for getting SMPP command_id values */
1023 {
1024     smpp_tap_rec_t* tap_rec = (smpp_tap_rec_t*)p;
1025
1026     tick_stat_node(st, "SMPP Operations", 0, TRUE);
1027
1028     if ((tap_rec->command_id & 0x80000000) == 0x80000000) /* Response */
1029     {
1030         tick_stat_node(st, "SMPP Responses", st_smpp_ops, TRUE);
1031         tick_stat_node(st, val_to_str(tap_rec->command_id, vals_command_id, "Unknown 0x%08x"), st_smpp_res, FALSE);
1032
1033         tick_stat_node(st, "SMPP Response Status", 0, TRUE);
1034         tick_stat_node(st, val_to_str(tap_rec->command_status, vals_command_status, "Unknown 0x%08x"), st_smpp_res_status, FALSE);
1035
1036     }
1037     else  /* Request */
1038     {
1039         tick_stat_node(st, "SMPP Requests", st_smpp_ops, TRUE);
1040         tick_stat_node(st, val_to_str(tap_rec->command_id, vals_command_id, "Unknown 0x%08x"), st_smpp_req, FALSE);
1041     }
1042
1043     return 1;
1044 }
1045
1046 /*!
1047  * SMPP equivalent of mktime() (3). Convert date to standard 'time_t' format
1048  *
1049  * \param       datestr The SMPP-formatted date to convert
1050  * \param       secs    Returns the 'time_t' equivalent
1051  * \param       nsecs   Returns the additional nano-seconds
1052  *
1053  * \return              Whether time is specified relative or absolute
1054  * \retval      TRUE    Relative time
1055  * \retval      FALSE   Absolute time
1056  */
1057 static gboolean
1058 smpp_mktime(const char *datestr, time_t *secs, int *nsecs)
1059 {
1060     struct tm    r_time;
1061     time_t       t_diff;
1062     gboolean     relative = (datestr[15] == 'R') ? TRUE : FALSE;
1063
1064     r_time.tm_year = 10 * (datestr[0] - '0') + (datestr[1] - '0');
1065     /*
1066      * Y2K rollover date as recommended in appendix C
1067      */
1068     if (r_time.tm_year < 38)
1069         r_time.tm_year += 100;
1070     r_time.tm_mon  = 10 * (datestr[2] - '0') + (datestr[3] - '0');
1071     r_time.tm_mon--;
1072     r_time.tm_mday = 10 * (datestr[4] - '0') + (datestr[5] - '0');
1073     r_time.tm_hour = 10 * (datestr[6] - '0') + (datestr[7] - '0');
1074     r_time.tm_min  = 10 * (datestr[8] - '0') + (datestr[9] - '0');
1075     r_time.tm_sec  = 10 * (datestr[10] - '0') + (datestr[11] - '0');
1076     r_time.tm_isdst = -1;
1077
1078     if (relative == FALSE) {
1079         *secs = mktime(&r_time);
1080         *nsecs = (datestr[12] - '0') * 100000000;
1081         t_diff = (10 * (datestr[13] - '0') + (datestr[14] - '0')) * 900;
1082         if (datestr[15] == '+')
1083             *secs += t_diff;
1084         else if (datestr[15] == '-')
1085             *secs -= t_diff;
1086     } else {
1087         *secs = r_time.tm_sec + 60 *
1088             (r_time.tm_min + 60 *
1089              (r_time.tm_hour + 24 *
1090               r_time.tm_mday));
1091         *nsecs = 0;
1092     }
1093
1094     return relative;
1095 }
1096
1097 /*!
1098  * Scanning routines to add standard types (byte, int, string...) to the
1099  * protocol tree.
1100  *
1101  * \param       tree    The protocol tree to add to
1102  * \param       tvb     Buffer containing the data
1103  * \param       field   Actual field whose value needs displaying
1104  * \param       offset  Location of field in buffer, returns location of
1105  *                      next field
1106  */
1107 static void
1108 smpp_handle_string(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
1109 {
1110     guint        len;
1111
1112     len = tvb_strsize(tvb, *offset);
1113     if (len > 1) {
1114         proto_tree_add_item(tree, field, tvb, *offset, len, ENC_NA);
1115     }
1116     (*offset) += len;
1117 }
1118
1119 /* NOTE - caller must free the returned string! */
1120 static char *
1121 smpp_handle_string_return(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
1122 {
1123     gint         len;
1124     char        *str;
1125
1126     len = tvb_strsize(tvb, *offset);
1127     if (len > 1) {
1128         str = (char *)tvb_get_ephemeral_stringz(tvb, *offset, &len);
1129         proto_tree_add_string(tree, field, tvb, *offset, len, str);
1130     } else {
1131         str = "";
1132     }
1133     (*offset) += len;
1134     return str;
1135 }
1136
1137 static void
1138 smpp_handle_string_z(proto_tree *tree, tvbuff_t *tvb, int field, int *offset,
1139                 const char *null_string)
1140 {
1141     gint         len;
1142
1143     len = tvb_strsize(tvb, *offset);
1144     if (len > 1) {
1145         proto_tree_add_item(tree, field, tvb, *offset, len, ENC_NA);
1146     } else {
1147         proto_tree_add_string(tree, field, tvb, *offset, len, null_string);
1148     }
1149     (*offset) += len;
1150 }
1151
1152 static void
1153 smpp_handle_int1(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
1154 {
1155     guint8       val;
1156
1157     val = tvb_get_guint8(tvb, *offset);
1158     proto_tree_add_uint(tree, field, tvb, *offset, 1, val);
1159     (*offset)++;
1160 }
1161
1162 static void
1163 smpp_handle_int2(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
1164 {
1165     guint        val;
1166
1167     val = tvb_get_ntohs(tvb, *offset);
1168     proto_tree_add_uint(tree, field, tvb, *offset, 2, val);
1169     (*offset) += 2;
1170 }
1171
1172 static void
1173 smpp_handle_int4(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
1174 {
1175     guint        val;
1176
1177     val = tvb_get_ntohl(tvb, *offset);
1178     proto_tree_add_uint(tree, field, tvb, *offset, 4, val);
1179     (*offset) += 4;
1180 }
1181
1182 static void
1183 smpp_handle_time(proto_tree *tree, tvbuff_t *tvb,
1184                  int field, int field_R, int *offset)
1185 {
1186     char         *strval;
1187     gint         len;
1188     nstime_t     tmptime;
1189
1190     strval = (char *) tvb_get_ephemeral_stringz(tvb, *offset, &len);
1191     if (*strval)
1192     {
1193         if (len >= 16)
1194         {
1195             if (smpp_mktime(strval, &tmptime.secs, &tmptime.nsecs))
1196                 proto_tree_add_time(tree, field_R, tvb, *offset, len, &tmptime);
1197             else
1198                 proto_tree_add_time(tree, field, tvb, *offset, len, &tmptime);
1199         }
1200         else
1201         {
1202             proto_tree_add_text(tree, tvb, *offset, len, "Invalid time: %s", strval);
1203         }
1204     }
1205     *offset += len;
1206 }
1207
1208 /*!
1209  * Scanning routine to handle the destination-list of 'submit_multi'
1210  *
1211  * \param       tree    The protocol tree to add to
1212  * \param       tvb     Buffer containing the data
1213  * \param       offset  Location of field in buffer, returns location of
1214  *                      next field
1215  */
1216 static void
1217 smpp_handle_dlist(proto_tree *tree, tvbuff_t *tvb, int *offset)
1218 {
1219     guint8       entries;
1220     int          tmpoff = *offset;
1221     proto_tree  *sub_tree = NULL;
1222     guint8       dest_flag;
1223
1224     if ((entries = tvb_get_guint8(tvb, tmpoff++))) {
1225         proto_item  *pi;
1226         pi = proto_tree_add_item(tree, hf_smpp_dlist, tvb, *offset, 1, FALSE);
1227         sub_tree = proto_item_add_subtree(pi, ett_dlist);
1228     }
1229     while (entries--)
1230     {
1231         dest_flag = tvb_get_guint8(tvb, tmpoff++);
1232         if (dest_flag == 1)                     /* SME address  */
1233         {
1234             smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_ton, &tmpoff);
1235             smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_npi, &tmpoff);
1236             smpp_handle_string(sub_tree,tvb,hf_smpp_destination_addr,&tmpoff);
1237         }
1238         else                                    /* Distribution list    */
1239         {
1240             smpp_handle_string(sub_tree, tvb, hf_smpp_dl_name, &tmpoff);
1241         }
1242     }
1243     *offset = tmpoff;
1244 }
1245
1246 /*!
1247  * Scanning routine to handle the destination result list
1248  * of 'submit_multi_resp'
1249  *
1250  * \param       tree    The protocol tree to add to
1251  * \param       tvb     Buffer containing the data
1252  * \param       offset  Location of field in buffer, returns location of
1253  *                      next field
1254  */
1255 static void
1256 smpp_handle_dlist_resp(proto_tree *tree, tvbuff_t *tvb, int *offset)
1257 {
1258     guint8       entries;
1259     int          tmpoff = *offset;
1260     proto_tree  *sub_tree = NULL;
1261
1262     if ((entries = tvb_get_guint8(tvb, tmpoff++))) {
1263         proto_item  *pi;
1264         pi = proto_tree_add_item(tree, hf_smpp_dlist_resp,
1265                                  tvb, *offset, 1, FALSE);
1266         sub_tree = proto_item_add_subtree(pi, ett_dlist_resp);
1267     }
1268     while (entries--)
1269     {
1270         smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_ton, &tmpoff);
1271         smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_npi, &tmpoff);
1272         smpp_handle_string(sub_tree,tvb,hf_smpp_destination_addr,&tmpoff);
1273         smpp_handle_int4(sub_tree, tvb, hf_smpp_error_status_code, &tmpoff);
1274     }
1275     *offset = tmpoff;
1276 }
1277
1278 /*!
1279  * Scanning routine to handle all optional parameters of SMPP-operations.
1280  * The parameters have the format Tag Length Value (TLV), with a 2-byte tag
1281  * and 2-byte length.
1282  *
1283  * \param       tree    The protocol tree to add to
1284  * \param       tvb     Buffer containing the data
1285  * \param       offset  Location of field in buffer, returns location of
1286  *                      next field
1287  */
1288 static void
1289 smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
1290 {
1291     proto_tree *tlvs_tree = NULL;
1292     proto_item *pi;
1293
1294     if (tvb_reported_length_remaining(tvb, *offset) >= 1) {
1295         pi = proto_tree_add_item(tree, hf_smpp_opt_params,
1296                                  tvb, *offset, -1, FALSE);
1297         tlvs_tree = proto_item_add_subtree(pi, ett_opt_params);
1298     }
1299
1300     while (tvb_reported_length_remaining(tvb, *offset) >= 1)
1301     {
1302         proto_item *sub_tree;
1303         guint16  tag;
1304         guint16  length;
1305
1306         guint8   field;
1307         guint16  field16;
1308         guint8   major, minor;
1309         char     *strval=NULL;
1310
1311         tag = tvb_get_ntohs(tvb, *offset);
1312         length = tvb_get_ntohs(tvb, (*offset+2));
1313
1314         pi = proto_tree_add_none_format(tlvs_tree, hf_smpp_opt_param, tvb,
1315                                         *offset, length+4,
1316                                         "Optional parameter: %s (0x%04x)",
1317                                         val_to_str(tag, vals_tlv_tags, "0x%04x"), tag);
1318         sub_tree = proto_item_add_subtree(pi, ett_opt_param);
1319         proto_tree_add_uint(sub_tree,hf_smpp_opt_param_tag,tvb,*offset,2,tag);
1320         proto_tree_add_uint(sub_tree,hf_smpp_opt_param_len,tvb,*offset+2,2,length);
1321
1322         *offset += 4;
1323
1324         switch (tag) {
1325             case  0x0005:       /* dest_addr_subunit    */
1326                 smpp_handle_int1(sub_tree, tvb,
1327                                  hf_smpp_dest_addr_subunit, offset);
1328                 break;
1329             case  0x0006:       /* dest_network_type    */
1330                 smpp_handle_int1(sub_tree, tvb,
1331                                  hf_smpp_dest_network_type, offset);
1332                 break;
1333             case  0x0007:       /* dest_bearer_type     */
1334                 smpp_handle_int1(sub_tree, tvb,
1335                                  hf_smpp_dest_bearer_type, offset);
1336                 break;
1337             case  0x0008:       /* dest_telematics_id   */
1338                 smpp_handle_int2(sub_tree, tvb,
1339                                  hf_smpp_dest_telematics_id, offset);
1340                 break;
1341             case  0x000D:       /* source_addr_subunit  */
1342                 smpp_handle_int1(sub_tree, tvb,
1343                                  hf_smpp_source_addr_subunit, offset);
1344                 break;
1345             case  0x000E:       /* source_network_type  */
1346                 smpp_handle_int1(sub_tree, tvb,
1347                                  hf_smpp_source_network_type, offset);
1348                 break;
1349             case  0x000F:       /* source_bearer_type   */
1350                 smpp_handle_int1(sub_tree, tvb,
1351                                  hf_smpp_source_bearer_type, offset);
1352                 break;
1353             case  0x0010:       /* source_telematics_id */
1354                 smpp_handle_int2(sub_tree, tvb,
1355                                  hf_smpp_source_telematics_id, offset);
1356                 break;
1357             case  0x0017:       /* qos_time_to_live     */
1358                 smpp_handle_int4(sub_tree, tvb,
1359                                  hf_smpp_qos_time_to_live, offset);
1360                 break;
1361             case  0x0019:       /* payload_type */
1362                 smpp_handle_int1(sub_tree, tvb,
1363                                  hf_smpp_payload_type, offset);
1364                 break;
1365             case  0x001D:       /* additional_status_info_text  */
1366                 smpp_handle_string(sub_tree, tvb,
1367                                    hf_smpp_additional_status_info_text, offset);
1368                 break;
1369             case  0x001E:       /* receipted_message_id */
1370                 smpp_handle_string(sub_tree, tvb,
1371                                    hf_smpp_receipted_message_id, offset);
1372                 break;
1373             case  0x0030:       /* ms_msg_wait_facilities       */
1374                 field = tvb_get_guint8(tvb, *offset);
1375                 proto_tree_add_item(sub_tree, hf_smpp_msg_wait_ind,
1376                                     tvb, *offset, 1, field);
1377                 proto_tree_add_item(sub_tree, hf_smpp_msg_wait_type,
1378                                     tvb, *offset, 1, field);
1379                 (*offset)++;
1380                 break;
1381             case  0x0201:       /* privacy_indicator    */
1382                 smpp_handle_int1(sub_tree, tvb,
1383                                  hf_smpp_privacy_indicator, offset);
1384                 break;
1385             case  0x0202:       /* source_subaddress    */
1386                 if (length) {
1387                     proto_tree_add_item(sub_tree, hf_smpp_source_subaddress,
1388                                     tvb, *offset, length, FALSE);
1389                     (*offset) += length;
1390                 }
1391                 break;
1392             case  0x0203:       /* dest_subaddress      */
1393                 if (length) {
1394                     proto_tree_add_item(sub_tree, hf_smpp_dest_subaddress,
1395                                     tvb, *offset, length, FALSE);
1396                     (*offset) += length;
1397                 }
1398                 break;
1399             case  0x0204:       /* user_message_reference       */
1400                 smpp_handle_int2(sub_tree, tvb,
1401                                  hf_smpp_user_message_reference, offset);
1402                 break;
1403             case  0x0205:       /* user_response_code   */
1404                 smpp_handle_int1(sub_tree, tvb,
1405                                  hf_smpp_user_response_code, offset);
1406                 break;
1407             case  0x020A:       /* source_port  */
1408                 smpp_handle_int2(sub_tree, tvb,
1409                                  hf_smpp_source_port, offset);
1410                 break;
1411             case  0x020B:       /* destination_port     */
1412                 smpp_handle_int2(sub_tree, tvb,
1413                                  hf_smpp_destination_port, offset);
1414                 break;
1415             case  0x020C:       /* sar_msg_ref_num      */
1416                 smpp_handle_int2(sub_tree, tvb,
1417                                  hf_smpp_sar_msg_ref_num, offset);
1418                 break;
1419             case  0x020D:       /* language_indicator   */
1420                 smpp_handle_int1(sub_tree, tvb,
1421                                  hf_smpp_language_indicator, offset);
1422                 break;
1423             case  0x020E:       /* sar_total_segments   */
1424                 smpp_handle_int1(sub_tree, tvb,
1425                                  hf_smpp_sar_total_segments, offset);
1426                 break;
1427             case  0x020F:       /* sar_segment_seqnum   */
1428                 smpp_handle_int1(sub_tree, tvb,
1429                                  hf_smpp_sar_segment_seqnum, offset);
1430                 break;
1431             case  0x0210:       /* SC_interface_version */
1432                 field = tvb_get_guint8(tvb, *offset);
1433                 minor = field & 0x0F;
1434                 major = (field & 0xF0) >> 4;
1435                 strval=ep_strdup_printf("%u.%u", major, minor);
1436                 proto_tree_add_string(sub_tree, hf_smpp_SC_interface_version,
1437                                       tvb, *offset, 1, strval);
1438                 (*offset)++;
1439                 break;
1440             case  0x0302:       /* callback_num_pres_ind        */
1441                 field = tvb_get_guint8(tvb, *offset);
1442                 proto_tree_add_item(sub_tree, hf_smpp_callback_num_pres,
1443                                     tvb, *offset, 1, field);
1444                 proto_tree_add_item(sub_tree, hf_smpp_callback_num_scrn,
1445                                     tvb, *offset, 1, field);
1446                 (*offset)++;
1447                 break;
1448             case  0x0303:       /* callback_num_atag    */
1449                 if (length)
1450                     proto_tree_add_item(sub_tree, hf_smpp_callback_num_atag,
1451                                         tvb, *offset, length, FALSE);
1452                 (*offset) += length;
1453                 break;
1454             case  0x0304:       /* number_of_messages   */
1455                 smpp_handle_int1(sub_tree, tvb,
1456                                  hf_smpp_number_of_messages, offset);
1457                 break;
1458             case  0x0381:       /* callback_num */
1459                 if (length)
1460                     proto_tree_add_item(sub_tree, hf_smpp_callback_num,
1461                                         tvb, *offset, length, FALSE);
1462                 (*offset) += length;
1463                 break;
1464             case  0x0420:       /* dpf_result   */
1465                 smpp_handle_int1(sub_tree, tvb,
1466                                  hf_smpp_dpf_result, offset);
1467                 break;
1468             case  0x0421:       /* set_dpf      */
1469                 smpp_handle_int1(sub_tree, tvb,
1470                                  hf_smpp_set_dpf, offset);
1471                 break;
1472             case  0x0422:       /* ms_availability_status       */
1473                 smpp_handle_int1(sub_tree, tvb,
1474                                  hf_smpp_ms_availability_status, offset);
1475                 break;
1476             case  0x0423:       /* network_error_code   */
1477                 smpp_handle_int1(sub_tree, tvb,
1478                                  hf_smpp_network_error_type, offset);
1479                 smpp_handle_int2(sub_tree, tvb,
1480                                  hf_smpp_network_error_code, offset);
1481                 break;
1482             case  0x0424:       /* message_payload      */
1483                 if (length)
1484                     proto_tree_add_item(sub_tree, hf_smpp_message_payload,
1485                                         tvb, *offset, length, FALSE);
1486                 (*offset) += length;
1487                 break;
1488             case  0x0425:       /* delivery_failure_reason      */
1489                 smpp_handle_int1(sub_tree, tvb,
1490                                  hf_smpp_delivery_failure_reason, offset);
1491                 break;
1492             case  0x0426:       /* more_messages_to_send        */
1493                 smpp_handle_int1(sub_tree, tvb,
1494                                  hf_smpp_more_messages_to_send, offset);
1495                 break;
1496             case  0x0427:       /* message_state        */
1497                 smpp_handle_int1(sub_tree, tvb,
1498                                  hf_smpp_message_state, offset);
1499                 break;
1500             case        0x0428: /* congestion_state */
1501                 smpp_handle_int1(sub_tree, tvb,
1502                                  hf_smpp_congestion_state, offset);
1503
1504                 break;
1505             case  0x0501:       /* ussd_service_op      */
1506                 smpp_handle_int1(sub_tree, tvb,
1507                                  hf_smpp_ussd_service_op, offset);
1508                 break;
1509             case 0x0600:        /* broadcast_channel_indicator */
1510                 smpp_handle_int1(sub_tree, tvb,
1511                                  hf_smpp_broadcast_channel_indicator, offset);
1512                 break;
1513             case 0x0601:        /* broadcast_content_type */
1514                 field = tvb_get_guint8(tvb, *offset);
1515                 proto_tree_add_uint(sub_tree, hf_smpp_broadcast_content_type_nw, tvb, *offset, 1, field);
1516                 (*offset)++;
1517                 field16 = tvb_get_ntohs(tvb, *offset);
1518                 proto_tree_add_uint(sub_tree, hf_smpp_broadcast_content_type_type, tvb, *offset, 2, field16);
1519                 (*offset) += 2;
1520                 break;
1521             case 0x0602:        /* broadcast_content_type_info */
1522                 if (length)
1523                     proto_tree_add_item(sub_tree, hf_smpp_broadcast_content_type_info,
1524                                         tvb, *offset, length, FALSE);
1525                 (*offset) += length;
1526                 break;
1527             case 0x0603:        /* broadcast_message_class */
1528                 smpp_handle_int1(sub_tree, tvb,
1529                                 hf_smpp_broadcast_message_class, offset);
1530                 break;
1531             case 0x0604:        /* broadcast_rep_num */
1532                 smpp_handle_int1(sub_tree, tvb,
1533                                 hf_smpp_broadcast_rep_num, offset);
1534                 break;
1535             case 0x0605:        /* broadcast_frequency_interval */
1536                 field = tvb_get_guint8(tvb, *offset);
1537                 proto_tree_add_uint(sub_tree, hf_smpp_broadcast_frequency_interval_unit, tvb, *offset, 1, field);
1538                 (*offset)++;
1539                 field16 = tvb_get_ntohs(tvb, *offset);
1540                 proto_tree_add_uint(sub_tree, hf_smpp_broadcast_frequency_interval_value, tvb, *offset, 2, field16);
1541                 (*offset) += 2;
1542                 break;
1543             case 0x0606:        /* broadcast_area_identifier */
1544                 field = tvb_get_guint8(tvb, *offset);
1545                 proto_tree_add_uint(sub_tree, hf_smpp_broadcast_area_identifier_format, tvb, *offset, 1, field);
1546                 proto_tree_add_item(sub_tree, hf_smpp_broadcast_area_identifier,
1547                                         tvb, *offset, length, FALSE);
1548                 (*offset) += length;
1549                 break;
1550             case 0x0607:        /* broadcast_error_status */
1551                 smpp_handle_int4(sub_tree, tvb,
1552                                 hf_smpp_broadcast_error_status, offset);
1553                 break;
1554             case 0x0608:        /* broadcast_area_success */
1555                 smpp_handle_int1(sub_tree, tvb,
1556                                 hf_smpp_broadcast_area_success, offset);
1557                 break;
1558             case 0x0609:        /* broadcast_end_time */
1559                 smpp_handle_time(sub_tree, tvb, hf_smpp_broadcast_end_time,
1560                                 hf_smpp_broadcast_end_time_r, offset);
1561                 break;
1562             case 0x060A:        /* broadcast_service_group */
1563                 if (length)
1564                     proto_tree_add_item(sub_tree, hf_smpp_broadcast_service_group,
1565                                         tvb, *offset, length, FALSE);
1566                 (*offset) += length;
1567                 break;
1568             case 0x060B:        /* billing_identification */
1569                 if (length)
1570                     proto_tree_add_item(sub_tree, hf_smpp_billing_identification,
1571                                         tvb, *offset, length, FALSE);
1572                 (*offset) += length;
1573                 break;
1574             /* 0x060C is skipped in the specs for some reason :-? */
1575             case 0x060D:        /* source_network_id */
1576                 smpp_handle_string_z(sub_tree, tvb, hf_smpp_source_network_id,
1577                                 offset, "Empty!");
1578                 break;
1579             case 0x060E:        /* dest_network_id */
1580                 smpp_handle_string_z(sub_tree, tvb, hf_smpp_dest_network_id,
1581                                 offset, "Empty!");
1582                 break;
1583             case 0x060F:        /* source_node_id */
1584                 if (length)
1585                     proto_tree_add_item(sub_tree, hf_smpp_source_node_id,
1586                                         tvb, *offset, length, FALSE);
1587                 (*offset) += length;
1588                 break;
1589             case 0x0610:        /* dest_node_id */
1590                 if (length)
1591                     proto_tree_add_item(sub_tree, hf_smpp_dest_node_id,
1592                                         tvb, *offset, length, FALSE);
1593                 (*offset) += length;
1594                 break;
1595             case 0x0611:        /* dest_addr_np_resolution */
1596                 smpp_handle_int1(sub_tree, tvb,
1597                                 hf_smpp_dest_addr_np_resolution, offset);
1598                 break;
1599             case 0x0612:        /* dest_addr_np_information */
1600                 if (length)
1601                     proto_tree_add_item(sub_tree, hf_smpp_dest_addr_np_information,
1602                                         tvb, *offset, length, FALSE);
1603                 (*offset) += length;
1604                 break;
1605             case 0x0613:        /* dest_addr_np_country */
1606                 /* TODO : Fetch values from packet-e164? */
1607                 if (length)
1608                     proto_tree_add_item(sub_tree, hf_smpp_dest_addr_np_country,
1609                                         tvb, *offset, length, FALSE);
1610                 (*offset) += length;
1611                 break;
1612             case  0x1201:       /* display_time */
1613                 smpp_handle_int1(sub_tree, tvb,
1614                                  hf_smpp_display_time, offset);
1615                 break;
1616             case  0x1203:       /* sms_signal   */
1617                 smpp_handle_int2(sub_tree, tvb,
1618                                  hf_smpp_sms_signal, offset);
1619                 /*! \todo Fill as per TIA/EIA-136-710-A         */
1620                 break;
1621             case  0x1204:       /* ms_validity  */
1622                 smpp_handle_int1(sub_tree, tvb,
1623                                  hf_smpp_ms_validity, offset);
1624                 break;
1625             case  0x130C:       /* alert_on_message_delivery    */
1626                 if (length == 0) {
1627                         proto_tree_add_item(sub_tree,
1628                                     hf_smpp_alert_on_message_delivery_null,
1629                                     tvb, *offset, length, FALSE);
1630                 } else {
1631                         smpp_handle_int1(sub_tree, tvb,
1632                                     hf_smpp_alert_on_message_delivery, offset);
1633                 }
1634                 break;
1635             case  0x1380:       /* its_reply_type       */
1636                 smpp_handle_int1(sub_tree, tvb,
1637                                  hf_smpp_its_reply_type, offset);
1638                 break;
1639             case  0x1383:       /* its_session_info     */
1640                 smpp_handle_int1(sub_tree, tvb,
1641                                  hf_smpp_its_session_number, offset);
1642                 field = tvb_get_guint8(tvb, *offset);
1643                 proto_tree_add_item(sub_tree, hf_smpp_its_session_sequence,
1644                                     tvb, *offset, 1, field);
1645                 proto_tree_add_item(sub_tree, hf_smpp_its_session_ind,
1646                                     tvb, *offset, 1, field);
1647                 (*offset)++;
1648                 break;
1649
1650             default:
1651                 /* TODO : Hopefully to be implemented soon - handle vendor specific TLVs
1652                  * from a dictionary before treating them as unknown! */
1653                 if ((tag >= 0x1400) && (tag <= 0x3FFF)) {
1654                     proto_tree_add_item(sub_tree, hf_smpp_vendor_op, tvb,
1655                                         *offset, length, FALSE);
1656                 } else {
1657                     proto_tree_add_item(sub_tree, hf_smpp_reserved_op, tvb,
1658                                         *offset, length, FALSE);
1659                 }
1660
1661                 proto_item_append_text(sub_tree,": %s", tvb_bytes_to_str(tvb,*offset,length));
1662                 (*offset) += length;
1663                 break;
1664         }
1665     }
1666 }
1667
1668 void
1669 smpp_handle_dcs(proto_tree *tree, tvbuff_t *tvb, int *offset)
1670 {
1671     guint8       val;
1672     int off = *offset;
1673     proto_tree *subtree = NULL;
1674     proto_item *pi;
1675
1676     val = tvb_get_guint8(tvb, off);
1677     pi = proto_tree_add_uint(tree, hf_smpp_data_coding, tvb, off, 1, val);
1678     subtree = proto_item_add_subtree(pi, ett_dcs);
1679     /* SMPP Data Coding Scheme */
1680     proto_tree_add_uint(subtree, hf_smpp_dcs, tvb, off, 1, val);
1681     /* GSM SMS Data Coding Scheme */
1682     proto_tree_add_text(subtree, tvb, off, 1,
1683                         "GSM SMS Data Coding");
1684     proto_tree_add_uint(subtree,
1685                         hf_smpp_dcs_sms_coding_group, tvb, off, 1, val);
1686     if (val>>6 == 2) { /* Reserved */
1687         ;
1688     } else if (val < 0xF0) {
1689         proto_tree_add_boolean(subtree,
1690                                hf_smpp_dcs_text_compression, tvb, off, 1, val);
1691         proto_tree_add_boolean(subtree,
1692                                hf_smpp_dcs_class_present, tvb, off, 1, val);
1693         proto_tree_add_uint(subtree,
1694                             hf_smpp_dcs_charset, tvb, off, 1, val);
1695         if (val & 0x10)
1696             proto_tree_add_uint(subtree,
1697                                 hf_smpp_dcs_class, tvb, off, 1, val);
1698     } else {
1699         if (val & 0x08)
1700             proto_tree_add_text(subtree, tvb, off, 1,
1701                                 "SMPP: Bit .... 1... should be 0 (reserved)");
1702         proto_tree_add_uint(subtree,
1703                             hf_smpp_dcs_charset, tvb, off, 1, val);
1704         proto_tree_add_uint(subtree,
1705                             hf_smpp_dcs_class, tvb, off, 1, val);
1706     }
1707     /* Cell Broadcast Service (CBS) Data Coding Scheme */
1708     proto_tree_add_text(subtree, tvb, off, 1,
1709                         "GSM CBS Data Coding");
1710     proto_tree_add_uint(subtree,
1711                         hf_smpp_dcs_cbs_coding_group, tvb, off, 1, val);
1712     if (val < 0x40) { /* Language specified */
1713         proto_tree_add_uint(subtree,
1714                             hf_smpp_dcs_cbs_language, tvb, off, 1, val);
1715     } else if (val>>6 == 1) { /* General Data Coding indication */
1716         proto_tree_add_boolean(subtree,
1717                                hf_smpp_dcs_text_compression, tvb, off, 1, val);
1718         proto_tree_add_boolean(subtree,
1719                                hf_smpp_dcs_class_present, tvb, off, 1, val);
1720         proto_tree_add_uint(subtree,
1721                             hf_smpp_dcs_charset, tvb, off, 1, val);
1722         if (val & 0x10)
1723             proto_tree_add_uint(subtree,
1724                                 hf_smpp_dcs_class, tvb, off, 1, val);
1725     } else if (val>>6 == 2) { /* Message with UDH structure */
1726         proto_tree_add_uint(subtree,
1727                             hf_smpp_dcs_charset, tvb, off, 1, val);
1728         proto_tree_add_uint(subtree,
1729                             hf_smpp_dcs_class, tvb, off, 1, val);
1730     } else if (val>>4 == 14) { /* WAP Forum */
1731         proto_tree_add_uint(subtree,
1732                             hf_smpp_dcs_wap_charset, tvb, off, 1, val);
1733         proto_tree_add_uint(subtree,
1734                             hf_smpp_dcs_wap_class, tvb, off, 1, val);
1735     } else if (val>>4 == 15) { /* Data coding / message handling */
1736         if (val & 0x08)
1737             proto_tree_add_text(subtree, tvb, off, 1,
1738                                 "SMPP: Bit .... 1... should be 0 (reserved)");
1739         proto_tree_add_uint(subtree,
1740                             hf_smpp_dcs_charset, tvb, off, 1, val);
1741         proto_tree_add_uint(subtree,
1742                             hf_smpp_dcs_cbs_class, tvb, off, 1, val);
1743     }
1744
1745     (*offset)++;
1746 }
1747
1748 /*!
1749  * The next set of routines handle the different operations, associated
1750  * with SMPP.
1751  */
1752 static void
1753 bind_receiver(proto_tree *tree, tvbuff_t *tvb)
1754 {
1755     int          offset = 0;
1756     guint8       field;
1757     guint8       major, minor;
1758     char         *strval;
1759
1760     smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
1761     smpp_handle_string(tree, tvb, hf_smpp_password, &offset);
1762     smpp_handle_string(tree, tvb, hf_smpp_system_type, &offset);
1763     field = tvb_get_guint8(tvb, offset++);
1764     minor = field & 0x0F;
1765     major = (field & 0xF0) >> 4;
1766     strval=ep_strdup_printf("%u.%u", major, minor);
1767     proto_tree_add_string(tree, hf_smpp_interface_version, tvb,
1768                           offset - 1, 1, strval);
1769     smpp_handle_int1(tree, tvb, hf_smpp_addr_ton, &offset);
1770     smpp_handle_int1(tree, tvb, hf_smpp_addr_npi, &offset);
1771     smpp_handle_string(tree, tvb, hf_smpp_address_range, &offset);
1772 }
1773
1774 #define bind_transmitter(a, b) bind_receiver(a, b)
1775
1776 static void
1777 query_sm(proto_tree *tree, tvbuff_t *tvb)
1778 {
1779     int          offset = 0;
1780
1781     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1782     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1783     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1784     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1785 }
1786
1787 #define bind_transceiver(a, b) bind_receiver(a, b)
1788
1789 static void
1790 outbind(proto_tree *tree, tvbuff_t *tvb)
1791 {
1792     int          offset = 0;
1793
1794     smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
1795     smpp_handle_string(tree, tvb, hf_smpp_password, &offset);
1796 }
1797
1798 static void
1799 submit_sm(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
1800                 proto_tree *top_tree)
1801 {
1802     tvbuff_t    *tvb_msg;
1803     int          offset = 0;
1804     guint8       flag, udhi;
1805     guint8       length;
1806     char *src_str = NULL;
1807     char *dst_str = NULL;
1808     address save_src, save_dst;
1809
1810     smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1811     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1812     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1813     src_str = smpp_handle_string_return(tree, tvb, hf_smpp_source_addr, &offset);
1814     smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
1815     smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
1816     dst_str = smpp_handle_string_return(tree, tvb, hf_smpp_destination_addr, &offset);
1817     flag = tvb_get_guint8(tvb, offset);
1818     udhi = flag & 0x40;
1819     proto_tree_add_item(tree, hf_smpp_esm_submit_msg_mode,
1820                         tvb, offset, 1, flag);
1821     proto_tree_add_item(tree, hf_smpp_esm_submit_msg_type,
1822                         tvb, offset, 1, flag);
1823     proto_tree_add_item(tree, hf_smpp_esm_submit_features,
1824                         tvb, offset, 1, flag);
1825     offset++;
1826     smpp_handle_int1(tree, tvb, hf_smpp_protocol_id, &offset);
1827     smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
1828     if (tvb_get_guint8(tvb,offset)) {
1829         smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
1830                          hf_smpp_schedule_delivery_time_r, &offset);
1831     } else { /* Time = NULL means Immediate delivery */
1832         proto_tree_add_text(tree, tvb, offset++, 1,
1833                             "Scheduled delivery time: Immediate delivery");
1834     }
1835     if (tvb_get_guint8(tvb,offset)) {
1836         smpp_handle_time(tree, tvb, hf_smpp_validity_period,
1837                          hf_smpp_validity_period_r, &offset);
1838     } else { /* Time = NULL means SMSC default validity */
1839         proto_tree_add_text(tree, tvb, offset++, 1,
1840                             "Validity period: SMSC default validity period");
1841     }
1842     flag = tvb_get_guint8(tvb, offset);
1843     proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1844     proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1845     proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1846     offset++;
1847     smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
1848         smpp_handle_dcs(tree, tvb, &offset);
1849     smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
1850     length = tvb_get_guint8(tvb, offset);
1851     proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
1852     if (length)
1853     {
1854         proto_tree_add_item(tree, hf_smpp_short_message,
1855                             tvb, offset, length, FALSE);
1856         if (udhi) /* UDHI indicator present */
1857         {
1858             DebugLog(("UDHI present - set addresses\n"));
1859             /* Save original addresses */
1860             SET_ADDRESS(&save_src, pinfo->src.type, pinfo->src.len, pinfo->src.data);
1861             SET_ADDRESS(&save_dst, pinfo->dst.type, pinfo->dst.len, pinfo->dst.data);
1862             /* Set SMPP source and destination address */
1863             SET_ADDRESS(&(pinfo->src), AT_STRINGZ, 1+(int)strlen(src_str), src_str);
1864             SET_ADDRESS(&(pinfo->dst), AT_STRINGZ, 1+(int)strlen(dst_str), dst_str);
1865             tvb_msg = tvb_new_subset (tvb, offset,
1866                     MIN(length, tvb_reported_length(tvb) - offset), length);
1867             call_dissector (gsm_sms_handle, tvb_msg, pinfo, top_tree);
1868             /* Restore original addresses */
1869             SET_ADDRESS(&(pinfo->src), save_src.type, save_src.len, save_src.data );
1870             SET_ADDRESS(&(pinfo->dst), save_dst.type, save_dst.len, save_dst.data);
1871         }
1872         offset += length;
1873     }
1874     /* Get rid of SMPP text string addresses */
1875     smpp_handle_tlv(tree, tvb, &offset);
1876 }
1877
1878 #define deliver_sm(a, b, c, d) submit_sm(a, b, c, d)
1879
1880 static void
1881 replace_sm(proto_tree *tree, tvbuff_t *tvb)
1882 {
1883     int          offset = 0;
1884     guint8       flag;
1885     guint8       length;
1886
1887     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1888     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1889     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1890     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1891         if (tvb_get_guint8(tvb,offset)) {
1892     smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
1893                                 hf_smpp_schedule_delivery_time_r, &offset);
1894         } else { /* Time = NULL */
1895                 proto_tree_add_text(tree, tvb, offset++, 1,
1896                                 "Scheduled delivery time: Keep initial delivery time setting");
1897         }
1898         if (tvb_get_guint8(tvb,offset)) {
1899     smpp_handle_time(tree, tvb, hf_smpp_validity_period,
1900                                 hf_smpp_validity_period_r, &offset);
1901         } else { /* Time = NULL */
1902                 proto_tree_add_text(tree, tvb, offset++, 1,
1903                                 "Validity period: Keep initial validity period setting");
1904         }
1905     flag = tvb_get_guint8(tvb, offset);
1906     proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1907     proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1908     proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1909     offset++;
1910     smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
1911     length = tvb_get_guint8(tvb, offset);
1912     proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
1913     if (length)
1914         proto_tree_add_item(tree, hf_smpp_short_message,
1915                             tvb, offset, length, FALSE);
1916     offset += length;
1917 }
1918
1919 static void
1920 cancel_sm(proto_tree *tree, tvbuff_t *tvb)
1921 {
1922     int          offset = 0;
1923
1924     smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1925     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1926     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1927     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1928     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1929     smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
1930     smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
1931     smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
1932 }
1933
1934 static void
1935 submit_multi(proto_tree *tree, tvbuff_t *tvb)
1936 {
1937     int          offset = 0;
1938     guint8       flag;
1939     guint8       length;
1940
1941     smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1942     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1943     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1944     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1945
1946     smpp_handle_dlist(tree, tvb, &offset);
1947
1948     flag = tvb_get_guint8(tvb, offset);
1949     proto_tree_add_item(tree, hf_smpp_esm_submit_msg_mode,
1950             tvb, offset, 1, flag);
1951     proto_tree_add_item(tree, hf_smpp_esm_submit_msg_type,
1952             tvb, offset, 1, flag);
1953     proto_tree_add_item(tree, hf_smpp_esm_submit_features,
1954             tvb, offset, 1, flag);
1955     offset++;
1956     smpp_handle_int1(tree, tvb, hf_smpp_protocol_id, &offset);
1957     smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
1958     if (tvb_get_guint8(tvb,offset)) {
1959         smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
1960                 hf_smpp_schedule_delivery_time_r, &offset);
1961     } else { /* Time = NULL means Immediate delivery */
1962         proto_tree_add_text(tree, tvb, offset++, 1,
1963                 "Scheduled delivery time: Immediate delivery");
1964     }
1965     if (tvb_get_guint8(tvb,offset)) {
1966         smpp_handle_time(tree, tvb, hf_smpp_validity_period,
1967                 hf_smpp_validity_period_r, &offset);
1968     } else { /* Time = NULL means SMSC default validity */
1969         proto_tree_add_text(tree, tvb, offset++, 1,
1970                 "Validity period: SMSC default validity period");
1971     }
1972     flag = tvb_get_guint8(tvb, offset);
1973     proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1974     proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1975     proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1976     offset++;
1977     smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
1978     smpp_handle_dcs(tree, tvb, &offset);
1979     smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
1980     length = tvb_get_guint8(tvb, offset);
1981     proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
1982     if (length)
1983         proto_tree_add_item(tree, hf_smpp_short_message,
1984                 tvb, offset, length, FALSE);
1985     offset += length;
1986     smpp_handle_tlv(tree, tvb, &offset);
1987 }
1988
1989 static void
1990 alert_notification(proto_tree *tree, tvbuff_t *tvb)
1991 {
1992     int          offset = 0;
1993
1994     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1995     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1996     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1997     smpp_handle_int1(tree, tvb, hf_smpp_esme_addr_ton, &offset);
1998     smpp_handle_int1(tree, tvb, hf_smpp_esme_addr_npi, &offset);
1999     smpp_handle_string(tree, tvb, hf_smpp_esme_addr, &offset);
2000     smpp_handle_tlv(tree, tvb, &offset);
2001 }
2002
2003 static void
2004 data_sm(proto_tree *tree, tvbuff_t *tvb)
2005 {
2006     int          offset = 0;
2007     guint8       flag;
2008
2009     smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
2010     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
2011     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
2012     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
2013     smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
2014     smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
2015     smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
2016     flag = tvb_get_guint8(tvb, offset);
2017     proto_tree_add_item(tree, hf_smpp_esm_submit_msg_mode,
2018                         tvb, offset, 1, flag);
2019     proto_tree_add_item(tree, hf_smpp_esm_submit_msg_type,
2020                         tvb, offset, 1, flag);
2021     proto_tree_add_item(tree, hf_smpp_esm_submit_features,
2022                         tvb, offset, 1, flag);
2023     offset++;
2024     flag = tvb_get_guint8(tvb, offset);
2025     proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
2026     proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
2027     proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
2028     offset++;
2029         smpp_handle_dcs(tree, tvb, &offset);
2030     smpp_handle_tlv(tree, tvb, &offset);
2031 }
2032
2033 /*
2034  * Request operations introduced in the SMPP 5.0
2035  */
2036 static void
2037 broadcast_sm(proto_tree *tree, tvbuff_t *tvb)
2038 {
2039     int          offset = 0;
2040
2041     smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
2042     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
2043     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
2044     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
2045     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2046     smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
2047     if (tvb_get_guint8(tvb,offset)) {
2048         smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
2049                 hf_smpp_schedule_delivery_time_r, &offset);
2050     } else { /* Time = NULL means Immediate delivery */
2051         proto_tree_add_text(tree, tvb, offset++, 1,
2052                 "Scheduled delivery time: Immediate delivery");
2053     }
2054     if (tvb_get_guint8(tvb,offset)) {
2055         smpp_handle_time(tree, tvb, hf_smpp_validity_period,
2056                 hf_smpp_validity_period_r, &offset);
2057     } else { /* Time = NULL means SMSC default validity */
2058         proto_tree_add_text(tree, tvb, offset++, 1,
2059                 "Validity period: SMSC default validity period");
2060     }
2061     smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
2062     smpp_handle_dcs(tree, tvb, &offset);
2063     smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
2064     smpp_handle_tlv(tree, tvb, &offset);
2065 }
2066
2067 static void
2068 query_broadcast_sm(proto_tree *tree, tvbuff_t *tvb)
2069 {
2070     int          offset = 0;
2071
2072     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2073     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
2074     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
2075     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
2076     smpp_handle_tlv(tree, tvb, &offset);
2077 }
2078
2079 static void
2080 cancel_broadcast_sm(proto_tree *tree, tvbuff_t *tvb)
2081 {
2082     int          offset = 0;
2083
2084     smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
2085     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2086     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
2087     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
2088     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
2089     smpp_handle_tlv(tree, tvb, &offset);
2090 }
2091
2092 /*!
2093  * The next set of routines handle the different operation-responses,
2094  * associated with SMPP.
2095  */
2096 static void
2097 bind_receiver_resp(proto_tree *tree, tvbuff_t *tvb)
2098 {
2099     int          offset = 0;
2100
2101     smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
2102     smpp_handle_tlv(tree, tvb, &offset);
2103 }
2104
2105 #define bind_transmitter_resp(a, b) bind_receiver_resp(a, b)
2106
2107 static void
2108 query_sm_resp(proto_tree *tree, tvbuff_t *tvb)
2109 {
2110     int          offset = 0;
2111
2112     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2113     smpp_handle_time(tree, tvb, hf_smpp_final_date,
2114                                 hf_smpp_final_date_r, &offset);
2115     smpp_handle_int1(tree, tvb, hf_smpp_message_state, &offset);
2116     smpp_handle_int1(tree, tvb, hf_smpp_error_code, &offset);
2117 }
2118
2119 #define bind_transceiver_resp(a, b) bind_receiver_resp(a, b)
2120
2121 static void
2122 submit_sm_resp(proto_tree *tree, tvbuff_t *tvb)
2123 {
2124     int          offset = 0;
2125
2126     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2127     smpp_handle_tlv(tree, tvb, &offset);
2128 }
2129
2130 #define deliver_sm_resp(a, b) submit_sm_resp(a, b)
2131
2132 static void
2133 submit_multi_resp(proto_tree *tree, tvbuff_t *tvb)
2134 {
2135     int          offset = 0;
2136
2137     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2138     smpp_handle_dlist_resp(tree, tvb, &offset);
2139     smpp_handle_tlv(tree, tvb, &offset);
2140 }
2141
2142 static void
2143 data_sm_resp(proto_tree *tree, tvbuff_t *tvb)
2144 {
2145     int          offset = 0;
2146
2147     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2148     smpp_handle_tlv(tree, tvb, &offset);
2149 }
2150
2151 #define broadcast_sm_resp(a, b) submit_sm_resp(a, b)
2152
2153 static void
2154 query_broadcast_sm_resp(proto_tree *tree, tvbuff_t *tvb)
2155 {
2156     int          offset = 0;
2157
2158     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2159     smpp_handle_tlv(tree, tvb, &offset);
2160 }
2161
2162
2163 /*
2164  * A 'heuristic dissector' that attemtps to establish whether we have
2165  * a genuine SMPP PDU here.
2166  * Only works when:
2167  *      at least the fixed header is there
2168  *      it has a correct overall PDU length
2169  *      it is a 'well-known' operation
2170  *      has a 'well-known' status
2171  */
2172 static gboolean
2173 dissect_smpp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2174 {
2175     guint        command_id;            /* SMPP command         */
2176     guint        command_status;        /* Status code          */
2177     guint        command_length;        /* length of PDU        */
2178
2179     if (tvb_reported_length(tvb) < SMPP_MIN_LENGTH)     /* Mandatory header     */
2180         return FALSE;
2181     command_length = tvb_get_ntohl(tvb, 0);
2182     if (command_length > 64 * 1024 || command_length < SMPP_MIN_LENGTH)
2183         return FALSE;
2184     command_id = tvb_get_ntohl(tvb, 4);         /* Only known commands  */
2185     if (match_strval(command_id, vals_command_id) == NULL)
2186         return FALSE;
2187     command_status = tvb_get_ntohl(tvb, 8);     /* ..with known status  */
2188     if (match_strval(command_status, vals_command_status) == NULL)
2189         return FALSE;
2190     dissect_smpp(tvb, pinfo, tree);
2191     return TRUE;
2192 }
2193
2194 static guint
2195 get_smpp_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
2196 {
2197     return tvb_get_ntohl(tvb, offset);
2198 }
2199
2200 /*
2201  * This global SMPP variable is used to determine whether the PDU to dissect
2202  * is the first SMPP PDU in the packet (or reassembled buffer), requiring
2203  * different column update code than subsequent SMPP PDUs within this packet
2204  * (or reassembled buffer).
2205  *
2206  * FIXME - This approach is NOT dissection multi-thread safe!
2207  */
2208 static gboolean first = TRUE;
2209
2210 static void
2211 dissect_smpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2212 {
2213     first = TRUE;
2214     if (pinfo->ptype == PT_TCP) {       /* are we running on top of TCP */
2215         tcp_dissect_pdus(tvb, pinfo, tree,
2216                 reassemble_over_tcp,    /* Do we try to reassemble      */
2217                 16,                     /* Length of fixed header       */
2218                 get_smpp_pdu_len,       /* Function returning PDU len   */
2219                 dissect_smpp_pdu);      /* PDU dissector                */
2220     } else {                            /* no? probably X.25            */
2221         guint32 offset = 0;
2222         while (tvb_reported_length_remaining(tvb, offset) > 0) {
2223             guint16 pdu_len = tvb_get_ntohl(tvb, offset);
2224             gint pdu_real_len = tvb_length_remaining(tvb, offset);
2225             tvbuff_t *pdu_tvb;
2226
2227             if (pdu_len < 1)
2228                 THROW(ReportedBoundsError);
2229
2230             if (pdu_real_len <= 0)
2231                 return;
2232             if (pdu_real_len > pdu_len)
2233                 pdu_real_len = pdu_len;
2234             pdu_tvb = tvb_new_subset(tvb, offset, pdu_real_len, pdu_len);
2235             dissect_smpp_pdu(pdu_tvb, pinfo, tree);
2236             offset += pdu_len;
2237             first = FALSE;
2238         }
2239     }
2240 }
2241
2242
2243 /* Dissect a single SMPP PDU contained within "tvb". */
2244 static void
2245 dissect_smpp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2246 {
2247     int          offset = 0;            /* Offset within tvbuff */
2248     guint        command_length;        /* length of PDU        */
2249     guint        command_id;            /* SMPP command         */
2250     guint        command_status;        /* Status code          */
2251     guint        sequence_number;       /* ...of command        */
2252     smpp_tap_rec_t* tap_rec;            /* Tap record           */
2253     const gchar *command_str;
2254     const gchar *command_status_str = NULL;
2255     /* Set up structures needed to add the protocol subtree and manage it */
2256     proto_item  *ti = NULL;
2257     proto_tree  *smpp_tree = NULL;
2258
2259     /*
2260      * Safety: don't even try to dissect the PDU
2261      * when the mandatory header isn't present.
2262      */
2263     if (tvb_reported_length(tvb) < SMPP_MIN_LENGTH)
2264         return;
2265     command_length = tvb_get_ntohl(tvb, offset);
2266     offset += 4;
2267     command_id = tvb_get_ntohl(tvb, offset);
2268     command_str = val_to_str(command_id, vals_command_id,
2269             "(Unknown SMPP Operation 0x%08X)");
2270     offset += 4;
2271     command_status = tvb_get_ntohl(tvb, offset);
2272     if (command_id & 0x80000000) {
2273         command_status_str = val_to_str(command_status, vals_command_status,
2274                 "(Reserved Error 0x%08X)");
2275     }
2276     offset += 4;
2277     sequence_number = tvb_get_ntohl(tvb, offset);
2278     offset += 4;
2279
2280     /*
2281      * Update the protocol column.
2282      */
2283     if (first == TRUE) {
2284         col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMPP");
2285     }
2286
2287     /*
2288      * Create display subtree for the protocol
2289      */
2290     if (tree) {
2291         ti = proto_tree_add_item (tree, proto_smpp, tvb, 0, tvb_length(tvb), FALSE);
2292         smpp_tree = proto_item_add_subtree (ti, ett_smpp);
2293     }
2294
2295     /*
2296      * Cycle over the encapsulated PDUs
2297      */
2298     {
2299         tvbuff_t *pdu_tvb;
2300
2301         /*
2302          * Make entries in the Info column on the summary display
2303          */
2304         if (check_col(pinfo->cinfo, COL_INFO)) {
2305             if (first == TRUE) {
2306                 /*
2307                  * First PDU - We already computed the fixed header
2308                  */
2309                 col_clear(pinfo->cinfo, COL_INFO);
2310                 col_add_fstr(pinfo->cinfo, COL_INFO, "SMPP %s", command_str);
2311                 first = FALSE;
2312             } else {
2313                 /*
2314                  * Subsequent PDUs
2315                  */
2316                 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", command_str);
2317             }
2318             /*
2319              * Display command status of responses in Info column
2320              */
2321             if (command_id & 0x80000000) {
2322                 col_append_fstr(pinfo->cinfo, COL_INFO, ": \"%s\"",
2323                         command_status_str);
2324             }
2325         }
2326
2327         /*
2328          * Create a tvb for the current PDU.
2329          * Physical length: at most command_length
2330          * Reported length: command_length
2331          */
2332         if (tvb_length_remaining(tvb, offset - 16 + command_length) > 0) {
2333             pdu_tvb = tvb_new_subset(tvb, offset - 16,
2334                     command_length,     /* Physical length */
2335                     command_length);    /* Length reported by the protocol */
2336         } else {
2337             pdu_tvb = tvb_new_subset(tvb, offset - 16,
2338                     tvb_length_remaining(tvb, offset - 16),/* Physical length */
2339                     command_length);    /* Length reported by the protocol */
2340         }
2341
2342         /*
2343          * Dissect the PDU
2344          *
2345          * If "tree" is NULL, Wireshark is only interested in creation
2346          * of conversations, reassembly and subdissection but not in
2347          * the detailed protocol tree.
2348          * In the interest of speed, skip the generation of protocol tree
2349          * items when "tree" is NULL.
2350          *
2351          * The only PDU which requires subdissection currently is the
2352          * sm_submit PDU (command ID = 0x00000004).
2353          */
2354         if (tree || (command_id == 4))
2355         {
2356             /*
2357              * Create display subtree for the PDU
2358              */
2359             if (tree) {
2360                 proto_tree_add_uint(smpp_tree, hf_smpp_command_length,
2361                         pdu_tvb, 0, 4, command_length);
2362                 proto_tree_add_uint(smpp_tree, hf_smpp_command_id,
2363                         pdu_tvb, 4, 4, command_id);
2364                 proto_item_append_text(ti, ", Command: %s", command_str);
2365
2366                 /*
2367                  * Status is only meaningful with responses
2368                  */
2369                 if (command_id & 0x80000000) {
2370                     proto_tree_add_uint(smpp_tree, hf_smpp_command_status,
2371                             pdu_tvb, 8, 4, command_status);
2372                     proto_item_append_text (ti, ", Status: \"%s\"",
2373                             command_status_str);
2374                 }
2375                 proto_tree_add_uint(smpp_tree, hf_smpp_sequence_number,
2376                         pdu_tvb, 12, 4, sequence_number);
2377                 proto_item_append_text(ti, ", Seq: %u, Len: %u",
2378                         sequence_number, command_length);
2379             }
2380
2381             /*
2382              * End of fixed header.
2383              * Don't dissect variable part if it is shortened.
2384              *
2385              * FIXME - We then do not report a Short Frame or Malformed Packet
2386              */
2387             if (command_length <= tvb_reported_length(pdu_tvb))
2388             {
2389                 tvbuff_t *tmp_tvb = tvb_new_subset(pdu_tvb, 16,
2390                         -1, command_length - 16);
2391                 if (command_id & 0x80000000)
2392                 {
2393                     switch (command_id & 0x7FFFFFFF) {
2394                         /*
2395                          * All of these only have a fixed header
2396                          */
2397                         case   0:       /* Generic nack         */
2398                         case   6:       /* Unbind resp          */
2399                         case   7:       /* Replace SM resp      */
2400                         case   8:       /* Cancel SM resp       */
2401                         case  21:       /* Enquire link resp    */
2402                         case 275:       /* Cancel Broadcast SM resp */
2403                             break;
2404                         /* FIXME: The body of the response PDUs are only
2405                          * only dissected if the request was successful.
2406                          * However, in SMPP 5.0 some responses might
2407                          * contain body to provide additional information
2408                          * about the error. This needs to be handled.
2409                          */
2410                         case   1:
2411                             if (!command_status)
2412                                 bind_receiver_resp(smpp_tree, tmp_tvb);
2413                             break;
2414                         case   2:
2415                             if (!command_status)
2416                                 bind_transmitter_resp(smpp_tree, tmp_tvb);
2417                             break;
2418                         case   3:
2419                             if (!command_status)
2420                                 query_sm_resp(smpp_tree, tmp_tvb);
2421                             break;
2422                         case   4:
2423                             if (!command_status)
2424                                 submit_sm_resp(smpp_tree, tmp_tvb);
2425                             break;
2426                         case   5:
2427                             if (!command_status)
2428                                 deliver_sm_resp(smpp_tree, tmp_tvb);
2429                             break;
2430                         case   9:
2431                             if (!command_status)
2432                                 bind_transceiver_resp(smpp_tree, tmp_tvb);
2433                             break;
2434                         case  33:
2435                             if (!command_status)
2436                                 submit_multi_resp(smpp_tree, tmp_tvb);
2437                             break;
2438                         case 259:
2439                             if (!command_status)
2440                                 data_sm_resp(smpp_tree, tmp_tvb);
2441                             break;
2442                         case 273:
2443                             if (!command_status)
2444                                 broadcast_sm_resp(smpp_tree, tmp_tvb);
2445                             break;
2446                         case 274:
2447                             if (!command_status)
2448                                 query_broadcast_sm_resp(smpp_tree, tmp_tvb);
2449                             break;
2450                         default:
2451                             break;
2452                     } /* switch (command_id & 0x7FFFFFFF) */
2453                 }
2454                 else
2455                 {
2456                     switch (command_id) {
2457                         case   1:
2458                             bind_receiver(smpp_tree, tmp_tvb);
2459                             break;
2460                         case   2:
2461                             bind_transmitter(smpp_tree, tmp_tvb);
2462                             break;
2463                         case   3:
2464                             query_sm(smpp_tree, tmp_tvb);
2465                             break;
2466                         case   4:
2467                             submit_sm(smpp_tree, tmp_tvb, pinfo, tree);
2468                             break;
2469                         case   5:
2470                             deliver_sm(smpp_tree, tmp_tvb, pinfo, tree);
2471                             break;
2472                         case   6:       /* Unbind               */
2473                         case  21:       /* Enquire link         */
2474                             break;
2475                         case   7:
2476                             replace_sm(smpp_tree, tmp_tvb);
2477                             break;
2478                         case   8:
2479                             cancel_sm(smpp_tree, tmp_tvb);
2480                             break;
2481                         case   9:
2482                             bind_transceiver(smpp_tree, tmp_tvb);
2483                             break;
2484                         case  11:
2485                             outbind(smpp_tree, tmp_tvb);
2486                             break;
2487                         case  33:
2488                             submit_multi(smpp_tree, tmp_tvb);
2489                             break;
2490                         case  258:
2491                             alert_notification(smpp_tree, tmp_tvb);
2492                             break;
2493                         case  259:
2494                             data_sm(smpp_tree, tmp_tvb);
2495                             break;
2496                         case 273:
2497                             broadcast_sm(smpp_tree, tmp_tvb);
2498                             break;
2499                         case 274:
2500                             query_broadcast_sm(smpp_tree, tmp_tvb);
2501                             break;
2502                         case 275:
2503                             cancel_broadcast_sm(smpp_tree, tmp_tvb);
2504                             break;
2505                         default:
2506                             break;
2507                     } /* switch (command_id) */
2508                 } /* if (command_id & 0x80000000) */
2509
2510             } /* if (command_length <= tvb_reported_length(pdu_tvb)) */
2511             offset += command_length;
2512         } /* if (tree || (command_id == 4)) */
2513
2514         /* Queue packet for Tap */
2515         tap_rec = ep_alloc0(sizeof(smpp_tap_rec_t));
2516         tap_rec->command_id = command_id;
2517         tap_rec->command_status = command_status;
2518         tap_queue_packet(smpp_tap, pinfo, tap_rec);
2519
2520         first = FALSE;
2521     }
2522
2523     return;
2524 }
2525
2526
2527 /* Register the protocol with Wireshark */
2528 void
2529 proto_register_smpp(void)
2530 {
2531     module_t *smpp_module; /* Preferences for SMPP */
2532
2533     /* Setup list of header fields      */
2534     static hf_register_info hf[] = {
2535         {   &hf_smpp_command_length,
2536             {   "Length", "smpp.command_length",
2537                 FT_UINT32, BASE_DEC, NULL, 0x00,
2538                 "Total length of the SMPP PDU.",
2539                 HFILL
2540             }
2541         },
2542         {   &hf_smpp_command_id,
2543             {   "Operation", "smpp.command_id",
2544                 FT_UINT32, BASE_HEX, VALS(vals_command_id), 0x00,
2545                 "Defines the SMPP PDU.",
2546                 HFILL
2547             }
2548         },
2549         {   &hf_smpp_command_status,
2550             {   "Result", "smpp.command_status",
2551                 FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
2552                 "Indicates success or failure of the SMPP request.",
2553                 HFILL
2554             }
2555         },
2556         {   &hf_smpp_sequence_number,
2557             {   "Sequence #", "smpp.sequence_number",
2558                 FT_UINT32, BASE_DEC, NULL, 0x00,
2559                 "A number to correlate requests with responses.",
2560                 HFILL
2561             }
2562         },
2563         {   &hf_smpp_system_id,
2564             {   "System ID", "smpp.system_id",
2565                 FT_STRING, BASE_NONE, NULL, 0x00,
2566                 "Identifies a system.",
2567                 HFILL
2568             }
2569         },
2570         {   &hf_smpp_password,
2571             {   "Password", "smpp.password",
2572                 FT_STRING, BASE_NONE, NULL, 0x00,
2573                 "Password used for authentication.",
2574                 HFILL
2575             }
2576         },
2577         {   &hf_smpp_system_type,
2578             {   "System type", "smpp.system_type",
2579                 FT_STRING, BASE_NONE, NULL, 0x00,
2580                 "Categorizes the system.",
2581                 HFILL
2582             }
2583         },
2584         {   &hf_smpp_interface_version,
2585             {   "Version (if)", "smpp.interface_version",
2586                 FT_STRING, BASE_NONE, NULL, 0x00,
2587                 "Version of SMPP interface supported.",
2588                 HFILL
2589             }
2590         },
2591         {   &hf_smpp_service_type,
2592             {   "Service type", "smpp.service_type",
2593                 FT_STRING, BASE_NONE, NULL, 0x00,
2594                 "SMS application service associated with the message.",
2595                 HFILL
2596             }
2597         },
2598         {   &hf_smpp_addr_ton,
2599             {   "Type of number", "smpp.addr_ton",
2600                 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2601                 "Indicates the type of number, given in the address.",
2602                 HFILL
2603             }
2604         },
2605         {   &hf_smpp_source_addr_ton,
2606             {   "Type of number (originator)", "smpp.source_addr_ton",
2607                 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2608                 "Indicates originator type of number, given in the address.",
2609                 HFILL
2610             }
2611         },
2612         {   &hf_smpp_dest_addr_ton,
2613             {   "Type of number (recipient)", "smpp.dest_addr_ton",
2614                 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2615                 "Indicates recipient type of number, given in the address.",
2616                 HFILL
2617             }
2618         },
2619         {   &hf_smpp_addr_npi,
2620             {   "Numbering plan indicator", "smpp.addr_npi",
2621                 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2622                 "Gives the numbering plan this address belongs to.",
2623                 HFILL
2624             }
2625         },
2626         {   &hf_smpp_source_addr_npi,
2627             {   "Numbering plan indicator (originator)", "smpp.source_addr_npi",
2628                 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2629                 "Gives originator numbering plan this address belongs to.",
2630                 HFILL
2631             }
2632         },
2633         {   &hf_smpp_dest_addr_npi,
2634             {   "Numbering plan indicator (recipient)", "smpp.dest_addr_npi",
2635                 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2636                 "Gives recipient numbering plan this address belongs to.",
2637                 HFILL
2638             }
2639         },
2640         {   &hf_smpp_address_range,
2641             {   "Address", "smpp.address_range",
2642                 FT_STRING, BASE_NONE, NULL, 0x00,
2643                 "Given address or address range.",
2644                 HFILL
2645             }
2646         },
2647         {   &hf_smpp_source_addr,
2648             {   "Originator address", "smpp.source_addr",
2649                 FT_STRING, BASE_NONE, NULL, 0x00,
2650                 "Address of SME originating this message.",
2651                 HFILL
2652             }
2653         },
2654         {   &hf_smpp_destination_addr,
2655             {   "Recipient address", "smpp.destination_addr",
2656                 FT_STRING, BASE_NONE, NULL, 0x00,
2657                 "Address of SME receiving this message.",
2658                 HFILL
2659             }
2660         },
2661         {   &hf_smpp_esm_submit_msg_mode,
2662             {   "Messaging mode", "smpp.esm.submit.msg_mode",
2663                 FT_UINT8, BASE_HEX, VALS(vals_esm_submit_msg_mode), 0x03,
2664                 "Mode attribute for this message.",
2665                 HFILL
2666             }
2667         },
2668         {   &hf_smpp_esm_submit_msg_type,
2669             {   "Message type", "smpp.esm.submit.msg_type",
2670                 FT_UINT8, BASE_HEX, VALS(vals_esm_submit_msg_type), 0x3C,
2671                 "Type attribute for this message.",
2672                 HFILL
2673             }
2674         },
2675         {   &hf_smpp_esm_submit_features,
2676             {   "GSM features", "smpp.esm.submit.features",
2677                 FT_UINT8, BASE_HEX, VALS(vals_esm_submit_features), 0xC0,
2678                 "GSM network specific features.",
2679                 HFILL
2680             }
2681         },
2682         /*! \todo Get proper values from GSM-spec.      */
2683         {   &hf_smpp_protocol_id,
2684             {   "Protocol id.", "smpp.protocol_id",
2685                 FT_UINT8, BASE_HEX, NULL, 0x00,
2686                 "Protocol identifier according GSM 03.40.",
2687                 HFILL
2688             }
2689         },
2690         {   &hf_smpp_priority_flag,
2691             {   "Priority level", "smpp.priority_flag",
2692                 FT_UINT8, BASE_HEX, VALS(vals_priority_flag), 0x00,
2693                 "The priority level of the short message.",
2694                 HFILL
2695             }
2696         },
2697         {   &hf_smpp_schedule_delivery_time,
2698             {   "Scheduled delivery time", "smpp.schedule_delivery_time",
2699                 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,
2700                 "Scheduled time for delivery of short message.",
2701                 HFILL
2702             }
2703         },
2704         {   &hf_smpp_schedule_delivery_time_r,
2705             {   "Scheduled delivery time", "smpp.schedule_delivery_time_r",
2706                 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
2707                 "Scheduled time for delivery of short message.",
2708                 HFILL
2709             }
2710         },
2711         {   &hf_smpp_validity_period,
2712             {   "Validity period", "smpp.validity_period",
2713                 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,
2714                 "Validity period of this message.",
2715                 HFILL
2716             }
2717         },
2718         {   &hf_smpp_validity_period_r,
2719             {   "Validity period", "smpp.validity_period_r",
2720                 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
2721                 "Validity period of this message.",
2722                 HFILL
2723             }
2724         },
2725         {   &hf_smpp_regdel_receipt,
2726             {   "Delivery receipt", "smpp.regdel.receipt",
2727                 FT_UINT8, BASE_HEX, VALS(vals_regdel_receipt), 0x03,
2728                 "SMSC delivery receipt request.",
2729                 HFILL
2730             }
2731         },
2732         {   &hf_smpp_regdel_acks,
2733             {   "Message type", "smpp.regdel.acks",
2734                 FT_UINT8, BASE_HEX, VALS(vals_regdel_acks), 0x0C,
2735                 "SME acknowledgement request.",
2736                 HFILL
2737             }
2738         },
2739         {   &hf_smpp_regdel_notif,
2740             {   "Intermediate notif", "smpp.regdel.notif",
2741                 FT_UINT8, BASE_HEX, VALS(vals_regdel_notif), 0x10,
2742                 "Intermediate notification request.",
2743                 HFILL
2744             }
2745         },
2746         {   &hf_smpp_replace_if_present_flag,
2747             {   "Replace", "smpp.replace_if_present_flag",
2748                 FT_UINT8, BASE_HEX, VALS(vals_replace_if_present_flag), 0x01,
2749                 "Replace the short message with this one or not.",
2750                 HFILL
2751             }
2752         },
2753         {   &hf_smpp_data_coding,
2754             {   "Data coding", "smpp.data_coding",
2755                 FT_UINT8, BASE_HEX, NULL, 0x00,
2756                 "Defines the encoding scheme of the message.",
2757                 HFILL
2758             }
2759         },
2760         {   &hf_smpp_sm_default_msg_id,
2761             {   "Predefined message", "smpp.sm_default_msg_id",
2762                 FT_UINT8, BASE_DEC, NULL, 0x00,
2763                 "Index of a predefined ('canned') short message.",
2764                 HFILL
2765             }
2766         },
2767         {   &hf_smpp_sm_length,
2768             {   "Message length", "smpp.sm_length",
2769                 FT_UINT8, BASE_DEC, NULL, 0x00,
2770                 "Length of the message content.",
2771                 HFILL
2772             }
2773         },
2774         {   &hf_smpp_short_message,
2775             {   "Message", "smpp.message",
2776                 FT_NONE, BASE_NONE, NULL, 0x00,
2777                 "The actual message or data.",
2778                 HFILL
2779             }
2780         },
2781         {   &hf_smpp_message_id,
2782             {   "Message id.", "smpp.message_id",
2783                 FT_STRING, BASE_NONE, NULL, 0x00,
2784                 "Identifier of the submitted short message.",
2785                 HFILL
2786             }
2787         },
2788         {   &hf_smpp_dlist,
2789             {   "Destination list", "smpp.dlist",
2790                 FT_NONE, BASE_NONE, NULL, 0x00,
2791                 "The list of destinations for a short message.",
2792                 HFILL
2793             }
2794         },
2795         {   &hf_smpp_dlist_resp,
2796             {   "Unsuccessful delivery list", "smpp.dlist_resp",
2797                 FT_NONE, BASE_NONE, NULL, 0x00,
2798                 "The list of unsuccessful deliveries to destinations.",
2799                 HFILL
2800             }
2801         },
2802         {   &hf_smpp_dl_name,
2803             {   "Distr. list name", "smpp.dl_name",
2804                 FT_STRING, BASE_NONE, NULL, 0x00,
2805                 "The name of the distribution list.",
2806                 HFILL
2807             }
2808         },
2809         {   &hf_smpp_final_date,
2810             {   "Final date", "smpp.final_date",
2811                 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,
2812                 "Date-time when the queried message reached a final state.",
2813                 HFILL
2814             }
2815         },
2816         {   &hf_smpp_final_date_r,
2817             {   "Final date", "smpp.final_date_r",
2818                 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
2819                 "Date-time when the queried message reached a final state.",
2820                 HFILL
2821             }
2822         },
2823         {   &hf_smpp_message_state,
2824             {   "Message state", "smpp.message_state",
2825                 FT_UINT8, BASE_DEC, VALS(vals_message_state), 0x00,
2826                 "Specifies the status of the queried short message.",
2827                 HFILL
2828             }
2829         },
2830         {   &hf_smpp_error_code,
2831             {   "Error code", "smpp.error_code",
2832                 FT_UINT8, BASE_DEC, NULL, 0x00,
2833                 "Network specific error code defining reason for failure.",
2834                 HFILL
2835             }
2836         },
2837         {   &hf_smpp_error_status_code,
2838             {   "Status", "smpp.error_status_code",
2839                 FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
2840                 "Indicates success/failure of request for this address.",
2841                 HFILL
2842             }
2843         },
2844         {   &hf_smpp_esme_addr_ton,
2845             {   "Type of number (ESME)", "smpp.esme_addr_ton",
2846                 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2847                 "Indicates recipient type of number, given in the address.",
2848                 HFILL
2849             }
2850         },
2851         {   &hf_smpp_esme_addr_npi,
2852             {   "Numbering plan indicator (ESME)", "smpp.esme_addr_npi",
2853                 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2854                 "Gives the numbering plan this address belongs to.",
2855                 HFILL
2856             }
2857         },
2858         {   &hf_smpp_esme_addr,
2859             {   "ESME address", "smpp.esme_addr",
2860                 FT_STRING, BASE_NONE, NULL, 0x00,
2861                 "Address of ESME originating this message.",
2862                 HFILL
2863             }
2864         },
2865         {   &hf_smpp_dest_addr_subunit,
2866             {   "Subunit destination", "smpp.dest_addr_subunit",
2867                 FT_UINT8, BASE_HEX, VALS(vals_addr_subunit), 0x00,
2868                 "Subunit address within mobile to route message to.",
2869                 HFILL
2870             }
2871         },
2872         {   &hf_smpp_source_addr_subunit,
2873             {   "Subunit origin", "smpp.source_addr_subunit",
2874                 FT_UINT8, BASE_HEX, VALS(vals_addr_subunit), 0x00,
2875                 "Subunit address within mobile that generated the message.",
2876                 HFILL
2877             }
2878         },
2879         {   &hf_smpp_dest_network_type,
2880             {   "Destination network", "smpp.dest_network_type",
2881                 FT_UINT8, BASE_HEX, VALS(vals_network_type), 0x00,
2882                 "Network associated with the destination address.",
2883                 HFILL
2884             }
2885         },
2886         {   &hf_smpp_source_network_type,
2887             {   "Originator network", "smpp.source_network_type",
2888                 FT_UINT8, BASE_HEX, VALS(vals_network_type), 0x00,
2889                 "Network associated with the originator address.",
2890                 HFILL
2891             }
2892         },
2893         {   &hf_smpp_dest_bearer_type,
2894             {   "Destination bearer", "smpp.dest_bearer_type",
2895                 FT_UINT8, BASE_HEX, VALS(vals_bearer_type), 0x00,
2896                 "Desired bearer for delivery of message.",
2897                 HFILL
2898             }
2899         },
2900         {   &hf_smpp_source_bearer_type,
2901             {   "Originator bearer", "smpp.source_bearer_type",
2902                 FT_UINT8, BASE_HEX, VALS(vals_bearer_type), 0x00,
2903                 "Bearer over which the message originated.",
2904                 HFILL
2905             }
2906         },
2907         {   &hf_smpp_dest_telematics_id,
2908             {   "Telematic interworking (dest)", "smpp.dest_telematics_id",
2909                 FT_UINT16, BASE_HEX, NULL, 0x00,
2910                 "Telematic interworking to be used for message delivery.",
2911                 HFILL
2912             }
2913         },
2914         {   &hf_smpp_source_telematics_id,
2915             {   "Telematic interworking (orig)", "smpp.source_telematics_id",
2916                 FT_UINT16, BASE_HEX, NULL, 0x00,
2917                 "Telematic interworking used for message submission.",
2918                 HFILL
2919             }
2920         },
2921         {   &hf_smpp_qos_time_to_live,
2922             {   "Validity period", "smpp.qos_time_to_live",
2923                 FT_UINT32, BASE_DEC, NULL, 0x00,
2924                 "Number of seconds to retain message before expiry.",
2925                 HFILL
2926             }
2927         },
2928         {   &hf_smpp_payload_type,
2929             {   "Payload", "smpp.payload_type",
2930                 FT_UINT8, BASE_DEC, VALS(vals_payload_type), 0x00,
2931                 "PDU type contained in the message payload.",
2932                 HFILL
2933             }
2934         },
2935         {   &hf_smpp_additional_status_info_text,
2936             {   "Information", "smpp.additional_status_info_text",
2937                 FT_STRING, BASE_NONE, NULL, 0x00,
2938                 "Description of the meaning of a response PDU.",
2939                 HFILL
2940             }
2941         },
2942         {   &hf_smpp_receipted_message_id,
2943             {   "SMSC identifier", "smpp.receipted_message_id",
2944                 FT_STRING, BASE_NONE, NULL, 0x00,
2945                 "SMSC handle of the message being received.",
2946                 HFILL
2947             }
2948         },
2949         {   &hf_smpp_privacy_indicator,
2950             {   "Privacy indicator", "smpp.privacy_indicator",
2951                 FT_UINT8, BASE_DEC, VALS(vals_privacy_indicator), 0x00,
2952                 "Indicates the privacy level of the message.",
2953                 HFILL
2954             }
2955         },
2956     {   &hf_smpp_source_subaddress,
2957             {   "Source Subaddress", "smpp.source_subaddress",
2958                 FT_BYTES, BASE_NONE, NULL, 0x00,
2959                 NULL,
2960                 HFILL
2961             }
2962         },
2963     {   &hf_smpp_dest_subaddress,
2964             {   "Destination Subaddress", "smpp.dest_subaddress",
2965                 FT_BYTES, BASE_NONE, NULL, 0x00,
2966                 NULL,
2967                 HFILL
2968             }
2969         },
2970     {   &hf_smpp_user_message_reference,
2971             {   "Message reference", "smpp.user_message_reference",
2972                 FT_UINT16, BASE_HEX, NULL, 0x00,
2973                 "Reference to the message, assigned by the user.",
2974                 HFILL
2975             }
2976         },
2977         {   &hf_smpp_user_response_code,
2978             {   "Application response code", "smpp.user_response_code",
2979                 FT_UINT8, BASE_HEX, NULL, 0x00,
2980                 "A response code set by the user.",
2981                 HFILL
2982             }
2983         },
2984         {   &hf_smpp_language_indicator,
2985             {   "Language", "smpp.language_indicator",
2986                 FT_UINT8, BASE_DEC, VALS(vals_language_indicator), 0x00,
2987                 "Indicates the language of the short message.",
2988                 HFILL
2989             }
2990         },
2991         {   &hf_smpp_source_port,
2992             {   "Source port", "smpp.source_port",
2993                 FT_UINT16, BASE_HEX, NULL, 0x00,
2994                 "Application port associated with the source of the message.",
2995                 HFILL
2996             }
2997         },
2998         {   &hf_smpp_destination_port,
2999             {   "Destination port", "smpp.destination_port",
3000                 FT_UINT16, BASE_HEX, NULL, 0x00,
3001                 "Application port associated with the destination of the message.",
3002                 HFILL
3003             }
3004         },
3005         {   &hf_smpp_sar_msg_ref_num,
3006             {   "SAR reference number", "smpp.sar_msg_ref_num",
3007                 FT_UINT16, BASE_DEC, NULL, 0x00,
3008                 "Reference number for a concatenated short message.",
3009                 HFILL
3010             }
3011         },
3012         {   &hf_smpp_sar_total_segments,
3013             {   "SAR size", "smpp.sar_total_segments",
3014                 FT_UINT16, BASE_DEC, NULL, 0x00,
3015                 "Number of segments of a concatenated short message.",
3016                 HFILL
3017             }
3018         },
3019         {   &hf_smpp_sar_segment_seqnum,
3020             {   "SAR sequence number", "smpp.sar_segment_seqnum",
3021                 FT_UINT8, BASE_DEC, NULL, 0x00,
3022                 "Segment number within a concatenated short message.",
3023                 HFILL
3024             }
3025         },
3026         {   &hf_smpp_display_time,
3027             {   "Display time", "smpp.display_time",
3028                 FT_UINT8, BASE_DEC, VALS(vals_display_time), 0x00,
3029                 "Associates a display time with the message on the handset.",
3030                 HFILL
3031             }
3032         },
3033         {   &hf_smpp_sms_signal,
3034             {   "SMS signal", "smpp.sms_signal",
3035                 FT_UINT16, BASE_HEX, NULL, 0x00,
3036                 "Alert the user according to the information contained within this information element.",
3037                 HFILL
3038             }
3039         },
3040         {   &hf_smpp_ms_validity,
3041             {   "Validity info", "smpp.ms_validity",
3042                 FT_UINT8, BASE_DEC, VALS(vals_ms_validity), 0x00,
3043                 "Associates validity info with the message on the handset.",
3044                 HFILL
3045             }
3046         },
3047         {   &hf_smpp_dpf_result,
3048             {   "Delivery pending set?", "smpp.dpf_result",
3049                 FT_UINT8, BASE_DEC, VALS(vals_dpf_result), 0x00,
3050                 "Indicates whether Delivery Pending Flag was set.",
3051                 HFILL
3052             }
3053         },
3054         {   &hf_smpp_set_dpf,
3055             {   "Request DPF set", "smpp.set_dpf",
3056                 FT_UINT8, BASE_DEC, VALS(vals_set_dpf), 0x00,
3057                 "Request to set the DPF for certain failure scenario's.",
3058                 HFILL
3059             }
3060         },
3061         {   &hf_smpp_ms_availability_status,
3062             {   "Availability status", "smpp.ms_availability_status",