2 * Routines for Short Message Peer to Peer dissection
3 * Copyright 2001, Tom Uijldert <tom.uijldert@cmg.nl>
5 * UDH and WSP dissection of SMS message, Short Message reassembly,
6 * "Decode Short Message with Port Number UDH as CL-WSP" preference,
7 * "Always try subdissection of 1st fragment" preference,
8 * Data Coding Scheme decoding for GSM (SMS and CBS),
9 * provided by Olivier Biot.
11 * $Id: packet-smpp.c,v 1.19 2003/09/17 20:24:45 guy Exp $
13 * Note on SMS Message reassembly
14 * ------------------------------
15 * The current Short Message reassembly is possible thanks to the
16 * message identifier (8 or 16 bit identifier). It is able to reassemble
17 * short messages that are sent over either the same SMPP connection or
18 * distinct SMPP connections. Normally the reassembly code is able to deal
19 * with duplicate message identifiers since the fragment_add_seq_check()
22 * The SMPP preference "always try subdissection of 1st fragment" allows
23 * a subdissector to be called for the first Short Message fragment,
24 * even if reassembly is not possible. This way partial dissection
25 * is still possible. This preference is switched off by default.
27 * Note on Short Message decoding as CL-WSP
28 * ----------------------------------------
29 * The SMPP preference "port_number_udh_means_wsp" is switched off
30 * by default. If it is enabled, then any Short Message with a Port Number
31 * UDH will be decoded as CL-WSP if:
32 * - The Short Message is not segmented
33 * - The entire segmented Short Message is reassembled
34 * - It is the 1st segment of an unreassembled Short Message (if the
35 * "always try subdissection of 1st fragment" preference is enabled)
37 * Ethereal - Network traffic analyzer
38 * By Gerald Combs <gerald@ethereal.com>
39 * Copyright 1998 Gerald Combs
41 * This program is free software; you can redistribute it and/or
42 * modify it under the terms of the GNU General Public License
43 * as published by the Free Software Foundation; either version 2
44 * of the License, or (at your option) any later version.
46 * This program is distributed in the hope that it will be useful,
47 * but WITHOUT ANY WARRANTY; without even the implied warranty of
48 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
49 * GNU General Public License for more details.
51 * You should have received a copy of the GNU General Public License
52 * along with this program; if not, write to the Free Software
53 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
56 * Dissector of an SMPP (Short Message Peer to Peer) PDU, as defined by the
57 * SMS forum (www.smsforum.net) in "SMPP protocol specification v3.4"
58 * (document version: 12-Oct-1999 Issue 1.2)
72 #include <epan/packet.h>
75 #include "reassemble.h"
77 /* Forward declarations */
78 static void dissect_smpp(tvbuff_t *, packet_info *, proto_tree *t);
81 * Initialize the protocol and registered fields
83 * Fixed header section
85 static int proto_smpp = -1;
87 static int hf_smpp_command_id = -1;
88 static int hf_smpp_command_length = -1;
89 static int hf_smpp_command_status = -1;
90 static int hf_smpp_sequence_number = -1;
95 static int hf_smpp_system_id = -1;
96 static int hf_smpp_password = -1;
97 static int hf_smpp_system_type = -1;
98 static int hf_smpp_interface_version = -1;
99 static int hf_smpp_addr_ton = -1;
100 static int hf_smpp_addr_npi = -1;
101 static int hf_smpp_address_range = -1;
102 static int hf_smpp_service_type = -1;
103 static int hf_smpp_source_addr_ton = -1;
104 static int hf_smpp_source_addr_npi = -1;
105 static int hf_smpp_source_addr = -1;
106 static int hf_smpp_dest_addr_ton = -1;
107 static int hf_smpp_dest_addr_npi = -1;
108 static int hf_smpp_destination_addr = -1;
109 static int hf_smpp_esm_submit_msg_mode = -1;
110 static int hf_smpp_esm_submit_msg_type = -1;
111 static int hf_smpp_esm_submit_features = -1;
112 static int hf_smpp_protocol_id = -1;
113 static int hf_smpp_priority_flag = -1;
114 static int hf_smpp_schedule_delivery_time = -1;
115 static int hf_smpp_schedule_delivery_time_r = -1;
116 static int hf_smpp_validity_period = -1;
117 static int hf_smpp_validity_period_r = -1;
118 static int hf_smpp_regdel_receipt = -1;
119 static int hf_smpp_regdel_acks = -1;
120 static int hf_smpp_regdel_notif = -1;
121 static int hf_smpp_replace_if_present_flag = -1;
122 static int hf_smpp_data_coding = -1;
123 static int hf_smpp_sm_default_msg_id = -1;
124 static int hf_smpp_sm_length = -1;
125 static int hf_smpp_short_message = -1;
126 static int hf_smpp_message_id = -1;
127 static int hf_smpp_dlist = -1;
128 static int hf_smpp_dlist_resp = -1;
129 static int hf_smpp_dl_name = -1;
130 static int hf_smpp_final_date = -1;
131 static int hf_smpp_final_date_r = -1;
132 static int hf_smpp_message_state = -1;
133 static int hf_smpp_error_code = -1;
134 static int hf_smpp_error_status_code = -1;
135 static int hf_smpp_esme_addr_ton = -1;
136 static int hf_smpp_esme_addr_npi = -1;
137 static int hf_smpp_esme_addr = -1;
140 * Optional parameter section
142 static int hf_smpp_opt_param = -1;
143 static int hf_smpp_vendor_op = -1;
144 static int hf_smpp_reserved_op = -1;
146 static int hf_smpp_dest_addr_subunit = -1;
147 static int hf_smpp_dest_network_type = -1;
148 static int hf_smpp_dest_bearer_type = -1;
149 static int hf_smpp_dest_telematics_id = -1;
150 static int hf_smpp_source_addr_subunit = -1;
151 static int hf_smpp_source_network_type = -1;
152 static int hf_smpp_source_bearer_type = -1;
153 static int hf_smpp_source_telematics_id = -1;
154 static int hf_smpp_qos_time_to_live = -1;
155 static int hf_smpp_payload_type = -1;
156 static int hf_smpp_additional_status_info_text = -1;
157 static int hf_smpp_receipted_message_id = -1;
158 static int hf_smpp_msg_wait_ind = -1;
159 static int hf_smpp_msg_wait_type = -1;
160 static int hf_smpp_privacy_indicator = -1;
161 static int hf_smpp_source_subaddress = -1;
162 static int hf_smpp_dest_subaddress = -1;
163 static int hf_smpp_user_message_reference = -1;
164 static int hf_smpp_user_response_code = -1;
165 static int hf_smpp_source_port = -1;
166 static int hf_smpp_destination_port = -1;
167 static int hf_smpp_sar_msg_ref_num = -1;
168 static int hf_smpp_language_indicator = -1;
169 static int hf_smpp_sar_total_segments = -1;
170 static int hf_smpp_sar_segment_seqnum = -1;
171 static int hf_smpp_SC_interface_version = -1;
172 static int hf_smpp_callback_num_pres = -1;
173 static int hf_smpp_callback_num_scrn = -1;
174 static int hf_smpp_callback_num_atag = -1;
175 static int hf_smpp_number_of_messages = -1;
176 static int hf_smpp_callback_num = -1;
177 static int hf_smpp_dpf_result = -1;
178 static int hf_smpp_set_dpf = -1;
179 static int hf_smpp_ms_availability_status = -1;
180 static int hf_smpp_network_error_type = -1;
181 static int hf_smpp_network_error_code = -1;
182 static int hf_smpp_message_payload = -1;
183 static int hf_smpp_delivery_failure_reason = -1;
184 static int hf_smpp_more_messages_to_send = -1;
185 static int hf_smpp_ussd_service_op = -1;
186 static int hf_smpp_display_time = -1;
187 static int hf_smpp_sms_signal = -1;
188 static int hf_smpp_ms_validity = -1;
189 static int hf_smpp_alert_on_message_delivery = -1;
190 static int hf_smpp_its_reply_type = -1;
191 static int hf_smpp_its_session_number = -1;
192 static int hf_smpp_its_session_sequence = -1;
193 static int hf_smpp_its_session_ind = -1;
196 * Data Coding Scheme section
198 static int hf_smpp_dcs = -1;
199 static int hf_smpp_dcs_sms_coding_group = -1;
200 static int hf_smpp_dcs_text_compression = -1;
201 static int hf_smpp_dcs_class_present = -1;
202 static int hf_smpp_dcs_charset = -1;
203 static int hf_smpp_dcs_class = -1;
204 static int hf_smpp_dcs_cbs_coding_group = -1;
205 static int hf_smpp_dcs_cbs_language = -1;
206 static int hf_smpp_dcs_wap_charset = -1;
207 static int hf_smpp_dcs_wap_class = -1;
208 static int hf_smpp_dcs_cbs_class = -1;
211 * User Data Header section
213 static int hf_smpp_udh_length = -1;
214 static int hf_smpp_udh_iei = -1;
215 static int hf_smpp_udh_multiple_messages = -1;
216 static int hf_smpp_udh_multiple_messages_msg_id = -1;
217 static int hf_smpp_udh_multiple_messages_msg_parts = -1;
218 static int hf_smpp_udh_multiple_messages_msg_part = -1;
219 static int hf_smpp_udh_ports = -1;
220 static int hf_smpp_udh_ports_src = -1;
221 static int hf_smpp_udh_ports_dst = -1;
224 * Short Message fragment handling
226 static int hf_sm_fragments = -1;
227 static int hf_sm_fragment = -1;
228 static int hf_sm_fragment_overlap = -1;
229 static int hf_sm_fragment_overlap_conflicts = -1;
230 static int hf_sm_fragment_multiple_tails = -1;
231 static int hf_sm_fragment_too_long_fragment = -1;
232 static int hf_sm_fragment_error = -1;
234 /* Initialize the subtree pointers */
235 static gint ett_smpp = -1;
236 static gint ett_dlist = -1;
237 static gint ett_dlist_resp = -1;
238 static gint ett_opt_param = -1;
239 static gint ett_dcs = -1;
240 static gint ett_udh = -1;
241 static gint ett_udh_multiple_messages = -1;
242 static gint ett_udh_ports = -1;
243 static gint ett_sm_fragment = -1;
244 static gint ett_sm_fragments = -1;
246 /* Subdissector declarations */
247 static dissector_table_t smpp_dissector_table;
249 /* Short Message reassembly */
250 static GHashTable *sm_fragment_table = NULL;
251 static GHashTable *sm_reassembled_table = NULL;
253 static const fragment_items sm_frag_items = {
254 /* Fragment subtrees */
257 /* Fragment fields */
260 &hf_sm_fragment_overlap,
261 &hf_sm_fragment_overlap_conflicts,
262 &hf_sm_fragment_multiple_tails,
263 &hf_sm_fragment_too_long_fragment,
264 &hf_sm_fragment_error,
265 /* Reassembled in field */
268 "Short Message fragments"
271 /* Dissect all SM data as WSP if the UDH contains a Port Number IE */
272 static gboolean port_number_udh_means_wsp = FALSE;
273 /* Always try dissecting the 1st fragment of a SM,
274 * even if it is not reassembled */
275 static gboolean try_dissect_1st_frag = FALSE;
277 static dissector_handle_t wsp_handle;
280 sm_defragment_init (void)
282 fragment_table_init (&sm_fragment_table);
283 reassembled_table_init(&sm_reassembled_table);
287 * Value-arrays for field-contents
289 static const value_string vals_command_id[] = { /* Operation */
290 { 0x80000000, "Generic_nack" },
291 { 0x00000001, "Bind_receiver" },
292 { 0x80000001, "Bind_receiver - resp" },
293 { 0x00000002, "Bind_transmitter" },
294 { 0x80000002, "Bind_transmitter - resp" },
295 { 0x00000003, "Query_sm" },
296 { 0x80000003, "Query_sm - resp" },
297 { 0x00000004, "Submit_sm" },
298 { 0x80000004, "Submit_sm - resp" },
299 { 0x00000005, "Deliver_sm" },
300 { 0x80000005, "Deliver_sm - resp" },
301 { 0x00000006, "Unbind" },
302 { 0x80000006, "Unbind - resp" },
303 { 0x00000007, "Replace_sm" },
304 { 0x80000007, "Replace_sm - resp" },
305 { 0x00000008, "Cancel_sm" },
306 { 0x80000008, "Cancel_sm - resp" },
307 { 0x00000009, "Bind_transceiver" },
308 { 0x80000009, "Bind_transceiver - resp" },
309 { 0x0000000B, "Outbind" },
310 { 0x00000015, "Enquire_link" },
311 { 0x80000015, "Enquire_link - resp" },
312 { 0x00000021, "Submit_multi" },
313 { 0x80000021, "Submit_multi - resp" },
314 { 0x00000102, "Alert_notification" },
315 { 0x00000103, "Data_sm" },
316 { 0x80000103, "Data_sm - resp" },
320 static const value_string vals_command_status[] = { /* Status */
321 { 0x00000000, "Ok" },
322 { 0x00000001, "Message length is invalid" },
323 { 0x00000002, "Command length is invalid" },
324 { 0x00000003, "Invalid command ID" },
325 { 0x00000004, "Incorrect BIND status for given command" },
326 { 0x00000005, "ESME already in bound state" },
327 { 0x00000006, "Invalid priority flag" },
328 { 0x00000007, "Invalid registered delivery flag" },
329 { 0x00000008, "System error" },
330 { 0x00000009, "[Reserved]" },
331 { 0x0000000A, "Invalid source address" },
332 { 0x0000000B, "Invalid destination address" },
333 { 0x0000000C, "Message ID is invalid" },
334 { 0x0000000D, "Bind failed" },
335 { 0x0000000E, "Invalid password" },
336 { 0x0000000F, "Invalid system ID" },
337 { 0x00000010, "[Reserved]" },
338 { 0x00000011, "Cancel SM failed" },
339 { 0x00000012, "[Reserved]" },
340 { 0x00000013, "Replace SM failed" },
341 { 0x00000014, "Message queue full" },
342 { 0x00000015, "Invalid service type" },
343 { 0x00000033, "Invalid number of destinations" },
344 { 0x00000034, "Invalid distribution list name" },
345 { 0x00000040, "Destination flag is invalid (submit_multi)" },
346 { 0x00000041, "[Reserved]" },
347 { 0x00000042, "Invalid 'submit with replace' request" },
348 { 0x00000043, "Invalid esm_class field data" },
349 { 0x00000044, "Cannot submit to distribution list" },
350 { 0x00000045, "submit_sm or submit_multi failed" },
351 { 0x00000046, "[Reserved]" },
352 { 0x00000047, "[Reserved]" },
353 { 0x00000048, "Invalid source address TON" },
354 { 0x00000049, "Invalid source address NPI" },
355 { 0x00000050, "Invalid destination address TON" },
356 { 0x00000051, "Invalid destination address NPI" },
357 { 0x00000052, "[Reserved]" },
358 { 0x00000053, "Invalid system_type field" },
359 { 0x00000054, "Invalid replace_if_present flag" },
360 { 0x00000055, "Invalid number of messages" },
361 { 0x00000056, "[Reserved]" },
362 { 0x00000057, "[Reserved]" },
363 { 0x00000058, "Throttling error (ESME exceeded allowed message limits)" },
364 { 0x00000059, "[Reserved]" },
365 { 0x00000060, "[Reserved]" },
366 { 0x00000061, "Invalid scheduled delivery time" },
367 { 0x00000062, "Invalid message validity period (expirey time)" },
368 { 0x00000063, "Predefined message invalid or not found" },
369 { 0x00000064, "ESME receiver temporary app error code" },
370 { 0x00000065, "ESME receiver permanent app error code" },
371 { 0x00000066, "ESME receiver reject message error code" },
372 { 0x00000067, "query_sm request failed" },
373 { 0x000000C0, "Error in the optional part of the PDU body" },
374 { 0x000000C1, "Optional parameter not allowed" },
375 { 0x000000C2, "Invalid parameter length" },
376 { 0x000000C3, "Expected optional parameter missing" },
377 { 0x000000C4, "Invalid optional parameter value" },
378 { 0x000000FE, "Delivery failure (used for data_sm_resp)" },
379 { 0x000000FF, "Unknown error" },
383 static const value_string vals_addr_ton[] = {
385 { 1, "International" },
387 { 3, "Network specific" },
388 { 4, "Subscriber number" },
389 { 5, "Alphanumeric" },
390 { 6, "Abbreviated" },
394 static const value_string vals_addr_npi[] = {
396 { 1, "ISDN (E163/E164)" },
397 { 3, "Data (X.121)" },
398 { 4, "Telex (F.69)" },
399 { 6, "Land mobile (E.212)" },
403 { 14, "Internet (IP)" },
404 { 18, "WAP client Id" },
408 static const value_string vals_esm_submit_msg_mode[] = {
409 { 0x0, "Default SMSC mode" },
410 { 0x1, "Datagram mode" },
411 { 0x2, "Forward mode" },
412 { 0x3, "Store and forward mode" },
416 static const value_string vals_esm_submit_msg_type[] = {
417 { 0x0, "Default message type" },
418 { 0x1, "Short message contains SMSC Delivery Receipt" },
419 { 0x2, "Short message contains (E)SME delivery acknowledgement" },
421 { 0x4, "Short message contains (E)SME manual/user acknowledgement" },
423 { 0x6, "Short message contains conversation abort" },
425 { 0x8, "Short message contains intermediate delivery notification" },
429 static const value_string vals_esm_submit_features[] = {
430 { 0x0, "No specific features selected" },
431 { 0x1, "UDHI indicator" },
432 { 0x2, "Reply path" },
433 { 0x3, "UDHI and reply path" },
437 static const value_string vals_priority_flag[] = {
438 { 0, "GSM: None ANSI-136: Bulk IS-95: Normal" },
439 { 1, "GSM: priority ANSI-136: Normal IS-95: Interactive" },
440 { 2, "GSM: priority ANSI-136: Urgent IS-95: Urgent" },
441 { 3, "GSM: priority ANSI-136: Very Urgent IS-95: Emergency" },
445 static const value_string vals_regdel_receipt[] = {
446 { 0x0, "No SMSC delivery receipt requested" },
447 { 0x1, "Delivery receipt requested (for success or failure)" },
448 { 0x2, "Delivery receipt requested (for failure)" },
453 static const value_string vals_regdel_acks[] = {
454 { 0x0, "No recipient SME acknowledgement requested" },
455 { 0x1, "SME delivery acknowledgement requested" },
456 { 0x2, "SME manual/user acknowledgement requested" },
457 { 0x3, "Both delivery and manual/user acknowledgement requested" },
461 static const value_string vals_regdel_notif[] = {
462 { 0x0, "No intermediate notification requested" },
463 { 0x1, "Intermediate notification requested" },
467 static const value_string vals_replace_if_present_flag[] = {
468 { 0x0, "Don't replace" },
473 static const value_string vals_data_coding[] = {
474 { 0, "SMSC default alphabet" },
475 { 1, "IA5 (CCITT T.50/ASCII (ANSI X3.4)" },
476 { 2, "Octet unspecified (8-bit binary)" },
477 { 3, "Latin 1 (ISO-8859-1)" },
478 { 4, "Octet unspecified (8-bit binary)" },
479 { 5, "JIS (X 0208-1990)" },
480 { 6, "Cyrillic (ISO-8859-5)" },
481 { 7, "Latin/Hebrew (ISO-8859-8)" },
482 { 8, "UCS2 (ISO/IEC-10646)" },
483 { 9, "Pictogram encoding" },
484 { 10, "ISO-2022-JP (Music codes)" },
487 { 13, "Extended Kanji JIS(X 0212-1990)" },
489 /*! \todo Rest to be defined (bitmask?) according GSM 03.38 */
493 static const value_string vals_message_state[] = {
498 { 5, "UNDELIVERABLE" },
505 static const value_string vals_addr_subunit[] = {
506 { 0, "Unknown -default-" },
508 { 2, "Mobile equipment" },
509 { 3, "Smart card 1" },
510 { 4, "External unit 1" },
514 static const value_string vals_network_type[] = {
517 { 2, "ANSI-136/TDMA" },
523 { 8, "Paging network" },
527 static const value_string vals_bearer_type[] = {
530 { 2, "Circuit Switched Data (CSD)" },
531 { 3, "Packet data" },
535 { 7, "FLEX/ReFLEX" },
536 { 8, "Cell Broadcast" },
540 static const value_string vals_payload_type[] = {
542 { 1, "WCMP message" },
546 static const value_string vals_privacy_indicator[] = {
547 { 0, "Not restricted -default-" },
549 { 2, "Confidential" },
554 static const value_string vals_language_indicator[] = {
555 { 0, "Unspecified -default-" },
564 static const value_string vals_display_time[] = {
566 { 1, "Default -default-" },
571 static const value_string vals_ms_validity[] = {
572 { 0, "Store indefinitely -default-" },
574 { 2, "SID based registration area" },
575 { 3, "Display only" },
579 static const value_string vals_dpf_result[] = {
580 { 0, "DPF not set" },
585 static const value_string vals_set_dpf[] = {
586 { 0, "Not requested (Set DPF for delivery failure)" },
587 { 1, "Requested (Set DPF for delivery failure)" },
591 static const value_string vals_ms_availability_status[] = {
592 { 0, "Available -default-" },
594 { 2, "Unavailable" },
598 static const value_string vals_delivery_failure_reason[] = {
599 { 0, "Destination unavailable" },
600 { 1, "Destination address invalid" },
601 { 2, "Permanent network error" },
602 { 3, "Temporary network error" },
606 static const value_string vals_more_messages_to_send[] = {
607 { 0, "No more messages" },
608 { 1, "More messages -default-" },
612 static const value_string vals_its_reply_type[] = {
615 { 2, "Telephone no." },
617 { 4, "Character line" },
625 static const value_string vals_ussd_service_op[] = {
626 { 0, "PSSD indication" },
627 { 1, "PSSR indication" },
628 { 2, "USSR request" },
629 { 3, "USSN request" },
630 { 16, "PSSD response" },
631 { 17, "PSSR response" },
632 { 18, "USSR confirm" },
633 { 19, "USSN confirm" },
637 static const value_string vals_msg_wait_ind[] = {
638 { 0, "Set indication inactive" },
639 { 1, "Set indication active" },
643 static const value_string vals_msg_wait_type[] = {
644 { 0, "Voicemail message waiting" },
645 { 1, "Fax message waiting" },
646 { 2, "Electronic mail message waiting" },
647 { 3, "Other message waiting" },
651 static const value_string vals_callback_num_pres[] = {
652 { 0, "Presentation allowed" },
653 { 1, "Presentation restricted" },
654 { 2, "Number not available" },
659 static const value_string vals_callback_num_scrn[] = {
660 { 0, "User provided, not screened" },
661 { 1, "User provided, verified and passed" },
662 { 2, "User provided, verified and failed" },
663 { 3, "Network provided" },
667 static const value_string vals_network_error_type[] = {
675 static const value_string vals_its_session_ind[] = {
676 { 0, "End of session indicator inactive" },
677 { 1, "End of session indicator active" },
681 /* Data Coding Scheme: see 3GPP TS 23.040 and 3GPP TS 23.038 */
682 static const value_string vals_dcs_sms_coding_group[] = {
683 { 0x00, "SMS DCS: General Data Coding indication - Uncompressed text, no message class" },
684 { 0x01, "SMS DCS: General Data Coding indication - Uncompressed text" },
685 { 0x02, "SMS DCS: General Data Coding indication - Compressed text, no message class" },
686 { 0x03, "SMS DCS: General Data Coding indication - Compressed text" },
687 { 0x04, "SMS DCS: Message Marked for Automatic Deletion - Uncompressed text, no message class" },
688 { 0x05, "SMS DCS: Message Marked for Automatic Deletion - Uncompressed text" },
689 { 0x06, "SMS DCS: Message Marked for Automatic Deletion - Compressed text, no message class" },
690 { 0x07, "SMS DCS: Message Marked for Automatic Deletion - Compressed text" },
691 { 0x08, "SMS DCS: Reserved" },
692 { 0x09, "SMS DCS: Reserved" },
693 { 0x0A, "SMS DCS: Reserved" },
694 { 0x0B, "SMS DCS: Reserved" },
695 { 0x0C, "SMS DCS: Message Waiting Indication - Discard Message" },
696 { 0x0D, "SMS DCS: Message Waiting Indication - Store Message (GSM 7-bit default alphabet)" },
697 { 0x0E, "SMS DCS: Message Waiting Indication - Store Message (UCS-2 character set)" },
698 { 0x0F, "SMS DCS: Data coding / message class" },
702 static const true_false_string tfs_dcs_text_compression = {
707 static const true_false_string tfs_dcs_class_present = {
708 "Message class is present",
712 static const value_string vals_dcs_charset[] = {
713 { 0x00, "GSM 7-bit default alphabet" },
714 { 0x01, "8-bit data" },
715 { 0x02, "UCS-2 (16-bit) data" },
716 { 0x03, "Reserved" },
720 static const value_string vals_dcs_class[] = {
722 { 0x01, "Class 1 - ME specific" },
723 { 0x02, "Class 2 - (U)SIM specific" },
724 { 0x03, "Class 3 - TE specific" },
728 static const value_string vals_dcs_cbs_coding_group[] = {
729 { 0x00, "CBS DCS: Language using the GSM 7-bit default alphabet" },
730 { 0x01, "CBS DCS: Language indication at beginning of message" },
731 { 0x02, "CBS DCS: Language using the GSM 7-bit default alphabet" },
732 { 0x03, "CBS DCS: Reserved" },
733 { 0x04, "CBS DCS: General Data Coding indication - Uncompressed text, no message class" },
734 { 0x05, "CBS DCS: General Data Coding indication - Uncompressed text" },
735 { 0x06, "CBS DCS: General Data Coding indication - Compressed text, no message class" },
736 { 0x07, "CBS DCS: General Data Coding indication - Compressed text" },
737 { 0x08, "CBS DCS: Reserved" },
738 { 0x09, "CBS DCS: Message with User Data Header structure" },
739 { 0x0A, "CBS DCS: Reserved" },
740 { 0x0B, "CBS DCS: Reserved" },
741 { 0x0C, "CBS DCS: Reserved" },
742 { 0x0D, "CBS DCS: Reserved" },
743 { 0x0E, "CBS DCS: Defined by the WAP Forum" },
744 { 0x0F, "SMS DCS: Data coding / message class" },
748 static const value_string vals_dcs_cbs_language[] = {
757 { 0x08, "Portuguese" },
759 { 0x0A, "Norwegian" },
762 { 0x0D, "Hungarian" },
764 { 0x0F, "Language not specified" },
765 { 0x10, "GSM 7-bit default alphabet - message preceeded by language indication" },
766 { 0x11, "UCS-2 (16-bit) - message preceeded by language indication" },
771 { 0x24, "Icelandic" },
775 static const value_string vals_dcs_cbs_class[] = {
776 { 0x00, "No message class" },
777 { 0x01, "Class 1 - User defined" },
778 { 0x02, "Class 2 - User defined" },
779 { 0x03, "Class 3 - TE specific" },
783 static const value_string vals_dcs_wap_class[] = {
784 { 0x00, "No message class" },
785 { 0x01, "Class 1 - ME specific" },
786 { 0x02, "Class 2 - (U)SIM specific" },
787 { 0x03, "Class 3 - TE specific" },
791 static const value_string vals_dcs_wap_charset[] = {
792 { 0x00, "Reserved" },
793 { 0x01, "8-bit data" },
794 { 0x02, "Reserved" },
795 { 0x03, "Reserved" },
800 /* 3GPP TS 23.040 V6.1.0 (2003-06) */
801 static const value_string vals_udh_iei[] = {
802 { 0x00, "SMS - Concatenated short messages, 8-bit reference number" },
803 { 0x01, "SMS - Special SMS Message Indication" },
804 { 0x02, "Reserved" },
805 { 0x03, "Value not used to avoid misinterpretation as <LF> character" },
806 { 0x04, "SMS - Application port addressing scheme, 8 bit address" },
807 { 0x05, "SMS - Application port addressing scheme, 16 bit address" },
808 { 0x06, "SMS - SMSC Control Parameters" },
809 { 0x07, "SMS - UDH Source Indicator" },
810 { 0x08, "SMS - Concatenated short message, 16-bit reference number" },
811 { 0x09, "SMS - Wireless Control Message Protocol" },
812 { 0x0A, "EMS - Text Formatting" },
813 { 0x0B, "EMS - Predefined Sound" },
814 { 0x0C, "EMS - User Defined Sound (iMelody max 128 bytes)" },
815 { 0x0D, "EMS - Predefined Animation" },
816 { 0x0E, "EMS - Large Animation (16*16 times 4 = 32*4 =128 bytes)" },
817 { 0x0F, "EMS - Small Animation (8*8 times 4 = 8*4 =32 bytes)" },
818 { 0x10, "EMS - Large Picture (32*32 = 128 bytes)" },
819 { 0x11, "EMS - Small Picture (16*16 = 32 bytes)" },
820 { 0x12, "EMS - Variable Picture" },
821 { 0x13, "EMS - User prompt indicator" },
822 { 0x14, "EMS - Extended Object" },
823 { 0x15, "EMS - Reused Extended Object" },
824 { 0x16, "EMS - Compression Control" },
825 { 0x17, "EMS - Object Distribution Indicator" },
826 { 0x18, "EMS - Standard WVG object" },
827 { 0x19, "EMS - Character Size WVG object" },
828 { 0x1A, "EMS - Extended Object Data Request Command" },
829 { 0x20, "SMS - RFC 822 E-Mail Header" },
830 { 0x21, "SMS - Hyperlink format element" },
831 { 0x22, "SMS - Reply Address Element" },
836 * SMPP equivalent of mktime() (3). Convert date to standard 'time_t' format
838 * \param datestr The SMPP-formatted date to convert
839 * \param secs Returns the 'time_t' equivalent
840 * \param nsecs Returns the additional nano-seconds
842 * \return Whether time is specified relative or absolute
843 * \retval TRUE Relative time
844 * \retval FALSE Absolute time
847 smpp_mktime(const char *datestr, time_t *secs, int *nsecs)
851 gboolean relative = FALSE;
853 r_time.tm_year = 10 * (datestr[0] - '0') + (datestr[1] - '0');
855 * Y2K rollover date as recommended in appendix C
857 if (r_time.tm_year < 38)
858 r_time.tm_year += 100;
859 r_time.tm_mon = 10 * (datestr[2] - '0') + (datestr[3] - '0');
861 r_time.tm_mday = 10 * (datestr[4] - '0') + (datestr[5] - '0');
862 r_time.tm_hour = 10 * (datestr[6] - '0') + (datestr[7] - '0');
863 r_time.tm_min = 10 * (datestr[8] - '0') + (datestr[9] - '0');
864 r_time.tm_sec = 10 * (datestr[10] - '0') + (datestr[11] - '0');
865 r_time.tm_isdst = -1;
866 *secs = mktime(&r_time);
867 *nsecs = (datestr[12] - '0') * 100000000;
868 t_diff = (10 * (datestr[13] - '0') + (datestr[14] - '0')) * 900;
869 if (datestr[15] == '+')
871 else if (datestr[15] == '-')
873 else /* Must be relative ('R') */
879 * Scanning routines to add standard types (byte, int, string...) to the
882 * \param tree The protocol tree to add to
883 * \param tvb Buffer containing the data
884 * \param field Actual field whose value needs displaying
885 * \param offset Location of field in buffer, returns location of
889 smpp_handle_string(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
893 len = tvb_strsize(tvb, *offset);
895 proto_tree_add_string(tree, field, tvb, *offset, len,
896 tvb_get_ptr(tvb, *offset, len));
902 smpp_handle_string_z(proto_tree *tree, tvbuff_t *tvb, int field, int *offset,
903 const char *null_string)
907 len = tvb_strsize(tvb, *offset);
909 proto_tree_add_string(tree, field, tvb, *offset, len,
910 tvb_get_ptr(tvb, *offset, len));
912 proto_tree_add_string(tree, field, tvb, *offset, len, null_string);
918 smpp_handle_int1(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
922 val = tvb_get_guint8(tvb, *offset);
923 proto_tree_add_uint(tree, field, tvb, *offset, 1, val);
928 smpp_handle_int2(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
932 val = tvb_get_ntohs(tvb, *offset);
933 proto_tree_add_uint(tree, field, tvb, *offset, 2, val);
938 smpp_handle_int4(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
942 val = tvb_get_ntohl(tvb, *offset);
943 proto_tree_add_uint(tree, field, tvb, *offset, 4, val);
948 smpp_handle_time(proto_tree *tree, tvbuff_t *tvb,
949 int field, int field_R, int *offset)
955 strval = tvb_get_stringz(tvb, *offset, &len);
958 if (smpp_mktime(strval, &tmptime.secs, &tmptime.nsecs))
959 proto_tree_add_time(tree, field_R, tvb, *offset, len, &tmptime);
961 proto_tree_add_time(tree, field, tvb, *offset, len, &tmptime);
968 * Scanning routine to handle the destination-list of 'submit_multi'
970 * \param tree The protocol tree to add to
971 * \param tvb Buffer containing the data
972 * \param offset Location of field in buffer, returns location of
976 smpp_handle_dlist(proto_tree *tree, tvbuff_t *tvb, int *offset)
979 int tmpoff = *offset;
980 proto_item *sub_tree = NULL;
983 if ((entries = tvb_get_guint8(tvb, tmpoff++)))
985 sub_tree = proto_tree_add_item(tree, hf_smpp_dlist,
986 tvb, *offset, 1, FALSE);
987 proto_item_add_subtree(sub_tree, ett_dlist);
991 dest_flag = tvb_get_guint8(tvb, tmpoff++);
992 if (dest_flag == 1) /* SME address */
994 smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_ton, &tmpoff);
995 smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_npi, &tmpoff);
996 smpp_handle_string(sub_tree,tvb,hf_smpp_destination_addr,&tmpoff);
998 else /* Distribution list */
1000 smpp_handle_string(sub_tree, tvb, hf_smpp_dl_name, &tmpoff);
1007 * Scanning routine to handle the destination result list
1008 * of 'submit_multi_resp'
1010 * \param tree The protocol tree to add to
1011 * \param tvb Buffer containing the data
1012 * \param offset Location of field in buffer, returns location of
1016 smpp_handle_dlist_resp(proto_tree *tree, tvbuff_t *tvb, int *offset)
1019 int tmpoff = *offset;
1020 proto_item *sub_tree = NULL;
1022 if ((entries = tvb_get_guint8(tvb, tmpoff++)))
1024 sub_tree = proto_tree_add_item(tree, hf_smpp_dlist_resp,
1025 tvb, *offset, 1, FALSE);
1026 proto_item_add_subtree(sub_tree, ett_dlist_resp);
1030 smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_ton, &tmpoff);
1031 smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_npi, &tmpoff);
1032 smpp_handle_string(sub_tree,tvb,hf_smpp_destination_addr,&tmpoff);
1033 smpp_handle_int4(sub_tree, tvb, hf_smpp_error_status_code, &tmpoff);
1039 * Scanning routine to handle all optional parameters of SMPP-operations.
1040 * The parameters have the format Tag Length Value (TLV), with a 2-byte tag
1041 * and 2-byte length.
1043 * \param tree The protocol tree to add to
1044 * \param tvb Buffer containing the data
1045 * \param offset Location of field in buffer, returns location of
1049 smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
1051 proto_item *sub_tree = NULL;
1055 guint8 major, minor;
1056 char strval[BUFSIZ];
1058 if (tvb_reported_length_remaining(tvb, *offset) >= 4)
1060 sub_tree = proto_tree_add_item(tree, hf_smpp_opt_param,
1061 tvb, *offset, 0, FALSE);
1062 proto_item_add_subtree(sub_tree, ett_opt_param);
1065 while (tvb_reported_length_remaining(tvb, *offset) >= 4)
1067 tag = tvb_get_ntohs(tvb, *offset);
1069 length = tvb_get_ntohs(tvb, *offset);
1072 case 0x0005: /* dest_addr_subunit */
1073 smpp_handle_int1(sub_tree, tvb,
1074 hf_smpp_dest_addr_subunit, offset);
1076 case 0x0006: /* dest_network_type */
1077 smpp_handle_int1(sub_tree, tvb,
1078 hf_smpp_dest_network_type, offset);
1080 case 0x0007: /* dest_bearer_type */
1081 smpp_handle_int1(sub_tree, tvb,
1082 hf_smpp_dest_bearer_type, offset);
1084 case 0x0008: /* dest_telematics_id */
1085 smpp_handle_int2(sub_tree, tvb,
1086 hf_smpp_dest_telematics_id, offset);
1088 case 0x000D: /* source_addr_subunit */
1089 smpp_handle_int1(sub_tree, tvb,
1090 hf_smpp_source_addr_subunit, offset);
1092 case 0x000E: /* source_network_type */
1093 smpp_handle_int1(sub_tree, tvb,
1094 hf_smpp_source_network_type, offset);
1096 case 0x000F: /* source_bearer_type */
1097 smpp_handle_int1(sub_tree, tvb,
1098 hf_smpp_source_bearer_type, offset);
1100 case 0x0010: /* source_telematics_id */
1101 smpp_handle_int2(sub_tree, tvb,
1102 hf_smpp_source_telematics_id, offset);
1104 case 0x0017: /* qos_time_to_live */
1105 smpp_handle_int4(sub_tree, tvb,
1106 hf_smpp_qos_time_to_live, offset);
1108 case 0x0019: /* payload_type */
1109 smpp_handle_int1(sub_tree, tvb,
1110 hf_smpp_payload_type, offset);
1112 case 0x001D: /* additional_status_info_text */
1113 smpp_handle_string(sub_tree, tvb,
1114 hf_smpp_additional_status_info_text, offset);
1116 case 0x001E: /* receipted_message_id */
1117 smpp_handle_string(sub_tree, tvb,
1118 hf_smpp_receipted_message_id, offset);
1120 case 0x0030: /* ms_msg_wait_facilities */
1121 field = tvb_get_guint8(tvb, *offset);
1122 proto_tree_add_item(sub_tree, hf_smpp_msg_wait_ind,
1123 tvb, *offset, 1, field);
1124 proto_tree_add_item(sub_tree, hf_smpp_msg_wait_type,
1125 tvb, *offset, 1, field);
1128 case 0x0201: /* privacy_indicator */
1129 smpp_handle_int1(sub_tree, tvb,
1130 hf_smpp_privacy_indicator, offset);
1132 case 0x0202: /* source_subaddress */
1133 smpp_handle_string(sub_tree, tvb,
1134 hf_smpp_source_subaddress, offset);
1136 case 0x0203: /* dest_subaddress */
1137 smpp_handle_string(sub_tree, tvb,
1138 hf_smpp_dest_subaddress, offset);
1140 case 0x0204: /* user_message_reference */
1141 smpp_handle_int2(sub_tree, tvb,
1142 hf_smpp_user_message_reference, offset);
1144 case 0x0205: /* user_response_code */
1145 smpp_handle_int1(sub_tree, tvb,
1146 hf_smpp_user_response_code, offset);
1148 case 0x020A: /* source_port */
1149 smpp_handle_int2(sub_tree, tvb,
1150 hf_smpp_source_port, offset);
1152 case 0x020B: /* destination_port */
1153 smpp_handle_int2(sub_tree, tvb,
1154 hf_smpp_destination_port, offset);
1156 case 0x020C: /* sar_msg_ref_num */
1157 smpp_handle_int2(sub_tree, tvb,
1158 hf_smpp_sar_msg_ref_num, offset);
1160 case 0x020D: /* language_indicator */
1161 smpp_handle_int1(sub_tree, tvb,
1162 hf_smpp_language_indicator, offset);
1164 case 0x020E: /* sar_total_segments */
1165 smpp_handle_int1(sub_tree, tvb,
1166 hf_smpp_sar_total_segments, offset);
1168 case 0x020F: /* sar_segment_seqnum */
1169 smpp_handle_int1(sub_tree, tvb,
1170 hf_smpp_sar_segment_seqnum, offset);
1172 case 0x0210: /* SC_interface_version */
1173 field = tvb_get_guint8(tvb, *offset);
1174 minor = field & 0x0F;
1175 major = (field & 0xF0) >> 4;
1176 sprintf(strval, "%u.%u", major, minor);
1177 proto_tree_add_string(sub_tree, hf_smpp_SC_interface_version,
1178 tvb, *offset, 1, strval);
1181 case 0x0302: /* callback_num_pres_ind */
1182 field = tvb_get_guint8(tvb, *offset);
1183 proto_tree_add_item(sub_tree, hf_smpp_callback_num_pres,
1184 tvb, *offset, 1, field);
1185 proto_tree_add_item(sub_tree, hf_smpp_callback_num_scrn,
1186 tvb, *offset, 1, field);
1189 case 0x0303: /* callback_num_atag */
1191 proto_tree_add_item(sub_tree, hf_smpp_callback_num_atag,
1192 tvb, *offset, length, FALSE);
1193 (*offset) += length;
1195 case 0x0304: /* number_of_messages */
1196 smpp_handle_int1(sub_tree, tvb,
1197 hf_smpp_number_of_messages, offset);
1199 case 0x0381: /* callback_num */
1201 proto_tree_add_item(sub_tree, hf_smpp_callback_num,
1202 tvb, *offset, length, FALSE);
1203 (*offset) += length;
1205 case 0x0420: /* dpf_result */
1206 smpp_handle_int1(sub_tree, tvb,
1207 hf_smpp_dpf_result, offset);
1209 case 0x0421: /* set_dpf */
1210 smpp_handle_int1(sub_tree, tvb,
1211 hf_smpp_set_dpf, offset);
1213 case 0x0422: /* ms_availability_status */
1214 smpp_handle_int1(sub_tree, tvb,
1215 hf_smpp_ms_availability_status, offset);
1217 case 0x0423: /* network_error_code */
1218 smpp_handle_int1(sub_tree, tvb,
1219 hf_smpp_network_error_type, offset);
1220 smpp_handle_int2(sub_tree, tvb,
1221 hf_smpp_network_error_code, offset);
1222 (*offset) += length;
1224 case 0x0424: /* message_payload */
1226 proto_tree_add_item(sub_tree, hf_smpp_message_payload,
1227 tvb, *offset, length, FALSE);
1228 (*offset) += length;
1230 case 0x0425: /* delivery_failure_reason */
1231 smpp_handle_int1(sub_tree, tvb,
1232 hf_smpp_delivery_failure_reason, offset);
1234 case 0x0426: /* more_messages_to_send */
1235 smpp_handle_int1(sub_tree, tvb,
1236 hf_smpp_more_messages_to_send, offset);
1238 case 0x0427: /* message_state */
1239 smpp_handle_int1(sub_tree, tvb,
1240 hf_smpp_message_state, offset);
1242 case 0x0501: /* ussd_service_op */
1243 smpp_handle_int1(sub_tree, tvb,
1244 hf_smpp_ussd_service_op, offset);
1246 case 0x1201: /* display_time */
1247 smpp_handle_int1(sub_tree, tvb,
1248 hf_smpp_display_time, offset);
1250 case 0x1203: /* sms_signal */
1251 smpp_handle_int2(sub_tree, tvb,
1252 hf_smpp_sms_signal, offset);
1253 /*! \todo Fill as per TIA/EIA-136-710-A */
1255 case 0x1204: /* ms_validity */
1256 smpp_handle_int1(sub_tree, tvb,
1257 hf_smpp_ms_validity, offset);
1259 case 0x130C: /* alert_on_message_delivery */
1260 proto_tree_add_item(sub_tree,
1261 hf_smpp_alert_on_message_delivery,
1262 tvb, *offset, length, FALSE);
1263 (*offset) += length;
1265 case 0x1380: /* its_reply_type */
1266 smpp_handle_int1(sub_tree, tvb,
1267 hf_smpp_its_reply_type, offset);
1269 case 0x1383: /* its_session_info */
1270 smpp_handle_int1(sub_tree, tvb,
1271 hf_smpp_its_session_number, offset);
1272 field = tvb_get_guint8(tvb, *offset);
1273 proto_tree_add_item(sub_tree, hf_smpp_its_session_sequence,
1274 tvb, *offset, 1, field);
1275 proto_tree_add_item(sub_tree, hf_smpp_its_session_ind,
1276 tvb, *offset, 1, field);
1280 if ((tag >= 0x1400) && (tag <= 0x3FFF))
1281 proto_tree_add_item(sub_tree, hf_smpp_vendor_op, tvb,
1282 *offset, length, FALSE);
1284 proto_tree_add_item(sub_tree, hf_smpp_reserved_op, tvb,
1285 *offset, length, FALSE);
1286 (*offset) += length;
1293 smpp_handle_dcs(proto_tree *tree, tvbuff_t *tvb, int *offset)
1297 proto_item *subtree = NULL;
1299 val = tvb_get_guint8(tvb, off);
1300 subtree = proto_tree_add_uint(tree,
1301 hf_smpp_data_coding, tvb, off, 1, val);
1302 proto_item_add_subtree(subtree, ett_dcs);
1303 /* SMPP Data Coding Scheme */
1304 proto_tree_add_uint(subtree, hf_smpp_dcs, tvb, off, 1, val);
1305 /* GSM SMS Data Coding Scheme */
1306 proto_tree_add_text(subtree, tvb, off, 1,
1307 "GSM SMS Data Coding");
1308 proto_tree_add_uint(subtree,
1309 hf_smpp_dcs_sms_coding_group, tvb, off, 1, val);
1310 if (val>>6 == 2) { /* Reserved */
1312 } else if (val < 0xF0) {
1313 proto_tree_add_boolean(subtree,
1314 hf_smpp_dcs_text_compression, tvb, off, 1, val);
1315 proto_tree_add_boolean(subtree,
1316 hf_smpp_dcs_class_present, tvb, off, 1, val);
1317 proto_tree_add_uint(subtree,
1318 hf_smpp_dcs_charset, tvb, off, 1, val);
1320 proto_tree_add_uint(subtree,
1321 hf_smpp_dcs_class, tvb, off, 1, val);
1324 proto_tree_add_text(subtree, tvb, off, 1,
1325 "SMPP: Bit .... 1... should be 0 (reserved)");
1326 proto_tree_add_uint(subtree,
1327 hf_smpp_dcs_charset, tvb, off, 1, val);
1328 proto_tree_add_uint(subtree,
1329 hf_smpp_dcs_class, tvb, off, 1, val);
1331 /* Cell Broadcast Service (CBS) Data Coding Scheme */
1332 proto_tree_add_text(subtree, tvb, off, 1,
1333 "GSM CBS Data Coding");
1334 proto_tree_add_uint(subtree,
1335 hf_smpp_dcs_cbs_coding_group, tvb, off, 1, val);
1336 if (val < 0x40) { /* Language specified */
1337 proto_tree_add_uint(subtree,
1338 hf_smpp_dcs_cbs_language, tvb, off, 1, val);
1339 } else if (val>>6 == 1) { /* General Data Coding indication */
1340 proto_tree_add_boolean(subtree,
1341 hf_smpp_dcs_text_compression, tvb, off, 1, val);
1342 proto_tree_add_boolean(subtree,
1343 hf_smpp_dcs_class_present, tvb, off, 1, val);
1344 proto_tree_add_uint(subtree,
1345 hf_smpp_dcs_charset, tvb, off, 1, val);
1347 proto_tree_add_uint(subtree,
1348 hf_smpp_dcs_class, tvb, off, 1, val);
1349 } else if (val>>6 == 2) { /* Message with UDH structure */
1350 proto_tree_add_uint(subtree,
1351 hf_smpp_dcs_charset, tvb, off, 1, val);
1352 proto_tree_add_uint(subtree,
1353 hf_smpp_dcs_class, tvb, off, 1, val);
1354 } else if (val>>4 == 14) { /* WAP Forum */
1355 proto_tree_add_uint(subtree,
1356 hf_smpp_dcs_wap_charset, tvb, off, 1, val);
1357 proto_tree_add_uint(subtree,
1358 hf_smpp_dcs_wap_class, tvb, off, 1, val);
1359 } else if (val>>4 == 15) { /* Data coding / message handling */
1361 proto_tree_add_text(subtree, tvb, off, 1,
1362 "SMPP: Bit .... 1... should be 0 (reserved)");
1363 proto_tree_add_uint(subtree,
1364 hf_smpp_dcs_charset, tvb, off, 1, val);
1365 proto_tree_add_uint(subtree,
1366 hf_smpp_dcs_cbs_class, tvb, off, 1, val);
1373 * The next set of routines handle the different operations, associated
1377 bind_receiver(proto_tree *tree, tvbuff_t *tvb)
1381 guint8 major, minor;
1382 char strval[BUFSIZ];
1384 smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
1385 smpp_handle_string(tree, tvb, hf_smpp_password, &offset);
1386 smpp_handle_string(tree, tvb, hf_smpp_system_type, &offset);
1387 field = tvb_get_guint8(tvb, offset++);
1388 minor = field & 0x0F;
1389 major = (field & 0xF0) >> 4;
1390 sprintf(strval, "%u.%u", major, minor);
1391 proto_tree_add_string(tree, hf_smpp_interface_version, tvb,
1392 offset - 1, 1, strval);
1393 smpp_handle_int1(tree, tvb, hf_smpp_addr_ton, &offset);
1394 smpp_handle_int1(tree, tvb, hf_smpp_addr_npi, &offset);
1395 smpp_handle_string(tree, tvb, hf_smpp_address_range, &offset);
1398 #define bind_transmitter(a, b) bind_receiver(a, b)
1401 query_sm(proto_tree *tree, tvbuff_t *tvb)
1405 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1406 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1407 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1408 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1411 #define bind_transceiver(a, b) bind_receiver(a, b)
1414 outbind(proto_tree *tree, tvbuff_t *tvb)
1418 smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
1419 smpp_handle_string(tree, tvb, hf_smpp_password, &offset);
1422 /* Parse Short Message, only if UDH present
1423 * (otherwise this function is not called).
1424 * Call WSP dissector if port matches WSP traffic.
1427 parse_sm_message(proto_tree *sm_tree, tvbuff_t *tvb, packet_info *pinfo)
1429 tvbuff_t *sm_tvb = NULL;
1430 proto_item *subtree, *tree;
1431 guint8 udh_len, udh, len;
1432 guint8 sm_len = tvb_reported_length (tvb);
1435 /* Multiple Messages UDH */
1436 fragment_data *fd_sm = NULL;
1437 guint16 sm_id = 0, frags = 0, frag = 0;
1438 gboolean save_fragmented = FALSE, try_sm_reassemble = FALSE;
1439 /* Port Number UDH */
1440 guint16 p_src = 0, p_dst = 0;
1441 gboolean ports_available = FALSE;
1443 udh_len = tvb_get_guint8(tvb, i++);
1444 tree = proto_tree_add_uint(sm_tree, hf_smpp_udh_length, tvb, 0, 1, udh_len);
1445 tree = proto_item_add_subtree(tree, ett_udh);
1446 sm_data_len = sm_len - (1 + udh_len);
1447 while (i < udh_len) {
1448 udh = tvb_get_guint8(tvb, i++);
1449 len = tvb_get_guint8(tvb, i++);
1450 subtree = proto_tree_add_uint(tree, hf_smpp_udh_iei,
1451 tvb, i-2, 2+len, udh);
1453 case 0x00: /* Multiple messages - 8-bit message ID */
1455 sm_id = tvb_get_guint8(tvb, i++);
1456 frags = tvb_get_guint8(tvb, i++);
1457 frag = tvb_get_guint8(tvb, i++);
1458 proto_item_append_text(subtree,
1459 ": message %u, part %u of %u", sm_id, frag, frags);
1460 subtree = proto_item_add_subtree(subtree,
1461 ett_udh_multiple_messages);
1462 proto_tree_add_uint (subtree,
1463 hf_smpp_udh_multiple_messages_msg_id,
1464 tvb, i-3, 1, sm_id);
1465 proto_tree_add_uint (subtree,
1466 hf_smpp_udh_multiple_messages_msg_parts,
1467 tvb, i-2, 1, frags);
1468 proto_tree_add_uint (subtree,
1469 hf_smpp_udh_multiple_messages_msg_part,
1472 proto_item_append_text(subtree, " - Invalid format!");
1477 case 0x08: /* Multiple messages - 16-bit message ID */
1479 sm_id = tvb_get_ntohs(tvb, i); i += 2;
1480 frags = tvb_get_guint8(tvb, i++);
1481 frag = tvb_get_guint8(tvb, i++);
1482 proto_item_append_text(subtree,
1483 ": message %u, part %u of %u", sm_id, frag, frags);
1484 subtree = proto_item_add_subtree(subtree,
1485 ett_udh_multiple_messages);
1486 proto_tree_add_uint (subtree,
1487 hf_smpp_udh_multiple_messages_msg_id,
1488 tvb, i-4, 2, sm_id);
1489 proto_tree_add_uint (subtree,
1490 hf_smpp_udh_multiple_messages_msg_parts,
1491 tvb, i-2, 1, frags);
1492 proto_tree_add_uint (subtree,
1493 hf_smpp_udh_multiple_messages_msg_part,
1496 proto_item_append_text(subtree, " - Invalid format!");
1501 case 0x04: /* Port Number UDH - 8-bit address */
1502 if (len == 2) { /* Port fields */
1503 p_dst = tvb_get_guint8(tvb, i++);
1504 p_src = tvb_get_guint8(tvb, i++);
1505 proto_item_append_text(subtree,
1506 ": source port %u, destination port %u",
1508 subtree = proto_item_add_subtree(subtree, ett_udh_ports);
1509 proto_tree_add_uint (subtree, hf_smpp_udh_ports_dst,
1510 tvb, i-2, 1, p_dst);
1511 proto_tree_add_uint (subtree, hf_smpp_udh_ports_src,
1512 tvb, i-1, 1, p_src);
1513 ports_available = TRUE;
1515 proto_item_append_text(subtree, " - Invalid format!");
1520 case 0x05: /* Port Number UDH - 16-bit address */
1521 if (len == 4) { /* Port fields */
1522 p_dst = tvb_get_ntohs(tvb, i); i += 2;
1523 p_src = tvb_get_ntohs(tvb, i); i += 2;
1524 proto_item_append_text(subtree,
1525 ": source port %u, destination port %u",
1527 subtree = proto_item_add_subtree(subtree, ett_udh_ports);
1528 proto_tree_add_uint (subtree, hf_smpp_udh_ports_dst,
1529 tvb, i-4, 2, p_dst);
1530 proto_tree_add_uint (subtree, hf_smpp_udh_ports_src,
1531 tvb, i-2, 2, p_src);
1532 ports_available = TRUE;
1534 proto_item_append_text(subtree, " - Invalid format!");
1544 if (tvb_reported_length_remaining(tvb, i) <= 0)
1545 return; /* No more data */
1547 /* Try reassembling the packets */
1548 if ( frags && tvb_bytes_exist (tvb, i, sm_data_len) ) {
1549 try_sm_reassemble = TRUE;
1550 save_fragmented = pinfo->fragmented;
1551 pinfo->fragmented = TRUE;
1552 fd_sm = fragment_add_seq_check (tvb, i, pinfo,
1553 sm_id, /* guint32 ID for fragments belonging together */
1554 sm_fragment_table, /* list of message fragments */
1555 sm_reassembled_table, /* list of reassembled messages */
1556 frag-1, /* guint32 fragment sequence number */
1557 sm_data_len, /* guint32 fragment length */
1558 (frag != frags)); /* More fragments? */
1559 if (fd_sm) { /* Reassembled */
1560 sm_tvb = tvb_new_real_data (fd_sm->data, fd_sm->len, fd_sm->len);
1561 tvb_set_child_real_data_tvbuff (tvb, sm_tvb);
1562 add_new_data_source (pinfo, sm_tvb, "Reassembled Short Message");
1563 pinfo->fragmented = FALSE;
1564 /* Show all fragments */
1565 show_fragment_seq_tree (fd_sm, &sm_frag_items,
1566 sm_tree, pinfo, sm_tvb);
1568 if (check_col (pinfo->cinfo, COL_INFO))
1569 col_append_str (pinfo->cinfo, COL_INFO,
1570 " (Short Message unreassembled)");
1574 if (! sm_tvb) /* One single Short Message, or not reassembled */
1575 sm_tvb = tvb_new_subset (tvb, i, -1, -1);
1576 /* Try calling a subdissector */
1578 if (fd_sm || frag==0 || (frag==1 && try_dissect_1st_frag)) {
1579 /* Try calling a subdissector only if:
1580 * - the Short Message is reassembled,
1581 * - the Short Message consists of only one "fragment",
1582 * - the preference "Always Try Dissection for 1st SM fragment"
1583 * is switched on, and this is the SM's 1st fragment. */
1584 if ( ports_available ) {
1585 if ( port_number_udh_means_wsp ) {
1586 call_dissector (wsp_handle, sm_tvb, pinfo, sm_tree);
1588 if (! dissector_try_port(smpp_dissector_table, p_src,
1589 sm_tvb, pinfo, sm_tree)) {
1590 if (! dissector_try_port(smpp_dissector_table, p_dst,
1591 sm_tvb, pinfo, sm_tree)) {
1592 if (sm_tree) { /* Only display if needed */
1593 proto_tree_add_text (sm_tree, sm_tvb, 0, -1,
1594 "Short Message body");
1599 } else { /* No ports IE */
1600 proto_tree_add_text (sm_tree, sm_tvb, 0, -1,
1601 "Short Message body");
1603 } else { /* Not 1st fragment and not reassembled */
1604 proto_tree_add_text (sm_tree, sm_tvb, 0, -1,
1605 "Unreassembled Short Message fragment %u of %u",
1610 if (try_sm_reassemble) /* Clean up defragmentation */
1611 pinfo->fragmented = save_fragmented;
1616 submit_sm(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo)
1623 smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1624 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1625 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1626 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1627 smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
1628 smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
1629 smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
1630 flag = tvb_get_guint8(tvb, offset);
1632 proto_tree_add_item(tree, hf_smpp_esm_submit_msg_mode,
1633 tvb, offset, 1, flag);
1634 proto_tree_add_item(tree, hf_smpp_esm_submit_msg_type,
1635 tvb, offset, 1, flag);
1636 proto_tree_add_item(tree, hf_smpp_esm_submit_features,
1637 tvb, offset, 1, flag);
1639 smpp_handle_int1(tree, tvb, hf_smpp_protocol_id, &offset);
1640 smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
1641 if (tvb_get_guint8(tvb,offset)) {
1642 smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
1643 hf_smpp_schedule_delivery_time_r, &offset);
1644 } else { /* Time = NULL means Immediate delivery */
1645 proto_tree_add_text(tree, tvb, offset++, 1,
1646 "Scheduled delivery time: Immediate delivery");
1648 if (tvb_get_guint8(tvb,offset)) {
1649 smpp_handle_time(tree, tvb, hf_smpp_validity_period,
1650 hf_smpp_validity_period_r, &offset);
1651 } else { /* Time = NULL means SMSC default validity */
1652 proto_tree_add_text(tree, tvb, offset++, 1,
1653 "Validity period: SMSC default validity period");
1655 flag = tvb_get_guint8(tvb, offset);
1656 proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1657 proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1658 proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1660 smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
1661 smpp_handle_dcs(tree, tvb, &offset);
1662 smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
1663 length = tvb_get_guint8(tvb, offset);
1664 proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
1667 proto_tree_add_item(tree, hf_smpp_short_message,
1668 tvb, offset, length, FALSE);
1669 if (udhi) /* UDHI indicator present */
1671 tvb_msg = tvb_new_subset (tvb, offset,
1672 MIN(length, tvb_reported_length(tvb) - offset), length);
1673 parse_sm_message(tree, tvb_msg, pinfo);
1677 smpp_handle_tlv(tree, tvb, &offset);
1680 #define deliver_sm(a, b, c) submit_sm(a, b, c)
1683 replace_sm(proto_tree *tree, tvbuff_t *tvb)
1689 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1690 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1691 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1692 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1693 if (tvb_get_guint8(tvb,offset)) {
1694 smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
1695 hf_smpp_schedule_delivery_time_r, &offset);
1696 } else { /* Time = NULL */
1697 proto_tree_add_text(tree, tvb, offset++, 1,
1698 "Scheduled delivery time: Keep initial delivery time setting");
1700 if (tvb_get_guint8(tvb,offset)) {
1701 smpp_handle_time(tree, tvb, hf_smpp_validity_period,
1702 hf_smpp_validity_period_r, &offset);
1703 } else { /* Time = NULL */
1704 proto_tree_add_text(tree, tvb, offset++, 1,
1705 "Validity period: Keep initial validity period setting");
1707 flag = tvb_get_guint8(tvb, offset);
1708 proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1709 proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1710 proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1712 smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
1713 length = tvb_get_guint8(tvb, offset);
1714 proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
1716 proto_tree_add_item(tree, hf_smpp_short_message,
1717 tvb, offset, length, FALSE);
1722 cancel_sm(proto_tree *tree, tvbuff_t *tvb)
1726 smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1727 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1728 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1729 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1730 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1731 smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
1732 smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
1733 smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
1737 submit_multi(proto_tree *tree, tvbuff_t *tvb)
1743 smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1744 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1745 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1746 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1748 smpp_handle_dlist(tree, tvb, &offset);
1750 flag = tvb_get_guint8(tvb, offset);
1751 proto_tree_add_item(tree, hf_smpp_esm_submit_msg_mode,
1752 tvb, offset, 1, flag);
1753 proto_tree_add_item(tree, hf_smpp_esm_submit_msg_type,
1754 tvb, offset, 1, flag);
1755 proto_tree_add_item(tree, hf_smpp_esm_submit_features,
1756 tvb, offset, 1, flag);
1758 smpp_handle_int1(tree, tvb, hf_smpp_protocol_id, &offset);
1759 smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
1760 if (tvb_get_guint8(tvb,offset)) {
1761 smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
1762 hf_smpp_schedule_delivery_time_r, &offset);
1763 } else { /* Time = NULL means Immediate delivery */
1764 proto_tree_add_text(tree, tvb, offset++, 1,
1765 "Scheduled delivery time: Immediate delivery");
1767 if (tvb_get_guint8(tvb,offset)) {
1768 smpp_handle_time(tree, tvb, hf_smpp_validity_period,
1769 hf_smpp_validity_period_r, &offset);
1770 } else { /* Time = NULL means SMSC default validity */
1771 proto_tree_add_text(tree, tvb, offset++, 1,
1772 "Validity period: SMSC default validity period");
1774 flag = tvb_get_guint8(tvb, offset);
1775 proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1776 proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1777 proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1779 smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
1780 smpp_handle_dcs(tree, tvb, &offset);
1781 smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
1782 length = tvb_get_guint8(tvb, offset);
1783 proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
1785 proto_tree_add_item(tree, hf_smpp_short_message,
1786 tvb, offset, length, FALSE);
1788 smpp_handle_tlv(tree, tvb, &offset);
1792 alert_notification(proto_tree *tree, tvbuff_t *tvb)
1796 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1797 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1798 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1799 smpp_handle_int1(tree, tvb, hf_smpp_esme_addr_ton, &offset);
1800 smpp_handle_int1(tree, tvb, hf_smpp_esme_addr_npi, &offset);
1801 smpp_handle_string(tree, tvb, hf_smpp_esme_addr, &offset);
1802 smpp_handle_tlv(tree, tvb, &offset);
1806 data_sm(proto_tree *tree, tvbuff_t *tvb)
1811 smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1812 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1813 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1814 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1815 smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
1816 smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
1817 smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
1818 flag = tvb_get_guint8(tvb, offset);
1819 proto_tree_add_item(tree, hf_smpp_esm_submit_msg_mode,
1820 tvb, offset, 1, flag);
1821 proto_tree_add_item(tree, hf_smpp_esm_submit_msg_type,
1822 tvb, offset, 1, flag);
1823 proto_tree_add_item(tree, hf_smpp_esm_submit_features,
1824 tvb, offset, 1, flag);
1826 flag = tvb_get_guint8(tvb, offset);
1827 proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1828 proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1829 proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1831 smpp_handle_dcs(tree, tvb, &offset);
1832 smpp_handle_tlv(tree, tvb, &offset);
1836 * The next set of routines handle the different operation-responses,
1837 * associated with SMPP.
1840 bind_receiver_resp(proto_tree *tree, tvbuff_t *tvb)
1844 smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
1845 smpp_handle_tlv(tree, tvb, &offset);
1848 #define bind_transmitter_resp(a, b) bind_receiver_resp(a, b)
1851 query_sm_resp(proto_tree *tree, tvbuff_t *tvb)
1855 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1856 smpp_handle_time(tree, tvb, hf_smpp_final_date,
1857 hf_smpp_final_date_r, &offset);
1858 smpp_handle_int1(tree, tvb, hf_smpp_message_state, &offset);
1859 smpp_handle_int1(tree, tvb, hf_smpp_error_code, &offset);
1862 #define bind_transceiver_resp(a, b) bind_receiver_resp(a, b)
1865 submit_sm_resp(proto_tree *tree, tvbuff_t *tvb)
1869 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1872 #define deliver_sm_resp(a, b) submit_sm_resp(a, b)
1875 submit_multi_resp(proto_tree *tree, tvbuff_t *tvb)
1879 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1880 smpp_handle_dlist_resp(tree, tvb, &offset);
1884 data_sm_resp(proto_tree *tree, tvbuff_t *tvb)
1888 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1889 smpp_handle_tlv(tree, tvb, &offset);
1893 * A 'heuristic dissector' that attemtps to establish whether we have
1894 * a genuine SMPP PDU here.
1896 * at least the fixed header is there
1897 * it has a correct overall PDU length
1898 * it is a 'well-known' operation
1899 * has a 'well-known' status
1902 dissect_smpp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1904 guint command_id; /* SMPP command */
1905 guint command_status; /* Status code */
1906 guint command_length; /* length of PDU */
1908 if (tvb_reported_length(tvb) < 4 * 4) /* Mandatory header */
1910 command_length = tvb_get_ntohl(tvb, 0);
1911 if (command_length > 64 * 1024)
1913 command_id = tvb_get_ntohl(tvb, 4); /* Only known commands */
1914 if (match_strval(command_id, vals_command_id) == NULL)
1916 command_status = tvb_get_ntohl(tvb, 8); /* ..with known status */
1917 if (match_strval(command_status, vals_command_status) == NULL)
1919 dissect_smpp(tvb, pinfo, tree);
1923 /* Code to actually dissect the packets */
1925 dissect_smpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1927 int offset = 0; /* Offset within tvbuff */
1928 guint command_length; /* length of PDU */
1929 guint command_id; /* SMPP command */
1930 guint command_status; /* Status code */
1931 guint sequence_number; /* ...of command */
1933 /* Set up structures needed to add the protocol subtree and manage it */
1935 proto_tree *smpp_tree;
1939 * Safety: don't even try it when the mandatory header isn't present.
1941 if (tvb_reported_length(tvb) < 4 * 4)
1943 command_length = tvb_get_ntohl(tvb, offset);
1945 command_id = tvb_get_ntohl(tvb, offset);
1947 command_status = tvb_get_ntohl(tvb, offset);
1949 sequence_number = tvb_get_ntohl(tvb, offset);
1951 /* Make entries in Protocol column and Info column on summary display */
1952 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1953 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMPP");
1955 if (check_col(pinfo->cinfo, COL_INFO))
1957 col_clear(pinfo->cinfo, COL_INFO);
1958 col_add_fstr(pinfo->cinfo, COL_INFO, "SMPP %s",
1959 val_to_str(command_id,vals_command_id,"unknown operation"));
1960 if (command_id & 0x80000000)
1961 col_append_fstr(pinfo->cinfo, COL_INFO, ": \"%s\"",
1962 val_to_str(command_status, vals_command_status,
1964 if (command_length > tvb_reported_length(tvb))
1965 col_append_str(pinfo->cinfo, COL_INFO, " [short packet]");
1966 if (command_length < tvb_reported_length(tvb))
1967 col_append_str(pinfo->cinfo, COL_INFO, " [trailing data]");
1970 /* In the interest of speed, if "tree" is NULL, don't do any work not
1971 * necessary to generate protocol tree items.
1975 /* create display subtree for the protocol */
1976 ti = proto_tree_add_item(tree, proto_smpp, tvb, 0,
1977 command_length, FALSE);
1978 smpp_tree = proto_item_add_subtree(ti, ett_smpp);
1980 /* add an item to the subtree */
1981 proto_tree_add_uint(smpp_tree, hf_smpp_command_length, tvb,
1982 0, 4, command_length);
1983 proto_tree_add_uint(smpp_tree, hf_smpp_command_id, tvb,
1985 proto_item_append_text (ti, ", %s",
1986 match_strval (command_id, vals_command_id));
1987 /* Status is only meaningful with responses */
1988 if (command_id & 0x80000000) {
1989 proto_tree_add_uint(smpp_tree, hf_smpp_command_status, tvb,
1990 8, 4, command_status);
1991 proto_item_append_text (ti, ": \"%s\"",
1992 match_strval (command_status, vals_command_status));
1994 proto_tree_add_uint(smpp_tree, hf_smpp_sequence_number, tvb,
1995 12, 4, sequence_number);
1996 proto_item_append_text (ti, ", Seq: %u, Len: %u",
1997 sequence_number, command_length);
1999 * End of header. Don't dissect variable part if it is shortened.
2001 if (command_length > tvb_reported_length(tvb))
2003 tmp_tvb = tvb_new_subset(tvb, offset, -1, command_length - offset);
2004 if (command_id & 0x80000000)
2006 switch (command_id & 0x7FFFFFFF) {
2008 * All of these only have a fixed header
2010 case 0: /* Generic nack */
2011 case 6: /* Unbind resp */
2012 case 7: /* Replace SM resp */
2013 case 8: /* Cancel SM resp */
2014 case 21: /* Enquire link resp */
2017 if (!command_status)
2018 bind_receiver_resp(smpp_tree, tmp_tvb);
2021 if (!command_status)
2022 bind_transmitter_resp(smpp_tree, tmp_tvb);
2025 if (!command_status)
2026 query_sm_resp(smpp_tree, tmp_tvb);
2029 if (!command_status)
2030 submit_sm_resp(smpp_tree, tmp_tvb);
2033 if (!command_status)
2034 deliver_sm_resp(smpp_tree, tmp_tvb);
2037 if (!command_status)
2038 bind_transceiver_resp(smpp_tree, tmp_tvb);
2041 if (!command_status)
2042 submit_multi_resp(smpp_tree, tmp_tvb);
2045 if (!command_status)
2046 data_sm_resp(smpp_tree, tmp_tvb);
2054 switch (command_id) {
2056 bind_receiver(smpp_tree, tmp_tvb);
2059 bind_transmitter(smpp_tree, tmp_tvb);
2062 query_sm(smpp_tree, tmp_tvb);
2065 submit_sm(smpp_tree, tmp_tvb, pinfo);
2068 deliver_sm(smpp_tree, tmp_tvb, pinfo);
2070 case 6: /* Unbind */
2071 case 21: /* Enquire link */
2074 replace_sm(smpp_tree, tmp_tvb);
2077 cancel_sm(smpp_tree, tmp_tvb);
2080 bind_transceiver(smpp_tree, tmp_tvb);
2083 outbind(smpp_tree, tmp_tvb);
2086 submit_multi(smpp_tree, tmp_tvb);
2089 alert_notification(smpp_tree, tmp_tvb);
2092 data_sm(smpp_tree, tmp_tvb);
2099 /* If this protocol has a sub-dissector call it here. */
2103 /* Register the protocol with Ethereal */
2105 proto_register_smpp(void)
2107 module_t *smpp_module; /* Preferences for SMPP */
2109 /* Setup list of header fields */
2110 static hf_register_info hf[] = {
2111 { &hf_smpp_command_length,
2112 { "Length ", "smpp.command_length",
2113 FT_UINT32, BASE_DEC, NULL, 0x00,
2114 "Total length of the SMPP PDU.",
2118 { &hf_smpp_command_id,
2119 { "Operation ", "smpp.command_id",
2120 FT_UINT32, BASE_HEX, VALS(vals_command_id), 0x00,
2121 "Defines the SMPP PDU.",
2125 { &hf_smpp_command_status,
2126 { "Result ", "smpp.command_status",
2127 FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
2128 "Indicates success or failure of the SMPP request.",
2132 { &hf_smpp_sequence_number,
2133 { "Sequence #", "smpp.sequence_number",
2134 FT_UINT32, BASE_DEC, NULL, 0x00,
2135 "A number to correlate requests with responses.",
2139 { &hf_smpp_system_id,
2140 { "System ID", "smpp.system_id",
2141 FT_STRING, BASE_NONE, NULL, 0x00,
2142 "Identifies a system.",
2146 { &hf_smpp_password,
2147 { "Password", "smpp.password",
2148 FT_STRING, BASE_NONE, NULL, 0x00,
2149 "Password used for authentication.",
2153 { &hf_smpp_system_type,
2154 { "System type", "smpp.system_type",
2155 FT_STRING, BASE_NONE, NULL, 0x00,
2156 "Categorises the system.",
2160 { &hf_smpp_interface_version,
2161 { "Version (if)", "smpp.interface_version",
2162 FT_STRING, BASE_NONE, NULL, 0x00,
2163 "Version of SMPP interface supported.",
2167 { &hf_smpp_service_type,
2168 { "Service type", "smpp.service_type",
2169 FT_STRING, BASE_NONE, NULL, 0x00,
2170 "SMS application service associated with the message.",
2174 { &hf_smpp_addr_ton,
2175 { "Type of number", "smpp.addr_ton",
2176 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2177 "Indicates the type of number, given in the address.",
2181 { &hf_smpp_source_addr_ton,
2182 { "Type of number (originator)", "smpp.source_addr_ton",
2183 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2184 "Indicates originator type of number, given in the address.",
2188 { &hf_smpp_dest_addr_ton,
2189 { "Type of number (recipient)", "smpp.dest_addr_ton",
2190 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2191 "Indicates recipient type of number, given in the address.",
2195 { &hf_smpp_addr_npi,
2196 { "Numbering plan indicator", "smpp.addr_npi",
2197 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2198 "Gives the numbering plan this address belongs to.",
2202 { &hf_smpp_source_addr_npi,
2203 { "Numbering plan indicator (originator)", "smpp.source_addr_npi",
2204 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2205 "Gives originator numbering plan this address belongs to.",
2209 { &hf_smpp_dest_addr_npi,
2210 { "Numbering plan indicator (recipient)", "smpp.dest_addr_npi",
2211 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2212 "Gives recipient numbering plan this address belongs to.",
2216 { &hf_smpp_address_range,
2217 { "Address", "smpp.address_range",
2218 FT_STRING, BASE_NONE, NULL, 0x00,
2219 "Given address or address range.",
2223 { &hf_smpp_source_addr,
2224 { "Originator address", "smpp.source_addr",
2225 FT_STRING, BASE_NONE, NULL, 0x00,
2226 "Address of SME originating this message.",
2230 { &hf_smpp_destination_addr,
2231 { "Recipient address", "smpp.destination_addr",
2232 FT_STRING, BASE_NONE, NULL, 0x00,
2233 "Address of SME receiving this message.",
2237 { &hf_smpp_esm_submit_msg_mode,
2238 { "Messaging mode", "smpp.esm.submit.msg_mode",
2239 FT_UINT8, BASE_HEX, VALS(vals_esm_submit_msg_mode), 0x03,
2240 "Mode attribute for this message.",
2244 { &hf_smpp_esm_submit_msg_type,
2245 { "Message type ", "smpp.esm.submit.msg_type",
2246 FT_UINT8, BASE_HEX, VALS(vals_esm_submit_msg_type), 0x3C,
2247 "Type attribute for this message.",
2251 { &hf_smpp_esm_submit_features,
2252 { "GSM features ", "smpp.esm.submit.features",
2253 FT_UINT8, BASE_HEX, VALS(vals_esm_submit_features), 0xC0,
2254 "GSM network specific features.",
2258 /*! \todo Get proper values from GSM-spec. */
2259 { &hf_smpp_protocol_id,
2260 { "Protocol id.", "smpp.protocol_id",
2261 FT_UINT8, BASE_HEX, NULL, 0x00,
2262 "Protocol identifier according GSM 03.40.",
2266 { &hf_smpp_priority_flag,
2267 { "Priority level", "smpp.priority_flag",
2268 FT_UINT8, BASE_HEX, VALS(vals_priority_flag), 0x00,
2269 "The priority level of the short message.",
2273 { &hf_smpp_schedule_delivery_time,
2274 { "Scheduled delivery time", "smpp.schedule_delivery_time",
2275 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
2276 "Scheduled time for delivery of short message.",
2280 { &hf_smpp_schedule_delivery_time_r,
2281 { "Scheduled delivery time", "smpp.schedule_delivery_time_r",
2282 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
2283 "Scheduled time for delivery of short message.",
2287 { &hf_smpp_validity_period,
2288 { "Validity period", "smpp.validity_period",
2289 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
2290 "Validity period of this message.",
2294 { &hf_smpp_validity_period_r,
2295 { "Validity period", "smpp.validity_period_r",
2296 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
2297 "Validity period of this message.",
2301 { &hf_smpp_regdel_receipt,
2302 { "Delivery receipt ", "smpp.regdel.receipt",
2303 FT_UINT8, BASE_HEX, VALS(vals_regdel_receipt), 0x03,
2304 "SMSC delivery receipt request.",
2308 { &hf_smpp_regdel_acks,
2309 { "Message type ", "smpp.regdel.acks",
2310 FT_UINT8, BASE_HEX, VALS(vals_regdel_acks), 0x0C,
2311 "SME acknowledgement request.",
2315 { &hf_smpp_regdel_notif,
2316 { "Intermediate notif", "smpp.regdel.notif",
2317 FT_UINT8, BASE_HEX, VALS(vals_regdel_notif), 0x10,
2318 "Intermediate notification request.",
2322 { &hf_smpp_replace_if_present_flag,
2323 { "Replace ", "smpp.replace_if_present_flag",
2324 FT_UINT8, BASE_HEX, VALS(vals_replace_if_present_flag), 0x01,
2325 "Replace the short message with this one or not.",
2329 { &hf_smpp_data_coding,
2330 { "Data coding", "smpp.data_coding",
2331 FT_UINT8, BASE_HEX, NULL, 0x00,
2332 "Defines the encoding scheme of the message.",
2336 { &hf_smpp_sm_default_msg_id,
2337 { "Predefined message", "smpp.sm_default_msg_id",
2338 FT_UINT8, BASE_DEC, NULL, 0x00,
2339 "Index of a predefined ('canned') short message.",
2343 { &hf_smpp_sm_length,
2344 { "Message length", "smpp.sm_length",
2345 FT_UINT8, BASE_DEC, NULL, 0x00,
2346 "Length of the message content.",
2350 { &hf_smpp_short_message,
2351 { "Message", "smpp.message",
2352 FT_NONE, BASE_NONE, NULL, 0x00,
2353 "The actual message or data.",
2357 { &hf_smpp_message_id,
2358 { "Message id.", "smpp.message_id",
2359 FT_STRING, BASE_NONE, NULL, 0x00,
2360 "Identifier of the submitted short message.",
2365 { "Destination list", "smpp.dlist",
2366 FT_NONE, BASE_NONE, NULL, 0x00,
2367 "The list of destinations for a short message.",
2371 { &hf_smpp_dlist_resp,
2372 { "Unsuccesfull delivery list", "smpp.dlist_resp",
2373 FT_NONE, BASE_NONE, NULL, 0x00,
2374 "The list of unsuccesfull deliveries to destinations.",
2379 { "Distr. list name", "smpp.dl_name",
2380 FT_STRING, BASE_NONE, NULL, 0x00,
2381 "The name of the distribution list.",
2385 { &hf_smpp_final_date,
2386 { "Final date", "smpp.final_date",
2387 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
2388 "Date-time when the queried message reached a final state.",
2392 { &hf_smpp_final_date_r,
2393 { "Final date", "smpp.final_date_r",
2394 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
2395 "Date-time when the queried message reached a final state.",
2399 { &hf_smpp_message_state,
2400 { "Message state", "smpp.message_state",
2401 FT_UINT8, BASE_DEC, VALS(vals_message_state), 0x00,
2402 "Specifies the status of the queried short message.",
2406 { &hf_smpp_error_code,
2407 { "Error code", "smpp.error_code",
2408 FT_UINT8, BASE_DEC, NULL, 0x00,
2409 "Network specific error code defining reason for failure.",
2413 { &hf_smpp_error_status_code,
2414 { "Status", "smpp.error_status_code",
2415 FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
2416 "Indicates success/failure of request for this address.",
2420 { &hf_smpp_esme_addr_ton,
2421 { "Type of number (ESME)", "smpp.esme_addr_ton",
2422 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2423 "Indicates recipient type of number, given in the address.",
2427 { &hf_smpp_esme_addr_npi,
2428 { "Numbering plan indicator (ESME)", "smpp.esme_addr_npi",
2429 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2430 "Gives the numbering plan this address belongs to.",
2434 { &hf_smpp_esme_addr,
2435 { "ESME address", "smpp.esme_addr",
2436 FT_STRING, BASE_NONE, NULL, 0x00,
2437 "Address of ESME originating this message.",
2441 { &hf_smpp_dest_addr_subunit,
2442 { "Subunit destination", "smpp.dest_addr_subunit",
2443 FT_UINT8, BASE_HEX, VALS(vals_addr_subunit), 0x00,
2444 "Subunit address within mobile to route message to.",
2448 { &hf_smpp_source_addr_subunit,
2449 { "Subunit origin", "smpp.source_addr_subunit",
2450 FT_UINT8, BASE_HEX, VALS(vals_addr_subunit), 0x00,
2451 "Subunit address within mobile that generated the message.",
2455 { &hf_smpp_dest_network_type,
2456 { "Destination network", "smpp.dest_network_type",
2457 FT_UINT8, BASE_HEX, VALS(vals_network_type), 0x00,
2458 "Network associated with the destination address.",
2462 { &hf_smpp_source_network_type,
2463 { "Originator network", "smpp.source_network_type",
2464 FT_UINT8, BASE_HEX, VALS(vals_network_type), 0x00,
2465 "Network associated with the originator address.",
2469 { &hf_smpp_dest_bearer_type,
2470 { "Destination bearer", "smpp.dest_bearer_type",
2471 FT_UINT8, BASE_HEX, VALS(vals_bearer_type), 0x00,
2472 "Desired bearer for delivery of message.",
2476 { &hf_smpp_source_bearer_type,
2477 { "Originator bearer", "smpp.source_bearer_type",
2478 FT_UINT8, BASE_HEX, VALS(vals_bearer_type), 0x00,
2479 "Bearer over which the message originated.",
2483 { &hf_smpp_dest_telematics_id,
2484 { "Telematic interworking (dest)", "smpp.dest_telematics_id",
2485 FT_UINT16, BASE_HEX, NULL, 0x00,
2486 "Telematic interworking to be used for message delivery.",
2490 { &hf_smpp_source_telematics_id,
2491 { "Telematic interworking (orig)", "smpp.source_telematics_id",
2492 FT_UINT16, BASE_HEX, NULL, 0x00,
2493 "Telematic interworking used for message submission.",
2497 { &hf_smpp_qos_time_to_live,
2498 { "Validity period", "smpp.qos_time_to_live",
2499 FT_UINT32, BASE_DEC, NULL, 0x00,
2500 "Number of seconds to retain message before expiry.",
2504 { &hf_smpp_payload_type,
2505 { "Payload", "smpp.payload_type",
2506 FT_UINT8, BASE_DEC, VALS(vals_payload_type), 0x00,
2507 "PDU type contained in the message payload.",
2511 { &hf_smpp_additional_status_info_text,
2512 { "Information", "smpp.additional_status_info_text",
2513 FT_STRING, BASE_NONE, NULL, 0x00,
2514 "Description of the meaning of a response PDU.",
2518 { &hf_smpp_receipted_message_id,
2519 { "SMSC identifier", "smpp.receipted_message_id",
2520 FT_STRING, BASE_NONE, NULL, 0x00,
2521 "SMSC handle of the message being received.",
2525 { &hf_smpp_privacy_indicator,
2526 { "Privacy indicator", "smpp.privacy_indicator",
2527 FT_UINT8, BASE_DEC, VALS(vals_privacy_indicator), 0x00,
2528 "Indicates the privacy level of the message.",
2532 { &hf_smpp_user_message_reference,
2533 { "Message reference", "smpp.user_message_reference",
2534 FT_UINT16, BASE_HEX, NULL, 0x00,
2535 "Reference to the message, assigned by the user.",
2539 { &hf_smpp_user_response_code,
2540 { "Application response code", "smpp.user_response_code",
2541 FT_UINT8, BASE_HEX, NULL, 0x00,
2542 "A response code set by the user.",
2546 { &hf_smpp_language_indicator,
2547 { "Language", "smpp.language_indicator",
2548 FT_UINT8, BASE_DEC, VALS(vals_language_indicator), 0x00,
2549 "Indicates the language of the short message.",
2553 { &hf_smpp_source_port,
2554 { "Source port", "smpp.source_port",
2555 FT_UINT16, BASE_HEX, NULL, 0x00,
2556 "Application port associated with the source of the message.",
2560 { &hf_smpp_destination_port,
2561 { "Destination port", "smpp.destination_port",
2562 FT_UINT16, BASE_HEX, NULL, 0x00,
2563 "Application port associated with the destination of the message.",
2567 { &hf_smpp_sar_msg_ref_num,
2568 { "SAR reference number", "smpp.sar_msg_ref_num",
2569 FT_UINT16, BASE_DEC, NULL, 0x00,
2570 "Reference number for a concatenated short message.",
2574 { &hf_smpp_sar_total_segments,
2575 { "SAR size", "smpp.sar_total_segments",
2576 FT_UINT16, BASE_DEC, NULL, 0x00,
2577 "Number of segments of a concatenated short message.",
2581 { &hf_smpp_sar_segment_seqnum,
2582 { "SAR sequence number", "smpp.sar_segment_seqnum",
2583 FT_UINT8, BASE_DEC, NULL, 0x00,
2584 "Segment number within a concatenated short message.",
2588 { &hf_smpp_display_time,
2589 { "Display time", "smpp.display_time",
2590 FT_UINT8, BASE_DEC, VALS(vals_display_time), 0x00,
2591 "Associates a display time with the message on the handset.",
2595 { &hf_smpp_ms_validity,
2596 { "Validity info", "smpp.ms_validity",
2597 FT_UINT8, BASE_DEC, VALS(vals_ms_validity), 0x00,
2598 "Associates validity info with the message on the handset.",
2602 { &hf_smpp_dpf_result,
2603 { "Delivery pending set?", "smpp.dpf_result",
2604 FT_UINT8, BASE_DEC, VALS(vals_dpf_result), 0x00,
2605 "Indicates whether Delivery Pending Flag was set.",
2610 { "Request DPF set", "smpp.set_dpf",
2611 FT_UINT8, BASE_DEC, VALS(vals_set_dpf), 0x00,
2612 "Request to set the DPF for certain failure scenario's.",
2616 { &hf_smpp_ms_availability_status,
2617 { "Availability status", "smpp.ms_availability_status",
2618 FT_UINT8, BASE_DEC, VALS(vals_ms_availability_status), 0x00,
2619 "Indicates the availability state of the handset.",
2623 { &hf_smpp_delivery_failure_reason,
2624 { "Delivery failure reason", "smpp.delivery_failure_reason",
2625 FT_UINT8, BASE_DEC, VALS(vals_delivery_failure_reason), 0x00,
2626 "Indicates the reason for a failed delivery attempt.",
2630 { &hf_smpp_more_messages_to_send,
2631 { "More messages?", "smpp.more_messages_to_send",
2632 FT_UINT8, BASE_DEC, VALS(vals_more_messages_to_send), 0x00,
2633 "Indicates more messages pending for the same destination.",
2637 { &hf_smpp_number_of_messages,
2638 { "Number of messages", "smpp.number_of_messages",
2639 FT_UINT8, BASE_DEC, NULL, 0x00,
2640 "Indicates number of messages stored in a mailbox.",
2644 { &hf_smpp_its_reply_type,
2645 { "Reply method", "smpp.its_reply_type",
2646 FT_UINT8, BASE_DEC, VALS(vals_its_reply_type), 0x00,
2647 "Indicates the handset reply method on message receipt.",
2651 { &hf_smpp_ussd_service_op,
2652 { "USSD service operation", "smpp.ussd_service_op",
2653 FT_UINT8, BASE_DEC, VALS(vals_ussd_service_op), 0x00,
2654 "Indicates the USSD service operation.",
2658 { &hf_smpp_vendor_op,
2659 { "Optional parameter - Vendor-specific", "smpp.vendor_op",
2660 FT_NONE, BASE_NONE, NULL, 0x00,
2661 "A supplied optional parameter specific to an SMSC-vendor.",
2665 { &hf_smpp_reserved_op,
2666 { "Optional parameter - Reserved", "smpp.reserved_op",
2667 FT_NONE, BASE_NONE, NULL, 0x00,
2668 "An optional parameter that is reserved in this version.",
2672 { &hf_smpp_msg_wait_ind,
2673 { "Indication", "smpp.msg_wait.ind",
2674 FT_UINT8, BASE_HEX, VALS(vals_msg_wait_ind), 0x80,
2675 "Indicates to the handset that a message is waiting.",
2679 { &hf_smpp_msg_wait_type,
2680 { "Type ", "smpp.msg_wait.type",
2681 FT_UINT8, BASE_HEX, VALS(vals_msg_wait_type), 0x03,
2682 "Indicates type of message that is waiting.",
2686 { &hf_smpp_SC_interface_version,
2687 { "SMSC-supported version", "smpp.SC_interface_version",
2688 FT_STRING, BASE_NONE, NULL, 0x00,
2689 "Version of SMPP interface supported by the SMSC.",
2693 { &hf_smpp_callback_num_pres,
2694 { "Presentation", "smpp.callback_num.pres",
2695 FT_UINT8, BASE_HEX, VALS(vals_callback_num_pres), 0x0C,
2696 "Controls the presentation indication.",
2700 { &hf_smpp_callback_num_scrn,
2701 { "Screening ", "smpp.callback_num.scrn",
2702 FT_UINT8, BASE_HEX, VALS(vals_callback_num_scrn), 0x03,
2703 "Controls screening of the callback-number.",
2707 { &hf_smpp_callback_num_atag,
2708 { "Callback number - alphanumeric display tag",
2709 "smpp.callback_num_atag",
2710 FT_NONE, BASE_NONE, NULL, 0x00,
2711 "Associates an alphanumeric display with call back number.",
2715 { &hf_smpp_callback_num,
2716 { "Callback number", "smpp.callback_num",
2717 FT_NONE, BASE_NONE, NULL, 0x00,
2718 "Associates a call back number with the message.",
2722 { &hf_smpp_network_error_type,
2723 { "Error type", "smpp.network_error.type",
2724 FT_UINT8, BASE_DEC, VALS(vals_network_error_type), 0x00,
2725 "Indicates the network type.",
2729 { &hf_smpp_network_error_code,
2730 { "Error code", "smpp.network_error.code",
2731 FT_UINT16, BASE_HEX, NULL, 0x00,
2732 "Gives the actual network error code.",
2736 { &hf_smpp_message_payload,
2737 { "Payload", "smpp.message_payload",
2738 FT_NONE, BASE_NONE, NULL, 0x00,
2739 "Short message user data.",
2743 { &hf_smpp_alert_on_message_delivery,
2744 { "Alert on delivery", "smpp.alert_on_message_delivery",
2745 FT_NONE, BASE_NONE, NULL, 0x00,
2746 "Instructs the handset to alert user on message delivery.",
2750 { &hf_smpp_its_session_number,
2751 { "Session number", "smpp.its_session.number",
2752 FT_UINT8, BASE_DEC, NULL, 0x00,
2753 "Session number of interactive teleservice.",
2757 { &hf_smpp_its_session_sequence,
2758 { "Sequence number ", "smpp.its_session.sequence",
2759 FT_UINT8, BASE_HEX, NULL, 0xFE,
2760 "Sequence number of the dialogue unit.",
2764 { &hf_smpp_its_session_ind,
2765 { "Session indicator", "smpp.its_session.ind",
2766 FT_UINT8, BASE_HEX, VALS(vals_its_session_ind), 0x01,
2767 "Indicates whether this message is end of conversation.",
2771 { &hf_smpp_opt_param,
2772 { "Optional parameters", "smpp.opt_param",
2773 FT_NONE, BASE_NONE, NULL, 0x00,
2774 "The list of optional parameters in this operation.",
2779 { "SMPP Data Coding Scheme", "smpp.dcs",
2780 FT_UINT8, BASE_HEX, VALS(vals_data_coding), 0x00,
2781 "Data Coding Scheme according to SMPP.",
2785 { &hf_smpp_dcs_sms_coding_group,
2786 { "DCS Coding Group for SMS", "smpp.dcs.sms_coding_group",
2787 FT_UINT8, BASE_HEX, VALS(vals_dcs_sms_coding_group), 0xF0,
2788 "Data Coding Scheme coding group for GSM Short Message Service.",
2792 { &hf_smpp_dcs_text_compression,
2793 { "DCS Text compression", "smpp.dcs.text_compression",
2794 FT_BOOLEAN, 8, TFS(&tfs_dcs_text_compression), 0x20,
2795 "Indicates if text compression is used.", HFILL
2798 { &hf_smpp_dcs_class_present,
2799 { "DCS Class present", "smpp.dcs.class_present",
2800 FT_BOOLEAN, 8, TFS(&tfs_dcs_class_present), 0x10,
2801 "Indicates if the message class is present (defined).", HFILL
2804 { &hf_smpp_dcs_charset,
2805 { "DCS Character set", "smpp.dcs.charset",
2806 FT_UINT8, BASE_HEX, VALS(vals_dcs_charset), 0x0C,
2807 "Specifies the character set used in the message.", HFILL
2810 { &hf_smpp_dcs_class,
2811 { "DCS Message class", "smpp.dcs.class",
2812 FT_UINT8, BASE_HEX, VALS(vals_dcs_class), 0x03,
2813 "Specifies the message class.", HFILL
2816 { &hf_smpp_dcs_cbs_coding_group,
2817 { "DCS Coding Group for CBS", "smpp.dcs.cbs_coding_group",
2818 FT_UINT8, BASE_HEX, VALS(vals_dcs_cbs_coding_group), 0xF0,
2819 "Data Coding Scheme coding group for GSM Cell Broadcast Service.",
2823 { &hf_smpp_dcs_cbs_language,
2824 { "DCS CBS Message language", "smpp.dcs.cbs_language",
2825 FT_UINT8, BASE_HEX, VALS(vals_dcs_cbs_language), 0x3F,
2826 "Language of the GSM Cell Broadcast Service message.", HFILL
2829 { &hf_smpp_dcs_cbs_class,
2830 { "DCS CBS Message class", "smpp.dcs.cbs_class",
2831 FT_UINT8, BASE_HEX, VALS(vals_dcs_cbs_class), 0x03,
2832 "Specifies the message class for GSM Cell Broadcast Service, "
2833 "for the Data coding / message handling code group.", HFILL
2836 { &hf_smpp_dcs_wap_charset,
2837 { "DCS Message coding", "smpp.dcs.wap_coding",
2838 FT_UINT8, BASE_HEX, VALS(vals_dcs_wap_charset), 0x0C,
2839 "Specifies the used message encoding, "
2840 "as specified by the WAP Forum (WAP over GSM USSD).", HFILL
2843 { &hf_smpp_dcs_wap_class,
2844 { "DCS CBS Message class", "smpp.dcs.wap_class",
2845 FT_UINT8, BASE_HEX, VALS(vals_dcs_wap_class), 0x03,
2846 "Specifies the message class for GSM Cell Broadcast Service, "
2847 "as specified by the WAP Forum (WAP over GSM USSD).", HFILL
2851 { "IE Id", "smpp.udh.iei",
2852 FT_UINT8, BASE_HEX, VALS(vals_udh_iei), 0x00,
2853 "Name of the User Data Header Information Element.",
2857 { &hf_smpp_udh_length,
2858 { "UDH Length", "smpp.udh.len",
2859 FT_UINT8, BASE_DEC, NULL, 0x00,
2860 "Length of the User Data Header (bytes)",
2864 { &hf_smpp_udh_multiple_messages,
2865 { "Multiple messages UDH", "smpp.udh.mm",
2866 FT_NONE, BASE_NONE, NULL, 0x00,
2867 "Multiple messages User Data Header",
2871 { &hf_smpp_udh_multiple_messages_msg_id,
2872 { "Message identifier", "smpp.udh.mm.msg_id",
2873 FT_UINT16, BASE_DEC, NULL, 0x00,
2874 "Identification of the message",
2878 { &hf_smpp_udh_multiple_messages_msg_parts,
2879 { "Message parts", "smpp.udh.mm.msg_parts",
2880 FT_UINT8, BASE_DEC, NULL, 0x00,
2881 "Total number of message parts (fragments)",
2885 { &hf_smpp_udh_multiple_messages_msg_part,
2886 { "Message part number", "smpp.udh.mm.msg_part",
2887 FT_UINT8, BASE_DEC, NULL, 0x00,
2888 "Message part (fragment) sequence number",
2892 { &hf_smpp_udh_ports,
2893 { "Port number UDH", "smpp.udh.ports",
2894 FT_NONE, BASE_NONE, NULL, 0x00,
2895 "Port number User Data Header",
2899 { &hf_smpp_udh_ports_src,
2900 { "Source port", "smpp.udh.ports.src",
2901 FT_UINT8, BASE_DEC, NULL, 0x00,
2906 { &hf_smpp_udh_ports_dst,
2907 { "Destination port", "smpp.udh.ports.dst",
2908 FT_UINT8, BASE_DEC, NULL, 0x00,
2913 /* Short Message fragment reassembly */
2915 { "Short Message fragments", "smpp.fragments",
2916 FT_NONE, BASE_NONE, NULL, 0x00,
2917 "SMPP Short Message fragments",
2922 { "Short Message fragment", "smpp.fragment",
2923 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
2924 "SMPP Short Message fragment",
2928 { &hf_sm_fragment_overlap,
2929 { "Short Message fragment overlap", "smpp.fragment.overlap",
2930 FT_BOOLEAN, BASE_NONE, NULL, 0x00,
2931 "SMPP Short Message fragment overlaps with other fragment(s)",
2935 { &hf_sm_fragment_overlap_conflicts,
2936 { "Short Message fragment overlapping with conflicting data",
2937 "smpp.fragment.overlap.conflicts",
2938 FT_BOOLEAN, BASE_NONE, NULL, 0x00,
2939 "SMPP Short Message fragment overlaps with conflicting data",
2943 { &hf_sm_fragment_multiple_tails,
2944 { "Short Message has multiple tail fragments",
2945 "smpp.fragment.multiple_tails",
2946 FT_BOOLEAN, BASE_NONE, NULL, 0x00,
2947 "SMPP Short Message fragment has multiple tail fragments",
2951 { &hf_sm_fragment_too_long_fragment,
2952 { "Short Message fragment too long",
2953 "smpp.fragment.too_long_fragment",
2954 FT_BOOLEAN, BASE_NONE, NULL, 0x00,
2955 "SMPP Short Message fragment data goes beyond the packet end",
2959 { &hf_sm_fragment_error,
2960 { "Short Message defragmentation error", "smpp.fragment.error",
2961 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
2962 "SMPP Short Message defragmentation error due to illegal fragments",
2967 /* Setup protocol subtree array */
2968 static gint *ett[] = {
2975 &ett_udh_multiple_messages,
2980 /* Register the protocol name and description */
2981 proto_smpp = proto_register_protocol("Short Message Peer to Peer",
2984 /* Required function calls to register header fields and subtrees used */
2985 proto_register_field_array(proto_smpp, hf, array_length(hf));
2986 proto_register_subtree_array(ett, array_length(ett));
2988 /* Subdissector code */
2989 smpp_dissector_table = register_dissector_table("smpp.udh.port",
2990 "SMPP UDH port", FT_UINT16, BASE_DEC);
2992 /* Preferences for SMPP */
2993 smpp_module = prefs_register_protocol (proto_smpp, NULL);
2994 prefs_register_bool_preference (smpp_module, "port_number_udh_means_wsp",
2995 "Port Number UDH always triggers CL-WSP dissection",
2996 "Always decode a Short Message as Connectionless WSP "
2997 "if a Port Number User Data Header is present",
2998 &port_number_udh_means_wsp);
2999 prefs_register_bool_preference (smpp_module, "try_dissect_1st_fragment",
3000 "Always try subdissection of 1st Short Message fragment",
3001 "Always try subdissection of the 1st fragment of a fragmented "
3002 "Short Message. If reassembly is possible, the Short Message "
3003 "may be dissected twice (once as a short frame, once in its "
3005 &try_dissect_1st_frag);
3007 /* SMPP dissector initialization routines */
3008 register_init_routine (sm_defragment_init);
3012 * If dissector uses sub-dissector registration add a registration routine.
3013 * This format is required because a script is used to find these routines and
3014 * create the code that calls these routines.
3017 proto_reg_handoff_smpp(void)
3019 dissector_handle_t smpp_handle;
3022 * SMPP can be spoken on any port under TCP or X.25
3023 * ...how *do* we do that under X.25?
3025 * We can register the heuristic SMPP dissector with X.25, for one
3026 * thing. We don't currently have any mechanism to allow the user
3027 * to specify that a given X.25 circuit is to be dissected as SMPP,
3030 smpp_handle = create_dissector_handle(dissect_smpp, proto_smpp);
3031 dissector_add_handle("tcp.port", smpp_handle);
3032 heur_dissector_add("tcp", dissect_smpp_heur, proto_smpp);
3033 heur_dissector_add("x.25", dissect_smpp_heur, proto_smpp);
3035 /* Required for call_dissector() */
3036 wsp_handle = find_dissector ("wsp-cl");
3037 assert (wsp_handle);