From Robert Groenenberg:
[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 (expiry 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                 break;
1406             case  0x0424:       /* message_payload      */
1407                 if (length)
1408                     proto_tree_add_item(sub_tree, hf_smpp_message_payload,
1409                                         tvb, *offset, length, FALSE);
1410                 (*offset) += length;
1411                 break;
1412             case  0x0425:       /* delivery_failure_reason      */
1413                 smpp_handle_int1(sub_tree, tvb,
1414                                  hf_smpp_delivery_failure_reason, offset);
1415                 break;
1416             case  0x0426:       /* more_messages_to_send        */
1417                 smpp_handle_int1(sub_tree, tvb,
1418                                  hf_smpp_more_messages_to_send, offset);
1419                 break;
1420             case  0x0427:       /* message_state        */
1421                 smpp_handle_int1(sub_tree, tvb,
1422                                  hf_smpp_message_state, offset);
1423                 break;
1424             case        0x0428: /* congestion_state */
1425                 smpp_handle_int1(sub_tree, tvb,
1426                                  hf_smpp_congestion_state, offset);
1427
1428                 break;
1429             case  0x0501:       /* ussd_service_op      */
1430                 smpp_handle_int1(sub_tree, tvb,
1431                                  hf_smpp_ussd_service_op, offset);
1432                 break;
1433             case 0x0600:        /* broadcast_channel_indicator */
1434                 smpp_handle_int1(sub_tree, tvb,
1435                                  hf_smpp_broadcast_channel_indicator, offset);
1436                 break;
1437             case 0x0601:        /* broadcast_content_type */
1438                 field = tvb_get_guint8(tvb, *offset);
1439                 proto_tree_add_uint(sub_tree, hf_smpp_broadcast_content_type_nw, tvb, *offset, 1, field);
1440                 (*offset)++;
1441                 field16 = tvb_get_ntohs(tvb, *offset);
1442                 proto_tree_add_uint(sub_tree, hf_smpp_broadcast_content_type_type, tvb, *offset, 2, field16);
1443                 (*offset) += 2;
1444                 break;
1445             case 0x0602:        /* broadcast_content_type_info */
1446                 if (length)
1447                     proto_tree_add_item(sub_tree, hf_smpp_broadcast_content_type_info,
1448                                         tvb, *offset, length, FALSE);
1449                 (*offset) += length;
1450                 break;
1451             case 0x0603:        /* broadcast_message_class */
1452                 smpp_handle_int1(sub_tree, tvb,
1453                                 hf_smpp_broadcast_message_class, offset);
1454                 break;
1455             case 0x0604:        /* broadcast_rep_num */
1456                 smpp_handle_int1(sub_tree, tvb,
1457                                 hf_smpp_broadcast_rep_num, offset);
1458                 break;
1459             case 0x0605:        /* broadcast_frequency_interval */
1460                 field = tvb_get_guint8(tvb, *offset);
1461                 proto_tree_add_uint(sub_tree, hf_smpp_broadcast_frequency_interval_unit, tvb, *offset, 1, field);
1462                 (*offset)++;
1463                 field16 = tvb_get_ntohs(tvb, *offset);
1464                 proto_tree_add_uint(sub_tree, hf_smpp_broadcast_frequency_interval_value, tvb, *offset, 2, field16);
1465                 (*offset) += 2;
1466                 break;
1467             case 0x0606:        /* broadcast_area_identifier */
1468                 field = tvb_get_guint8(tvb, *offset);
1469                 proto_tree_add_uint(sub_tree, hf_smpp_broadcast_area_identifier_format, tvb, *offset, 1, field);
1470                 proto_tree_add_item(sub_tree, hf_smpp_broadcast_area_identifier,
1471                                         tvb, *offset, length, FALSE);
1472                 (*offset) += length;
1473                 break;
1474             case 0x0607:        /* broadcast_error_status */
1475                 smpp_handle_int4(sub_tree, tvb,
1476                                 hf_smpp_broadcast_error_status, offset);
1477                 break;
1478             case 0x0608:        /* broadcast_area_success */
1479                 smpp_handle_int1(sub_tree, tvb,
1480                                 hf_smpp_broadcast_area_success, offset);
1481                 break;
1482             case 0x0609:        /* broadcast_end_time */
1483                 smpp_handle_time(sub_tree, tvb, hf_smpp_broadcast_end_time,
1484                                 hf_smpp_broadcast_end_time_r, offset);
1485                 break;
1486             case 0x060A:        /* broadcast_service_group */
1487                 if (length)
1488                     proto_tree_add_item(sub_tree, hf_smpp_broadcast_service_group,
1489                                         tvb, *offset, length, FALSE);
1490                 (*offset) += length;
1491                 break;
1492             case 0x060B:        /* billing_identification */
1493                 if (length)
1494                     proto_tree_add_item(sub_tree, hf_smpp_billing_identification,
1495                                         tvb, *offset, length, FALSE);
1496                 (*offset) += length;
1497                 break;
1498             /* 0x060C is skipped in the specs for some reason :-? */
1499             case 0x060D:        /* source_network_id */
1500                 smpp_handle_string_z(sub_tree, tvb, hf_smpp_source_network_id,
1501                                 offset, "Empty!");
1502                 break;
1503             case 0x060E:        /* dest_network_id */
1504                 smpp_handle_string_z(sub_tree, tvb, hf_smpp_dest_network_id,
1505                                 offset, "Empty!");
1506                 break;
1507             case 0x060F:        /* source_node_id */
1508                 if (length)
1509                     proto_tree_add_item(sub_tree, hf_smpp_source_node_id,
1510                                         tvb, *offset, length, FALSE);
1511                 (*offset) += length;
1512                 break;
1513             case 0x0610:        /* dest_node_id */
1514                 if (length)
1515                     proto_tree_add_item(sub_tree, hf_smpp_dest_node_id,
1516                                         tvb, *offset, length, FALSE);
1517                 (*offset) += length;
1518                 break;
1519             case 0x0611:        /* dest_addr_np_resolution */
1520                 smpp_handle_int1(sub_tree, tvb,
1521                                 hf_smpp_dest_addr_np_resolution, offset);
1522                 break;
1523             case 0x0612:        /* dest_addr_np_information */
1524                 if (length)
1525                     proto_tree_add_item(sub_tree, hf_smpp_dest_addr_np_information,
1526                                         tvb, *offset, length, FALSE);
1527                 (*offset) += length;
1528                 break;
1529             case 0x0613:        /* dest_addr_np_country */
1530                 /* TODO : Fetch values from packet-e164? */
1531                 if (length)
1532                     proto_tree_add_item(sub_tree, hf_smpp_dest_addr_np_country,
1533                                         tvb, *offset, length, FALSE);
1534                 (*offset) += length;
1535                 break;
1536             case  0x1201:       /* display_time */
1537                 smpp_handle_int1(sub_tree, tvb,
1538                                  hf_smpp_display_time, offset);
1539                 break;
1540             case  0x1203:       /* sms_signal   */
1541                 smpp_handle_int2(sub_tree, tvb,
1542                                  hf_smpp_sms_signal, offset);
1543                 /*! \todo Fill as per TIA/EIA-136-710-A         */
1544                 break;
1545             case  0x1204:       /* ms_validity  */
1546                 smpp_handle_int1(sub_tree, tvb,
1547                                  hf_smpp_ms_validity, offset);
1548                 break;
1549             case  0x130C:       /* alert_on_message_delivery    */
1550                 if (length == 0) {
1551                         proto_tree_add_item(sub_tree,
1552                                     hf_smpp_alert_on_message_delivery_null,
1553                                     tvb, *offset, length, FALSE);
1554                 } else {
1555                         smpp_handle_int1(sub_tree, tvb,
1556                                     hf_smpp_alert_on_message_delivery, offset);
1557                 }
1558                 break;
1559             case  0x1380:       /* its_reply_type       */
1560                 smpp_handle_int1(sub_tree, tvb,
1561                                  hf_smpp_its_reply_type, offset);
1562                 break;
1563             case  0x1383:       /* its_session_info     */
1564                 smpp_handle_int1(sub_tree, tvb,
1565                                  hf_smpp_its_session_number, offset);
1566                 field = tvb_get_guint8(tvb, *offset);
1567                 proto_tree_add_item(sub_tree, hf_smpp_its_session_sequence,
1568                                     tvb, *offset, 1, field);
1569                 proto_tree_add_item(sub_tree, hf_smpp_its_session_ind,
1570                                     tvb, *offset, 1, field);
1571                 (*offset)++;
1572                 break;
1573
1574             default:
1575                 /* TODO : Hopefully to be implemented soon - handle vendor specific TLVs
1576                  * from a dictionary before treating them as unknown! */
1577                 if ((tag >= 0x1400) && (tag <= 0x3FFF))
1578                     proto_tree_add_item(sub_tree, hf_smpp_vendor_op, tvb,
1579                                         *offset, length, FALSE);
1580                 else
1581                     proto_tree_add_item(sub_tree, hf_smpp_reserved_op, tvb,
1582                                         *offset, length, FALSE);
1583                 (*offset) += length;
1584                 break;
1585         }
1586     }
1587 }
1588
1589 void
1590 smpp_handle_dcs(proto_tree *tree, tvbuff_t *tvb, int *offset)
1591 {
1592     guint8       val;
1593         int off = *offset;
1594         proto_item *subtree = NULL;
1595
1596     val = tvb_get_guint8(tvb, off);
1597         subtree = proto_tree_add_uint(tree,
1598                         hf_smpp_data_coding, tvb, off, 1, val);
1599         proto_item_add_subtree(subtree, ett_dcs);
1600         /* SMPP Data Coding Scheme */
1601         proto_tree_add_uint(subtree, hf_smpp_dcs, tvb, off, 1, val);
1602         /* GSM SMS Data Coding Scheme */
1603         proto_tree_add_text(subtree, tvb, off, 1,
1604                                         "GSM SMS Data Coding");
1605         proto_tree_add_uint(subtree,
1606                         hf_smpp_dcs_sms_coding_group, tvb, off, 1, val);
1607         if (val>>6 == 2) { /* Reserved */
1608                         ;
1609         } else if (val < 0xF0) {
1610                 proto_tree_add_boolean(subtree,
1611                                 hf_smpp_dcs_text_compression, tvb, off, 1, val);
1612                 proto_tree_add_boolean(subtree,
1613                                 hf_smpp_dcs_class_present, tvb, off, 1, val);
1614                 proto_tree_add_uint(subtree,
1615                                 hf_smpp_dcs_charset, tvb, off, 1, val);
1616                 if (val & 0x10)
1617                         proto_tree_add_uint(subtree,
1618                                         hf_smpp_dcs_class, tvb, off, 1, val);
1619         } else {
1620                 if (val & 0x08)
1621                         proto_tree_add_text(subtree, tvb, off, 1,
1622                                         "SMPP: Bit .... 1... should be 0 (reserved)");
1623                 proto_tree_add_uint(subtree,
1624                                 hf_smpp_dcs_charset, tvb, off, 1, val);
1625                 proto_tree_add_uint(subtree,
1626                                 hf_smpp_dcs_class, tvb, off, 1, val);
1627         }
1628         /* Cell Broadcast Service (CBS) Data Coding Scheme */
1629         proto_tree_add_text(subtree, tvb, off, 1,
1630                                         "GSM CBS Data Coding");
1631         proto_tree_add_uint(subtree,
1632                         hf_smpp_dcs_cbs_coding_group, tvb, off, 1, val);
1633         if (val < 0x40) { /* Language specified */
1634                 proto_tree_add_uint(subtree,
1635                                 hf_smpp_dcs_cbs_language, tvb, off, 1, val);
1636         } else if (val>>6 == 1) { /* General Data Coding indication */
1637                 proto_tree_add_boolean(subtree,
1638                                 hf_smpp_dcs_text_compression, tvb, off, 1, val);
1639                 proto_tree_add_boolean(subtree,
1640                                 hf_smpp_dcs_class_present, tvb, off, 1, val);
1641                 proto_tree_add_uint(subtree,
1642                                 hf_smpp_dcs_charset, tvb, off, 1, val);
1643                 if (val & 0x10)
1644                         proto_tree_add_uint(subtree,
1645                                         hf_smpp_dcs_class, tvb, off, 1, val);
1646         } else if (val>>6 == 2) { /* Message with UDH structure */
1647                 proto_tree_add_uint(subtree,
1648                                 hf_smpp_dcs_charset, tvb, off, 1, val);
1649                 proto_tree_add_uint(subtree,
1650                                 hf_smpp_dcs_class, tvb, off, 1, val);
1651         } else if (val>>4 == 14) { /* WAP Forum */
1652                 proto_tree_add_uint(subtree,
1653                                 hf_smpp_dcs_wap_charset, tvb, off, 1, val);
1654                 proto_tree_add_uint(subtree,
1655                                 hf_smpp_dcs_wap_class, tvb, off, 1, val);
1656         } else if (val>>4 == 15) { /* Data coding / message handling */
1657                 if (val & 0x08)
1658                         proto_tree_add_text(subtree, tvb, off, 1,
1659                                         "SMPP: Bit .... 1... should be 0 (reserved)");
1660                 proto_tree_add_uint(subtree,
1661                                 hf_smpp_dcs_charset, tvb, off, 1, val);
1662                 proto_tree_add_uint(subtree,
1663                                 hf_smpp_dcs_cbs_class, tvb, off, 1, val);
1664         }
1665
1666     (*offset)++;
1667 }
1668
1669 /*!
1670  * The next set of routines handle the different operations, associated
1671  * with SMPP.
1672  */
1673 static void
1674 bind_receiver(proto_tree *tree, tvbuff_t *tvb)
1675 {
1676     int          offset = 0;
1677     guint8       field;
1678     guint8       major, minor;
1679     char         *strval;
1680
1681     strval=ep_alloc(BUFSIZ);
1682     smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
1683     smpp_handle_string(tree, tvb, hf_smpp_password, &offset);
1684     smpp_handle_string(tree, tvb, hf_smpp_system_type, &offset);
1685     field = tvb_get_guint8(tvb, offset++);
1686     minor = field & 0x0F;
1687     major = (field & 0xF0) >> 4;
1688     g_snprintf(strval, BUFSIZ, "%u.%u", major, minor);
1689     proto_tree_add_string(tree, hf_smpp_interface_version, tvb,
1690                           offset - 1, 1, strval);
1691     smpp_handle_int1(tree, tvb, hf_smpp_addr_ton, &offset);
1692     smpp_handle_int1(tree, tvb, hf_smpp_addr_npi, &offset);
1693     smpp_handle_string(tree, tvb, hf_smpp_address_range, &offset);
1694 }
1695
1696 #define bind_transmitter(a, b) bind_receiver(a, b)
1697
1698 static void
1699 query_sm(proto_tree *tree, tvbuff_t *tvb)
1700 {
1701     int          offset = 0;
1702
1703     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1704     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1705     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1706     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1707 }
1708
1709 #define bind_transceiver(a, b) bind_receiver(a, b)
1710
1711 static void
1712 outbind(proto_tree *tree, tvbuff_t *tvb)
1713 {
1714     int          offset = 0;
1715
1716     smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
1717     smpp_handle_string(tree, tvb, hf_smpp_password, &offset);
1718 }
1719
1720 static void
1721 submit_sm(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
1722                 proto_tree *top_tree)
1723 {
1724     tvbuff_t    *tvb_msg;
1725     int          offset = 0;
1726     guint8       flag, udhi;
1727     guint8       length;
1728     char *src_str = NULL;
1729     char *dst_str = NULL;
1730     address save_src, save_dst;
1731
1732     smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1733     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1734     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1735     src_str = smpp_handle_string_return(tree, tvb, hf_smpp_source_addr, &offset);
1736     smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
1737     smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
1738     dst_str = smpp_handle_string_return(tree, tvb, hf_smpp_destination_addr, &offset);
1739     flag = tvb_get_guint8(tvb, offset);
1740     udhi = flag & 0x40;
1741     proto_tree_add_item(tree, hf_smpp_esm_submit_msg_mode,
1742                         tvb, offset, 1, flag);
1743     proto_tree_add_item(tree, hf_smpp_esm_submit_msg_type,
1744                         tvb, offset, 1, flag);
1745     proto_tree_add_item(tree, hf_smpp_esm_submit_features,
1746                         tvb, offset, 1, flag);
1747     offset++;
1748     smpp_handle_int1(tree, tvb, hf_smpp_protocol_id, &offset);
1749     smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
1750     if (tvb_get_guint8(tvb,offset)) {
1751         smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
1752                          hf_smpp_schedule_delivery_time_r, &offset);
1753     } else { /* Time = NULL means Immediate delivery */
1754         proto_tree_add_text(tree, tvb, offset++, 1,
1755                             "Scheduled delivery time: Immediate delivery");
1756     }
1757     if (tvb_get_guint8(tvb,offset)) {
1758         smpp_handle_time(tree, tvb, hf_smpp_validity_period,
1759                          hf_smpp_validity_period_r, &offset);
1760     } else { /* Time = NULL means SMSC default validity */
1761         proto_tree_add_text(tree, tvb, offset++, 1,
1762                             "Validity period: SMSC default validity period");
1763     }
1764     flag = tvb_get_guint8(tvb, offset);
1765     proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1766     proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1767     proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1768     offset++;
1769     smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
1770         smpp_handle_dcs(tree, tvb, &offset);
1771     smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
1772     length = tvb_get_guint8(tvb, offset);
1773     proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
1774     if (length)
1775     {
1776         proto_tree_add_item(tree, hf_smpp_short_message,
1777                             tvb, offset, length, FALSE);
1778         if (udhi) /* UDHI indicator present */
1779         {
1780             DebugLog(("UDHI present - set addresses\n"));
1781             /* Save original addresses */
1782             SET_ADDRESS(&save_src, pinfo->src.type, pinfo->src.len, pinfo->src.data);
1783             SET_ADDRESS(&save_dst, pinfo->dst.type, pinfo->dst.len, pinfo->dst.data);
1784             /* Set SMPP source and destination address */
1785             SET_ADDRESS(&(pinfo->src), AT_STRINGZ, 1+strlen(src_str), src_str);
1786             SET_ADDRESS(&(pinfo->dst), AT_STRINGZ, 1+strlen(dst_str), dst_str);
1787             tvb_msg = tvb_new_subset (tvb, offset,
1788                     MIN(length, tvb_reported_length(tvb) - offset), length);
1789             call_dissector (gsm_sms_handle, tvb_msg, pinfo, top_tree);
1790             /* Restore original addresses */
1791             SET_ADDRESS(&(pinfo->src), save_src.type, save_src.len, save_src.data );
1792             SET_ADDRESS(&(pinfo->dst), save_dst.type, save_dst.len, save_dst.data);
1793         }
1794         offset += length;
1795     }
1796     /* Get rid of SMPP text string addresses */
1797     smpp_handle_tlv(tree, tvb, &offset);
1798 }
1799
1800 #define deliver_sm(a, b, c, d) submit_sm(a, b, c, d)
1801
1802 static void
1803 replace_sm(proto_tree *tree, tvbuff_t *tvb)
1804 {
1805     int          offset = 0;
1806     guint8       flag;
1807     guint8       length;
1808
1809     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1810     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1811     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1812     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1813         if (tvb_get_guint8(tvb,offset)) {
1814     smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
1815                                 hf_smpp_schedule_delivery_time_r, &offset);
1816         } else { /* Time = NULL */
1817                 proto_tree_add_text(tree, tvb, offset++, 1,
1818                                 "Scheduled delivery time: Keep initial delivery time setting");
1819         }
1820         if (tvb_get_guint8(tvb,offset)) {
1821     smpp_handle_time(tree, tvb, hf_smpp_validity_period,
1822                                 hf_smpp_validity_period_r, &offset);
1823         } else { /* Time = NULL */
1824                 proto_tree_add_text(tree, tvb, offset++, 1,
1825                                 "Validity period: Keep initial validity period setting");
1826         }
1827     flag = tvb_get_guint8(tvb, offset);
1828     proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1829     proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1830     proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1831     offset++;
1832     smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
1833     length = tvb_get_guint8(tvb, offset);
1834     proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
1835     if (length)
1836         proto_tree_add_item(tree, hf_smpp_short_message,
1837                             tvb, offset, length, FALSE);
1838     offset += length;
1839 }
1840
1841 static void
1842 cancel_sm(proto_tree *tree, tvbuff_t *tvb)
1843 {
1844     int          offset = 0;
1845
1846     smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1847     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1848     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1849     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1850     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1851     smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
1852     smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
1853     smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
1854 }
1855
1856 static void
1857 submit_multi(proto_tree *tree, tvbuff_t *tvb)
1858 {
1859     int          offset = 0;
1860     guint8       flag;
1861     guint8       length;
1862
1863     smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1864     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1865     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1866     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1867
1868     smpp_handle_dlist(tree, tvb, &offset);
1869
1870     flag = tvb_get_guint8(tvb, offset);
1871     proto_tree_add_item(tree, hf_smpp_esm_submit_msg_mode,
1872             tvb, offset, 1, flag);
1873     proto_tree_add_item(tree, hf_smpp_esm_submit_msg_type,
1874             tvb, offset, 1, flag);
1875     proto_tree_add_item(tree, hf_smpp_esm_submit_features,
1876             tvb, offset, 1, flag);
1877     offset++;
1878     smpp_handle_int1(tree, tvb, hf_smpp_protocol_id, &offset);
1879     smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
1880     if (tvb_get_guint8(tvb,offset)) {
1881         smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
1882                 hf_smpp_schedule_delivery_time_r, &offset);
1883     } else { /* Time = NULL means Immediate delivery */
1884         proto_tree_add_text(tree, tvb, offset++, 1,
1885                 "Scheduled delivery time: Immediate delivery");
1886     }
1887     if (tvb_get_guint8(tvb,offset)) {
1888         smpp_handle_time(tree, tvb, hf_smpp_validity_period,
1889                 hf_smpp_validity_period_r, &offset);
1890     } else { /* Time = NULL means SMSC default validity */
1891         proto_tree_add_text(tree, tvb, offset++, 1,
1892                 "Validity period: SMSC default validity period");
1893     }
1894     flag = tvb_get_guint8(tvb, offset);
1895     proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1896     proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1897     proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1898     offset++;
1899     smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
1900     smpp_handle_dcs(tree, tvb, &offset);
1901     smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
1902     length = tvb_get_guint8(tvb, offset);
1903     proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
1904     if (length)
1905         proto_tree_add_item(tree, hf_smpp_short_message,
1906                 tvb, offset, length, FALSE);
1907     offset += length;
1908     smpp_handle_tlv(tree, tvb, &offset);
1909 }
1910
1911 static void
1912 alert_notification(proto_tree *tree, tvbuff_t *tvb)
1913 {
1914     int          offset = 0;
1915
1916     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1917     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1918     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1919     smpp_handle_int1(tree, tvb, hf_smpp_esme_addr_ton, &offset);
1920     smpp_handle_int1(tree, tvb, hf_smpp_esme_addr_npi, &offset);
1921     smpp_handle_string(tree, tvb, hf_smpp_esme_addr, &offset);
1922     smpp_handle_tlv(tree, tvb, &offset);
1923 }
1924
1925 static void
1926 data_sm(proto_tree *tree, tvbuff_t *tvb)
1927 {
1928     int          offset = 0;
1929     guint8       flag;
1930
1931     smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1932     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1933     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1934     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1935     smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
1936     smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
1937     smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
1938     flag = tvb_get_guint8(tvb, offset);
1939     proto_tree_add_item(tree, hf_smpp_esm_submit_msg_mode,
1940                         tvb, offset, 1, flag);
1941     proto_tree_add_item(tree, hf_smpp_esm_submit_msg_type,
1942                         tvb, offset, 1, flag);
1943     proto_tree_add_item(tree, hf_smpp_esm_submit_features,
1944                         tvb, offset, 1, flag);
1945     offset++;
1946     flag = tvb_get_guint8(tvb, offset);
1947     proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1948     proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1949     proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1950     offset++;
1951         smpp_handle_dcs(tree, tvb, &offset);
1952     smpp_handle_tlv(tree, tvb, &offset);
1953 }
1954
1955 /*
1956  * Request operations introduced in the SMPP 5.0
1957  */
1958 static void
1959 broadcast_sm(proto_tree *tree, tvbuff_t *tvb)
1960 {
1961     int          offset = 0;
1962
1963     smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1964     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1965     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1966     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1967     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1968     smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
1969     if (tvb_get_guint8(tvb,offset)) {
1970         smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
1971                 hf_smpp_schedule_delivery_time_r, &offset);
1972     } else { /* Time = NULL means Immediate delivery */
1973         proto_tree_add_text(tree, tvb, offset++, 1,
1974                 "Scheduled delivery time: Immediate delivery");
1975     }
1976     if (tvb_get_guint8(tvb,offset)) {
1977         smpp_handle_time(tree, tvb, hf_smpp_validity_period,
1978                 hf_smpp_validity_period_r, &offset);
1979     } else { /* Time = NULL means SMSC default validity */
1980         proto_tree_add_text(tree, tvb, offset++, 1,
1981                 "Validity period: SMSC default validity period");
1982     }
1983     smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
1984     smpp_handle_dcs(tree, tvb, &offset);
1985     smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
1986     smpp_handle_tlv(tree, tvb, &offset);
1987 }
1988
1989 static void
1990 query_broadcast_sm(proto_tree *tree, tvbuff_t *tvb)
1991 {
1992     int          offset = 0;
1993
1994     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1995     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1996     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1997     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1998     smpp_handle_tlv(tree, tvb, &offset);
1999 }
2000
2001 static void
2002 cancel_broadcast_sm(proto_tree *tree, tvbuff_t *tvb)
2003 {
2004     int          offset = 0;
2005
2006     smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
2007     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2008     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
2009     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
2010     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
2011     smpp_handle_tlv(tree, tvb, &offset);
2012 }
2013
2014 /*!
2015  * The next set of routines handle the different operation-responses,
2016  * associated with SMPP.
2017  */
2018 static void
2019 bind_receiver_resp(proto_tree *tree, tvbuff_t *tvb)
2020 {
2021     int          offset = 0;
2022
2023     smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
2024     smpp_handle_tlv(tree, tvb, &offset);
2025 }
2026
2027 #define bind_transmitter_resp(a, b) bind_receiver_resp(a, b)
2028
2029 static void
2030 query_sm_resp(proto_tree *tree, tvbuff_t *tvb)
2031 {
2032     int          offset = 0;
2033
2034     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2035     smpp_handle_time(tree, tvb, hf_smpp_final_date,
2036                                 hf_smpp_final_date_r, &offset);
2037     smpp_handle_int1(tree, tvb, hf_smpp_message_state, &offset);
2038     smpp_handle_int1(tree, tvb, hf_smpp_error_code, &offset);
2039 }
2040
2041 #define bind_transceiver_resp(a, b) bind_receiver_resp(a, b)
2042
2043 static void
2044 submit_sm_resp(proto_tree *tree, tvbuff_t *tvb)
2045 {
2046     int          offset = 0;
2047
2048     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2049     smpp_handle_tlv(tree, tvb, &offset);
2050 }
2051
2052 #define deliver_sm_resp(a, b) submit_sm_resp(a, b)
2053
2054 static void
2055 submit_multi_resp(proto_tree *tree, tvbuff_t *tvb)
2056 {
2057     int          offset = 0;
2058
2059     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2060     smpp_handle_dlist_resp(tree, tvb, &offset);
2061     smpp_handle_tlv(tree, tvb, &offset);
2062 }
2063
2064 static void
2065 data_sm_resp(proto_tree *tree, tvbuff_t *tvb)
2066 {
2067     int          offset = 0;
2068
2069     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2070     smpp_handle_tlv(tree, tvb, &offset);
2071 }
2072
2073 #define broadcast_sm_resp(a, b) submit_sm_resp(a, b)
2074
2075 static void
2076 query_broadcast_sm_resp(proto_tree *tree, tvbuff_t *tvb)
2077 {
2078     int          offset = 0;
2079
2080     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2081     smpp_handle_tlv(tree, tvb, &offset);
2082 }
2083
2084
2085 /*
2086  * A 'heuristic dissector' that attemtps to establish whether we have
2087  * a genuine SMPP PDU here.
2088  * Only works when:
2089  *      at least the fixed header is there
2090  *      it has a correct overall PDU length
2091  *      it is a 'well-known' operation
2092  *      has a 'well-known' status
2093  */
2094 static gboolean
2095 dissect_smpp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2096 {
2097     guint        command_id;            /* SMPP command         */
2098     guint        command_status;        /* Status code          */
2099     guint        command_length;        /* length of PDU        */
2100
2101     if (tvb_reported_length(tvb) < SMPP_MIN_LENGTH)     /* Mandatory header     */
2102         return FALSE;
2103     command_length = tvb_get_ntohl(tvb, 0);
2104     if (command_length > 64 * 1024 || command_length < SMPP_MIN_LENGTH)
2105         return FALSE;
2106     command_id = tvb_get_ntohl(tvb, 4);         /* Only known commands  */
2107     if (match_strval(command_id, vals_command_id) == NULL)
2108         return FALSE;
2109     command_status = tvb_get_ntohl(tvb, 8);     /* ..with known status  */
2110     if (match_strval(command_status, vals_command_status) == NULL)
2111         return FALSE;
2112     dissect_smpp(tvb, pinfo, tree);
2113     return TRUE;
2114 }
2115
2116 static guint
2117 get_smpp_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
2118 {
2119     return tvb_get_ntohl(tvb, offset);
2120 }
2121
2122 /*
2123  * This global SMPP variable is used to determine whether the PDU to dissect
2124  * is the first SMPP PDU in the packet (or reassembled buffer), requiring
2125  * different column update code than subsequent SMPP PDUs within this packet
2126  * (or reassembled buffer).
2127  *
2128  * FIXME - This approach is NOT dissection multi-thread safe!
2129  */
2130 static gboolean first = TRUE;
2131
2132 static void
2133 dissect_smpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2134 {
2135     first = TRUE;
2136     if (pinfo->ptype == PT_TCP) {       /* are we running on top of TCP */
2137         tcp_dissect_pdus(tvb, pinfo, tree,
2138                 reassemble_over_tcp,    /* Do we try to reassemble      */
2139                 16,                     /* Length of fixed header       */
2140                 get_smpp_pdu_len,       /* Function returning PDU len   */
2141                 dissect_smpp_pdu);      /* PDU dissector                */
2142     } else {                            /* no? probably X.25            */
2143         guint32 offset = 0;
2144         while (tvb_reported_length_remaining(tvb, offset) > 0) {
2145             guint16 pdu_len = tvb_get_ntohl(tvb, offset);
2146             gint pdu_real_len = tvb_length_remaining(tvb, offset);
2147             tvbuff_t *pdu_tvb;
2148
2149             if (pdu_len < 1)
2150                 THROW(ReportedBoundsError);
2151
2152             if (pdu_real_len <= 0)
2153                 return;
2154             if (pdu_real_len > pdu_len)
2155                 pdu_real_len = pdu_len;
2156             pdu_tvb = tvb_new_subset(tvb, offset, pdu_real_len, pdu_len);
2157             dissect_smpp_pdu(pdu_tvb, pinfo, tree);
2158             offset += pdu_len;
2159             first = FALSE;
2160         }
2161     }
2162 }
2163
2164
2165 /* Dissect a single SMPP PDU contained within "tvb". */
2166 static void
2167 dissect_smpp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2168 {
2169     int          offset = 0;            /* Offset within tvbuff */
2170     guint        command_length;        /* length of PDU        */
2171     guint        command_id;            /* SMPP command         */
2172     guint        command_status;        /* Status code          */
2173     guint        sequence_number;       /* ...of command        */
2174     smpp_tap_rec_t* tap_rec;            /* Tap record           */
2175     const gchar *command_str;
2176     const gchar *command_status_str = NULL;
2177     /* Set up structures needed to add the protocol subtree and manage it */
2178     proto_item  *ti = NULL;
2179     proto_tree  *smpp_tree = NULL;
2180
2181     /*
2182      * Safety: don't even try to dissect the PDU
2183      * when the mandatory header isn't present.
2184      */
2185     if (tvb_reported_length(tvb) < SMPP_MIN_LENGTH)
2186         return;
2187     command_length = tvb_get_ntohl(tvb, offset);
2188     offset += 4;
2189     command_id = tvb_get_ntohl(tvb, offset);
2190     command_str = val_to_str(command_id, vals_command_id,
2191             "(Unknown SMPP Operation 0x%08X)");
2192     offset += 4;
2193     command_status = tvb_get_ntohl(tvb, offset);
2194     if (command_id & 0x80000000) {
2195         command_status_str = val_to_str(command_status, vals_command_status,
2196                 "(Reserved Error 0x%08X)");
2197     }
2198     offset += 4;
2199     sequence_number = tvb_get_ntohl(tvb, offset);
2200     offset += 4;
2201
2202     /*
2203      * Update the protocol column.
2204      */
2205     if (first == TRUE) {
2206         if (check_col(pinfo->cinfo, COL_PROTOCOL))
2207             col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMPP");
2208     }
2209
2210     /*
2211      * Create display subtree for the protocol
2212      */
2213     if (tree) {
2214         ti = proto_tree_add_item (tree, proto_smpp, tvb, 0, tvb->length, FALSE);
2215         smpp_tree = proto_item_add_subtree (ti, ett_smpp);
2216     }
2217
2218     /*
2219      * Cycle over the encapsulated PDUs
2220      */
2221     {
2222         tvbuff_t *pdu_tvb;
2223
2224         /*
2225          * Make entries in the Info column on the summary display
2226          */
2227         if (check_col(pinfo->cinfo, COL_INFO)) {
2228             if (first == TRUE) {
2229                 /*
2230                  * First PDU - We already computed the fixed header
2231                  */
2232                 col_clear(pinfo->cinfo, COL_INFO);
2233                 col_add_fstr(pinfo->cinfo, COL_INFO, "SMPP %s", command_str);
2234                 first = FALSE;
2235             } else {
2236                 /*
2237                  * Subsequent PDUs
2238                  */
2239                 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", command_str);
2240             }
2241             /*
2242              * Display command status of responses in Info column
2243              */
2244             if (command_id & 0x80000000) {
2245                 col_append_fstr(pinfo->cinfo, COL_INFO, ": \"%s\"",
2246                         command_status_str);
2247             }
2248         }
2249
2250         /*
2251          * Create a tvb for the current PDU.
2252          * Physical length: at most command_length
2253          * Reported length: command_length
2254          */
2255         if (tvb_length_remaining(tvb, offset - 16 + command_length) > 0) {
2256             pdu_tvb = tvb_new_subset(tvb, offset - 16,
2257                     command_length,     /* Physical length */
2258                     command_length);    /* Length reported by the protocol */
2259         } else {
2260             pdu_tvb = tvb_new_subset(tvb, offset - 16,
2261                     tvb_length_remaining(tvb, offset - 16),/* Physical length */
2262                     command_length);    /* Length reported by the protocol */
2263         }
2264
2265         /*
2266          * Dissect the PDU
2267          *
2268          * If "tree" is NULL, Wireshark is only interested in creation
2269          * of conversations, reassembly and subdissection but not in
2270          * the detailed protocol tree.
2271          * In the interest of speed, skip the generation of protocol tree
2272          * items when "tree" is NULL.
2273          *
2274          * The only PDU which requires subdissection currently is the
2275          * sm_submit PDU (command ID = 0x00000004).
2276          */
2277         if (tree || (command_id == 4))
2278         {
2279             /*
2280              * Create display subtree for the PDU
2281              */
2282             if (tree) {
2283                 proto_tree_add_uint(smpp_tree, hf_smpp_command_length,
2284                         pdu_tvb, 0, 4, command_length);
2285                 proto_tree_add_uint(smpp_tree, hf_smpp_command_id,
2286                         pdu_tvb, 4, 4, command_id);
2287                 proto_item_append_text(ti, ", Command: %s", command_str);
2288
2289                 /*
2290                  * Status is only meaningful with responses
2291                  */
2292                 if (command_id & 0x80000000) {
2293                     proto_tree_add_uint(smpp_tree, hf_smpp_command_status,
2294                             pdu_tvb, 8, 4, command_status);
2295                     proto_item_append_text (ti, ", Status: \"%s\"",
2296                             command_status_str);
2297                 }
2298                 proto_tree_add_uint(smpp_tree, hf_smpp_sequence_number,
2299                         pdu_tvb, 12, 4, sequence_number);
2300                 proto_item_append_text(ti, ", Seq: %u, Len: %u",
2301                         sequence_number, command_length);
2302             }
2303
2304             /*
2305              * End of fixed header.
2306              * Don't dissect variable part if it is shortened.
2307              *
2308              * FIXME - We then do not report a Short Frame or Malformed Packet
2309              */
2310             if (command_length <= tvb_reported_length(pdu_tvb))
2311             {
2312                 tvbuff_t *tmp_tvb = tvb_new_subset(pdu_tvb, 16,
2313                         -1, command_length - 16);
2314                 if (command_id & 0x80000000)
2315                 {
2316                     switch (command_id & 0x7FFFFFFF) {
2317                         /*
2318                          * All of these only have a fixed header
2319                          */
2320                         case   0:       /* Generic nack         */
2321                         case   6:       /* Unbind resp          */
2322                         case   7:       /* Replace SM resp      */
2323                         case   8:       /* Cancel SM resp       */
2324                         case  21:       /* Enquire link resp    */
2325                         case 275:       /* Cancel Broadcast SM resp */
2326                             break;
2327                         /* FIXME: The body of the response PDUs are only
2328                          * only dissected if the request was successful.
2329                          * However, in SMPP 5.0 some responses might
2330                          * contain body to provide additional information
2331                          * about the error. This needs to be handled.
2332                          */
2333                         case   1:
2334                             if (!command_status)
2335                                 bind_receiver_resp(smpp_tree, tmp_tvb);
2336                             break;
2337                         case   2:
2338                             if (!command_status)
2339                                 bind_transmitter_resp(smpp_tree, tmp_tvb);
2340                             break;
2341                         case   3:
2342                             if (!command_status)
2343                                 query_sm_resp(smpp_tree, tmp_tvb);
2344                             break;
2345                         case   4:
2346                             if (!command_status)
2347                                 submit_sm_resp(smpp_tree, tmp_tvb);
2348                             break;
2349                         case   5:
2350                             if (!command_status)
2351                                 deliver_sm_resp(smpp_tree, tmp_tvb);
2352                             break;
2353                         case   9:
2354                             if (!command_status)
2355                                 bind_transceiver_resp(smpp_tree, tmp_tvb);
2356                             break;
2357                         case  33:
2358                             if (!command_status)
2359                                 submit_multi_resp(smpp_tree, tmp_tvb);
2360                             break;
2361                         case 259:
2362                             if (!command_status)
2363                                 data_sm_resp(smpp_tree, tmp_tvb);
2364                             break;
2365                         case 273:
2366                             if (!command_status)
2367                                 broadcast_sm_resp(smpp_tree, tmp_tvb);
2368                             break;
2369                         case 274:
2370                             if (!command_status)
2371                                 query_broadcast_sm_resp(smpp_tree, tmp_tvb);
2372                             break;
2373                         default:
2374                             break;
2375                     } /* switch (command_id & 0x7FFFFFFF) */
2376                 }
2377                 else
2378                 {
2379                     switch (command_id) {
2380                         case   1:
2381                             bind_receiver(smpp_tree, tmp_tvb);
2382                             break;
2383                         case   2:
2384                             bind_transmitter(smpp_tree, tmp_tvb);
2385                             break;
2386                         case   3:
2387                             query_sm(smpp_tree, tmp_tvb);
2388                             break;
2389                         case   4:
2390                             submit_sm(smpp_tree, tmp_tvb, pinfo, tree);
2391                             break;
2392                         case   5:
2393                             deliver_sm(smpp_tree, tmp_tvb, pinfo, tree);
2394                             break;
2395                         case   6:       /* Unbind               */
2396                         case  21:       /* Enquire link         */
2397                             break;
2398                         case   7:
2399                             replace_sm(smpp_tree, tmp_tvb);
2400                             break;
2401                         case   8:
2402                             cancel_sm(smpp_tree, tmp_tvb);
2403                             break;
2404                         case   9:
2405                             bind_transceiver(smpp_tree, tmp_tvb);
2406                             break;
2407                         case  11:
2408                             outbind(smpp_tree, tmp_tvb);
2409                             break;
2410                         case  33:
2411                             submit_multi(smpp_tree, tmp_tvb);
2412                             break;
2413                         case  258:
2414                             alert_notification(smpp_tree, tmp_tvb);
2415                             break;
2416                         case  259:
2417                             data_sm(smpp_tree, tmp_tvb);
2418                             break;
2419                         case 273:
2420                             broadcast_sm(smpp_tree, tmp_tvb);
2421                             break;
2422                         case 274:
2423                             query_broadcast_sm(smpp_tree, tmp_tvb);
2424                             break;
2425                         case 275:
2426                             cancel_broadcast_sm(smpp_tree, tmp_tvb);
2427                             break;
2428                         default:
2429                             break;
2430                     } /* switch (command_id) */
2431                 } /* if (command_id & 0x80000000) */
2432
2433             } /* if (command_length <= tvb_reported_length(pdu_tvb)) */
2434             offset += command_length;
2435         } /* if (tree || (command_id == 4)) */
2436
2437         /* Queue packet for Tap */
2438         tap_rec = ep_alloc0(sizeof(smpp_tap_rec_t));
2439         tap_rec->command_id = command_id;
2440         tap_rec->command_status = command_status;
2441         tap_queue_packet(smpp_tap, pinfo, tap_rec);
2442
2443         first = FALSE;
2444     }
2445
2446     return;
2447 }
2448
2449
2450 /* Register the protocol with Wireshark */
2451 void
2452 proto_register_smpp(void)
2453 {
2454     module_t *smpp_module; /* Preferences for SMPP */
2455
2456     /* Setup list of header fields      */
2457     static hf_register_info hf[] = {
2458         {   &hf_smpp_command_length,
2459             {   "Length    ", "smpp.command_length",
2460                 FT_UINT32, BASE_DEC, NULL, 0x00,
2461                 "Total length of the SMPP PDU.",
2462                 HFILL
2463             }
2464         },
2465         {   &hf_smpp_command_id,
2466             {   "Operation ", "smpp.command_id",
2467                 FT_UINT32, BASE_HEX, VALS(vals_command_id), 0x00,
2468                 "Defines the SMPP PDU.",
2469                 HFILL
2470             }
2471         },
2472         {   &hf_smpp_command_status,
2473             {   "Result    ", "smpp.command_status",
2474                 FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
2475                 "Indicates success or failure of the SMPP request.",
2476                 HFILL
2477             }
2478         },
2479         {   &hf_smpp_sequence_number,
2480             {   "Sequence #", "smpp.sequence_number",
2481                 FT_UINT32, BASE_DEC, NULL, 0x00,
2482                 "A number to correlate requests with responses.",
2483                 HFILL
2484             }
2485         },
2486         {   &hf_smpp_system_id,
2487             {   "System ID", "smpp.system_id",
2488                 FT_STRING, BASE_NONE, NULL, 0x00,
2489                 "Identifies a system.",
2490                 HFILL
2491             }
2492         },
2493         {   &hf_smpp_password,
2494             {   "Password", "smpp.password",
2495                 FT_STRING, BASE_NONE, NULL, 0x00,
2496                 "Password used for authentication.",
2497                 HFILL
2498             }
2499         },
2500         {   &hf_smpp_system_type,
2501             {   "System type", "smpp.system_type",
2502                 FT_STRING, BASE_NONE, NULL, 0x00,
2503                 "Categorizes the system.",
2504                 HFILL
2505             }
2506         },
2507         {   &hf_smpp_interface_version,
2508             {   "Version (if)", "smpp.interface_version",
2509                 FT_STRING, BASE_NONE, NULL, 0x00,
2510                 "Version of SMPP interface supported.",
2511                 HFILL
2512             }
2513         },
2514         {   &hf_smpp_service_type,
2515             {   "Service type", "smpp.service_type",
2516                 FT_STRING, BASE_NONE, NULL, 0x00,
2517                 "SMS application service associated with the message.",
2518                 HFILL
2519             }
2520         },
2521         {   &hf_smpp_addr_ton,
2522             {   "Type of number", "smpp.addr_ton",
2523                 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2524                 "Indicates the type of number, given in the address.",
2525                 HFILL
2526             }
2527         },
2528         {   &hf_smpp_source_addr_ton,
2529             {   "Type of number (originator)", "smpp.source_addr_ton",
2530                 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2531                 "Indicates originator type of number, given in the address.",
2532                 HFILL
2533             }
2534         },
2535         {   &hf_smpp_dest_addr_ton,
2536             {   "Type of number (recipient)", "smpp.dest_addr_ton",
2537                 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2538                 "Indicates recipient type of number, given in the address.",
2539                 HFILL
2540             }
2541         },
2542         {   &hf_smpp_addr_npi,
2543             {   "Numbering plan indicator", "smpp.addr_npi",
2544                 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2545                 "Gives the numbering plan this address belongs to.",
2546                 HFILL
2547             }
2548         },
2549         {   &hf_smpp_source_addr_npi,
2550             {   "Numbering plan indicator (originator)", "smpp.source_addr_npi",
2551                 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2552                 "Gives originator numbering plan this address belongs to.",
2553                 HFILL
2554             }
2555         },
2556         {   &hf_smpp_dest_addr_npi,
2557             {   "Numbering plan indicator (recipient)", "smpp.dest_addr_npi",
2558                 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2559                 "Gives recipient numbering plan this address belongs to.",
2560                 HFILL
2561             }
2562         },
2563         {   &hf_smpp_address_range,
2564             {   "Address", "smpp.address_range",
2565                 FT_STRING, BASE_NONE, NULL, 0x00,
2566                 "Given address or address range.",
2567                 HFILL
2568             }
2569         },
2570         {   &hf_smpp_source_addr,
2571             {   "Originator address", "smpp.source_addr",
2572                 FT_STRING, BASE_NONE, NULL, 0x00,
2573                 "Address of SME originating this message.",
2574                 HFILL
2575             }
2576         },
2577         {   &hf_smpp_destination_addr,
2578             {   "Recipient address", "smpp.destination_addr",
2579                 FT_STRING, BASE_NONE, NULL, 0x00,
2580                 "Address of SME receiving this message.",
2581                 HFILL
2582             }
2583         },
2584         {   &hf_smpp_esm_submit_msg_mode,
2585             {   "Messaging mode", "smpp.esm.submit.msg_mode",
2586                 FT_UINT8, BASE_HEX, VALS(vals_esm_submit_msg_mode), 0x03,
2587                 "Mode attribute for this message.",
2588                 HFILL
2589             }
2590         },
2591         {   &hf_smpp_esm_submit_msg_type,
2592             {   "Message type  ", "smpp.esm.submit.msg_type",
2593                 FT_UINT8, BASE_HEX, VALS(vals_esm_submit_msg_type), 0x3C,
2594                 "Type attribute for this message.",
2595                 HFILL
2596             }
2597         },
2598         {   &hf_smpp_esm_submit_features,
2599             {   "GSM features  ", "smpp.esm.submit.features",
2600                 FT_UINT8, BASE_HEX, VALS(vals_esm_submit_features), 0xC0,
2601                 "GSM network specific features.",
2602                 HFILL
2603             }
2604         },
2605         /*! \todo Get proper values from GSM-spec.      */
2606         {   &hf_smpp_protocol_id,
2607             {   "Protocol id.", "smpp.protocol_id",
2608                 FT_UINT8, BASE_HEX, NULL, 0x00,
2609                 "Protocol identifier according GSM 03.40.",
2610                 HFILL
2611             }
2612         },
2613         {   &hf_smpp_priority_flag,
2614             {   "Priority level", "smpp.priority_flag",
2615                 FT_UINT8, BASE_HEX, VALS(vals_priority_flag), 0x00,
2616                 "The priority level of the short message.",
2617                 HFILL
2618             }
2619         },
2620         {   &hf_smpp_schedule_delivery_time,
2621             {   "Scheduled delivery time", "smpp.schedule_delivery_time",
2622                 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
2623                 "Scheduled time for delivery of short message.",
2624                 HFILL
2625             }
2626         },
2627         {   &hf_smpp_schedule_delivery_time_r,
2628             {   "Scheduled delivery time", "smpp.schedule_delivery_time_r",
2629                 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
2630                 "Scheduled time for delivery of short message.",
2631                 HFILL
2632             }
2633         },
2634         {   &hf_smpp_validity_period,
2635             {   "Validity period", "smpp.validity_period",
2636                 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
2637                 "Validity period of this message.",
2638                 HFILL
2639             }
2640         },
2641         {   &hf_smpp_validity_period_r,
2642             {   "Validity period", "smpp.validity_period_r",
2643                 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
2644                 "Validity period of this message.",
2645                 HFILL
2646             }
2647         },
2648         {   &hf_smpp_regdel_receipt,
2649             {   "Delivery receipt  ", "smpp.regdel.receipt",
2650                 FT_UINT8, BASE_HEX, VALS(vals_regdel_receipt), 0x03,
2651                 "SMSC delivery receipt request.",
2652                 HFILL
2653             }
2654         },
2655         {   &hf_smpp_regdel_acks,
2656             {   "Message type      ", "smpp.regdel.acks",
2657                 FT_UINT8, BASE_HEX, VALS(vals_regdel_acks), 0x0C,
2658                 "SME acknowledgement request.",
2659                 HFILL
2660             }
2661         },
2662         {   &hf_smpp_regdel_notif,
2663             {   "Intermediate notif", "smpp.regdel.notif",
2664                 FT_UINT8, BASE_HEX, VALS(vals_regdel_notif), 0x10,
2665                 "Intermediate notification request.",
2666                 HFILL
2667             }
2668         },
2669         {   &hf_smpp_replace_if_present_flag,
2670             {   "Replace           ", "smpp.replace_if_present_flag",
2671                 FT_UINT8, BASE_HEX, VALS(vals_replace_if_present_flag), 0x01,
2672                 "Replace the short message with this one or not.",
2673                 HFILL
2674             }
2675         },
2676         {   &hf_smpp_data_coding,
2677             {   "Data coding", "smpp.data_coding",
2678                 FT_UINT8, BASE_HEX, NULL, 0x00,
2679                 "Defines the encoding scheme of the message.",
2680                 HFILL
2681             }
2682         },
2683         {   &hf_smpp_sm_default_msg_id,
2684             {   "Predefined message", "smpp.sm_default_msg_id",
2685                 FT_UINT8, BASE_DEC, NULL, 0x00,
2686                 "Index of a predefined ('canned') short message.",
2687                 HFILL
2688             }
2689         },
2690         {   &hf_smpp_sm_length,
2691             {   "Message length", "smpp.sm_length",
2692                 FT_UINT8, BASE_DEC, NULL, 0x00,
2693                 "Length of the message content.",
2694                 HFILL
2695             }
2696         },
2697         {   &hf_smpp_short_message,
2698             {   "Message", "smpp.message",
2699                 FT_NONE, BASE_NONE, NULL, 0x00,
2700                 "The actual message or data.",
2701                 HFILL
2702             }
2703         },
2704         {   &hf_smpp_message_id,
2705             {   "Message id.", "smpp.message_id",
2706                 FT_STRING, BASE_NONE, NULL, 0x00,
2707                 "Identifier of the submitted short message.",
2708                 HFILL
2709             }
2710         },
2711         {   &hf_smpp_dlist,
2712             {   "Destination list", "smpp.dlist",
2713                 FT_NONE, BASE_NONE, NULL, 0x00,
2714                 "The list of destinations for a short message.",
2715                 HFILL
2716             }
2717         },
2718         {   &hf_smpp_dlist_resp,
2719             {   "Unsuccessful delivery list", "smpp.dlist_resp",
2720                 FT_NONE, BASE_NONE, NULL, 0x00,
2721                 "The list of unsuccessful deliveries to destinations.",
2722                 HFILL
2723             }
2724         },
2725         {   &hf_smpp_dl_name,
2726             {   "Distr. list name", "smpp.dl_name",
2727                 FT_STRING, BASE_NONE, NULL, 0x00,
2728                 "The name of the distribution list.",
2729                 HFILL
2730             }
2731         },
2732         {   &hf_smpp_final_date,
2733             {   "Final date", "smpp.final_date",
2734                 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
2735                 "Date-time when the queried message reached a final state.",
2736                 HFILL
2737             }
2738         },
2739         {   &hf_smpp_final_date_r,
2740             {   "Final date", "smpp.final_date_r",
2741                 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
2742                 "Date-time when the queried message reached a final state.",
2743                 HFILL
2744             }
2745         },
2746         {   &hf_smpp_message_state,
2747             {   "Message state", "smpp.message_state",
2748                 FT_UINT8, BASE_DEC, VALS(vals_message_state), 0x00,
2749                 "Specifies the status of the queried short message.",
2750                 HFILL
2751             }
2752         },
2753         {   &hf_smpp_error_code,
2754             {   "Error code", "smpp.error_code",
2755                 FT_UINT8, BASE_DEC, NULL, 0x00,
2756                 "Network specific error code defining reason for failure.",
2757                 HFILL
2758             }
2759         },
2760         {   &hf_smpp_error_status_code,
2761             {   "Status", "smpp.error_status_code",
2762                 FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
2763                 "Indicates success/failure of request for this address.",
2764                 HFILL
2765             }
2766         },
2767         {   &hf_smpp_esme_addr_ton,
2768             {   "Type of number (ESME)", "smpp.esme_addr_ton",
2769                 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2770                 "Indicates recipient type of number, given in the address.",
2771                 HFILL
2772             }
2773         },
2774         {   &hf_smpp_esme_addr_npi,
2775             {   "Numbering plan indicator (ESME)", "smpp.esme_addr_npi",
2776                 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2777                 "Gives the numbering plan this address belongs to.",
2778                 HFILL
2779             }
2780         },
2781         {   &hf_smpp_esme_addr,
2782             {   "ESME address", "smpp.esme_addr",
2783                 FT_STRING, BASE_NONE, NULL, 0x00,
2784                 "Address of ESME originating this message.",
2785                 HFILL
2786             }
2787         },
2788         {   &hf_smpp_dest_addr_subunit,
2789             {   "Subunit destination", "smpp.dest_addr_subunit",
2790                 FT_UINT8, BASE_HEX, VALS(vals_addr_subunit), 0x00,
2791                 "Subunit address within mobile to route message to.",
2792                 HFILL
2793             }
2794         },
2795         {   &hf_smpp_source_addr_subunit,
2796             {   "Subunit origin", "smpp.source_addr_subunit",
2797                 FT_UINT8, BASE_HEX, VALS(vals_addr_subunit), 0x00,
2798                 "Subunit address within mobile that generated the message.",
2799                 HFILL
2800             }
2801         },
2802         {   &hf_smpp_dest_network_type,
2803             {   "Destination network", "smpp.dest_network_type",
2804                 FT_UINT8, BASE_HEX, VALS(vals_network_type), 0x00,
2805                 "Network associated with the destination address.",
2806                 HFILL
2807             }
2808         },
2809         {   &hf_smpp_source_network_type,
2810             {   "Originator network", "smpp.source_network_type",
2811                 FT_UINT8, BASE_HEX, VALS(vals_network_type), 0x00,
2812                 "Network associated with the originator address.",
2813                 HFILL
2814             }
2815         },
2816         {   &hf_smpp_dest_bearer_type,
2817             {   "Destination bearer", "smpp.dest_bearer_type",
2818                 FT_UINT8, BASE_HEX, VALS(vals_bearer_type), 0x00,
2819                 "Desired bearer for delivery of message.",
2820                 HFILL
2821             }
2822         },
2823         {   &hf_smpp_source_bearer_type,
2824             {   "Originator bearer", "smpp.source_bearer_type",
2825                 FT_UINT8, BASE_HEX, VALS(vals_bearer_type), 0x00,
2826                 "Bearer over which the message originated.",
2827                 HFILL
2828             }
2829         },
2830         {   &hf_smpp_dest_telematics_id,
2831             {   "Telematic interworking (dest)", "smpp.dest_telematics_id",
2832                 FT_UINT16, BASE_HEX, NULL, 0x00,
2833                 "Telematic interworking to be used for message delivery.",
2834                 HFILL
2835             }
2836         },
2837         {   &hf_smpp_source_telematics_id,
2838             {   "Telematic interworking (orig)", "smpp.source_telematics_id",
2839                 FT_UINT16, BASE_HEX, NULL, 0x00,
2840                 "Telematic interworking used for message submission.",
2841                 HFILL
2842             }
2843         },
2844         {   &hf_smpp_qos_time_to_live,
2845             {   "Validity period", "smpp.qos_time_to_live",
2846                 FT_UINT32, BASE_DEC, NULL, 0x00,
2847                 "Number of seconds to retain message before expiry.",
2848                 HFILL
2849             }
2850         },
2851         {   &hf_smpp_payload_type,
2852             {   "Payload", "smpp.payload_type",
2853                 FT_UINT8, BASE_DEC, VALS(vals_payload_type), 0x00,
2854                 "PDU type contained in the message payload.",
2855                 HFILL
2856             }
2857         },
2858         {   &hf_smpp_additional_status_info_text,
2859             {   "Information", "smpp.additional_status_info_text",
2860                 FT_STRING, BASE_NONE, NULL, 0x00,
2861                 "Description of the meaning of a response PDU.",
2862                 HFILL
2863             }
2864         },
2865         {   &hf_smpp_receipted_message_id,
2866             {   "SMSC identifier", "smpp.receipted_message_id",
2867                 FT_STRING, BASE_NONE, NULL, 0x00,
2868                 "SMSC handle of the message being received.",
2869                 HFILL
2870             }
2871         },
2872         {   &hf_smpp_privacy_indicator,
2873             {   "Privacy indicator", "smpp.privacy_indicator",
2874                 FT_UINT8, BASE_DEC, VALS(vals_privacy_indicator), 0x00,
2875                 "Indicates the privacy level of the message.",
2876                 HFILL
2877             }
2878         },
2879     {   &hf_smpp_source_subaddress,
2880             {   "Source Subaddress", "smpp.source_subaddress",
2881                 FT_BYTES, BASE_HEX, NULL, 0x00,
2882                 "Source Subaddress",
2883                 HFILL
2884             }
2885         },
2886     {   &hf_smpp_dest_subaddress,
2887             {   "Destination Subaddress", "smpp.dest_subaddress",
2888                 FT_BYTES, BASE_HEX, NULL, 0x00,
2889                 "Destination Subaddress",
2890                 HFILL
2891             }
2892         },
2893     {   &hf_smpp_user_message_reference,
2894             {   "Message reference", "smpp.user_message_reference",
2895                 FT_UINT16, BASE_HEX, NULL, 0x00,
2896                 "Reference to the message, assigned by the user.",
2897                 HFILL
2898             }
2899         },
2900         {   &hf_smpp_user_response_code,
2901             {   "Application response code", "smpp.user_response_code",
2902                 FT_UINT8, BASE_HEX, NULL, 0x00,
2903                 "A response code set by the user.",
2904                 HFILL
2905             }
2906         },
2907         {   &hf_smpp_language_indicator,
2908             {   "Language", "smpp.language_indicator",
2909                 FT_UINT8, BASE_DEC, VALS(vals_language_indicator), 0x00,
2910                 "Indicates the language of the short message.",
2911                 HFILL
2912             }
2913         },
2914         {   &hf_smpp_source_port,
2915             {   "Source port", "smpp.source_port",
2916                 FT_UINT16, BASE_HEX, NULL, 0x00,
2917                 "Application port associated with the source of the message.",
2918                 HFILL
2919             }
2920         },
2921         {   &hf_smpp_destination_port,
2922             {   "Destination port", "smpp.destination_port",
2923                 FT_UINT16, BASE_HEX, NULL, 0x00,
2924                 "Application port associated with the destination of the message.",
2925                 HFILL
2926             }
2927         },
2928         {   &hf_smpp_sar_msg_ref_num,
2929             {   "SAR reference number", "smpp.sar_msg_ref_num",
2930                 FT_UINT16, BASE_DEC, NULL, 0x00,
2931                 "Reference number for a concatenated short message.",
2932                 HFILL
2933             }
2934         },
2935         {   &hf_smpp_sar_total_segments,
2936             {   "SAR size", "smpp.sar_total_segments",
2937                 FT_UINT16, BASE_DEC, NULL, 0x00,
2938                 "Number of segments of a concatenated short message.",
2939                 HFILL
2940             }
2941         },
2942         {   &hf_smpp_sar_segment_seqnum,
2943             {   "SAR sequence number", "smpp.sar_segment_seqnum",
2944                 FT_UINT8, BASE_DEC, NULL, 0x00,
2945                 "Segment number within a concatenated short message.",
2946                 HFILL
2947             }
2948         },
2949         {   &hf_smpp_display_time,
2950             {   "Display time", "smpp.display_time",
2951                 FT_UINT8, BASE_DEC, VALS(vals_display_time), 0x00,
2952                 "Associates a display time with the message on the handset.",
2953                 HFILL
2954             }
2955         },
2956         {   &hf_smpp_sms_signal,
2957             {   "SMS signal", "smpp.sms_signal",
2958                 FT_UINT16, BASE_HEX, NULL, 0x00,
2959                 "Alert the user according to the information contained within this information element.",
2960                 HFILL
2961             }
2962         },
2963         {   &hf_smpp_ms_validity,
2964             {   "Validity info", "smpp.ms_validity",
2965                 FT_UINT8, BASE_DEC, VALS(vals_ms_validity), 0x00,
2966                 "Associates validity info with the message on the handset.",
2967                 HFILL
2968             }
2969         },
2970         {   &hf_smpp_dpf_result,
2971             {   "Delivery pending set?", "smpp.dpf_result",
2972                 FT_UINT8, BASE_DEC, VALS(vals_dpf_result), 0x00,
2973                 "Indicates whether Delivery Pending Flag was set.",
2974                 HFILL
2975             }
2976         },
2977         {   &hf_smpp_set_dpf,
2978             {   "Request DPF set", "smpp.set_dpf",
2979                 FT_UINT8, BASE_DEC, VALS(vals_set_dpf), 0x00,
2980                 "Request to set the DPF for certain failure scenario's.",
2981                 HFILL
2982             }
2983         },
2984         {   &hf_smpp_ms_availability_status,
2985             {   "Availability status", "smpp.ms_availability_status",
2986                 FT_UINT8, BASE_DEC, VALS(vals_ms_availability_status), 0x00,
2987                 "Indicates the availability state of the handset.",
2988                 HFILL
2989             }
2990         },
2991         {   &hf_smpp_delivery_failure_reason,
2992             {   "Delivery failure reason", "smpp.delivery_failure_reason",
2993                 FT_UINT8, BASE_DEC, VALS(vals_delivery_failure_reason), 0x00,
2994                 "Indicates the reason for a failed delivery attempt.",
2995                 HFILL
2996             }
2997         },
2998         {   &hf_smpp_more_messages_to_send,
2999             {   "More messages?", "smpp.more_messages_to_send",
3000                 FT_UINT8, BASE_DEC, VALS(vals_more_messages_to_send), 0x00,
3001                 "Indicates more messages pending for the same destination.",
3002                 HFILL
3003             }
3004         },
3005         {   &hf_smpp_number_of_messages,
3006             {   "Number of messages", "smpp.number_of_messages",
3007                 FT_UINT8, BASE_DEC, NULL, 0x00,
3008                 "Indicates number of messages stored in a mailbox.",
3009                 HFILL
3010             }
3011         },
3012         {   &hf_smpp_its_reply_type,
3013             {   "Reply method", "smpp.its_reply_type",
3014                 FT_UINT8, BASE_DEC, VALS(vals_its_reply_type), 0x00,
3015                 "Indicates the handset reply method on message receipt.",
3016                 HFILL
3017             }
3018         },
3019         {   &hf_smpp_ussd_service_op,
3020             {   "USSD service operation", "smpp.ussd_service_op",
3021                 FT_UINT8, BASE_DEC, VALS(vals_ussd_service_op), 0x00,
3022                 "Indicates the USSD service operation.",
3023                 HFILL
3024             }
3025         },
3026         {   &hf_smpp_vendor_op,
3027             {   "Optional parameter - Vendor-specific", "smpp.vendor_op",
3028                 FT_NONE, BASE_NONE, NULL, 0x00,
3029                 "A supplied optional parameter specific to an SMSC-vendor.",
3030                 HFILL
3031             }
3032         },
3033         {   &hf_smpp_reserved_op,
3034             {   "Optional parameter - Reserved", "smpp.reserved_op",
3035                 FT_NONE, BASE_NONE, NULL, 0x00,
3036                 "An optional parameter that is reserved in this version.",
3037                 HFILL
3038             }
3039         },
3040         {   &hf_smpp_msg_wait_ind,
3041             {   "Indication", "smpp.msg_wait.ind",
3042                 FT_UINT8, BASE_HEX, VALS(vals_msg_wait_ind), 0x80,
3043                 "Indicates to the handset that a message is waiting.",
3044                 HFILL
3045             }
3046         },
3047         {   &hf_smpp_msg_wait_type,
3048             {   "Type      ", "smpp.msg_wait.type",
3049                 FT_UINT8, BASE_HEX, VALS(vals_msg_wait_type), 0x03,
3050                 "Indicates type of message that is waiting.",
3051                 HFILL
3052             }
3053         },
3054         {   &hf_smpp_SC_interface_version,
3055             {   "SMSC-supported version", "smpp.SC_interface_version",
3056                 FT_STRING, BASE_NONE, NULL, 0x00,
3057                 "Version of SMPP interface supported by the SMSC.",
3058                 HFILL
3059             }
3060         },
3061         {   &hf_smpp_callback_num_pres,
3062             {   "Presentation", "smpp.callback_num.pres",
3063                 FT_UINT8, BASE_HEX, VALS(vals_callback_num_pres), 0x0C,
3064                 "Controls the presentation indication.",
3065                 HFILL
3066             }
3067         },
3068         {   &hf_smpp_callback_num_scrn,
3069             {   "Screening   ", "smpp.callback_num.scrn",
3070                 FT_UINT8, BASE_HEX, VALS(vals_callback_num_scrn), 0x03,
3071                 "Controls screening of the callback-number.",
3072                 HFILL
3073             }
3074         },
3075         {   &hf_smpp_callback_num_atag,
3076             {   "Callback number - alphanumeric display tag",
3077                 "smpp.callback_num_atag",
3078                 FT_NONE, BASE_NONE, NULL, 0x00,
3079                 "Associates an alphanumeric display with call back number.",
3080                 HFILL
3081             }
3082         },
3083         {   &hf_smpp_callback_num,
3084             {   "Callback number", "smpp.callback_num",
3085                 FT_NONE, BASE_NONE, NULL, 0x00,
3086                 "Associates a call back number with the message.",
3087                 HFILL
3088             }
3089         },
3090         {   &hf_smpp_network_error_type,
3091             {   "Error type", "smpp.network_error.type",
3092                 FT_UINT8, BASE_DEC, VALS(vals_network_error_type), 0x00,
3093                 "Indicates the network type.",
3094                 HFILL
3095             }
3096         },
3097         {   &hf_smpp_network_error_code,
3098             {   "Error code", "smpp.network_error.code",
3099                 FT_UINT16, BASE_HEX, NULL, 0x00,
3100                 "Gives the actual network error code.",
3101                 HFILL
3102             }
3103         },
3104         {   &hf_smpp_message_payload,
3105             {   "Payload", "smpp.message_payload",
3106                 FT_NONE, BASE_NONE, NULL, 0x00,
3107                 "Short message user data.",
3108                 HFILL
3109             }
3110         },
3111         {   &hf_smpp_alert_on_message_delivery_null,
3112             {   "Alert on delivery", "smpp.alert_on_message_delivery",
3113                 FT_NONE, BASE_NONE, NULL, 0x00,
3114                 "Instructs the handset to alert user on message delivery.",
3115                 HFILL
3116             }
3117         },
3118         {   &hf_smpp_alert_on_message_delivery,
3119             {   "Alert on delivery", "smpp.alert_on_message_delivery",
3120                 FT_UINT8, BASE_DEC, VALS(vals_alert_on_message_delivery), 0x00,
3121                 "Instructs the handset to alert user on message delivery.",
3122                 HFILL
3123             }
3124         },
3125         {   &hf_smpp_its_session_number,
3126             {   "Session number", "smpp.its_session.number",
3127                 FT_UINT8, BASE_DEC, NULL, 0x00,
3128                 "Session number of interactive teleservice.",
3129                 HFILL
3130             }
3131         },
3132         {   &hf_smpp_its_session_sequence,
3133             {   "Sequence number  ", "smpp.its_session.sequence",
3134                 FT_UINT8, BASE_HEX, NULL, 0xFE,
3135                 "Sequence number of the dialogue unit.",
3136                 HFILL
3137             }
3138         },
3139         {   &hf_smpp_its_session_ind,
3140             {   "Session indicator", "smpp.its_session.ind",
3141                 FT_UINT8, BASE_HEX, VALS(vals_its_session_ind), 0x01,
3142                 "Indicates whether this message is end of conversation.",
3143                 HFILL
3144             }
3145         },
3146         {   &hf_smpp_opt_param,
3147             {   "Optional parameters", "smpp.opt_param",
3148                 FT_NONE, BASE_NONE, NULL, 0x00,
3149                 "The list of optional parameters in this operation.",
3150                 HFILL
3151             }
3152         },
3153         /*
3154          * Data Coding Scheme
3155          */
3156         {       &hf_smpp_dcs,
3157                 { "SMPP Data Coding Scheme", "smpp.dcs",
3158                 FT_UINT8, BASE_HEX, VALS(vals_data_coding), 0x00,
3159                 "Data Coding Scheme according to SMPP.",
3160                 HFILL
3161             }
3162         },
3163         {       &hf_smpp_dcs_sms_coding_group,
3164                 {       "DCS Coding Group for SMS", "smpp.dcs.sms_coding_group",
3165                         FT_UINT8, BASE_HEX, VALS(vals_dcs_sms_coding_group), 0xF0,
3166                         "Data Coding Scheme coding group for GSM Short Message Service.",
3167                         HFILL
3168                 }
3169         },
3170         {       &hf_smpp_dcs_text_compression,
3171                 {       "DCS Text compression", "smpp.dcs.text_compression",
3172                         FT_BOOLEAN, 8, TFS(&tfs_dcs_text_compression), 0x20,
3173                         "Indicates if text compression is used.", HFILL
3174                 }
3175         },
3176         {       &hf_smpp_dcs_class_present,
3177                 {       "DCS Class present", "smpp.dcs.class_present",
3178                         FT_BOOLEAN, 8, TFS(&tfs_dcs_class_present), 0x10,
3179                         "Indicates if the message class is present (defined).", HFILL
3180                 }
3181         },
3182         {       &hf_smpp_dcs_charset,
3183                 {       "DCS Character set", "smpp.dcs.charset",
3184                         FT_UINT8, BASE_HEX, VALS(vals_dcs_charset), 0x0C,
3185                         "Specifies the character set used in the message.", HFILL
3186                 }
3187         },
3188         {       &hf_smpp_dcs_class,
3189                 {       "DCS Message class", "smpp.dcs.class",
3190                         FT_UINT8, BASE_HEX, VALS(vals_dcs_class), 0x03,
3191                         "Specifies the message class.", HFILL
3192                 }
3193         },
3194         {       &hf_smpp_dcs_cbs_coding_group,
3195                 {       "DCS Coding Group for CBS", "smpp.dcs.cbs_coding_group",
3196                         FT_UINT8, BASE_HEX, VALS(vals_dcs_cbs_coding_group), 0xF0,
3197                         "Data Coding Scheme coding group for GSM Cell Broadcast Service.",
3198                         HFILL
3199                 }
3200         },
3201         {       &hf_smpp_dcs_cbs_language,
3202                 {       "DCS CBS Message language", "smpp.dcs.cbs_language",
3203                         FT_UINT8, BASE_HEX, VALS(vals_dcs_cbs_language), 0x3F,
3204                         "Language of the GSM Cell Broadcast Service message.", HFILL
3205                 }
3206         },
3207         {       &hf_smpp_dcs_cbs_class,
3208                 {       "DCS CBS Message class", "smpp.dcs.cbs_class",
3209                         FT_UINT8, BASE_HEX, VALS(vals_dcs_cbs_class), 0x03,
3210                         "Specifies the message class for GSM Cell Broadcast Service, "
3211                         "for the Data coding / message handling code group.", HFILL
3212                 }
3213         },
3214         {       &hf_smpp_dcs_wap_charset,
3215                 {       "DCS Message coding", "smpp.dcs.wap_coding",
3216                         FT_UINT8, BASE_HEX, VALS(vals_dcs_wap_charset), 0x0C,
3217                         "Specifies the used message encoding, "
3218                         "as specified by the WAP Forum (WAP over GSM USSD).", HFILL
3219                 }
3220         },
3221         {       &hf_smpp_dcs_wap_class,
3222                 {       "DCS CBS Message class", "smpp.dcs.wap_class",
3223                         FT_UINT8, BASE_HEX, VALS(vals_dcs_wap_class), 0x03,
3224                         "Specifies the message class for GSM Cell Broadcast Service, "
3225                         "as specified by the WAP Forum (WAP over GSM USSD).", HFILL
3226                 }
3227         },
3228         /* Changes in SMPP 5.0 */
3229         {       &hf_smpp_congestion_state,
3230                 {       "Congestion State", "smpp.congestion_state",
3231                         FT_UINT8, BASE_DEC, RVALS(vals_congestion_state), 0x00,
3232                         "Congestion info between ESME and MC for flow control/cong. control", HFILL
3233                 }
3234         },
3235         {       &hf_smpp_billing_identification,
3236                 {       "Billing Identification", "smpp.billing_id",
3237                         FT_BYTES, BASE_NONE, NULL, 0x00,
3238                         "Billing identification info", HFILL
3239                 }
3240         },
3241         {       &hf_smpp_dest_addr_np_country,
3242                 {       "Destination Country Code", "smpp.dest_addr_np_country",
3243                         FT_BYTES, BASE_NONE, NULL, 0x00,
3244                         "Destination Country Code (E.164 Region Code)", HFILL
3245                 }
3246         },
3247         {       &hf_smpp_dest_addr_np_information,
3248                 {       "Number Portability information", "smpp.dest_addr_np_info",
3249                         FT_BYTES, BASE_NONE, NULL, 0x00,
3250                         "Number Portability information", HFILL
3251                 }
3252         },
3253         {       &hf_smpp_dest_addr_np_resolution,
3254                 {       "Number Portability query information", "smpp.dest_addr_np_resolution",
3255                         FT_UINT8, BASE_DEC, VALS(vals_dest_addr_np_resolution), 0x00,
3256                         "Number Portability query information - method used to resolve number", HFILL
3257                 }
3258         },
3259         {       &hf_smpp_source_network_id,
3260                 {       "Source Network ID", "smpp.source_network_id",
3261                         FT_STRING, BASE_NONE, NULL, 0x00,
3262                         "Unique ID for a network or ESME operator", HFILL
3263                 }
3264         },
3265         {       &hf_smpp_source_node_id,
3266                 {       "Source Node ID", "smpp.source_node_id",
3267                         FT_BYTES, BASE_NONE, NULL, 0x00,
3268                         "Unique ID for a ESME or MC node", HFILL
3269                 }
3270         },
3271         {       &hf_smpp_dest_network_id,
3272                 {       "Destination Network ID", "smpp.dest_network_id",
3273                         FT_STRING, BASE_NONE, NULL, 0x00,
3274                         "Unique ID for a network or ESME operator", HFILL
3275                 }
3276         },
3277         {       &hf_smpp_dest_node_id,
3278                 {       "Destination Node ID", "smpp.dest_node_id",
3279                         FT_BYTES, BASE_NONE, NULL, 0x00,
3280                         "Unique ID for a ESME or MC node", HFILL
3281                 }
3282         },
3283         {       &hf_smpp_broadcast_channel_indicator,
3284                 {       "Cell Broadcast channel", "smpp.broadcast_channel_indicator",
3285                         FT_UINT8, BASE_DEC, RVALS(vals_broadcast_channel_indicator), 0x00,
3286                         "Cell Broadcast channel", HFILL
3287                 }
3288         },
3289         {       &hf_smpp_broadcast_content_type_nw,
3290                 {       "Broadcast Content Type - Network Tag", "smpp.broadcast_content_type.nw",
3291                         FT_UINT8, BASE_DEC, VALS(vals_broadcast_content_type_nw), 0x00,
3292                         "Cell Broadcast content type", HFILL
3293                 }
3294         },
3295         {       &hf_smpp_broadcast_content_type_type,
3296                 {       "Broadcast Content Type - Content Type", "smpp.broadcast_content_type.type",
3297                         FT_UINT16, BASE_HEX, VALS(vals_broadcast_content_type_type), 0x00,
3298                         "Cell Broadcast content type", HFILL
3299                 }
3300         },
3301         {       &hf_smpp_broadcast_content_type_info,
3302                 {       "Broadcast Content Type Info", "smpp.broadcast_content_type.type",
3303                         FT_BYTES, BASE_NONE, NULL, 0x00,
3304                         "Cell Broadcast content type Info", HFILL
3305                 }
3306         },
3307         {       &hf_smpp_broadcast_message_class,
3308                 {       "Broadcast Message Class", "smpp.broadcast_message_class",
3309                         FT_UINT8, BASE_HEX, VALS(vals_broadcast_message_class), 0x00,
3310                         "Cell Broadcast Message Class", HFILL
3311                 }
3312         },
3313         {       &hf_smpp_broadcast_rep_num,
3314                 {       "Broadcast Message - Number of repetitions requested", "smpp.broadcast_rep_num",
3315                         FT_UINT16, BASE_DEC, NULL, 0x00,
3316                         "Cell Broadcast Message - Number of repetitions requested", HFILL
3317                 }
3318         },
3319         {       &hf_smpp_broadcast_frequency_interval_unit,
3320                 {       "Broadcast Message - frequency interval - Unit", "smpp.broadcast_frequency_interval.unit",
3321                         FT_UINT8, BASE_HEX, VALS(vals_broadcast_frequency_interval_unit), 0x00,
3322                         "Cell Broadcast Message - frequency interval at which broadcast must be repeated", HFILL
3323                 }
3324         },
3325         {       &hf_smpp_broadcast_frequency_interval_value,
3326                 {       "Broadcast Message - frequency interval - Unit", "smpp.broadcast_frequency_interval.value",
3327                         FT_UINT16, BASE_DEC, NULL, 0x00,
3328                         "Cell Broadcast Message - frequency interval at which broadcast must be repeated", HFILL
3329                 }
3330         },
3331         {       &hf_smpp_broadcast_area_identifier,
3332                 {       "Broadcast Message - Area Identifier", "smpp.broadcast_area_identifier",
3333                         FT_BYTES, BASE_NONE, NULL, 0x00,
3334                         "Cell Broadcast Message - Area Identifier", HFILL
3335                 }
3336         },
3337         {       &hf_smpp_broadcast_area_identifier_format,
3338                 {       "Broadcast Message - Area Identifier Format", "smpp.broadcast_area_identifier.format",
3339                         FT_UINT8, BASE_HEX, RVALS(vals_broadcast_area_identifier_format), 0x00,
3340                         "Cell Broadcast Message - Area Identifier Format", HFILL
3341                 }
3342         },
3343         {       &hf_smpp_broadcast_error_status,
3344                 {       "Broadcast Message - Error Status", "smpp.broadcast_error_status",
3345                         FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
3346                         "Cell Broadcast Message - Error Status", HFILL
3347                 }
3348         },
3349         {       &hf_smpp_broadcast_area_success,
3350                 {       "Broadcast Message - Area Success", "smpp.broadcast_area_success",
3351                         FT_UINT8, BASE_DEC, RVALS(vals_broadcast_area_success), 0x00,
3352                         "Cell Broadcast Message - success rate indicator (ratio) - No. of BTS which accepted Message:Total BTS", HFILL
3353                 }
3354         },
3355         {       &hf_smpp_broadcast_end_time,
3356                 {       "Broadcast Message - End Time", "smpp.broadcast_end_time",
3357                         FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
3358                         "Cell Broadcast Message - Date and time at which MC set the state of the message to terminated", HFILL
3359                 }
3360         },
3361         {       &hf_smpp_broadcast_end_time_r,
3362                 {       "Broadcast Message - End Time", "smpp.broadcast_end_time_r",
3363                         FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
3364                         "Cell Broadcast Message - Date and time at which MC set the state of the message to terminated", HFILL
3365                 }
3366         },
3367         {       &hf_smpp_broadcast_service_group,
3368                 {       "Broadcast Message - Service Group", "smpp.broadcast_service_group",
3369                         FT_BYTES, BASE_NONE, NULL, 0x00,
3370                         "Cell Broadcast Message - Service Group", HFILL
3371                 }
3372         }
3373     };
3374     /* Setup protocol subtree array */
3375     static gint *ett[] = {
3376         &ett_smpp,
3377         &ett_dlist,
3378         &ett_dlist_resp,
3379         &ett_opt_param,
3380         &ett_dcs,
3381     };
3382     DebugLog(("Registering SMPP dissector\n"));
3383     /* Register the protocol name and description */
3384     proto_smpp = proto_register_protocol("Short Message Peer to Peer",
3385                                          "SMPP", "smpp");
3386
3387     /* Required function calls to register header fields and subtrees used */
3388     proto_register_field_array(proto_smpp, hf, array_length(hf));
3389     proto_register_subtree_array(ett, array_length(ett));
3390
3391     /* Allow other dissectors to find this one by name. */
3392     register_dissector("smpp", dissect_smpp, proto_smpp);
3393
3394     /* Register for tapping */
3395     smpp_tap = register_tap("smpp");
3396
3397     /* Preferences */
3398     smpp_module = prefs_register_protocol (proto_smpp, NULL);
3399     prefs_register_bool_preference (smpp_module,
3400             "reassemble_smpp_over_tcp",
3401             "Reassemble SMPP over TCP messages spanning multiple TCP segments",
3402             "Whether the SMPP dissector should reassemble messages spanning multiple TCP segments."
3403             " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
3404             &reassemble_over_tcp);
3405 }
3406
3407 /*
3408  * If dissector uses sub-dissector registration add a registration routine.
3409  * This format is required because a script is used to find these routines and
3410  * create the code that calls these routines.
3411  */
3412 void
3413 proto_reg_handoff_smpp(void)
3414 {
3415     dissector_handle_t smpp_handle;
3416
3417     /*
3418      * SMPP can be spoken on any port under TCP or X.25
3419      * ...how *do* we do that under X.25?
3420      *
3421      * We can register the heuristic SMPP dissector with X.25, for one
3422      * thing.  We don't currently have any mechanism to allow the user
3423      * to specify that a given X.25 circuit is to be dissected as SMPP,
3424      * however.
3425      */
3426     smpp_handle = find_dissector("smpp");