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