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