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