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