2 * Routines for Short Message Peer to Peer dissection
3 * Copyright 2001, Tom Uijldert.
5 * Data Coding Scheme decoding for GSM (SMS and CBS),
6 * provided by Olivier Biot.
8 * Dissection of multiple SMPP PDUs within one packet
9 * provided by Chris Wilson.
13 * Refer to the AUTHORS file or the AUTHORS section in the man page
14 * for contacting the author(s) of this file.
16 * Wireshark - Network traffic analyzer
17 * By Gerald Combs <gerald@wireshark.org>
18 * Copyright 1998 Gerald Combs
20 * This program is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU General Public License
22 * as published by the Free Software Foundation; either version 2
23 * of the License, or (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 * Dissector of an SMPP (Short Message Peer to Peer) PDU, as defined by the
36 * SMS forum (www.smsforum.net) in "SMPP protocol specification v3.4"
37 * (document version: 12-Oct-1999 Issue 1.2)
51 #include <epan/packet.h>
53 #include <epan/prefs.h>
54 #include <epan/emem.h>
55 #include "packet-tcp.h"
57 /* General-purpose debug logger.
58 * Requires double parentheses because of variable arguments of printf().
60 * Enable debug logging for SMPP by defining AM_CFLAGS
61 * so that it contains "-DDEBUG_smpp"
65 g_print("%s:%u: ", __FILE__, __LINE__); \
71 /* Forward declarations */
72 static void dissect_smpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
73 static guint get_smpp_pdu_len(packet_info *pinfo, tvbuff_t *tvb, int offset);
74 static void dissect_smpp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
77 * Initialize the protocol and registered fields
79 * Fixed header section
81 static int proto_smpp = -1;
83 static int hf_smpp_command_id = -1;
84 static int hf_smpp_command_length = -1;
85 static int hf_smpp_command_status = -1;
86 static int hf_smpp_sequence_number = -1;
91 static int hf_smpp_system_id = -1;
92 static int hf_smpp_password = -1;
93 static int hf_smpp_system_type = -1;
94 static int hf_smpp_interface_version = -1;
95 static int hf_smpp_addr_ton = -1;
96 static int hf_smpp_addr_npi = -1;
97 static int hf_smpp_address_range = -1;
98 static int hf_smpp_service_type = -1;
99 static int hf_smpp_source_addr_ton = -1;
100 static int hf_smpp_source_addr_npi = -1;
101 static int hf_smpp_source_addr = -1;
102 static int hf_smpp_dest_addr_ton = -1;
103 static int hf_smpp_dest_addr_npi = -1;
104 static int hf_smpp_destination_addr = -1;
105 static int hf_smpp_esm_submit_msg_mode = -1;
106 static int hf_smpp_esm_submit_msg_type = -1;
107 static int hf_smpp_esm_submit_features = -1;
108 static int hf_smpp_protocol_id = -1;
109 static int hf_smpp_priority_flag = -1;
110 static int hf_smpp_schedule_delivery_time = -1;
111 static int hf_smpp_schedule_delivery_time_r = -1;
112 static int hf_smpp_validity_period = -1;
113 static int hf_smpp_validity_period_r = -1;
114 static int hf_smpp_regdel_receipt = -1;
115 static int hf_smpp_regdel_acks = -1;
116 static int hf_smpp_regdel_notif = -1;
117 static int hf_smpp_replace_if_present_flag = -1;
118 static int hf_smpp_data_coding = -1;
119 static int hf_smpp_sm_default_msg_id = -1;
120 static int hf_smpp_sm_length = -1;
121 static int hf_smpp_short_message = -1;
122 static int hf_smpp_message_id = -1;
123 static int hf_smpp_dlist = -1;
124 static int hf_smpp_dlist_resp = -1;
125 static int hf_smpp_dl_name = -1;
126 static int hf_smpp_final_date = -1;
127 static int hf_smpp_final_date_r = -1;
128 static int hf_smpp_message_state = -1;
129 static int hf_smpp_error_code = -1;
130 static int hf_smpp_error_status_code = -1;
131 static int hf_smpp_esme_addr_ton = -1;
132 static int hf_smpp_esme_addr_npi = -1;
133 static int hf_smpp_esme_addr = -1;
136 * Optional parameter section
138 static int hf_smpp_opt_param = -1;
139 static int hf_smpp_vendor_op = -1;
140 static int hf_smpp_reserved_op = -1;
142 static int hf_smpp_dest_addr_subunit = -1;
143 static int hf_smpp_dest_network_type = -1;
144 static int hf_smpp_dest_bearer_type = -1;
145 static int hf_smpp_dest_telematics_id = -1;
146 static int hf_smpp_source_addr_subunit = -1;
147 static int hf_smpp_source_network_type = -1;
148 static int hf_smpp_source_bearer_type = -1;
149 static int hf_smpp_source_telematics_id = -1;
150 static int hf_smpp_qos_time_to_live = -1;
151 static int hf_smpp_payload_type = -1;
152 static int hf_smpp_additional_status_info_text = -1;
153 static int hf_smpp_receipted_message_id = -1;
154 static int hf_smpp_msg_wait_ind = -1;
155 static int hf_smpp_msg_wait_type = -1;
156 static int hf_smpp_privacy_indicator = -1;
157 static int hf_smpp_source_subaddress = -1;
158 static int hf_smpp_dest_subaddress = -1;
159 static int hf_smpp_user_message_reference = -1;
160 static int hf_smpp_user_response_code = -1;
161 static int hf_smpp_source_port = -1;
162 static int hf_smpp_destination_port = -1;
163 static int hf_smpp_sar_msg_ref_num = -1;
164 static int hf_smpp_language_indicator = -1;
165 static int hf_smpp_sar_total_segments = -1;
166 static int hf_smpp_sar_segment_seqnum = -1;
167 static int hf_smpp_SC_interface_version = -1;
168 static int hf_smpp_callback_num_pres = -1;
169 static int hf_smpp_callback_num_scrn = -1;
170 static int hf_smpp_callback_num_atag = -1;
171 static int hf_smpp_number_of_messages = -1;
172 static int hf_smpp_callback_num = -1;
173 static int hf_smpp_dpf_result = -1;
174 static int hf_smpp_set_dpf = -1;
175 static int hf_smpp_ms_availability_status = -1;
176 static int hf_smpp_network_error_type = -1;
177 static int hf_smpp_network_error_code = -1;
178 static int hf_smpp_message_payload = -1;
179 static int hf_smpp_delivery_failure_reason = -1;
180 static int hf_smpp_more_messages_to_send = -1;
181 static int hf_smpp_ussd_service_op = -1;
182 static int hf_smpp_display_time = -1;
183 static int hf_smpp_sms_signal = -1;
184 static int hf_smpp_ms_validity = -1;
185 static int hf_smpp_alert_on_message_delivery = -1;
186 static int hf_smpp_its_reply_type = -1;
187 static int hf_smpp_its_session_number = -1;
188 static int hf_smpp_its_session_sequence = -1;
189 static int hf_smpp_its_session_ind = -1;
192 * Data Coding Scheme section
194 static int hf_smpp_dcs = -1;
195 static int hf_smpp_dcs_sms_coding_group = -1;
196 static int hf_smpp_dcs_text_compression = -1;
197 static int hf_smpp_dcs_class_present = -1;
198 static int hf_smpp_dcs_charset = -1;
199 static int hf_smpp_dcs_class = -1;
200 static int hf_smpp_dcs_cbs_coding_group = -1;
201 static int hf_smpp_dcs_cbs_language = -1;
202 static int hf_smpp_dcs_wap_charset = -1;
203 static int hf_smpp_dcs_wap_class = -1;
204 static int hf_smpp_dcs_cbs_class = -1;
206 /* Initialize the subtree pointers */
207 static gint ett_smpp = -1;
208 static gint ett_dlist = -1;
209 static gint ett_dlist_resp = -1;
210 static gint ett_opt_param = -1;
211 static gint ett_dcs = -1;
213 /* Reassemble SMPP TCP segments */
214 static gboolean reassemble_over_tcp = TRUE;
217 * Value-arrays for field-contents
219 static const value_string vals_command_id[] = { /* Operation */
220 { 0x80000000, "Generic_nack" },
221 { 0x00000001, "Bind_receiver" },
222 { 0x80000001, "Bind_receiver - resp" },
223 { 0x00000002, "Bind_transmitter" },
224 { 0x80000002, "Bind_transmitter - resp" },
225 { 0x00000003, "Query_sm" },
226 { 0x80000003, "Query_sm - resp" },
227 { 0x00000004, "Submit_sm" },
228 { 0x80000004, "Submit_sm - resp" },
229 { 0x00000005, "Deliver_sm" },
230 { 0x80000005, "Deliver_sm - resp" },
231 { 0x00000006, "Unbind" },
232 { 0x80000006, "Unbind - resp" },
233 { 0x00000007, "Replace_sm" },
234 { 0x80000007, "Replace_sm - resp" },
235 { 0x00000008, "Cancel_sm" },
236 { 0x80000008, "Cancel_sm - resp" },
237 { 0x00000009, "Bind_transceiver" },
238 { 0x80000009, "Bind_transceiver - resp" },
239 { 0x0000000B, "Outbind" },
240 { 0x00000015, "Enquire_link" },
241 { 0x80000015, "Enquire_link - resp" },
242 { 0x00000021, "Submit_multi" },
243 { 0x80000021, "Submit_multi - resp" },
244 { 0x00000102, "Alert_notification" },
245 { 0x00000103, "Data_sm" },
246 { 0x80000103, "Data_sm - resp" },
250 static const value_string vals_command_status[] = { /* Status */
251 { 0x00000000, "Ok" },
252 { 0x00000001, "Message length is invalid" },
253 { 0x00000002, "Command length is invalid" },
254 { 0x00000003, "Invalid command ID" },
255 { 0x00000004, "Incorrect BIND status for given command" },
256 { 0x00000005, "ESME already in bound state" },
257 { 0x00000006, "Invalid priority flag" },
258 { 0x00000007, "Invalid registered delivery flag" },
259 { 0x00000008, "System error" },
260 { 0x00000009, "[Reserved]" },
261 { 0x0000000A, "Invalid source address" },
262 { 0x0000000B, "Invalid destination address" },
263 { 0x0000000C, "Message ID is invalid" },
264 { 0x0000000D, "Bind failed" },
265 { 0x0000000E, "Invalid password" },
266 { 0x0000000F, "Invalid system ID" },
267 { 0x00000010, "[Reserved]" },
268 { 0x00000011, "Cancel SM failed" },
269 { 0x00000012, "[Reserved]" },
270 { 0x00000013, "Replace SM failed" },
271 { 0x00000014, "Message queue full" },
272 { 0x00000015, "Invalid service type" },
273 { 0x00000033, "Invalid number of destinations" },
274 { 0x00000034, "Invalid distribution list name" },
275 { 0x00000040, "Destination flag is invalid (submit_multi)" },
276 { 0x00000041, "[Reserved]" },
277 { 0x00000042, "Invalid 'submit with replace' request" },
278 { 0x00000043, "Invalid esm_class field data" },
279 { 0x00000044, "Cannot submit to distribution list" },
280 { 0x00000045, "submit_sm or submit_multi failed" },
281 { 0x00000046, "[Reserved]" },
282 { 0x00000047, "[Reserved]" },
283 { 0x00000048, "Invalid source address TON" },
284 { 0x00000049, "Invalid source address NPI" },
285 { 0x00000050, "Invalid destination address TON" },
286 { 0x00000051, "Invalid destination address NPI" },
287 { 0x00000052, "[Reserved]" },
288 { 0x00000053, "Invalid system_type field" },
289 { 0x00000054, "Invalid replace_if_present flag" },
290 { 0x00000055, "Invalid number of messages" },
291 { 0x00000056, "[Reserved]" },
292 { 0x00000057, "[Reserved]" },
293 { 0x00000058, "Throttling error (ESME exceeded allowed message limits)" },
294 { 0x00000059, "[Reserved]" },
295 { 0x00000060, "[Reserved]" },
296 { 0x00000061, "Invalid scheduled delivery time" },
297 { 0x00000062, "Invalid message validity period (expirey time)" },
298 { 0x00000063, "Predefined message invalid or not found" },
299 { 0x00000064, "ESME receiver temporary app error code" },
300 { 0x00000065, "ESME receiver permanent app error code" },
301 { 0x00000066, "ESME receiver reject message error code" },
302 { 0x00000067, "query_sm request failed" },
303 { 0x000000C0, "Error in the optional part of the PDU body" },
304 { 0x000000C1, "Optional parameter not allowed" },
305 { 0x000000C2, "Invalid parameter length" },
306 { 0x000000C3, "Expected optional parameter missing" },
307 { 0x000000C4, "Invalid optional parameter value" },
308 { 0x000000FE, "Delivery failure (used for data_sm_resp)" },
309 { 0x000000FF, "Unknown error" },
313 static const value_string vals_addr_ton[] = {
315 { 1, "International" },
317 { 3, "Network specific" },
318 { 4, "Subscriber number" },
319 { 5, "Alphanumeric" },
320 { 6, "Abbreviated" },
324 static const value_string vals_addr_npi[] = {
326 { 1, "ISDN (E163/E164)" },
327 { 3, "Data (X.121)" },
328 { 4, "Telex (F.69)" },
329 { 6, "Land mobile (E.212)" },
333 { 14, "Internet (IP)" },
334 { 18, "WAP client Id" },
338 static const value_string vals_esm_submit_msg_mode[] = {
339 { 0x0, "Default SMSC mode" },
340 { 0x1, "Datagram mode" },
341 { 0x2, "Forward mode" },
342 { 0x3, "Store and forward mode" },
346 static const value_string vals_esm_submit_msg_type[] = {
347 { 0x0, "Default message type" },
348 { 0x1, "Short message contains SMSC Delivery Receipt" },
349 { 0x2, "Short message contains (E)SME delivery acknowledgement" },
351 { 0x4, "Short message contains (E)SME manual/user acknowledgement" },
353 { 0x6, "Short message contains conversation abort" },
355 { 0x8, "Short message contains intermediate delivery notification" },
359 static const value_string vals_esm_submit_features[] = {
360 { 0x0, "No specific features selected" },
361 { 0x1, "UDHI indicator" },
362 { 0x2, "Reply path" },
363 { 0x3, "UDHI and reply path" },
367 static const value_string vals_priority_flag[] = {
368 { 0, "GSM: None ANSI-136: Bulk IS-95: Normal" },
369 { 1, "GSM: priority ANSI-136: Normal IS-95: Interactive" },
370 { 2, "GSM: priority ANSI-136: Urgent IS-95: Urgent" },
371 { 3, "GSM: priority ANSI-136: Very Urgent IS-95: Emergency" },
375 static const value_string vals_regdel_receipt[] = {
376 { 0x0, "No SMSC delivery receipt requested" },
377 { 0x1, "Delivery receipt requested (for success or failure)" },
378 { 0x2, "Delivery receipt requested (for failure)" },
383 static const value_string vals_regdel_acks[] = {
384 { 0x0, "No recipient SME acknowledgement requested" },
385 { 0x1, "SME delivery acknowledgement requested" },
386 { 0x2, "SME manual/user acknowledgement requested" },
387 { 0x3, "Both delivery and manual/user acknowledgement requested" },
391 static const value_string vals_regdel_notif[] = {
392 { 0x0, "No intermediate notification requested" },
393 { 0x1, "Intermediate notification requested" },
397 static const value_string vals_replace_if_present_flag[] = {
398 { 0x0, "Don't replace" },
403 static const value_string vals_data_coding[] = {
404 { 0, "SMSC default alphabet" },
405 { 1, "IA5 (CCITT T.50/ASCII (ANSI X3.4)" },
406 { 2, "Octet unspecified (8-bit binary)" },
407 { 3, "Latin 1 (ISO-8859-1)" },
408 { 4, "Octet unspecified (8-bit binary)" },
409 { 5, "JIS (X 0208-1990)" },
410 { 6, "Cyrillic (ISO-8859-5)" },
411 { 7, "Latin/Hebrew (ISO-8859-8)" },
412 { 8, "UCS2 (ISO/IEC-10646)" },
413 { 9, "Pictogram encoding" },
414 { 10, "ISO-2022-JP (Music codes)" },
417 { 13, "Extended Kanji JIS(X 0212-1990)" },
419 /*! \todo Rest to be defined (bitmask?) according GSM 03.38 */
423 static const value_string vals_message_state[] = {
428 { 5, "UNDELIVERABLE" },
435 static const value_string vals_addr_subunit[] = {
436 { 0, "Unknown -default-" },
438 { 2, "Mobile equipment" },
439 { 3, "Smart card 1" },
440 { 4, "External unit 1" },
444 static const value_string vals_network_type[] = {
447 { 2, "ANSI-136/TDMA" },
453 { 8, "Paging network" },
457 static const value_string vals_bearer_type[] = {
460 { 2, "Circuit Switched Data (CSD)" },
461 { 3, "Packet data" },
465 { 7, "FLEX/ReFLEX" },
466 { 8, "Cell Broadcast" },
470 static const value_string vals_payload_type[] = {
472 { 1, "WCMP message" },
476 static const value_string vals_privacy_indicator[] = {
477 { 0, "Not restricted -default-" },
479 { 2, "Confidential" },
484 static const value_string vals_language_indicator[] = {
485 { 0, "Unspecified -default-" },
494 static const value_string vals_display_time[] = {
496 { 1, "Default -default-" },
501 static const value_string vals_ms_validity[] = {
502 { 0, "Store indefinitely -default-" },
504 { 2, "SID based registration area" },
505 { 3, "Display only" },
509 static const value_string vals_dpf_result[] = {
510 { 0, "DPF not set" },
515 static const value_string vals_set_dpf[] = {
516 { 0, "Not requested (Set DPF for delivery failure)" },
517 { 1, "Requested (Set DPF for delivery failure)" },
521 static const value_string vals_ms_availability_status[] = {
522 { 0, "Available -default-" },
524 { 2, "Unavailable" },
528 static const value_string vals_delivery_failure_reason[] = {
529 { 0, "Destination unavailable" },
530 { 1, "Destination address invalid" },
531 { 2, "Permanent network error" },
532 { 3, "Temporary network error" },
536 static const value_string vals_more_messages_to_send[] = {
537 { 0, "No more messages" },
538 { 1, "More messages -default-" },
542 static const value_string vals_its_reply_type[] = {
545 { 2, "Telephone no." },
547 { 4, "Character line" },
555 static const value_string vals_ussd_service_op[] = {
556 { 0, "PSSD indication" },
557 { 1, "PSSR indication" },
558 { 2, "USSR request" },
559 { 3, "USSN request" },
560 { 16, "PSSD response" },
561 { 17, "PSSR response" },
562 { 18, "USSR confirm" },
563 { 19, "USSN confirm" },
567 static const value_string vals_msg_wait_ind[] = {
568 { 0, "Set indication inactive" },
569 { 1, "Set indication active" },
573 static const value_string vals_msg_wait_type[] = {
574 { 0, "Voicemail message waiting" },
575 { 1, "Fax message waiting" },
576 { 2, "Electronic mail message waiting" },
577 { 3, "Other message waiting" },
581 static const value_string vals_callback_num_pres[] = {
582 { 0, "Presentation allowed" },
583 { 1, "Presentation restricted" },
584 { 2, "Number not available" },
589 static const value_string vals_callback_num_scrn[] = {
590 { 0, "User provided, not screened" },
591 { 1, "User provided, verified and passed" },
592 { 2, "User provided, verified and failed" },
593 { 3, "Network provided" },
597 static const value_string vals_network_error_type[] = {
605 static const value_string vals_its_session_ind[] = {
606 { 0, "End of session indicator inactive" },
607 { 1, "End of session indicator active" },
611 /* Data Coding Scheme: see 3GPP TS 23.040 and 3GPP TS 23.038 */
612 static const value_string vals_dcs_sms_coding_group[] = {
613 { 0x00, "SMS DCS: General Data Coding indication - Uncompressed text, no message class" },
614 { 0x01, "SMS DCS: General Data Coding indication - Uncompressed text" },
615 { 0x02, "SMS DCS: General Data Coding indication - Compressed text, no message class" },
616 { 0x03, "SMS DCS: General Data Coding indication - Compressed text" },
617 { 0x04, "SMS DCS: Message Marked for Automatic Deletion - Uncompressed text, no message class" },
618 { 0x05, "SMS DCS: Message Marked for Automatic Deletion - Uncompressed text" },
619 { 0x06, "SMS DCS: Message Marked for Automatic Deletion - Compressed text, no message class" },
620 { 0x07, "SMS DCS: Message Marked for Automatic Deletion - Compressed text" },
621 { 0x08, "SMS DCS: Reserved" },
622 { 0x09, "SMS DCS: Reserved" },
623 { 0x0A, "SMS DCS: Reserved" },
624 { 0x0B, "SMS DCS: Reserved" },
625 { 0x0C, "SMS DCS: Message Waiting Indication - Discard Message" },
626 { 0x0D, "SMS DCS: Message Waiting Indication - Store Message (GSM 7-bit default alphabet)" },
627 { 0x0E, "SMS DCS: Message Waiting Indication - Store Message (UCS-2 character set)" },
628 { 0x0F, "SMS DCS: Data coding / message class" },
632 static const true_false_string tfs_dcs_text_compression = {
637 static const true_false_string tfs_dcs_class_present = {
638 "Message class is present",
642 static const value_string vals_dcs_charset[] = {
643 { 0x00, "GSM 7-bit default alphabet" },
644 { 0x01, "8-bit data" },
645 { 0x02, "UCS-2 (16-bit) data" },
646 { 0x03, "Reserved" },
650 static const value_string vals_dcs_class[] = {
652 { 0x01, "Class 1 - ME specific" },
653 { 0x02, "Class 2 - (U)SIM specific" },
654 { 0x03, "Class 3 - TE specific" },
658 static const value_string vals_dcs_cbs_coding_group[] = {
659 { 0x00, "CBS DCS: Language using the GSM 7-bit default alphabet" },
660 { 0x01, "CBS DCS: Language indication at beginning of message" },
661 { 0x02, "CBS DCS: Language using the GSM 7-bit default alphabet" },
662 { 0x03, "CBS DCS: Reserved" },
663 { 0x04, "CBS DCS: General Data Coding indication - Uncompressed text, no message class" },
664 { 0x05, "CBS DCS: General Data Coding indication - Uncompressed text" },
665 { 0x06, "CBS DCS: General Data Coding indication - Compressed text, no message class" },
666 { 0x07, "CBS DCS: General Data Coding indication - Compressed text" },
667 { 0x08, "CBS DCS: Reserved" },
668 { 0x09, "CBS DCS: Message with User Data Header structure" },
669 { 0x0A, "CBS DCS: Reserved" },
670 { 0x0B, "CBS DCS: Reserved" },
671 { 0x0C, "CBS DCS: Reserved" },
672 { 0x0D, "CBS DCS: Reserved" },
673 { 0x0E, "CBS DCS: Defined by the WAP Forum" },
674 { 0x0F, "SMS DCS: Data coding / message class" },
678 static const value_string vals_dcs_cbs_language[] = {
687 { 0x08, "Portuguese" },
689 { 0x0A, "Norwegian" },
692 { 0x0D, "Hungarian" },
694 { 0x0F, "Language not specified" },
695 { 0x10, "GSM 7-bit default alphabet - message preceded by language indication" },
696 { 0x11, "UCS-2 (16-bit) - message preceded by language indication" },
701 { 0x24, "Icelandic" },
705 static const value_string vals_dcs_cbs_class[] = {
706 { 0x00, "No message class" },
707 { 0x01, "Class 1 - User defined" },
708 { 0x02, "Class 2 - User defined" },
709 { 0x03, "Class 3 - TE specific" },
713 static const value_string vals_dcs_wap_class[] = {
714 { 0x00, "No message class" },
715 { 0x01, "Class 1 - ME specific" },
716 { 0x02, "Class 2 - (U)SIM specific" },
717 { 0x03, "Class 3 - TE specific" },
721 static const value_string vals_dcs_wap_charset[] = {
722 { 0x00, "Reserved" },
723 { 0x01, "8-bit data" },
724 { 0x02, "Reserved" },
725 { 0x03, "Reserved" },
729 static dissector_handle_t gsm_sms_handle;
732 * SMPP equivalent of mktime() (3). Convert date to standard 'time_t' format
734 * \param datestr The SMPP-formatted date to convert
735 * \param secs Returns the 'time_t' equivalent
736 * \param nsecs Returns the additional nano-seconds
738 * \return Whether time is specified relative or absolute
739 * \retval TRUE Relative time
740 * \retval FALSE Absolute time
743 smpp_mktime(const char *datestr, time_t *secs, int *nsecs)
747 gboolean relative = FALSE;
749 r_time.tm_year = 10 * (datestr[0] - '0') + (datestr[1] - '0');
751 * Y2K rollover date as recommended in appendix C
753 if (r_time.tm_year < 38)
754 r_time.tm_year += 100;
755 r_time.tm_mon = 10 * (datestr[2] - '0') + (datestr[3] - '0');
757 r_time.tm_mday = 10 * (datestr[4] - '0') + (datestr[5] - '0');
758 r_time.tm_hour = 10 * (datestr[6] - '0') + (datestr[7] - '0');
759 r_time.tm_min = 10 * (datestr[8] - '0') + (datestr[9] - '0');
760 r_time.tm_sec = 10 * (datestr[10] - '0') + (datestr[11] - '0');
761 r_time.tm_isdst = -1;
762 *secs = mktime(&r_time);
763 *nsecs = (datestr[12] - '0') * 100000000;
764 t_diff = (10 * (datestr[13] - '0') + (datestr[14] - '0')) * 900;
765 if (datestr[15] == '+')
767 else if (datestr[15] == '-')
769 else /* Must be relative ('R') */
775 * Scanning routines to add standard types (byte, int, string...) to the
778 * \param tree The protocol tree to add to
779 * \param tvb Buffer containing the data
780 * \param field Actual field whose value needs displaying
781 * \param offset Location of field in buffer, returns location of
785 smpp_handle_string(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
789 len = tvb_strsize(tvb, *offset);
791 proto_tree_add_string(tree, field, tvb, *offset, len,
792 (const char *) tvb_get_ptr(tvb, *offset, len));
797 /* NOTE - caller must free the returned string! */
799 smpp_handle_string_return(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
804 len = tvb_strsize(tvb, *offset);
806 str = (char *)tvb_get_ephemeral_stringz(tvb, *offset, &len);
807 proto_tree_add_string(tree, field, tvb, *offset, len, str);
816 smpp_handle_string_z(proto_tree *tree, tvbuff_t *tvb, int field, int *offset,
817 const char *null_string)
821 len = tvb_strsize(tvb, *offset);
823 proto_tree_add_string(tree, field, tvb, *offset, len,
824 (const char *)tvb_get_ptr(tvb, *offset, len));
826 proto_tree_add_string(tree, field, tvb, *offset, len, null_string);
832 smpp_handle_int1(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
836 val = tvb_get_guint8(tvb, *offset);
837 proto_tree_add_uint(tree, field, tvb, *offset, 1, val);
842 smpp_handle_int2(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
846 val = tvb_get_ntohs(tvb, *offset);
847 proto_tree_add_uint(tree, field, tvb, *offset, 2, val);
852 smpp_handle_int4(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
856 val = tvb_get_ntohl(tvb, *offset);
857 proto_tree_add_uint(tree, field, tvb, *offset, 4, val);
862 smpp_handle_time(proto_tree *tree, tvbuff_t *tvb,
863 int field, int field_R, int *offset)
869 strval = (char *) tvb_get_ephemeral_stringz(tvb, *offset, &len);
872 if (smpp_mktime(strval, &tmptime.secs, &tmptime.nsecs))
873 proto_tree_add_time(tree, field_R, tvb, *offset, len, &tmptime);
875 proto_tree_add_time(tree, field, tvb, *offset, len, &tmptime);
881 * Scanning routine to handle the destination-list of 'submit_multi'
883 * \param tree The protocol tree to add to
884 * \param tvb Buffer containing the data
885 * \param offset Location of field in buffer, returns location of
889 smpp_handle_dlist(proto_tree *tree, tvbuff_t *tvb, int *offset)
892 int tmpoff = *offset;
893 proto_item *sub_tree = NULL;
896 if ((entries = tvb_get_guint8(tvb, tmpoff++)))
898 sub_tree = proto_tree_add_item(tree, hf_smpp_dlist,
899 tvb, *offset, 1, FALSE);
900 proto_item_add_subtree(sub_tree, ett_dlist);
904 dest_flag = tvb_get_guint8(tvb, tmpoff++);
905 if (dest_flag == 1) /* SME address */
907 smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_ton, &tmpoff);
908 smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_npi, &tmpoff);
909 smpp_handle_string(sub_tree,tvb,hf_smpp_destination_addr,&tmpoff);
911 else /* Distribution list */
913 smpp_handle_string(sub_tree, tvb, hf_smpp_dl_name, &tmpoff);
920 * Scanning routine to handle the destination result list
921 * of 'submit_multi_resp'
923 * \param tree The protocol tree to add to
924 * \param tvb Buffer containing the data
925 * \param offset Location of field in buffer, returns location of
929 smpp_handle_dlist_resp(proto_tree *tree, tvbuff_t *tvb, int *offset)
932 int tmpoff = *offset;
933 proto_item *sub_tree = NULL;
935 if ((entries = tvb_get_guint8(tvb, tmpoff++)))
937 sub_tree = proto_tree_add_item(tree, hf_smpp_dlist_resp,
938 tvb, *offset, 1, FALSE);
939 proto_item_add_subtree(sub_tree, ett_dlist_resp);
943 smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_ton, &tmpoff);
944 smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_npi, &tmpoff);
945 smpp_handle_string(sub_tree,tvb,hf_smpp_destination_addr,&tmpoff);
946 smpp_handle_int4(sub_tree, tvb, hf_smpp_error_status_code, &tmpoff);
952 * Scanning routine to handle all optional parameters of SMPP-operations.
953 * The parameters have the format Tag Length Value (TLV), with a 2-byte tag
956 * \param tree The protocol tree to add to
957 * \param tvb Buffer containing the data
958 * \param offset Location of field in buffer, returns location of
962 smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
964 proto_item *sub_tree = NULL;
971 if (tvb_reported_length_remaining(tvb, *offset) >= 4)
973 sub_tree = proto_tree_add_item(tree, hf_smpp_opt_param,
974 tvb, *offset, 0, FALSE);
975 proto_item_add_subtree(sub_tree, ett_opt_param);
978 while (tvb_reported_length_remaining(tvb, *offset) >= 4)
980 tag = tvb_get_ntohs(tvb, *offset);
982 length = tvb_get_ntohs(tvb, *offset);
985 case 0x0005: /* dest_addr_subunit */
986 smpp_handle_int1(sub_tree, tvb,
987 hf_smpp_dest_addr_subunit, offset);
989 case 0x0006: /* dest_network_type */
990 smpp_handle_int1(sub_tree, tvb,
991 hf_smpp_dest_network_type, offset);
993 case 0x0007: /* dest_bearer_type */
994 smpp_handle_int1(sub_tree, tvb,
995 hf_smpp_dest_bearer_type, offset);
997 case 0x0008: /* dest_telematics_id */
998 smpp_handle_int2(sub_tree, tvb,
999 hf_smpp_dest_telematics_id, offset);
1001 case 0x000D: /* source_addr_subunit */
1002 smpp_handle_int1(sub_tree, tvb,
1003 hf_smpp_source_addr_subunit, offset);
1005 case 0x000E: /* source_network_type */
1006 smpp_handle_int1(sub_tree, tvb,
1007 hf_smpp_source_network_type, offset);
1009 case 0x000F: /* source_bearer_type */
1010 smpp_handle_int1(sub_tree, tvb,
1011 hf_smpp_source_bearer_type, offset);
1013 case 0x0010: /* source_telematics_id */
1014 smpp_handle_int2(sub_tree, tvb,
1015 hf_smpp_source_telematics_id, offset);
1017 case 0x0017: /* qos_time_to_live */
1018 smpp_handle_int4(sub_tree, tvb,
1019 hf_smpp_qos_time_to_live, offset);
1021 case 0x0019: /* payload_type */
1022 smpp_handle_int1(sub_tree, tvb,
1023 hf_smpp_payload_type, offset);
1025 case 0x001D: /* additional_status_info_text */
1026 smpp_handle_string(sub_tree, tvb,
1027 hf_smpp_additional_status_info_text, offset);
1029 case 0x001E: /* receipted_message_id */
1030 smpp_handle_string(sub_tree, tvb,
1031 hf_smpp_receipted_message_id, offset);
1033 case 0x0030: /* ms_msg_wait_facilities */
1034 field = tvb_get_guint8(tvb, *offset);
1035 proto_tree_add_item(sub_tree, hf_smpp_msg_wait_ind,
1036 tvb, *offset, 1, field);
1037 proto_tree_add_item(sub_tree, hf_smpp_msg_wait_type,
1038 tvb, *offset, 1, field);
1041 case 0x0201: /* privacy_indicator */
1042 smpp_handle_int1(sub_tree, tvb,
1043 hf_smpp_privacy_indicator, offset);
1045 case 0x0202: /* source_subaddress */
1046 smpp_handle_string(sub_tree, tvb,
1047 hf_smpp_source_subaddress, offset);
1049 case 0x0203: /* dest_subaddress */
1050 smpp_handle_string(sub_tree, tvb,
1051 hf_smpp_dest_subaddress, offset);
1053 case 0x0204: /* user_message_reference */
1054 smpp_handle_int2(sub_tree, tvb,
1055 hf_smpp_user_message_reference, offset);
1057 case 0x0205: /* user_response_code */
1058 smpp_handle_int1(sub_tree, tvb,
1059 hf_smpp_user_response_code, offset);
1061 case 0x020A: /* source_port */
1062 smpp_handle_int2(sub_tree, tvb,
1063 hf_smpp_source_port, offset);
1065 case 0x020B: /* destination_port */
1066 smpp_handle_int2(sub_tree, tvb,
1067 hf_smpp_destination_port, offset);
1069 case 0x020C: /* sar_msg_ref_num */
1070 smpp_handle_int2(sub_tree, tvb,
1071 hf_smpp_sar_msg_ref_num, offset);
1073 case 0x020D: /* language_indicator */
1074 smpp_handle_int1(sub_tree, tvb,
1075 hf_smpp_language_indicator, offset);
1077 case 0x020E: /* sar_total_segments */
1078 smpp_handle_int1(sub_tree, tvb,
1079 hf_smpp_sar_total_segments, offset);
1081 case 0x020F: /* sar_segment_seqnum */
1082 smpp_handle_int1(sub_tree, tvb,
1083 hf_smpp_sar_segment_seqnum, offset);
1085 case 0x0210: /* SC_interface_version */
1086 field = tvb_get_guint8(tvb, *offset);
1087 minor = field & 0x0F;
1088 major = (field & 0xF0) >> 4;
1089 strval=ep_alloc(BUFSIZ);
1090 g_snprintf(strval, BUFSIZ, "%u.%u", major, minor);
1091 proto_tree_add_string(sub_tree, hf_smpp_SC_interface_version,
1092 tvb, *offset, 1, strval);
1095 case 0x0302: /* callback_num_pres_ind */
1096 field = tvb_get_guint8(tvb, *offset);
1097 proto_tree_add_item(sub_tree, hf_smpp_callback_num_pres,
1098 tvb, *offset, 1, field);
1099 proto_tree_add_item(sub_tree, hf_smpp_callback_num_scrn,
1100 tvb, *offset, 1, field);
1103 case 0x0303: /* callback_num_atag */
1105 proto_tree_add_item(sub_tree, hf_smpp_callback_num_atag,
1106 tvb, *offset, length, FALSE);
1107 (*offset) += length;
1109 case 0x0304: /* number_of_messages */
1110 smpp_handle_int1(sub_tree, tvb,
1111 hf_smpp_number_of_messages, offset);
1113 case 0x0381: /* callback_num */
1115 proto_tree_add_item(sub_tree, hf_smpp_callback_num,
1116 tvb, *offset, length, FALSE);
1117 (*offset) += length;
1119 case 0x0420: /* dpf_result */
1120 smpp_handle_int1(sub_tree, tvb,
1121 hf_smpp_dpf_result, offset);
1123 case 0x0421: /* set_dpf */
1124 smpp_handle_int1(sub_tree, tvb,
1125 hf_smpp_set_dpf, offset);
1127 case 0x0422: /* ms_availability_status */
1128 smpp_handle_int1(sub_tree, tvb,
1129 hf_smpp_ms_availability_status, offset);
1131 case 0x0423: /* network_error_code */
1132 smpp_handle_int1(sub_tree, tvb,
1133 hf_smpp_network_error_type, offset);
1134 smpp_handle_int2(sub_tree, tvb,
1135 hf_smpp_network_error_code, offset);
1136 (*offset) += length;
1138 case 0x0424: /* message_payload */
1140 proto_tree_add_item(sub_tree, hf_smpp_message_payload,
1141 tvb, *offset, length, FALSE);
1142 (*offset) += length;
1144 case 0x0425: /* delivery_failure_reason */
1145 smpp_handle_int1(sub_tree, tvb,
1146 hf_smpp_delivery_failure_reason, offset);
1148 case 0x0426: /* more_messages_to_send */
1149 smpp_handle_int1(sub_tree, tvb,
1150 hf_smpp_more_messages_to_send, offset);
1152 case 0x0427: /* message_state */
1153 smpp_handle_int1(sub_tree, tvb,
1154 hf_smpp_message_state, offset);
1156 case 0x0501: /* ussd_service_op */
1157 smpp_handle_int1(sub_tree, tvb,
1158 hf_smpp_ussd_service_op, offset);
1160 case 0x1201: /* display_time */
1161 smpp_handle_int1(sub_tree, tvb,
1162 hf_smpp_display_time, offset);
1164 case 0x1203: /* sms_signal */
1165 smpp_handle_int2(sub_tree, tvb,
1166 hf_smpp_sms_signal, offset);
1167 /*! \todo Fill as per TIA/EIA-136-710-A */
1169 case 0x1204: /* ms_validity */
1170 smpp_handle_int1(sub_tree, tvb,
1171 hf_smpp_ms_validity, offset);
1173 case 0x130C: /* alert_on_message_delivery */
1174 proto_tree_add_item(sub_tree,
1175 hf_smpp_alert_on_message_delivery,
1176 tvb, *offset, length, FALSE);
1177 (*offset) += length;
1179 case 0x1380: /* its_reply_type */
1180 smpp_handle_int1(sub_tree, tvb,
1181 hf_smpp_its_reply_type, offset);
1183 case 0x1383: /* its_session_info */
1184 smpp_handle_int1(sub_tree, tvb,
1185 hf_smpp_its_session_number, offset);
1186 field = tvb_get_guint8(tvb, *offset);
1187 proto_tree_add_item(sub_tree, hf_smpp_its_session_sequence,
1188 tvb, *offset, 1, field);
1189 proto_tree_add_item(sub_tree, hf_smpp_its_session_ind,
1190 tvb, *offset, 1, field);
1194 if ((tag >= 0x1400) && (tag <= 0x3FFF))
1195 proto_tree_add_item(sub_tree, hf_smpp_vendor_op, tvb,
1196 *offset, length, FALSE);
1198 proto_tree_add_item(sub_tree, hf_smpp_reserved_op, tvb,
1199 *offset, length, FALSE);
1200 (*offset) += length;
1207 smpp_handle_dcs(proto_tree *tree, tvbuff_t *tvb, int *offset)
1211 proto_item *subtree = NULL;
1213 val = tvb_get_guint8(tvb, off);
1214 subtree = proto_tree_add_uint(tree,
1215 hf_smpp_data_coding, tvb, off, 1, val);
1216 proto_item_add_subtree(subtree, ett_dcs);
1217 /* SMPP Data Coding Scheme */
1218 proto_tree_add_uint(subtree, hf_smpp_dcs, tvb, off, 1, val);
1219 /* GSM SMS Data Coding Scheme */
1220 proto_tree_add_text(subtree, tvb, off, 1,
1221 "GSM SMS Data Coding");
1222 proto_tree_add_uint(subtree,
1223 hf_smpp_dcs_sms_coding_group, tvb, off, 1, val);
1224 if (val>>6 == 2) { /* Reserved */
1226 } else if (val < 0xF0) {
1227 proto_tree_add_boolean(subtree,
1228 hf_smpp_dcs_text_compression, tvb, off, 1, val);
1229 proto_tree_add_boolean(subtree,
1230 hf_smpp_dcs_class_present, tvb, off, 1, val);
1231 proto_tree_add_uint(subtree,
1232 hf_smpp_dcs_charset, tvb, off, 1, val);
1234 proto_tree_add_uint(subtree,
1235 hf_smpp_dcs_class, tvb, off, 1, val);
1238 proto_tree_add_text(subtree, tvb, off, 1,
1239 "SMPP: Bit .... 1... should be 0 (reserved)");
1240 proto_tree_add_uint(subtree,
1241 hf_smpp_dcs_charset, tvb, off, 1, val);
1242 proto_tree_add_uint(subtree,
1243 hf_smpp_dcs_class, tvb, off, 1, val);
1245 /* Cell Broadcast Service (CBS) Data Coding Scheme */
1246 proto_tree_add_text(subtree, tvb, off, 1,
1247 "GSM CBS Data Coding");
1248 proto_tree_add_uint(subtree,
1249 hf_smpp_dcs_cbs_coding_group, tvb, off, 1, val);
1250 if (val < 0x40) { /* Language specified */
1251 proto_tree_add_uint(subtree,
1252 hf_smpp_dcs_cbs_language, tvb, off, 1, val);
1253 } else if (val>>6 == 1) { /* General Data Coding indication */
1254 proto_tree_add_boolean(subtree,
1255 hf_smpp_dcs_text_compression, tvb, off, 1, val);
1256 proto_tree_add_boolean(subtree,
1257 hf_smpp_dcs_class_present, tvb, off, 1, val);
1258 proto_tree_add_uint(subtree,
1259 hf_smpp_dcs_charset, tvb, off, 1, val);
1261 proto_tree_add_uint(subtree,
1262 hf_smpp_dcs_class, tvb, off, 1, val);
1263 } else if (val>>6 == 2) { /* Message with UDH structure */
1264 proto_tree_add_uint(subtree,
1265 hf_smpp_dcs_charset, tvb, off, 1, val);
1266 proto_tree_add_uint(subtree,
1267 hf_smpp_dcs_class, tvb, off, 1, val);
1268 } else if (val>>4 == 14) { /* WAP Forum */
1269 proto_tree_add_uint(subtree,
1270 hf_smpp_dcs_wap_charset, tvb, off, 1, val);
1271 proto_tree_add_uint(subtree,
1272 hf_smpp_dcs_wap_class, tvb, off, 1, val);
1273 } else if (val>>4 == 15) { /* Data coding / message handling */
1275 proto_tree_add_text(subtree, tvb, off, 1,
1276 "SMPP: Bit .... 1... should be 0 (reserved)");
1277 proto_tree_add_uint(subtree,
1278 hf_smpp_dcs_charset, tvb, off, 1, val);
1279 proto_tree_add_uint(subtree,
1280 hf_smpp_dcs_cbs_class, tvb, off, 1, val);
1287 * The next set of routines handle the different operations, associated
1291 bind_receiver(proto_tree *tree, tvbuff_t *tvb)
1295 guint8 major, minor;
1298 strval=ep_alloc(BUFSIZ);
1299 smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
1300 smpp_handle_string(tree, tvb, hf_smpp_password, &offset);
1301 smpp_handle_string(tree, tvb, hf_smpp_system_type, &offset);
1302 field = tvb_get_guint8(tvb, offset++);
1303 minor = field & 0x0F;
1304 major = (field & 0xF0) >> 4;
1305 g_snprintf(strval, BUFSIZ, "%u.%u", major, minor);
1306 proto_tree_add_string(tree, hf_smpp_interface_version, tvb,
1307 offset - 1, 1, strval);
1308 smpp_handle_int1(tree, tvb, hf_smpp_addr_ton, &offset);
1309 smpp_handle_int1(tree, tvb, hf_smpp_addr_npi, &offset);
1310 smpp_handle_string(tree, tvb, hf_smpp_address_range, &offset);
1313 #define bind_transmitter(a, b) bind_receiver(a, b)
1316 query_sm(proto_tree *tree, tvbuff_t *tvb)
1320 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1321 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1322 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1323 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1326 #define bind_transceiver(a, b) bind_receiver(a, b)
1329 outbind(proto_tree *tree, tvbuff_t *tvb)
1333 smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
1334 smpp_handle_string(tree, tvb, hf_smpp_password, &offset);
1338 submit_sm(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
1339 proto_tree *top_tree)
1345 char *src_str = NULL;
1346 char *dst_str = NULL;
1347 address save_src, save_dst;
1349 smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1350 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1351 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1352 src_str = smpp_handle_string_return(tree, tvb, hf_smpp_source_addr, &offset);
1353 smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
1354 smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
1355 dst_str = smpp_handle_string_return(tree, tvb, hf_smpp_destination_addr, &offset);
1356 flag = tvb_get_guint8(tvb, offset);
1358 proto_tree_add_item(tree, hf_smpp_esm_submit_msg_mode,
1359 tvb, offset, 1, flag);
1360 proto_tree_add_item(tree, hf_smpp_esm_submit_msg_type,
1361 tvb, offset, 1, flag);
1362 proto_tree_add_item(tree, hf_smpp_esm_submit_features,
1363 tvb, offset, 1, flag);
1365 smpp_handle_int1(tree, tvb, hf_smpp_protocol_id, &offset);
1366 smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
1367 if (tvb_get_guint8(tvb,offset)) {
1368 smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
1369 hf_smpp_schedule_delivery_time_r, &offset);
1370 } else { /* Time = NULL means Immediate delivery */
1371 proto_tree_add_text(tree, tvb, offset++, 1,
1372 "Scheduled delivery time: Immediate delivery");
1374 if (tvb_get_guint8(tvb,offset)) {
1375 smpp_handle_time(tree, tvb, hf_smpp_validity_period,
1376 hf_smpp_validity_period_r, &offset);
1377 } else { /* Time = NULL means SMSC default validity */
1378 proto_tree_add_text(tree, tvb, offset++, 1,
1379 "Validity period: SMSC default validity period");
1381 flag = tvb_get_guint8(tvb, offset);
1382 proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1383 proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1384 proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1386 smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
1387 smpp_handle_dcs(tree, tvb, &offset);
1388 smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
1389 length = tvb_get_guint8(tvb, offset);
1390 proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
1393 proto_tree_add_item(tree, hf_smpp_short_message,
1394 tvb, offset, length, FALSE);
1395 if (udhi) /* UDHI indicator present */
1397 DebugLog(("UDHI present - set addresses\n"));
1398 /* Save original addresses */
1399 COPY_ADDRESS(&save_src, &(pinfo->src));
1400 COPY_ADDRESS(&save_dst, &(pinfo->dst));
1401 /* Set SMPP source and destination address */
1402 SET_ADDRESS(&(pinfo->src), AT_STRINGZ, 1+strlen(src_str), src_str);
1403 SET_ADDRESS(&(pinfo->dst), AT_STRINGZ, 1+strlen(dst_str), dst_str);
1404 tvb_msg = tvb_new_subset (tvb, offset,
1405 MIN(length, tvb_reported_length(tvb) - offset), length);
1406 call_dissector (gsm_sms_handle, tvb_msg, pinfo, top_tree);
1407 /* Restore original addresses */
1408 COPY_ADDRESS(&(pinfo->src), &save_src);
1409 COPY_ADDRESS(&(pinfo->dst), &save_dst);
1413 /* Get rid of SMPP text string addresses */
1414 smpp_handle_tlv(tree, tvb, &offset);
1417 #define deliver_sm(a, b, c, d) submit_sm(a, b, c, d)
1420 replace_sm(proto_tree *tree, tvbuff_t *tvb)
1426 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1427 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1428 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1429 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1430 if (tvb_get_guint8(tvb,offset)) {
1431 smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
1432 hf_smpp_schedule_delivery_time_r, &offset);
1433 } else { /* Time = NULL */
1434 proto_tree_add_text(tree, tvb, offset++, 1,
1435 "Scheduled delivery time: Keep initial delivery time setting");
1437 if (tvb_get_guint8(tvb,offset)) {
1438 smpp_handle_time(tree, tvb, hf_smpp_validity_period,
1439 hf_smpp_validity_period_r, &offset);
1440 } else { /* Time = NULL */
1441 proto_tree_add_text(tree, tvb, offset++, 1,
1442 "Validity period: Keep initial validity period setting");
1444 flag = tvb_get_guint8(tvb, offset);
1445 proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1446 proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1447 proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1449 smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
1450 length = tvb_get_guint8(tvb, offset);
1451 proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
1453 proto_tree_add_item(tree, hf_smpp_short_message,
1454 tvb, offset, length, FALSE);
1459 cancel_sm(proto_tree *tree, tvbuff_t *tvb)
1463 smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1464 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1465 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1466 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1467 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1468 smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
1469 smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
1470 smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
1474 submit_multi(proto_tree *tree, tvbuff_t *tvb)
1480 smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1481 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1482 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1483 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1485 smpp_handle_dlist(tree, tvb, &offset);
1487 flag = tvb_get_guint8(tvb, offset);
1488 proto_tree_add_item(tree, hf_smpp_esm_submit_msg_mode,
1489 tvb, offset, 1, flag);
1490 proto_tree_add_item(tree, hf_smpp_esm_submit_msg_type,
1491 tvb, offset, 1, flag);
1492 proto_tree_add_item(tree, hf_smpp_esm_submit_features,
1493 tvb, offset, 1, flag);
1495 smpp_handle_int1(tree, tvb, hf_smpp_protocol_id, &offset);
1496 smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
1497 if (tvb_get_guint8(tvb,offset)) {
1498 smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
1499 hf_smpp_schedule_delivery_time_r, &offset);
1500 } else { /* Time = NULL means Immediate delivery */
1501 proto_tree_add_text(tree, tvb, offset++, 1,
1502 "Scheduled delivery time: Immediate delivery");
1504 if (tvb_get_guint8(tvb,offset)) {
1505 smpp_handle_time(tree, tvb, hf_smpp_validity_period,
1506 hf_smpp_validity_period_r, &offset);
1507 } else { /* Time = NULL means SMSC default validity */
1508 proto_tree_add_text(tree, tvb, offset++, 1,
1509 "Validity period: SMSC default validity period");
1511 flag = tvb_get_guint8(tvb, offset);
1512 proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1513 proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1514 proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1516 smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
1517 smpp_handle_dcs(tree, tvb, &offset);
1518 smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
1519 length = tvb_get_guint8(tvb, offset);
1520 proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
1522 proto_tree_add_item(tree, hf_smpp_short_message,
1523 tvb, offset, length, FALSE);
1525 smpp_handle_tlv(tree, tvb, &offset);
1529 alert_notification(proto_tree *tree, tvbuff_t *tvb)
1533 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1534 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1535 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1536 smpp_handle_int1(tree, tvb, hf_smpp_esme_addr_ton, &offset);
1537 smpp_handle_int1(tree, tvb, hf_smpp_esme_addr_npi, &offset);
1538 smpp_handle_string(tree, tvb, hf_smpp_esme_addr, &offset);
1539 smpp_handle_tlv(tree, tvb, &offset);
1543 data_sm(proto_tree *tree, tvbuff_t *tvb)
1548 smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1549 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1550 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1551 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1552 smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
1553 smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
1554 smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
1555 flag = tvb_get_guint8(tvb, offset);
1556 proto_tree_add_item(tree, hf_smpp_esm_submit_msg_mode,
1557 tvb, offset, 1, flag);
1558 proto_tree_add_item(tree, hf_smpp_esm_submit_msg_type,
1559 tvb, offset, 1, flag);
1560 proto_tree_add_item(tree, hf_smpp_esm_submit_features,
1561 tvb, offset, 1, flag);
1563 flag = tvb_get_guint8(tvb, offset);
1564 proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1565 proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1566 proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1568 smpp_handle_dcs(tree, tvb, &offset);
1569 smpp_handle_tlv(tree, tvb, &offset);
1573 * The next set of routines handle the different operation-responses,
1574 * associated with SMPP.
1577 bind_receiver_resp(proto_tree *tree, tvbuff_t *tvb)
1581 smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
1582 smpp_handle_tlv(tree, tvb, &offset);
1585 #define bind_transmitter_resp(a, b) bind_receiver_resp(a, b)
1588 query_sm_resp(proto_tree *tree, tvbuff_t *tvb)
1592 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1593 smpp_handle_time(tree, tvb, hf_smpp_final_date,
1594 hf_smpp_final_date_r, &offset);
1595 smpp_handle_int1(tree, tvb, hf_smpp_message_state, &offset);
1596 smpp_handle_int1(tree, tvb, hf_smpp_error_code, &offset);
1599 #define bind_transceiver_resp(a, b) bind_receiver_resp(a, b)
1602 submit_sm_resp(proto_tree *tree, tvbuff_t *tvb)
1606 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1609 #define deliver_sm_resp(a, b) submit_sm_resp(a, b)
1612 submit_multi_resp(proto_tree *tree, tvbuff_t *tvb)
1616 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1617 smpp_handle_dlist_resp(tree, tvb, &offset);
1621 data_sm_resp(proto_tree *tree, tvbuff_t *tvb)
1625 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1626 smpp_handle_tlv(tree, tvb, &offset);
1630 * A 'heuristic dissector' that attemtps to establish whether we have
1631 * a genuine SMPP PDU here.
1633 * at least the fixed header is there
1634 * it has a correct overall PDU length
1635 * it is a 'well-known' operation
1636 * has a 'well-known' status
1639 dissect_smpp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1641 guint command_id; /* SMPP command */
1642 guint command_status; /* Status code */
1643 guint command_length; /* length of PDU */
1645 if (tvb_reported_length(tvb) < 4 * 4) /* Mandatory header */
1647 command_length = tvb_get_ntohl(tvb, 0);
1648 if (command_length > 64 * 1024)
1650 command_id = tvb_get_ntohl(tvb, 4); /* Only known commands */
1651 if (match_strval(command_id, vals_command_id) == NULL)
1653 command_status = tvb_get_ntohl(tvb, 8); /* ..with known status */
1654 if (match_strval(command_status, vals_command_status) == NULL)
1656 dissect_smpp(tvb, pinfo, tree);
1661 get_smpp_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
1663 return tvb_get_ntohl(tvb, offset);
1667 * This global SMPP variable is used to determine whether the PDU to dissect
1668 * is the first SMPP PDU in the packet (or reassembled buffer), requiring
1669 * different column update code than subsequent SMPP PDUs within this packet
1670 * (or reassembled buffer).
1672 * FIXME - This approach is NOT dissection multi-thread safe!
1674 static gboolean first = TRUE;
1677 dissect_smpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1680 if (pinfo->ptype == PT_TCP) { /* are we running on top of TCP */
1681 tcp_dissect_pdus(tvb, pinfo, tree,
1682 reassemble_over_tcp, /* Do we try to reassemble */
1683 16, /* Length of fixed header */
1684 get_smpp_pdu_len, /* Function returning PDU len */
1685 dissect_smpp_pdu); /* PDU dissector */
1686 } else { /* no? probably X.25 */
1688 while (tvb_reported_length_remaining(tvb, offset) > 0) {
1689 guint16 pdu_len = tvb_get_ntohl(tvb, offset);
1690 gint pdu_real_len = tvb_length_remaining(tvb, offset);
1694 THROW(ReportedBoundsError);
1696 if (pdu_real_len <= 0)
1698 if (pdu_real_len > pdu_len)
1699 pdu_real_len = pdu_len;
1700 pdu_tvb = tvb_new_subset(tvb, offset, pdu_real_len, pdu_len);
1701 dissect_smpp_pdu(pdu_tvb, pinfo, tree);
1709 /* Dissect a single SMPP PDU contained within "tvb". */
1711 dissect_smpp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1713 int offset = 0; /* Offset within tvbuff */
1714 guint command_length; /* length of PDU */
1715 guint command_id; /* SMPP command */
1716 guint command_status; /* Status code */
1717 guint sequence_number; /* ...of command */
1718 const gchar *command_str;
1719 const gchar *command_status_str = NULL;
1720 /* Set up structures needed to add the protocol subtree and manage it */
1721 proto_item *ti = NULL;
1722 proto_tree *smpp_tree = NULL;
1725 * Safety: don't even try to dissect the PDU
1726 * when the mandatory header isn't present.
1728 if (tvb_reported_length(tvb) < 4 * 4)
1730 command_length = tvb_get_ntohl(tvb, offset);
1732 command_id = tvb_get_ntohl(tvb, offset);
1733 command_str = val_to_str(command_id, vals_command_id,
1734 "(Unknown SMPP Operation 0x%08X)");
1736 command_status = tvb_get_ntohl(tvb, offset);
1737 if (command_id & 0x80000000) {
1738 command_status_str = val_to_str(command_status, vals_command_status,
1739 "(Reserved Error 0x%08X)");
1742 sequence_number = tvb_get_ntohl(tvb, offset);
1746 * Update the protocol column.
1748 if (first == TRUE) {
1749 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1750 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMPP");
1754 * Create display subtree for the protocol
1757 ti = proto_tree_add_item (tree, proto_smpp, tvb, 0, tvb->length, FALSE);
1758 smpp_tree = proto_item_add_subtree (ti, ett_smpp);
1762 * Cycle over the encapsulated PDUs
1768 * Make entries in the Info column on the summary display
1770 if (check_col(pinfo->cinfo, COL_INFO)) {
1771 if (first == TRUE) {
1773 * First PDU - We already computed the fixed header
1775 col_clear(pinfo->cinfo, COL_INFO);
1776 col_add_fstr(pinfo->cinfo, COL_INFO, "SMPP %s", command_str);
1782 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", command_str);
1785 * Display command status of responses in Info column
1787 if (command_id & 0x80000000) {
1788 col_append_fstr(pinfo->cinfo, COL_INFO, ": \"%s\"",
1789 command_status_str);
1794 * Create a tvb for the current PDU.
1795 * Physical length: at most command_length
1796 * Reported length: command_length
1798 if (tvb_length_remaining(tvb, offset - 16 + command_length) > 0) {
1799 pdu_tvb = tvb_new_subset(tvb, offset - 16,
1800 command_length, /* Physical length */
1801 command_length); /* Length reported by the protocol */
1803 pdu_tvb = tvb_new_subset(tvb, offset - 16,
1804 tvb_length_remaining(tvb, offset - 16),/* Physical length */
1805 command_length); /* Length reported by the protocol */
1811 * If "tree" is NULL, Wireshark is only interested in creation
1812 * of conversations, reassembly and subdissection but not in
1813 * the detailed protocol tree.
1814 * In the interest of speed, skip the generation of protocol tree
1815 * items when "tree" is NULL.
1817 * The only PDU which requires subdissection currently is the
1818 * sm_submit PDU (command ID = 0x00000004).
1820 if (tree || (command_id == 4))
1823 * Create display subtree for the PDU
1826 proto_tree_add_uint(smpp_tree, hf_smpp_command_length,
1827 pdu_tvb, 0, 4, command_length);
1828 proto_tree_add_uint(smpp_tree, hf_smpp_command_id,
1829 pdu_tvb, 4, 4, command_id);
1830 proto_item_append_text(ti, ", Command: %s", command_str);
1833 * Status is only meaningful with responses
1835 if (command_id & 0x80000000) {
1836 proto_tree_add_uint(smpp_tree, hf_smpp_command_status,
1837 pdu_tvb, 8, 4, command_status);
1838 proto_item_append_text (ti, ", Status: \"%s\"",
1839 command_status_str);
1841 proto_tree_add_uint(smpp_tree, hf_smpp_sequence_number,
1842 pdu_tvb, 12, 4, sequence_number);
1843 proto_item_append_text(ti, ", Seq: %u, Len: %u",
1844 sequence_number, command_length);
1848 * End of fixed header.
1849 * Don't dissect variable part if it is shortened.
1851 * FIXME - We then do not report a Short Frame or Malformed Packet
1853 if (command_length <= tvb_reported_length(pdu_tvb))
1855 tvbuff_t *tmp_tvb = tvb_new_subset(pdu_tvb, 16,
1856 -1, command_length - 16);
1857 if (command_id & 0x80000000)
1859 switch (command_id & 0x7FFFFFFF) {
1861 * All of these only have a fixed header
1863 case 0: /* Generic nack */
1864 case 6: /* Unbind resp */
1865 case 7: /* Replace SM resp */
1866 case 8: /* Cancel SM resp */
1867 case 21: /* Enquire link resp */
1870 if (!command_status)
1871 bind_receiver_resp(smpp_tree, tmp_tvb);
1874 if (!command_status)
1875 bind_transmitter_resp(smpp_tree, tmp_tvb);
1878 if (!command_status)
1879 query_sm_resp(smpp_tree, tmp_tvb);
1882 if (!command_status)
1883 submit_sm_resp(smpp_tree, tmp_tvb);
1886 if (!command_status)
1887 deliver_sm_resp(smpp_tree, tmp_tvb);
1890 if (!command_status)
1891 bind_transceiver_resp(smpp_tree, tmp_tvb);
1894 if (!command_status)
1895 submit_multi_resp(smpp_tree, tmp_tvb);
1898 if (!command_status)
1899 data_sm_resp(smpp_tree, tmp_tvb);
1903 } /* switch (command_id & 0x7FFFFFFF) */
1907 switch (command_id) {
1909 bind_receiver(smpp_tree, tmp_tvb);
1912 bind_transmitter(smpp_tree, tmp_tvb);
1915 query_sm(smpp_tree, tmp_tvb);
1918 submit_sm(smpp_tree, tmp_tvb, pinfo, tree);
1921 deliver_sm(smpp_tree, tmp_tvb, pinfo, tree);
1923 case 6: /* Unbind */
1924 case 21: /* Enquire link */
1927 replace_sm(smpp_tree, tmp_tvb);
1930 cancel_sm(smpp_tree, tmp_tvb);
1933 bind_transceiver(smpp_tree, tmp_tvb);
1936 outbind(smpp_tree, tmp_tvb);
1939 submit_multi(smpp_tree, tmp_tvb);
1942 alert_notification(smpp_tree, tmp_tvb);
1945 data_sm(smpp_tree, tmp_tvb);
1949 } /* switch (command_id) */
1950 } /* if (command_id & 0x80000000) */
1951 } /* if (command_length <= tvb_reported_length(pdu_tvb)) */
1952 offset += command_length;
1953 } /* if (tree || (command_id == 4)) */
1961 /* Register the protocol with Wireshark */
1963 proto_register_smpp(void)
1965 module_t *smpp_module; /* Preferences for SMPP */
1967 /* Setup list of header fields */
1968 static hf_register_info hf[] = {
1969 { &hf_smpp_command_length,
1970 { "Length ", "smpp.command_length",
1971 FT_UINT32, BASE_DEC, NULL, 0x00,
1972 "Total length of the SMPP PDU.",
1976 { &hf_smpp_command_id,
1977 { "Operation ", "smpp.command_id",
1978 FT_UINT32, BASE_HEX, VALS(vals_command_id), 0x00,
1979 "Defines the SMPP PDU.",
1983 { &hf_smpp_command_status,
1984 { "Result ", "smpp.command_status",
1985 FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
1986 "Indicates success or failure of the SMPP request.",
1990 { &hf_smpp_sequence_number,
1991 { "Sequence #", "smpp.sequence_number",
1992 FT_UINT32, BASE_DEC, NULL, 0x00,
1993 "A number to correlate requests with responses.",
1997 { &hf_smpp_system_id,
1998 { "System ID", "smpp.system_id",
1999 FT_STRING, BASE_NONE, NULL, 0x00,
2000 "Identifies a system.",
2004 { &hf_smpp_password,
2005 { "Password", "smpp.password",
2006 FT_STRING, BASE_NONE, NULL, 0x00,
2007 "Password used for authentication.",
2011 { &hf_smpp_system_type,
2012 { "System type", "smpp.system_type",
2013 FT_STRING, BASE_NONE, NULL, 0x00,
2014 "Categorises the system.",
2018 { &hf_smpp_interface_version,
2019 { "Version (if)", "smpp.interface_version",
2020 FT_STRING, BASE_NONE, NULL, 0x00,
2021 "Version of SMPP interface supported.",
2025 { &hf_smpp_service_type,
2026 { "Service type", "smpp.service_type",
2027 FT_STRING, BASE_NONE, NULL, 0x00,
2028 "SMS application service associated with the message.",
2032 { &hf_smpp_addr_ton,
2033 { "Type of number", "smpp.addr_ton",
2034 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2035 "Indicates the type of number, given in the address.",
2039 { &hf_smpp_source_addr_ton,
2040 { "Type of number (originator)", "smpp.source_addr_ton",
2041 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2042 "Indicates originator type of number, given in the address.",
2046 { &hf_smpp_dest_addr_ton,
2047 { "Type of number (recipient)", "smpp.dest_addr_ton",
2048 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2049 "Indicates recipient type of number, given in the address.",
2053 { &hf_smpp_addr_npi,
2054 { "Numbering plan indicator", "smpp.addr_npi",
2055 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2056 "Gives the numbering plan this address belongs to.",
2060 { &hf_smpp_source_addr_npi,
2061 { "Numbering plan indicator (originator)", "smpp.source_addr_npi",
2062 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2063 "Gives originator numbering plan this address belongs to.",
2067 { &hf_smpp_dest_addr_npi,
2068 { "Numbering plan indicator (recipient)", "smpp.dest_addr_npi",
2069 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2070 "Gives recipient numbering plan this address belongs to.",
2074 { &hf_smpp_address_range,
2075 { "Address", "smpp.address_range",
2076 FT_STRING, BASE_NONE, NULL, 0x00,
2077 "Given address or address range.",
2081 { &hf_smpp_source_addr,
2082 { "Originator address", "smpp.source_addr",
2083 FT_STRING, BASE_NONE, NULL, 0x00,
2084 "Address of SME originating this message.",
2088 { &hf_smpp_destination_addr,
2089 { "Recipient address", "smpp.destination_addr",
2090 FT_STRING, BASE_NONE, NULL, 0x00,
2091 "Address of SME receiving this message.",
2095 { &hf_smpp_esm_submit_msg_mode,
2096 { "Messaging mode", "smpp.esm.submit.msg_mode",
2097 FT_UINT8, BASE_HEX, VALS(vals_esm_submit_msg_mode), 0x03,
2098 "Mode attribute for this message.",
2102 { &hf_smpp_esm_submit_msg_type,
2103 { "Message type ", "smpp.esm.submit.msg_type",
2104 FT_UINT8, BASE_HEX, VALS(vals_esm_submit_msg_type), 0x3C,
2105 "Type attribute for this message.",
2109 { &hf_smpp_esm_submit_features,
2110 { "GSM features ", "smpp.esm.submit.features",
2111 FT_UINT8, BASE_HEX, VALS(vals_esm_submit_features), 0xC0,
2112 "GSM network specific features.",
2116 /*! \todo Get proper values from GSM-spec. */
2117 { &hf_smpp_protocol_id,
2118 { "Protocol id.", "smpp.protocol_id",
2119 FT_UINT8, BASE_HEX, NULL, 0x00,
2120 "Protocol identifier according GSM 03.40.",
2124 { &hf_smpp_priority_flag,
2125 { "Priority level", "smpp.priority_flag",
2126 FT_UINT8, BASE_HEX, VALS(vals_priority_flag), 0x00,
2127 "The priority level of the short message.",
2131 { &hf_smpp_schedule_delivery_time,
2132 { "Scheduled delivery time", "smpp.schedule_delivery_time",
2133 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
2134 "Scheduled time for delivery of short message.",
2138 { &hf_smpp_schedule_delivery_time_r,
2139 { "Scheduled delivery time", "smpp.schedule_delivery_time_r",
2140 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
2141 "Scheduled time for delivery of short message.",
2145 { &hf_smpp_validity_period,
2146 { "Validity period", "smpp.validity_period",
2147 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
2148 "Validity period of this message.",
2152 { &hf_smpp_validity_period_r,
2153 { "Validity period", "smpp.validity_period_r",
2154 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
2155 "Validity period of this message.",
2159 { &hf_smpp_regdel_receipt,
2160 { "Delivery receipt ", "smpp.regdel.receipt",
2161 FT_UINT8, BASE_HEX, VALS(vals_regdel_receipt), 0x03,
2162 "SMSC delivery receipt request.",
2166 { &hf_smpp_regdel_acks,
2167 { "Message type ", "smpp.regdel.acks",
2168 FT_UINT8, BASE_HEX, VALS(vals_regdel_acks), 0x0C,
2169 "SME acknowledgement request.",
2173 { &hf_smpp_regdel_notif,
2174 { "Intermediate notif", "smpp.regdel.notif",
2175 FT_UINT8, BASE_HEX, VALS(vals_regdel_notif), 0x10,
2176 "Intermediate notification request.",
2180 { &hf_smpp_replace_if_present_flag,
2181 { "Replace ", "smpp.replace_if_present_flag",
2182 FT_UINT8, BASE_HEX, VALS(vals_replace_if_present_flag), 0x01,
2183 "Replace the short message with this one or not.",
2187 { &hf_smpp_data_coding,
2188 { "Data coding", "smpp.data_coding",
2189 FT_UINT8, BASE_HEX, NULL, 0x00,
2190 "Defines the encoding scheme of the message.",
2194 { &hf_smpp_sm_default_msg_id,
2195 { "Predefined message", "smpp.sm_default_msg_id",
2196 FT_UINT8, BASE_DEC, NULL, 0x00,
2197 "Index of a predefined ('canned') short message.",
2201 { &hf_smpp_sm_length,
2202 { "Message length", "smpp.sm_length",
2203 FT_UINT8, BASE_DEC, NULL, 0x00,
2204 "Length of the message content.",
2208 { &hf_smpp_short_message,
2209 { "Message", "smpp.message",
2210 FT_NONE, BASE_NONE, NULL, 0x00,
2211 "The actual message or data.",
2215 { &hf_smpp_message_id,
2216 { "Message id.", "smpp.message_id",
2217 FT_STRING, BASE_NONE, NULL, 0x00,
2218 "Identifier of the submitted short message.",
2223 { "Destination list", "smpp.dlist",
2224 FT_NONE, BASE_NONE, NULL, 0x00,
2225 "The list of destinations for a short message.",
2229 { &hf_smpp_dlist_resp,
2230 { "Unsuccessful delivery list", "smpp.dlist_resp",
2231 FT_NONE, BASE_NONE, NULL, 0x00,
2232 "The list of unsuccessful deliveries to destinations.",
2237 { "Distr. list name", "smpp.dl_name",
2238 FT_STRING, BASE_NONE, NULL, 0x00,
2239 "The name of the distribution list.",
2243 { &hf_smpp_final_date,
2244 { "Final date", "smpp.final_date",
2245 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
2246 "Date-time when the queried message reached a final state.",
2250 { &hf_smpp_final_date_r,
2251 { "Final date", "smpp.final_date_r",
2252 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
2253 "Date-time when the queried message reached a final state.",
2257 { &hf_smpp_message_state,
2258 { "Message state", "smpp.message_state",
2259 FT_UINT8, BASE_DEC, VALS(vals_message_state), 0x00,
2260 "Specifies the status of the queried short message.",
2264 { &hf_smpp_error_code,
2265 { "Error code", "smpp.error_code",
2266 FT_UINT8, BASE_DEC, NULL, 0x00,
2267 "Network specific error code defining reason for failure.",
2271 { &hf_smpp_error_status_code,
2272 { "Status", "smpp.error_status_code",
2273 FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
2274 "Indicates success/failure of request for this address.",
2278 { &hf_smpp_esme_addr_ton,
2279 { "Type of number (ESME)", "smpp.esme_addr_ton",
2280 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2281 "Indicates recipient type of number, given in the address.",
2285 { &hf_smpp_esme_addr_npi,
2286 { "Numbering plan indicator (ESME)", "smpp.esme_addr_npi",
2287 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2288 "Gives the numbering plan this address belongs to.",
2292 { &hf_smpp_esme_addr,
2293 { "ESME address", "smpp.esme_addr",
2294 FT_STRING, BASE_NONE, NULL, 0x00,
2295 "Address of ESME originating this message.",
2299 { &hf_smpp_dest_addr_subunit,
2300 { "Subunit destination", "smpp.dest_addr_subunit",
2301 FT_UINT8, BASE_HEX, VALS(vals_addr_subunit), 0x00,
2302 "Subunit address within mobile to route message to.",
2306 { &hf_smpp_source_addr_subunit,
2307 { "Subunit origin", "smpp.source_addr_subunit",
2308 FT_UINT8, BASE_HEX, VALS(vals_addr_subunit), 0x00,
2309 "Subunit address within mobile that generated the message.",
2313 { &hf_smpp_dest_network_type,
2314 { "Destination network", "smpp.dest_network_type",
2315 FT_UINT8, BASE_HEX, VALS(vals_network_type), 0x00,
2316 "Network associated with the destination address.",
2320 { &hf_smpp_source_network_type,
2321 { "Originator network", "smpp.source_network_type",
2322 FT_UINT8, BASE_HEX, VALS(vals_network_type), 0x00,
2323 "Network associated with the originator address.",
2327 { &hf_smpp_dest_bearer_type,
2328 { "Destination bearer", "smpp.dest_bearer_type",
2329 FT_UINT8, BASE_HEX, VALS(vals_bearer_type), 0x00,
2330 "Desired bearer for delivery of message.",
2334 { &hf_smpp_source_bearer_type,
2335 { "Originator bearer", "smpp.source_bearer_type",
2336 FT_UINT8, BASE_HEX, VALS(vals_bearer_type), 0x00,
2337 "Bearer over which the message originated.",
2341 { &hf_smpp_dest_telematics_id,
2342 { "Telematic interworking (dest)", "smpp.dest_telematics_id",
2343 FT_UINT16, BASE_HEX, NULL, 0x00,
2344 "Telematic interworking to be used for message delivery.",
2348 { &hf_smpp_source_telematics_id,
2349 { "Telematic interworking (orig)", "smpp.source_telematics_id",
2350 FT_UINT16, BASE_HEX, NULL, 0x00,
2351 "Telematic interworking used for message submission.",
2355 { &hf_smpp_qos_time_to_live,
2356 { "Validity period", "smpp.qos_time_to_live",
2357 FT_UINT32, BASE_DEC, NULL, 0x00,
2358 "Number of seconds to retain message before expiry.",
2362 { &hf_smpp_payload_type,
2363 { "Payload", "smpp.payload_type",
2364 FT_UINT8, BASE_DEC, VALS(vals_payload_type), 0x00,
2365 "PDU type contained in the message payload.",
2369 { &hf_smpp_additional_status_info_text,
2370 { "Information", "smpp.additional_status_info_text",
2371 FT_STRING, BASE_NONE, NULL, 0x00,
2372 "Description of the meaning of a response PDU.",
2376 { &hf_smpp_receipted_message_id,
2377 { "SMSC identifier", "smpp.receipted_message_id",
2378 FT_STRING, BASE_NONE, NULL, 0x00,
2379 "SMSC handle of the message being received.",
2383 { &hf_smpp_privacy_indicator,
2384 { "Privacy indicator", "smpp.privacy_indicator",
2385 FT_UINT8, BASE_DEC, VALS(vals_privacy_indicator), 0x00,
2386 "Indicates the privacy level of the message.",
2390 { &hf_smpp_source_subaddress,
2391 { "Source Subaddress", "smpp.source_subaddress",
2392 FT_STRING, BASE_NONE, NULL, 0x00,
2393 "Source Subaddress",
2397 { &hf_smpp_dest_subaddress,
2398 { "Destination Subaddress", "smpp.dest_subaddress",
2399 FT_STRING, BASE_NONE, NULL, 0x00,
2400 "Destination Subaddress",
2404 { &hf_smpp_user_message_reference,
2405 { "Message reference", "smpp.user_message_reference",
2406 FT_UINT16, BASE_HEX, NULL, 0x00,
2407 "Reference to the message, assigned by the user.",
2411 { &hf_smpp_user_response_code,
2412 { "Application response code", "smpp.user_response_code",
2413 FT_UINT8, BASE_HEX, NULL, 0x00,
2414 "A response code set by the user.",
2418 { &hf_smpp_language_indicator,
2419 { "Language", "smpp.language_indicator",
2420 FT_UINT8, BASE_DEC, VALS(vals_language_indicator), 0x00,
2421 "Indicates the language of the short message.",
2425 { &hf_smpp_source_port,
2426 { "Source port", "smpp.source_port",
2427 FT_UINT16, BASE_HEX, NULL, 0x00,
2428 "Application port associated with the source of the message.",
2432 { &hf_smpp_destination_port,
2433 { "Destination port", "smpp.destination_port",
2434 FT_UINT16, BASE_HEX, NULL, 0x00,
2435 "Application port associated with the destination of the message.",
2439 { &hf_smpp_sar_msg_ref_num,
2440 { "SAR reference number", "smpp.sar_msg_ref_num",
2441 FT_UINT16, BASE_DEC, NULL, 0x00,
2442 "Reference number for a concatenated short message.",
2446 { &hf_smpp_sar_total_segments,
2447 { "SAR size", "smpp.sar_total_segments",
2448 FT_UINT16, BASE_DEC, NULL, 0x00,
2449 "Number of segments of a concatenated short message.",
2453 { &hf_smpp_sar_segment_seqnum,
2454 { "SAR sequence number", "smpp.sar_segment_seqnum",
2455 FT_UINT8, BASE_DEC, NULL, 0x00,
2456 "Segment number within a concatenated short message.",
2460 { &hf_smpp_display_time,
2461 { "Display time", "smpp.display_time",
2462 FT_UINT8, BASE_DEC, VALS(vals_display_time), 0x00,
2463 "Associates a display time with the message on the handset.",
2467 { &hf_smpp_ms_validity,
2468 { "Validity info", "smpp.ms_validity",
2469 FT_UINT8, BASE_DEC, VALS(vals_ms_validity), 0x00,
2470 "Associates validity info with the message on the handset.",
2474 { &hf_smpp_dpf_result,
2475 { "Delivery pending set?", "smpp.dpf_result",
2476 FT_UINT8, BASE_DEC, VALS(vals_dpf_result), 0x00,
2477 "Indicates whether Delivery Pending Flag was set.",
2482 { "Request DPF set", "smpp.set_dpf",
2483 FT_UINT8, BASE_DEC, VALS(vals_set_dpf), 0x00,
2484 "Request to set the DPF for certain failure scenario's.",
2488 { &hf_smpp_ms_availability_status,
2489 { "Availability status", "smpp.ms_availability_status",
2490 FT_UINT8, BASE_DEC, VALS(vals_ms_availability_status), 0x00,
2491 "Indicates the availability state of the handset.",
2495 { &hf_smpp_delivery_failure_reason,
2496 { "Delivery failure reason", "smpp.delivery_failure_reason",
2497 FT_UINT8, BASE_DEC, VALS(vals_delivery_failure_reason), 0x00,
2498 "Indicates the reason for a failed delivery attempt.",
2502 { &hf_smpp_more_messages_to_send,
2503 { "More messages?", "smpp.more_messages_to_send",
2504 FT_UINT8, BASE_DEC, VALS(vals_more_messages_to_send), 0x00,
2505 "Indicates more messages pending for the same destination.",
2509 { &hf_smpp_number_of_messages,
2510 { "Number of messages", "smpp.number_of_messages",
2511 FT_UINT8, BASE_DEC, NULL, 0x00,
2512 "Indicates number of messages stored in a mailbox.",
2516 { &hf_smpp_its_reply_type,
2517 { "Reply method", "smpp.its_reply_type",
2518 FT_UINT8, BASE_DEC, VALS(vals_its_reply_type), 0x00,
2519 "Indicates the handset reply method on message receipt.",
2523 { &hf_smpp_ussd_service_op,
2524 { "USSD service operation", "smpp.ussd_service_op",
2525 FT_UINT8, BASE_DEC, VALS(vals_ussd_service_op), 0x00,
2526 "Indicates the USSD service operation.",
2530 { &hf_smpp_vendor_op,
2531 { "Optional parameter - Vendor-specific", "smpp.vendor_op",
2532 FT_NONE, BASE_NONE, NULL, 0x00,
2533 "A supplied optional parameter specific to an SMSC-vendor.",
2537 { &hf_smpp_reserved_op,
2538 { "Optional parameter - Reserved", "smpp.reserved_op",
2539 FT_NONE, BASE_NONE, NULL, 0x00,
2540 "An optional parameter that is reserved in this version.",
2544 { &hf_smpp_msg_wait_ind,
2545 { "Indication", "smpp.msg_wait.ind",
2546 FT_UINT8, BASE_HEX, VALS(vals_msg_wait_ind), 0x80,
2547 "Indicates to the handset that a message is waiting.",
2551 { &hf_smpp_msg_wait_type,
2552 { "Type ", "smpp.msg_wait.type",
2553 FT_UINT8, BASE_HEX, VALS(vals_msg_wait_type), 0x03,
2554 "Indicates type of message that is waiting.",
2558 { &hf_smpp_SC_interface_version,
2559 { "SMSC-supported version", "smpp.SC_interface_version",
2560 FT_STRING, BASE_NONE, NULL, 0x00,
2561 "Version of SMPP interface supported by the SMSC.",
2565 { &hf_smpp_callback_num_pres,
2566 { "Presentation", "smpp.callback_num.pres",
2567 FT_UINT8, BASE_HEX, VALS(vals_callback_num_pres), 0x0C,
2568 "Controls the presentation indication.",
2572 { &hf_smpp_callback_num_scrn,
2573 { "Screening ", "smpp.callback_num.scrn",
2574 FT_UINT8, BASE_HEX, VALS(vals_callback_num_scrn), 0x03,
2575 "Controls screening of the callback-number.",
2579 { &hf_smpp_callback_num_atag,
2580 { "Callback number - alphanumeric display tag",
2581 "smpp.callback_num_atag",
2582 FT_NONE, BASE_NONE, NULL, 0x00,
2583 "Associates an alphanumeric display with call back number.",
2587 { &hf_smpp_callback_num,
2588 { "Callback number", "smpp.callback_num",
2589 FT_NONE, BASE_NONE, NULL, 0x00,
2590 "Associates a call back number with the message.",
2594 { &hf_smpp_network_error_type,
2595 { "Error type", "smpp.network_error.type",
2596 FT_UINT8, BASE_DEC, VALS(vals_network_error_type), 0x00,
2597 "Indicates the network type.",
2601 { &hf_smpp_network_error_code,
2602 { "Error code", "smpp.network_error.code",
2603 FT_UINT16, BASE_HEX, NULL, 0x00,
2604 "Gives the actual network error code.",
2608 { &hf_smpp_message_payload,
2609 { "Payload", "smpp.message_payload",
2610 FT_NONE, BASE_NONE, NULL, 0x00,
2611 "Short message user data.",
2615 { &hf_smpp_alert_on_message_delivery,
2616 { "Alert on delivery", "smpp.alert_on_message_delivery",
2617 FT_NONE, BASE_NONE, NULL, 0x00,
2618 "Instructs the handset to alert user on message delivery.",
2622 { &hf_smpp_its_session_number,
2623 { "Session number", "smpp.its_session.number",
2624 FT_UINT8, BASE_DEC, NULL, 0x00,
2625 "Session number of interactive teleservice.",
2629 { &hf_smpp_its_session_sequence,
2630 { "Sequence number ", "smpp.its_session.sequence",
2631 FT_UINT8, BASE_HEX, NULL, 0xFE,
2632 "Sequence number of the dialogue unit.",
2636 { &hf_smpp_its_session_ind,
2637 { "Session indicator", "smpp.its_session.ind",
2638 FT_UINT8, BASE_HEX, VALS(vals_its_session_ind), 0x01,
2639 "Indicates whether this message is end of conversation.",
2643 { &hf_smpp_opt_param,
2644 { "Optional parameters", "smpp.opt_param",
2645 FT_NONE, BASE_NONE, NULL, 0x00,
2646 "The list of optional parameters in this operation.",
2651 * Data Coding Scheme
2654 { "SMPP Data Coding Scheme", "smpp.dcs",
2655 FT_UINT8, BASE_HEX, VALS(vals_data_coding), 0x00,
2656 "Data Coding Scheme according to SMPP.",
2660 { &hf_smpp_dcs_sms_coding_group,
2661 { "DCS Coding Group for SMS", "smpp.dcs.sms_coding_group",
2662 FT_UINT8, BASE_HEX, VALS(vals_dcs_sms_coding_group), 0xF0,
2663 "Data Coding Scheme coding group for GSM Short Message Service.",
2667 { &hf_smpp_dcs_text_compression,
2668 { "DCS Text compression", "smpp.dcs.text_compression",
2669 FT_BOOLEAN, 8, TFS(&tfs_dcs_text_compression), 0x20,
2670 "Indicates if text compression is used.", HFILL
2673 { &hf_smpp_dcs_class_present,
2674 { "DCS Class present", "smpp.dcs.class_present",
2675 FT_BOOLEAN, 8, TFS(&tfs_dcs_class_present), 0x10,
2676 "Indicates if the message class is present (defined).", HFILL
2679 { &hf_smpp_dcs_charset,
2680 { "DCS Character set", "smpp.dcs.charset",
2681 FT_UINT8, BASE_HEX, VALS(vals_dcs_charset), 0x0C,
2682 "Specifies the character set used in the message.", HFILL
2685 { &hf_smpp_dcs_class,
2686 { "DCS Message class", "smpp.dcs.class",
2687 FT_UINT8, BASE_HEX, VALS(vals_dcs_class), 0x03,
2688 "Specifies the message class.", HFILL
2691 { &hf_smpp_dcs_cbs_coding_group,
2692 { "DCS Coding Group for CBS", "smpp.dcs.cbs_coding_group",
2693 FT_UINT8, BASE_HEX, VALS(vals_dcs_cbs_coding_group), 0xF0,
2694 "Data Coding Scheme coding group for GSM Cell Broadcast Service.",
2698 { &hf_smpp_dcs_cbs_language,
2699 { "DCS CBS Message language", "smpp.dcs.cbs_language",
2700 FT_UINT8, BASE_HEX, VALS(vals_dcs_cbs_language), 0x3F,
2701 "Language of the GSM Cell Broadcast Service message.", HFILL
2704 { &hf_smpp_dcs_cbs_class,
2705 { "DCS CBS Message class", "smpp.dcs.cbs_class",
2706 FT_UINT8, BASE_HEX, VALS(vals_dcs_cbs_class), 0x03,
2707 "Specifies the message class for GSM Cell Broadcast Service, "
2708 "for the Data coding / message handling code group.", HFILL
2711 { &hf_smpp_dcs_wap_charset,
2712 { "DCS Message coding", "smpp.dcs.wap_coding",
2713 FT_UINT8, BASE_HEX, VALS(vals_dcs_wap_charset), 0x0C,
2714 "Specifies the used message encoding, "
2715 "as specified by the WAP Forum (WAP over GSM USSD).", HFILL
2718 { &hf_smpp_dcs_wap_class,
2719 { "DCS CBS Message class", "smpp.dcs.wap_class",
2720 FT_UINT8, BASE_HEX, VALS(vals_dcs_wap_class), 0x03,
2721 "Specifies the message class for GSM Cell Broadcast Service, "
2722 "as specified by the WAP Forum (WAP over GSM USSD).", HFILL
2726 /* Setup protocol subtree array */
2727 static gint *ett[] = {
2734 DebugLog(("Registering SMPP dissector\n"));
2735 /* Register the protocol name and description */
2736 proto_smpp = proto_register_protocol("Short Message Peer to Peer",
2739 /* Required function calls to register header fields and subtrees used */
2740 proto_register_field_array(proto_smpp, hf, array_length(hf));
2741 proto_register_subtree_array(ett, array_length(ett));
2744 smpp_module = prefs_register_protocol (proto_smpp, NULL);
2745 prefs_register_bool_preference (smpp_module,
2746 "reassemble_smpp_over_tcp",
2747 "Reassemble SMPP over TCP messages spanning multiple TCP segments",
2748 "Whether the SMPP dissector should reassemble messages spanning multiple TCP segments."
2749 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2750 &reassemble_over_tcp);
2754 * If dissector uses sub-dissector registration add a registration routine.
2755 * This format is required because a script is used to find these routines and
2756 * create the code that calls these routines.
2759 proto_reg_handoff_smpp(void)
2761 dissector_handle_t smpp_handle;
2764 * SMPP can be spoken on any port under TCP or X.25
2765 * ...how *do* we do that under X.25?
2767 * We can register the heuristic SMPP dissector with X.25, for one
2768 * thing. We don't currently have any mechanism to allow the user
2769 * to specify that a given X.25 circuit is to be dissected as SMPP,
2772 smpp_handle = create_dissector_handle(dissect_smpp, proto_smpp);
2773 dissector_add_handle("tcp.port", smpp_handle);
2774 heur_dissector_add("tcp", dissect_smpp_heur, proto_smpp);
2775 heur_dissector_add("x.25", dissect_smpp_heur, proto_smpp);
2777 /* Required for call_dissector() */
2778 DebugLog(("Finding gsm-sms-ud subdissector\n"));
2779 gsm_sms_handle = find_dissector("gsm-sms-ud");
2780 DISSECTOR_ASSERT(gsm_sms_handle);