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