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 * Dissection of multiple SMPP PDUs within one packet
12 * provided by Chris Wilson.
14 * $Id: packet-smpp.c,v 1.27 2004/01/20 17:58:37 obiot Exp $
16 * Note on SMS Message reassembly
17 * ------------------------------
18 * The current Short Message reassembly is possible thanks to the
19 * message identifier (8 or 16 bit identifier). It is able to reassemble
20 * short messages that are sent over either the same SMPP connection or
21 * distinct SMPP connections. Normally the reassembly code is able to deal
22 * with duplicate message identifiers since the fragment_add_seq_check()
25 * The SMPP preference "always try subdissection of 1st fragment" allows
26 * a subdissector to be called for the first Short Message fragment,
27 * even if reassembly is not possible. This way partial dissection
28 * is still possible. This preference is switched off by default.
30 * Note on Short Message decoding as CL-WSP
31 * ----------------------------------------
32 * The SMPP preference "port_number_udh_means_wsp" is switched off
33 * by default. If it is enabled, then any Short Message with a Port Number
34 * UDH will be decoded as CL-WSP if:
35 * - The Short Message is not segmented
36 * - The entire segmented Short Message is reassembled
37 * - It is the 1st segment of an unreassembled Short Message (if the
38 * "always try subdissection of 1st fragment" preference is enabled)
40 * Ethereal - Network traffic analyzer
41 * By Gerald Combs <gerald@ethereal.com>
42 * Copyright 1998 Gerald Combs
44 * This program is free software; you can redistribute it and/or
45 * modify it under the terms of the GNU General Public License
46 * as published by the Free Software Foundation; either version 2
47 * of the License, or (at your option) any later version.
49 * This program is distributed in the hope that it will be useful,
50 * but WITHOUT ANY WARRANTY; without even the implied warranty of
51 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52 * GNU General Public License for more details.
54 * You should have received a copy of the GNU General Public License
55 * along with this program; if not, write to the Free Software
56 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
59 * Dissector of an SMPP (Short Message Peer to Peer) PDU, as defined by the
60 * SMS forum (www.smsforum.net) in "SMPP protocol specification v3.4"
61 * (document version: 12-Oct-1999 Issue 1.2)
75 #include <epan/packet.h>
78 #include "reassemble.h"
79 #include "packet-tcp.h"
81 /* General-purpose debug logger.
82 * Requires double parentheses because of variable arguments of printf().
84 * Enable debug logging for SMPP by defining AM_CFLAGS
85 * so that it contains "-DDEBUG_smpp"
89 printf("%s:%u: ", __FILE__, __LINE__); \
96 /* Forward declarations */
97 static void dissect_smpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
98 static guint get_smpp_pdu_len(tvbuff_t *tvb, int offset);
99 static void dissect_smpp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
101 static void dissect_smpp_gsm_sms(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
104 * Initialize the protocol and registered fields
106 * Fixed header section
108 static int proto_smpp = -1;
109 static int proto_smpp_gsm_sms = -1;
111 static int hf_smpp_command_id = -1;
112 static int hf_smpp_command_length = -1;
113 static int hf_smpp_command_status = -1;
114 static int hf_smpp_sequence_number = -1;
119 static int hf_smpp_system_id = -1;
120 static int hf_smpp_password = -1;
121 static int hf_smpp_system_type = -1;
122 static int hf_smpp_interface_version = -1;
123 static int hf_smpp_addr_ton = -1;
124 static int hf_smpp_addr_npi = -1;
125 static int hf_smpp_address_range = -1;
126 static int hf_smpp_service_type = -1;
127 static int hf_smpp_source_addr_ton = -1;
128 static int hf_smpp_source_addr_npi = -1;
129 static int hf_smpp_source_addr = -1;
130 static int hf_smpp_dest_addr_ton = -1;
131 static int hf_smpp_dest_addr_npi = -1;
132 static int hf_smpp_destination_addr = -1;
133 static int hf_smpp_esm_submit_msg_mode = -1;
134 static int hf_smpp_esm_submit_msg_type = -1;
135 static int hf_smpp_esm_submit_features = -1;
136 static int hf_smpp_protocol_id = -1;
137 static int hf_smpp_priority_flag = -1;
138 static int hf_smpp_schedule_delivery_time = -1;
139 static int hf_smpp_schedule_delivery_time_r = -1;
140 static int hf_smpp_validity_period = -1;
141 static int hf_smpp_validity_period_r = -1;
142 static int hf_smpp_regdel_receipt = -1;
143 static int hf_smpp_regdel_acks = -1;
144 static int hf_smpp_regdel_notif = -1;
145 static int hf_smpp_replace_if_present_flag = -1;
146 static int hf_smpp_data_coding = -1;
147 static int hf_smpp_sm_default_msg_id = -1;
148 static int hf_smpp_sm_length = -1;
149 static int hf_smpp_short_message = -1;
150 static int hf_smpp_message_id = -1;
151 static int hf_smpp_dlist = -1;
152 static int hf_smpp_dlist_resp = -1;
153 static int hf_smpp_dl_name = -1;
154 static int hf_smpp_final_date = -1;
155 static int hf_smpp_final_date_r = -1;
156 static int hf_smpp_message_state = -1;
157 static int hf_smpp_error_code = -1;
158 static int hf_smpp_error_status_code = -1;
159 static int hf_smpp_esme_addr_ton = -1;
160 static int hf_smpp_esme_addr_npi = -1;
161 static int hf_smpp_esme_addr = -1;
164 * Optional parameter section
166 static int hf_smpp_opt_param = -1;
167 static int hf_smpp_vendor_op = -1;
168 static int hf_smpp_reserved_op = -1;
170 static int hf_smpp_dest_addr_subunit = -1;
171 static int hf_smpp_dest_network_type = -1;
172 static int hf_smpp_dest_bearer_type = -1;
173 static int hf_smpp_dest_telematics_id = -1;
174 static int hf_smpp_source_addr_subunit = -1;
175 static int hf_smpp_source_network_type = -1;
176 static int hf_smpp_source_bearer_type = -1;
177 static int hf_smpp_source_telematics_id = -1;
178 static int hf_smpp_qos_time_to_live = -1;
179 static int hf_smpp_payload_type = -1;
180 static int hf_smpp_additional_status_info_text = -1;
181 static int hf_smpp_receipted_message_id = -1;
182 static int hf_smpp_msg_wait_ind = -1;
183 static int hf_smpp_msg_wait_type = -1;
184 static int hf_smpp_privacy_indicator = -1;
185 static int hf_smpp_source_subaddress = -1;
186 static int hf_smpp_dest_subaddress = -1;
187 static int hf_smpp_user_message_reference = -1;
188 static int hf_smpp_user_response_code = -1;
189 static int hf_smpp_source_port = -1;
190 static int hf_smpp_destination_port = -1;
191 static int hf_smpp_sar_msg_ref_num = -1;
192 static int hf_smpp_language_indicator = -1;
193 static int hf_smpp_sar_total_segments = -1;
194 static int hf_smpp_sar_segment_seqnum = -1;
195 static int hf_smpp_SC_interface_version = -1;
196 static int hf_smpp_callback_num_pres = -1;
197 static int hf_smpp_callback_num_scrn = -1;
198 static int hf_smpp_callback_num_atag = -1;
199 static int hf_smpp_number_of_messages = -1;
200 static int hf_smpp_callback_num = -1;
201 static int hf_smpp_dpf_result = -1;
202 static int hf_smpp_set_dpf = -1;
203 static int hf_smpp_ms_availability_status = -1;
204 static int hf_smpp_network_error_type = -1;
205 static int hf_smpp_network_error_code = -1;
206 static int hf_smpp_message_payload = -1;
207 static int hf_smpp_delivery_failure_reason = -1;
208 static int hf_smpp_more_messages_to_send = -1;
209 static int hf_smpp_ussd_service_op = -1;
210 static int hf_smpp_display_time = -1;
211 static int hf_smpp_sms_signal = -1;
212 static int hf_smpp_ms_validity = -1;
213 static int hf_smpp_alert_on_message_delivery = -1;
214 static int hf_smpp_its_reply_type = -1;
215 static int hf_smpp_its_session_number = -1;
216 static int hf_smpp_its_session_sequence = -1;
217 static int hf_smpp_its_session_ind = -1;
220 * Data Coding Scheme section
222 static int hf_smpp_dcs = -1;
223 static int hf_smpp_dcs_sms_coding_group = -1;
224 static int hf_smpp_dcs_text_compression = -1;
225 static int hf_smpp_dcs_class_present = -1;
226 static int hf_smpp_dcs_charset = -1;
227 static int hf_smpp_dcs_class = -1;
228 static int hf_smpp_dcs_cbs_coding_group = -1;
229 static int hf_smpp_dcs_cbs_language = -1;
230 static int hf_smpp_dcs_wap_charset = -1;
231 static int hf_smpp_dcs_wap_class = -1;
232 static int hf_smpp_dcs_cbs_class = -1;
235 * User Data Header section
237 static int hf_smpp_udh_length = -1;
238 static int hf_smpp_udh_iei = -1;
239 static int hf_smpp_udh_multiple_messages = -1;
240 static int hf_smpp_udh_multiple_messages_msg_id = -1;
241 static int hf_smpp_udh_multiple_messages_msg_parts = -1;
242 static int hf_smpp_udh_multiple_messages_msg_part = -1;
243 static int hf_smpp_udh_ports = -1;
244 static int hf_smpp_udh_ports_src = -1;
245 static int hf_smpp_udh_ports_dst = -1;
248 * Short Message fragment handling
250 static int hf_sm_fragments = -1;
251 static int hf_sm_fragment = -1;
252 static int hf_sm_fragment_overlap = -1;
253 static int hf_sm_fragment_overlap_conflicts = -1;
254 static int hf_sm_fragment_multiple_tails = -1;
255 static int hf_sm_fragment_too_long_fragment = -1;
256 static int hf_sm_fragment_error = -1;
257 static int hf_sm_reassembled_in = -1;
259 /* Initialize the subtree pointers */
260 static gint ett_smpp = -1;
261 static gint ett_dlist = -1;
262 static gint ett_dlist_resp = -1;
263 static gint ett_opt_param = -1;
264 static gint ett_dcs = -1;
265 static gint ett_gsm_sms = -1;
266 static gint ett_udh = -1;
267 static gint ett_udh_ie = -1;
268 static gint ett_sm_fragment = -1;
269 static gint ett_sm_fragments = -1;
271 /* Subdissector declarations */
272 static dissector_table_t gsm_sms_dissector_table;
274 /* Short Message reassembly */
275 static GHashTable *sm_fragment_table = NULL;
276 static GHashTable *sm_reassembled_table = NULL;
278 static const fragment_items sm_frag_items = {
279 /* Fragment subtrees */
282 /* Fragment fields */
285 &hf_sm_fragment_overlap,
286 &hf_sm_fragment_overlap_conflicts,
287 &hf_sm_fragment_multiple_tails,
288 &hf_sm_fragment_too_long_fragment,
289 &hf_sm_fragment_error,
290 /* Reassembled in field */
291 &hf_sm_reassembled_in,
293 "Short Message fragments"
296 /* Reassemble SMPP TCP segments */
297 static gboolean reassemble_over_tcp = FALSE;
298 /* Dissect all SM data as WSP if the UDH contains a Port Number IE */
299 static gboolean port_number_udh_means_wsp = FALSE;
300 /* Always try dissecting the 1st fragment of a SM,
301 * even if it is not reassembled */
302 static gboolean try_dissect_1st_frag = FALSE;
305 static dissector_handle_t wsp_handle;
306 static dissector_handle_t gsm_sms_handle;
309 sm_defragment_init (void)
311 fragment_table_init (&sm_fragment_table);
312 reassembled_table_init(&sm_reassembled_table);
316 * Value-arrays for field-contents
318 static const value_string vals_command_id[] = { /* Operation */
319 { 0x80000000, "Generic_nack" },
320 { 0x00000001, "Bind_receiver" },
321 { 0x80000001, "Bind_receiver - resp" },
322 { 0x00000002, "Bind_transmitter" },
323 { 0x80000002, "Bind_transmitter - resp" },
324 { 0x00000003, "Query_sm" },
325 { 0x80000003, "Query_sm - resp" },
326 { 0x00000004, "Submit_sm" },
327 { 0x80000004, "Submit_sm - resp" },
328 { 0x00000005, "Deliver_sm" },
329 { 0x80000005, "Deliver_sm - resp" },
330 { 0x00000006, "Unbind" },
331 { 0x80000006, "Unbind - resp" },
332 { 0x00000007, "Replace_sm" },
333 { 0x80000007, "Replace_sm - resp" },
334 { 0x00000008, "Cancel_sm" },
335 { 0x80000008, "Cancel_sm - resp" },
336 { 0x00000009, "Bind_transceiver" },
337 { 0x80000009, "Bind_transceiver - resp" },
338 { 0x0000000B, "Outbind" },
339 { 0x00000015, "Enquire_link" },
340 { 0x80000015, "Enquire_link - resp" },
341 { 0x00000021, "Submit_multi" },
342 { 0x80000021, "Submit_multi - resp" },
343 { 0x00000102, "Alert_notification" },
344 { 0x00000103, "Data_sm" },
345 { 0x80000103, "Data_sm - resp" },
349 static const value_string vals_command_status[] = { /* Status */
350 { 0x00000000, "Ok" },
351 { 0x00000001, "Message length is invalid" },
352 { 0x00000002, "Command length is invalid" },
353 { 0x00000003, "Invalid command ID" },
354 { 0x00000004, "Incorrect BIND status for given command" },
355 { 0x00000005, "ESME already in bound state" },
356 { 0x00000006, "Invalid priority flag" },
357 { 0x00000007, "Invalid registered delivery flag" },
358 { 0x00000008, "System error" },
359 { 0x00000009, "[Reserved]" },
360 { 0x0000000A, "Invalid source address" },
361 { 0x0000000B, "Invalid destination address" },
362 { 0x0000000C, "Message ID is invalid" },
363 { 0x0000000D, "Bind failed" },
364 { 0x0000000E, "Invalid password" },
365 { 0x0000000F, "Invalid system ID" },
366 { 0x00000010, "[Reserved]" },
367 { 0x00000011, "Cancel SM failed" },
368 { 0x00000012, "[Reserved]" },
369 { 0x00000013, "Replace SM failed" },
370 { 0x00000014, "Message queue full" },
371 { 0x00000015, "Invalid service type" },
372 { 0x00000033, "Invalid number of destinations" },
373 { 0x00000034, "Invalid distribution list name" },
374 { 0x00000040, "Destination flag is invalid (submit_multi)" },
375 { 0x00000041, "[Reserved]" },
376 { 0x00000042, "Invalid 'submit with replace' request" },
377 { 0x00000043, "Invalid esm_class field data" },
378 { 0x00000044, "Cannot submit to distribution list" },
379 { 0x00000045, "submit_sm or submit_multi failed" },
380 { 0x00000046, "[Reserved]" },
381 { 0x00000047, "[Reserved]" },
382 { 0x00000048, "Invalid source address TON" },
383 { 0x00000049, "Invalid source address NPI" },
384 { 0x00000050, "Invalid destination address TON" },
385 { 0x00000051, "Invalid destination address NPI" },
386 { 0x00000052, "[Reserved]" },
387 { 0x00000053, "Invalid system_type field" },
388 { 0x00000054, "Invalid replace_if_present flag" },
389 { 0x00000055, "Invalid number of messages" },
390 { 0x00000056, "[Reserved]" },
391 { 0x00000057, "[Reserved]" },
392 { 0x00000058, "Throttling error (ESME exceeded allowed message limits)" },
393 { 0x00000059, "[Reserved]" },
394 { 0x00000060, "[Reserved]" },
395 { 0x00000061, "Invalid scheduled delivery time" },
396 { 0x00000062, "Invalid message validity period (expirey time)" },
397 { 0x00000063, "Predefined message invalid or not found" },
398 { 0x00000064, "ESME receiver temporary app error code" },
399 { 0x00000065, "ESME receiver permanent app error code" },
400 { 0x00000066, "ESME receiver reject message error code" },
401 { 0x00000067, "query_sm request failed" },
402 { 0x000000C0, "Error in the optional part of the PDU body" },
403 { 0x000000C1, "Optional parameter not allowed" },
404 { 0x000000C2, "Invalid parameter length" },
405 { 0x000000C3, "Expected optional parameter missing" },
406 { 0x000000C4, "Invalid optional parameter value" },
407 { 0x000000FE, "Delivery failure (used for data_sm_resp)" },
408 { 0x000000FF, "Unknown error" },
412 static const value_string vals_addr_ton[] = {
414 { 1, "International" },
416 { 3, "Network specific" },
417 { 4, "Subscriber number" },
418 { 5, "Alphanumeric" },
419 { 6, "Abbreviated" },
423 static const value_string vals_addr_npi[] = {
425 { 1, "ISDN (E163/E164)" },
426 { 3, "Data (X.121)" },
427 { 4, "Telex (F.69)" },
428 { 6, "Land mobile (E.212)" },
432 { 14, "Internet (IP)" },
433 { 18, "WAP client Id" },
437 static const value_string vals_esm_submit_msg_mode[] = {
438 { 0x0, "Default SMSC mode" },
439 { 0x1, "Datagram mode" },
440 { 0x2, "Forward mode" },
441 { 0x3, "Store and forward mode" },
445 static const value_string vals_esm_submit_msg_type[] = {
446 { 0x0, "Default message type" },
447 { 0x1, "Short message contains SMSC Delivery Receipt" },
448 { 0x2, "Short message contains (E)SME delivery acknowledgement" },
450 { 0x4, "Short message contains (E)SME manual/user acknowledgement" },
452 { 0x6, "Short message contains conversation abort" },
454 { 0x8, "Short message contains intermediate delivery notification" },
458 static const value_string vals_esm_submit_features[] = {
459 { 0x0, "No specific features selected" },
460 { 0x1, "UDHI indicator" },
461 { 0x2, "Reply path" },
462 { 0x3, "UDHI and reply path" },
466 static const value_string vals_priority_flag[] = {
467 { 0, "GSM: None ANSI-136: Bulk IS-95: Normal" },
468 { 1, "GSM: priority ANSI-136: Normal IS-95: Interactive" },
469 { 2, "GSM: priority ANSI-136: Urgent IS-95: Urgent" },
470 { 3, "GSM: priority ANSI-136: Very Urgent IS-95: Emergency" },
474 static const value_string vals_regdel_receipt[] = {
475 { 0x0, "No SMSC delivery receipt requested" },
476 { 0x1, "Delivery receipt requested (for success or failure)" },
477 { 0x2, "Delivery receipt requested (for failure)" },
482 static const value_string vals_regdel_acks[] = {
483 { 0x0, "No recipient SME acknowledgement requested" },
484 { 0x1, "SME delivery acknowledgement requested" },
485 { 0x2, "SME manual/user acknowledgement requested" },
486 { 0x3, "Both delivery and manual/user acknowledgement requested" },
490 static const value_string vals_regdel_notif[] = {
491 { 0x0, "No intermediate notification requested" },
492 { 0x1, "Intermediate notification requested" },
496 static const value_string vals_replace_if_present_flag[] = {
497 { 0x0, "Don't replace" },
502 static const value_string vals_data_coding[] = {
503 { 0, "SMSC default alphabet" },
504 { 1, "IA5 (CCITT T.50/ASCII (ANSI X3.4)" },
505 { 2, "Octet unspecified (8-bit binary)" },
506 { 3, "Latin 1 (ISO-8859-1)" },
507 { 4, "Octet unspecified (8-bit binary)" },
508 { 5, "JIS (X 0208-1990)" },
509 { 6, "Cyrillic (ISO-8859-5)" },
510 { 7, "Latin/Hebrew (ISO-8859-8)" },
511 { 8, "UCS2 (ISO/IEC-10646)" },
512 { 9, "Pictogram encoding" },
513 { 10, "ISO-2022-JP (Music codes)" },
516 { 13, "Extended Kanji JIS(X 0212-1990)" },
518 /*! \todo Rest to be defined (bitmask?) according GSM 03.38 */
522 static const value_string vals_message_state[] = {
527 { 5, "UNDELIVERABLE" },
534 static const value_string vals_addr_subunit[] = {
535 { 0, "Unknown -default-" },
537 { 2, "Mobile equipment" },
538 { 3, "Smart card 1" },
539 { 4, "External unit 1" },
543 static const value_string vals_network_type[] = {
546 { 2, "ANSI-136/TDMA" },
552 { 8, "Paging network" },
556 static const value_string vals_bearer_type[] = {
559 { 2, "Circuit Switched Data (CSD)" },
560 { 3, "Packet data" },
564 { 7, "FLEX/ReFLEX" },
565 { 8, "Cell Broadcast" },
569 static const value_string vals_payload_type[] = {
571 { 1, "WCMP message" },
575 static const value_string vals_privacy_indicator[] = {
576 { 0, "Not restricted -default-" },
578 { 2, "Confidential" },
583 static const value_string vals_language_indicator[] = {
584 { 0, "Unspecified -default-" },
593 static const value_string vals_display_time[] = {
595 { 1, "Default -default-" },
600 static const value_string vals_ms_validity[] = {
601 { 0, "Store indefinitely -default-" },
603 { 2, "SID based registration area" },
604 { 3, "Display only" },
608 static const value_string vals_dpf_result[] = {
609 { 0, "DPF not set" },
614 static const value_string vals_set_dpf[] = {
615 { 0, "Not requested (Set DPF for delivery failure)" },
616 { 1, "Requested (Set DPF for delivery failure)" },
620 static const value_string vals_ms_availability_status[] = {
621 { 0, "Available -default-" },
623 { 2, "Unavailable" },
627 static const value_string vals_delivery_failure_reason[] = {
628 { 0, "Destination unavailable" },
629 { 1, "Destination address invalid" },
630 { 2, "Permanent network error" },
631 { 3, "Temporary network error" },
635 static const value_string vals_more_messages_to_send[] = {
636 { 0, "No more messages" },
637 { 1, "More messages -default-" },
641 static const value_string vals_its_reply_type[] = {
644 { 2, "Telephone no." },
646 { 4, "Character line" },
654 static const value_string vals_ussd_service_op[] = {
655 { 0, "PSSD indication" },
656 { 1, "PSSR indication" },
657 { 2, "USSR request" },
658 { 3, "USSN request" },
659 { 16, "PSSD response" },
660 { 17, "PSSR response" },
661 { 18, "USSR confirm" },
662 { 19, "USSN confirm" },
666 static const value_string vals_msg_wait_ind[] = {
667 { 0, "Set indication inactive" },
668 { 1, "Set indication active" },
672 static const value_string vals_msg_wait_type[] = {
673 { 0, "Voicemail message waiting" },
674 { 1, "Fax message waiting" },
675 { 2, "Electronic mail message waiting" },
676 { 3, "Other message waiting" },
680 static const value_string vals_callback_num_pres[] = {
681 { 0, "Presentation allowed" },
682 { 1, "Presentation restricted" },
683 { 2, "Number not available" },
688 static const value_string vals_callback_num_scrn[] = {
689 { 0, "User provided, not screened" },
690 { 1, "User provided, verified and passed" },
691 { 2, "User provided, verified and failed" },
692 { 3, "Network provided" },
696 static const value_string vals_network_error_type[] = {
704 static const value_string vals_its_session_ind[] = {
705 { 0, "End of session indicator inactive" },
706 { 1, "End of session indicator active" },
710 /* Data Coding Scheme: see 3GPP TS 23.040 and 3GPP TS 23.038 */
711 static const value_string vals_dcs_sms_coding_group[] = {
712 { 0x00, "SMS DCS: General Data Coding indication - Uncompressed text, no message class" },
713 { 0x01, "SMS DCS: General Data Coding indication - Uncompressed text" },
714 { 0x02, "SMS DCS: General Data Coding indication - Compressed text, no message class" },
715 { 0x03, "SMS DCS: General Data Coding indication - Compressed text" },
716 { 0x04, "SMS DCS: Message Marked for Automatic Deletion - Uncompressed text, no message class" },
717 { 0x05, "SMS DCS: Message Marked for Automatic Deletion - Uncompressed text" },
718 { 0x06, "SMS DCS: Message Marked for Automatic Deletion - Compressed text, no message class" },
719 { 0x07, "SMS DCS: Message Marked for Automatic Deletion - Compressed text" },
720 { 0x08, "SMS DCS: Reserved" },
721 { 0x09, "SMS DCS: Reserved" },
722 { 0x0A, "SMS DCS: Reserved" },
723 { 0x0B, "SMS DCS: Reserved" },
724 { 0x0C, "SMS DCS: Message Waiting Indication - Discard Message" },
725 { 0x0D, "SMS DCS: Message Waiting Indication - Store Message (GSM 7-bit default alphabet)" },
726 { 0x0E, "SMS DCS: Message Waiting Indication - Store Message (UCS-2 character set)" },
727 { 0x0F, "SMS DCS: Data coding / message class" },
731 static const true_false_string tfs_dcs_text_compression = {
736 static const true_false_string tfs_dcs_class_present = {
737 "Message class is present",
741 static const value_string vals_dcs_charset[] = {
742 { 0x00, "GSM 7-bit default alphabet" },
743 { 0x01, "8-bit data" },
744 { 0x02, "UCS-2 (16-bit) data" },
745 { 0x03, "Reserved" },
749 static const value_string vals_dcs_class[] = {
751 { 0x01, "Class 1 - ME specific" },
752 { 0x02, "Class 2 - (U)SIM specific" },
753 { 0x03, "Class 3 - TE specific" },
757 static const value_string vals_dcs_cbs_coding_group[] = {
758 { 0x00, "CBS DCS: Language using the GSM 7-bit default alphabet" },
759 { 0x01, "CBS DCS: Language indication at beginning of message" },
760 { 0x02, "CBS DCS: Language using the GSM 7-bit default alphabet" },
761 { 0x03, "CBS DCS: Reserved" },
762 { 0x04, "CBS DCS: General Data Coding indication - Uncompressed text, no message class" },
763 { 0x05, "CBS DCS: General Data Coding indication - Uncompressed text" },
764 { 0x06, "CBS DCS: General Data Coding indication - Compressed text, no message class" },
765 { 0x07, "CBS DCS: General Data Coding indication - Compressed text" },
766 { 0x08, "CBS DCS: Reserved" },
767 { 0x09, "CBS DCS: Message with User Data Header structure" },
768 { 0x0A, "CBS DCS: Reserved" },
769 { 0x0B, "CBS DCS: Reserved" },
770 { 0x0C, "CBS DCS: Reserved" },
771 { 0x0D, "CBS DCS: Reserved" },
772 { 0x0E, "CBS DCS: Defined by the WAP Forum" },
773 { 0x0F, "SMS DCS: Data coding / message class" },
777 static const value_string vals_dcs_cbs_language[] = {
786 { 0x08, "Portuguese" },
788 { 0x0A, "Norwegian" },
791 { 0x0D, "Hungarian" },
793 { 0x0F, "Language not specified" },
794 { 0x10, "GSM 7-bit default alphabet - message preceeded by language indication" },
795 { 0x11, "UCS-2 (16-bit) - message preceeded by language indication" },
800 { 0x24, "Icelandic" },
804 static const value_string vals_dcs_cbs_class[] = {
805 { 0x00, "No message class" },
806 { 0x01, "Class 1 - User defined" },
807 { 0x02, "Class 2 - User defined" },
808 { 0x03, "Class 3 - TE specific" },
812 static const value_string vals_dcs_wap_class[] = {
813 { 0x00, "No message class" },
814 { 0x01, "Class 1 - ME specific" },
815 { 0x02, "Class 2 - (U)SIM specific" },
816 { 0x03, "Class 3 - TE specific" },
820 static const value_string vals_dcs_wap_charset[] = {
821 { 0x00, "Reserved" },
822 { 0x01, "8-bit data" },
823 { 0x02, "Reserved" },
824 { 0x03, "Reserved" },
829 /* 3GPP TS 23.040 V6.1.0 (2003-06) */
830 static const value_string vals_udh_iei[] = {
831 { 0x00, "SMS - Concatenated short messages, 8-bit reference number" },
832 { 0x01, "SMS - Special SMS Message Indication" },
833 { 0x02, "Reserved" },
834 { 0x03, "Value not used to avoid misinterpretation as <LF> character" },
835 { 0x04, "SMS - Application port addressing scheme, 8 bit address" },
836 { 0x05, "SMS - Application port addressing scheme, 16 bit address" },
837 { 0x06, "SMS - SMSC Control Parameters" },
838 { 0x07, "SMS - UDH Source Indicator" },
839 { 0x08, "SMS - Concatenated short message, 16-bit reference number" },
840 { 0x09, "SMS - Wireless Control Message Protocol" },
841 { 0x0A, "EMS - Text Formatting" },
842 { 0x0B, "EMS - Predefined Sound" },
843 { 0x0C, "EMS - User Defined Sound (iMelody max 128 bytes)" },
844 { 0x0D, "EMS - Predefined Animation" },
845 { 0x0E, "EMS - Large Animation (16*16 times 4 = 32*4 =128 bytes)" },
846 { 0x0F, "EMS - Small Animation (8*8 times 4 = 8*4 =32 bytes)" },
847 { 0x10, "EMS - Large Picture (32*32 = 128 bytes)" },
848 { 0x11, "EMS - Small Picture (16*16 = 32 bytes)" },
849 { 0x12, "EMS - Variable Picture" },
850 { 0x13, "EMS - User prompt indicator" },
851 { 0x14, "EMS - Extended Object" },
852 { 0x15, "EMS - Reused Extended Object" },
853 { 0x16, "EMS - Compression Control" },
854 { 0x17, "EMS - Object Distribution Indicator" },
855 { 0x18, "EMS - Standard WVG object" },
856 { 0x19, "EMS - Character Size WVG object" },
857 { 0x1A, "EMS - Extended Object Data Request Command" },
858 { 0x20, "SMS - RFC 822 E-Mail Header" },
859 { 0x21, "SMS - Hyperlink format element" },
860 { 0x22, "SMS - Reply Address Element" },
865 * SMPP equivalent of mktime() (3). Convert date to standard 'time_t' format
867 * \param datestr The SMPP-formatted date to convert
868 * \param secs Returns the 'time_t' equivalent
869 * \param nsecs Returns the additional nano-seconds
871 * \return Whether time is specified relative or absolute
872 * \retval TRUE Relative time
873 * \retval FALSE Absolute time
876 smpp_mktime(const char *datestr, time_t *secs, int *nsecs)
880 gboolean relative = FALSE;
882 r_time.tm_year = 10 * (datestr[0] - '0') + (datestr[1] - '0');
884 * Y2K rollover date as recommended in appendix C
886 if (r_time.tm_year < 38)
887 r_time.tm_year += 100;
888 r_time.tm_mon = 10 * (datestr[2] - '0') + (datestr[3] - '0');
890 r_time.tm_mday = 10 * (datestr[4] - '0') + (datestr[5] - '0');
891 r_time.tm_hour = 10 * (datestr[6] - '0') + (datestr[7] - '0');
892 r_time.tm_min = 10 * (datestr[8] - '0') + (datestr[9] - '0');
893 r_time.tm_sec = 10 * (datestr[10] - '0') + (datestr[11] - '0');
894 r_time.tm_isdst = -1;
895 *secs = mktime(&r_time);
896 *nsecs = (datestr[12] - '0') * 100000000;
897 t_diff = (10 * (datestr[13] - '0') + (datestr[14] - '0')) * 900;
898 if (datestr[15] == '+')
900 else if (datestr[15] == '-')
902 else /* Must be relative ('R') */
908 * Scanning routines to add standard types (byte, int, string...) to the
911 * \param tree The protocol tree to add to
912 * \param tvb Buffer containing the data
913 * \param field Actual field whose value needs displaying
914 * \param offset Location of field in buffer, returns location of
918 smpp_handle_string(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
922 len = tvb_strsize(tvb, *offset);
924 proto_tree_add_string(tree, field, tvb, *offset, len,
925 (const char *) tvb_get_ptr(tvb, *offset, len));
930 /* NOTE - caller must free the returned string! */
932 smpp_handle_string_return(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
937 len = tvb_strsize(tvb, *offset);
939 str = (char *)tvb_get_stringz(tvb, *offset, &len);
940 proto_tree_add_string(tree, field, tvb, *offset, len, str);
942 str = g_malloc(1 * sizeof(char));
950 smpp_handle_string_z(proto_tree *tree, tvbuff_t *tvb, int field, int *offset,
951 const char *null_string)
955 len = tvb_strsize(tvb, *offset);
957 proto_tree_add_string(tree, field, tvb, *offset, len,
958 (const char *)tvb_get_ptr(tvb, *offset, len));
960 proto_tree_add_string(tree, field, tvb, *offset, len, null_string);
966 smpp_handle_int1(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
970 val = tvb_get_guint8(tvb, *offset);
971 proto_tree_add_uint(tree, field, tvb, *offset, 1, val);
976 smpp_handle_int2(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
980 val = tvb_get_ntohs(tvb, *offset);
981 proto_tree_add_uint(tree, field, tvb, *offset, 2, val);
986 smpp_handle_int4(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
990 val = tvb_get_ntohl(tvb, *offset);
991 proto_tree_add_uint(tree, field, tvb, *offset, 4, val);
996 smpp_handle_time(proto_tree *tree, tvbuff_t *tvb,
997 int field, int field_R, int *offset)
1003 strval = (char *) tvb_get_stringz(tvb, *offset, &len);
1006 if (smpp_mktime(strval, &tmptime.secs, &tmptime.nsecs))
1007 proto_tree_add_time(tree, field_R, tvb, *offset, len, &tmptime);
1009 proto_tree_add_time(tree, field, tvb, *offset, len, &tmptime);
1016 * Scanning routine to handle the destination-list of 'submit_multi'
1018 * \param tree The protocol tree to add to
1019 * \param tvb Buffer containing the data
1020 * \param offset Location of field in buffer, returns location of
1024 smpp_handle_dlist(proto_tree *tree, tvbuff_t *tvb, int *offset)
1027 int tmpoff = *offset;
1028 proto_item *sub_tree = NULL;
1031 if ((entries = tvb_get_guint8(tvb, tmpoff++)))
1033 sub_tree = proto_tree_add_item(tree, hf_smpp_dlist,
1034 tvb, *offset, 1, FALSE);
1035 proto_item_add_subtree(sub_tree, ett_dlist);
1039 dest_flag = tvb_get_guint8(tvb, tmpoff++);
1040 if (dest_flag == 1) /* SME address */
1042 smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_ton, &tmpoff);
1043 smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_npi, &tmpoff);
1044 smpp_handle_string(sub_tree,tvb,hf_smpp_destination_addr,&tmpoff);
1046 else /* Distribution list */
1048 smpp_handle_string(sub_tree, tvb, hf_smpp_dl_name, &tmpoff);
1055 * Scanning routine to handle the destination result list
1056 * of 'submit_multi_resp'
1058 * \param tree The protocol tree to add to
1059 * \param tvb Buffer containing the data
1060 * \param offset Location of field in buffer, returns location of
1064 smpp_handle_dlist_resp(proto_tree *tree, tvbuff_t *tvb, int *offset)
1067 int tmpoff = *offset;
1068 proto_item *sub_tree = NULL;
1070 if ((entries = tvb_get_guint8(tvb, tmpoff++)))
1072 sub_tree = proto_tree_add_item(tree, hf_smpp_dlist_resp,
1073 tvb, *offset, 1, FALSE);
1074 proto_item_add_subtree(sub_tree, ett_dlist_resp);
1078 smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_ton, &tmpoff);
1079 smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_npi, &tmpoff);
1080 smpp_handle_string(sub_tree,tvb,hf_smpp_destination_addr,&tmpoff);
1081 smpp_handle_int4(sub_tree, tvb, hf_smpp_error_status_code, &tmpoff);
1087 * Scanning routine to handle all optional parameters of SMPP-operations.
1088 * The parameters have the format Tag Length Value (TLV), with a 2-byte tag
1089 * and 2-byte length.
1091 * \param tree The protocol tree to add to
1092 * \param tvb Buffer containing the data
1093 * \param offset Location of field in buffer, returns location of
1097 smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
1099 proto_item *sub_tree = NULL;
1103 guint8 major, minor;
1104 char strval[BUFSIZ];
1106 if (tvb_reported_length_remaining(tvb, *offset) >= 4)
1108 sub_tree = proto_tree_add_item(tree, hf_smpp_opt_param,
1109 tvb, *offset, 0, FALSE);
1110 proto_item_add_subtree(sub_tree, ett_opt_param);
1113 while (tvb_reported_length_remaining(tvb, *offset) >= 4)
1115 tag = tvb_get_ntohs(tvb, *offset);
1117 length = tvb_get_ntohs(tvb, *offset);
1120 case 0x0005: /* dest_addr_subunit */
1121 smpp_handle_int1(sub_tree, tvb,
1122 hf_smpp_dest_addr_subunit, offset);
1124 case 0x0006: /* dest_network_type */
1125 smpp_handle_int1(sub_tree, tvb,
1126 hf_smpp_dest_network_type, offset);
1128 case 0x0007: /* dest_bearer_type */
1129 smpp_handle_int1(sub_tree, tvb,
1130 hf_smpp_dest_bearer_type, offset);
1132 case 0x0008: /* dest_telematics_id */
1133 smpp_handle_int2(sub_tree, tvb,
1134 hf_smpp_dest_telematics_id, offset);
1136 case 0x000D: /* source_addr_subunit */
1137 smpp_handle_int1(sub_tree, tvb,
1138 hf_smpp_source_addr_subunit, offset);
1140 case 0x000E: /* source_network_type */
1141 smpp_handle_int1(sub_tree, tvb,
1142 hf_smpp_source_network_type, offset);
1144 case 0x000F: /* source_bearer_type */
1145 smpp_handle_int1(sub_tree, tvb,
1146 hf_smpp_source_bearer_type, offset);
1148 case 0x0010: /* source_telematics_id */
1149 smpp_handle_int2(sub_tree, tvb,
1150 hf_smpp_source_telematics_id, offset);
1152 case 0x0017: /* qos_time_to_live */
1153 smpp_handle_int4(sub_tree, tvb,
1154 hf_smpp_qos_time_to_live, offset);
1156 case 0x0019: /* payload_type */
1157 smpp_handle_int1(sub_tree, tvb,
1158 hf_smpp_payload_type, offset);
1160 case 0x001D: /* additional_status_info_text */
1161 smpp_handle_string(sub_tree, tvb,
1162 hf_smpp_additional_status_info_text, offset);
1164 case 0x001E: /* receipted_message_id */
1165 smpp_handle_string(sub_tree, tvb,
1166 hf_smpp_receipted_message_id, offset);
1168 case 0x0030: /* ms_msg_wait_facilities */
1169 field = tvb_get_guint8(tvb, *offset);
1170 proto_tree_add_item(sub_tree, hf_smpp_msg_wait_ind,
1171 tvb, *offset, 1, field);
1172 proto_tree_add_item(sub_tree, hf_smpp_msg_wait_type,
1173 tvb, *offset, 1, field);
1176 case 0x0201: /* privacy_indicator */
1177 smpp_handle_int1(sub_tree, tvb,
1178 hf_smpp_privacy_indicator, offset);
1180 case 0x0202: /* source_subaddress */
1181 smpp_handle_string(sub_tree, tvb,
1182 hf_smpp_source_subaddress, offset);
1184 case 0x0203: /* dest_subaddress */
1185 smpp_handle_string(sub_tree, tvb,
1186 hf_smpp_dest_subaddress, offset);
1188 case 0x0204: /* user_message_reference */
1189 smpp_handle_int2(sub_tree, tvb,
1190 hf_smpp_user_message_reference, offset);
1192 case 0x0205: /* user_response_code */
1193 smpp_handle_int1(sub_tree, tvb,
1194 hf_smpp_user_response_code, offset);
1196 case 0x020A: /* source_port */
1197 smpp_handle_int2(sub_tree, tvb,
1198 hf_smpp_source_port, offset);
1200 case 0x020B: /* destination_port */
1201 smpp_handle_int2(sub_tree, tvb,
1202 hf_smpp_destination_port, offset);
1204 case 0x020C: /* sar_msg_ref_num */
1205 smpp_handle_int2(sub_tree, tvb,
1206 hf_smpp_sar_msg_ref_num, offset);
1208 case 0x020D: /* language_indicator */
1209 smpp_handle_int1(sub_tree, tvb,
1210 hf_smpp_language_indicator, offset);
1212 case 0x020E: /* sar_total_segments */
1213 smpp_handle_int1(sub_tree, tvb,
1214 hf_smpp_sar_total_segments, offset);
1216 case 0x020F: /* sar_segment_seqnum */
1217 smpp_handle_int1(sub_tree, tvb,
1218 hf_smpp_sar_segment_seqnum, offset);
1220 case 0x0210: /* SC_interface_version */
1221 field = tvb_get_guint8(tvb, *offset);
1222 minor = field & 0x0F;
1223 major = (field & 0xF0) >> 4;
1224 sprintf(strval, "%u.%u", major, minor);
1225 proto_tree_add_string(sub_tree, hf_smpp_SC_interface_version,
1226 tvb, *offset, 1, strval);
1229 case 0x0302: /* callback_num_pres_ind */
1230 field = tvb_get_guint8(tvb, *offset);
1231 proto_tree_add_item(sub_tree, hf_smpp_callback_num_pres,
1232 tvb, *offset, 1, field);
1233 proto_tree_add_item(sub_tree, hf_smpp_callback_num_scrn,
1234 tvb, *offset, 1, field);
1237 case 0x0303: /* callback_num_atag */
1239 proto_tree_add_item(sub_tree, hf_smpp_callback_num_atag,
1240 tvb, *offset, length, FALSE);
1241 (*offset) += length;
1243 case 0x0304: /* number_of_messages */
1244 smpp_handle_int1(sub_tree, tvb,
1245 hf_smpp_number_of_messages, offset);
1247 case 0x0381: /* callback_num */
1249 proto_tree_add_item(sub_tree, hf_smpp_callback_num,
1250 tvb, *offset, length, FALSE);
1251 (*offset) += length;
1253 case 0x0420: /* dpf_result */
1254 smpp_handle_int1(sub_tree, tvb,
1255 hf_smpp_dpf_result, offset);
1257 case 0x0421: /* set_dpf */
1258 smpp_handle_int1(sub_tree, tvb,
1259 hf_smpp_set_dpf, offset);
1261 case 0x0422: /* ms_availability_status */
1262 smpp_handle_int1(sub_tree, tvb,
1263 hf_smpp_ms_availability_status, offset);
1265 case 0x0423: /* network_error_code */
1266 smpp_handle_int1(sub_tree, tvb,
1267 hf_smpp_network_error_type, offset);
1268 smpp_handle_int2(sub_tree, tvb,
1269 hf_smpp_network_error_code, offset);
1270 (*offset) += length;
1272 case 0x0424: /* message_payload */
1274 proto_tree_add_item(sub_tree, hf_smpp_message_payload,
1275 tvb, *offset, length, FALSE);
1276 (*offset) += length;
1278 case 0x0425: /* delivery_failure_reason */
1279 smpp_handle_int1(sub_tree, tvb,
1280 hf_smpp_delivery_failure_reason, offset);
1282 case 0x0426: /* more_messages_to_send */
1283 smpp_handle_int1(sub_tree, tvb,
1284 hf_smpp_more_messages_to_send, offset);
1286 case 0x0427: /* message_state */
1287 smpp_handle_int1(sub_tree, tvb,
1288 hf_smpp_message_state, offset);
1290 case 0x0501: /* ussd_service_op */
1291 smpp_handle_int1(sub_tree, tvb,
1292 hf_smpp_ussd_service_op, offset);
1294 case 0x1201: /* display_time */
1295 smpp_handle_int1(sub_tree, tvb,
1296 hf_smpp_display_time, offset);
1298 case 0x1203: /* sms_signal */
1299 smpp_handle_int2(sub_tree, tvb,
1300 hf_smpp_sms_signal, offset);
1301 /*! \todo Fill as per TIA/EIA-136-710-A */
1303 case 0x1204: /* ms_validity */
1304 smpp_handle_int1(sub_tree, tvb,
1305 hf_smpp_ms_validity, offset);
1307 case 0x130C: /* alert_on_message_delivery */
1308 proto_tree_add_item(sub_tree,
1309 hf_smpp_alert_on_message_delivery,
1310 tvb, *offset, length, FALSE);
1311 (*offset) += length;
1313 case 0x1380: /* its_reply_type */
1314 smpp_handle_int1(sub_tree, tvb,
1315 hf_smpp_its_reply_type, offset);
1317 case 0x1383: /* its_session_info */
1318 smpp_handle_int1(sub_tree, tvb,
1319 hf_smpp_its_session_number, offset);
1320 field = tvb_get_guint8(tvb, *offset);
1321 proto_tree_add_item(sub_tree, hf_smpp_its_session_sequence,
1322 tvb, *offset, 1, field);
1323 proto_tree_add_item(sub_tree, hf_smpp_its_session_ind,
1324 tvb, *offset, 1, field);
1328 if ((tag >= 0x1400) && (tag <= 0x3FFF))
1329 proto_tree_add_item(sub_tree, hf_smpp_vendor_op, tvb,
1330 *offset, length, FALSE);
1332 proto_tree_add_item(sub_tree, hf_smpp_reserved_op, tvb,
1333 *offset, length, FALSE);
1334 (*offset) += length;
1341 smpp_handle_dcs(proto_tree *tree, tvbuff_t *tvb, int *offset)
1345 proto_item *subtree = NULL;
1347 val = tvb_get_guint8(tvb, off);
1348 subtree = proto_tree_add_uint(tree,
1349 hf_smpp_data_coding, tvb, off, 1, val);
1350 proto_item_add_subtree(subtree, ett_dcs);
1351 /* SMPP Data Coding Scheme */
1352 proto_tree_add_uint(subtree, hf_smpp_dcs, tvb, off, 1, val);
1353 /* GSM SMS Data Coding Scheme */
1354 proto_tree_add_text(subtree, tvb, off, 1,
1355 "GSM SMS Data Coding");
1356 proto_tree_add_uint(subtree,
1357 hf_smpp_dcs_sms_coding_group, tvb, off, 1, val);
1358 if (val>>6 == 2) { /* Reserved */
1360 } else if (val < 0xF0) {
1361 proto_tree_add_boolean(subtree,
1362 hf_smpp_dcs_text_compression, tvb, off, 1, val);
1363 proto_tree_add_boolean(subtree,
1364 hf_smpp_dcs_class_present, tvb, off, 1, val);
1365 proto_tree_add_uint(subtree,
1366 hf_smpp_dcs_charset, tvb, off, 1, val);
1368 proto_tree_add_uint(subtree,
1369 hf_smpp_dcs_class, tvb, off, 1, val);
1372 proto_tree_add_text(subtree, tvb, off, 1,
1373 "SMPP: Bit .... 1... should be 0 (reserved)");
1374 proto_tree_add_uint(subtree,
1375 hf_smpp_dcs_charset, tvb, off, 1, val);
1376 proto_tree_add_uint(subtree,
1377 hf_smpp_dcs_class, tvb, off, 1, val);
1379 /* Cell Broadcast Service (CBS) Data Coding Scheme */
1380 proto_tree_add_text(subtree, tvb, off, 1,
1381 "GSM CBS Data Coding");
1382 proto_tree_add_uint(subtree,
1383 hf_smpp_dcs_cbs_coding_group, tvb, off, 1, val);
1384 if (val < 0x40) { /* Language specified */
1385 proto_tree_add_uint(subtree,
1386 hf_smpp_dcs_cbs_language, tvb, off, 1, val);
1387 } else if (val>>6 == 1) { /* General Data Coding indication */
1388 proto_tree_add_boolean(subtree,
1389 hf_smpp_dcs_text_compression, tvb, off, 1, val);
1390 proto_tree_add_boolean(subtree,
1391 hf_smpp_dcs_class_present, tvb, off, 1, val);
1392 proto_tree_add_uint(subtree,
1393 hf_smpp_dcs_charset, tvb, off, 1, val);
1395 proto_tree_add_uint(subtree,
1396 hf_smpp_dcs_class, tvb, off, 1, val);
1397 } else if (val>>6 == 2) { /* Message with UDH structure */
1398 proto_tree_add_uint(subtree,
1399 hf_smpp_dcs_charset, tvb, off, 1, val);
1400 proto_tree_add_uint(subtree,
1401 hf_smpp_dcs_class, tvb, off, 1, val);
1402 } else if (val>>4 == 14) { /* WAP Forum */
1403 proto_tree_add_uint(subtree,
1404 hf_smpp_dcs_wap_charset, tvb, off, 1, val);
1405 proto_tree_add_uint(subtree,
1406 hf_smpp_dcs_wap_class, tvb, off, 1, val);
1407 } else if (val>>4 == 15) { /* Data coding / message handling */
1409 proto_tree_add_text(subtree, tvb, off, 1,
1410 "SMPP: Bit .... 1... should be 0 (reserved)");
1411 proto_tree_add_uint(subtree,
1412 hf_smpp_dcs_charset, tvb, off, 1, val);
1413 proto_tree_add_uint(subtree,
1414 hf_smpp_dcs_cbs_class, tvb, off, 1, val);
1421 * The next set of routines handle the different operations, associated
1425 bind_receiver(proto_tree *tree, tvbuff_t *tvb)
1429 guint8 major, minor;
1430 char strval[BUFSIZ];
1432 smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
1433 smpp_handle_string(tree, tvb, hf_smpp_password, &offset);
1434 smpp_handle_string(tree, tvb, hf_smpp_system_type, &offset);
1435 field = tvb_get_guint8(tvb, offset++);
1436 minor = field & 0x0F;
1437 major = (field & 0xF0) >> 4;
1438 sprintf(strval, "%u.%u", major, minor);
1439 proto_tree_add_string(tree, hf_smpp_interface_version, tvb,
1440 offset - 1, 1, strval);
1441 smpp_handle_int1(tree, tvb, hf_smpp_addr_ton, &offset);
1442 smpp_handle_int1(tree, tvb, hf_smpp_addr_npi, &offset);
1443 smpp_handle_string(tree, tvb, hf_smpp_address_range, &offset);
1446 #define bind_transmitter(a, b) bind_receiver(a, b)
1449 query_sm(proto_tree *tree, tvbuff_t *tvb)
1453 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1454 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1455 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1456 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1459 #define bind_transceiver(a, b) bind_receiver(a, b)
1462 outbind(proto_tree *tree, tvbuff_t *tvb)
1466 smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
1467 smpp_handle_string(tree, tvb, hf_smpp_password, &offset);
1470 /* Parse Short Message, only if UDH present
1471 * (otherwise this function is not called).
1472 * Call WSP dissector if port matches WSP traffic.
1475 parse_sm_message(proto_tree *sm_tree, tvbuff_t *tvb, packet_info *pinfo,
1476 proto_tree *top_tree)
1478 tvbuff_t *sm_tvb = NULL;
1479 proto_item *subtree, *tree;
1480 guint8 udh_len, udh, len;
1481 guint sm_len = tvb_reported_length (tvb);
1484 /* Multiple Messages UDH */
1485 gboolean is_fragmented = FALSE;
1486 fragment_data *fd_sm = NULL;
1487 guint16 sm_id = 0, frags = 0, frag = 0;
1488 gboolean save_fragmented = FALSE, try_sm_reassemble = FALSE;
1489 /* SMS Message reassembly */
1490 gboolean reassembled = FALSE;
1491 guint32 reassembled_in = 0;
1492 /* Port Number UDH */
1493 guint16 p_src = 0, p_dst = 0;
1494 gboolean ports_available = FALSE;
1496 udh_len = tvb_get_guint8(tvb, i++);
1497 tree = proto_tree_add_uint(sm_tree, hf_smpp_udh_length, tvb, 0, 1, udh_len);
1498 tree = proto_item_add_subtree(tree, ett_udh);
1499 while (i < udh_len) {
1500 udh = tvb_get_guint8(tvb, i++);
1501 len = tvb_get_guint8(tvb, i++);
1502 subtree = proto_tree_add_uint(tree, hf_smpp_udh_iei,
1503 tvb, i-2, 2+len, udh);
1505 case 0x00: /* Multiple messages - 8-bit message ID */
1507 is_fragmented = TRUE;
1508 sm_id = tvb_get_guint8(tvb, i++);
1509 frags = tvb_get_guint8(tvb, i++);
1510 frag = tvb_get_guint8(tvb, i++);
1511 proto_item_append_text(subtree,
1512 ": message %u, part %u of %u", sm_id, frag, frags);
1513 subtree = proto_item_add_subtree(subtree,
1515 proto_tree_add_uint (subtree,
1516 hf_smpp_udh_multiple_messages_msg_id,
1517 tvb, i-3, 1, sm_id);
1518 proto_tree_add_uint (subtree,
1519 hf_smpp_udh_multiple_messages_msg_parts,
1520 tvb, i-2, 1, frags);
1521 proto_tree_add_uint (subtree,
1522 hf_smpp_udh_multiple_messages_msg_part,
1525 proto_item_append_text(subtree, " - Invalid format!");
1530 case 0x08: /* Multiple messages - 16-bit message ID */
1532 is_fragmented = TRUE;
1533 sm_id = tvb_get_ntohs(tvb, i); i += 2;
1534 frags = tvb_get_guint8(tvb, i++);
1535 frag = tvb_get_guint8(tvb, i++);
1536 proto_item_append_text(subtree,
1537 ": message %u, part %u of %u", sm_id, frag, frags);
1538 subtree = proto_item_add_subtree(subtree,
1540 proto_tree_add_uint (subtree,
1541 hf_smpp_udh_multiple_messages_msg_id,
1542 tvb, i-4, 2, sm_id);
1543 proto_tree_add_uint (subtree,
1544 hf_smpp_udh_multiple_messages_msg_parts,
1545 tvb, i-2, 1, frags);
1546 proto_tree_add_uint (subtree,
1547 hf_smpp_udh_multiple_messages_msg_part,
1550 proto_item_append_text(subtree, " - Invalid format!");
1555 case 0x04: /* Port Number UDH - 8-bit address */
1556 if (len == 2) { /* Port fields */
1557 p_dst = tvb_get_guint8(tvb, i++);
1558 p_src = tvb_get_guint8(tvb, i++);
1559 proto_item_append_text(subtree,
1560 ": source port %u, destination port %u",
1562 subtree = proto_item_add_subtree(subtree, ett_udh_ie);
1563 proto_tree_add_uint (subtree, hf_smpp_udh_ports_dst,
1564 tvb, i-2, 1, p_dst);
1565 proto_tree_add_uint (subtree, hf_smpp_udh_ports_src,
1566 tvb, i-1, 1, p_src);
1567 ports_available = TRUE;
1569 proto_item_append_text(subtree, " - Invalid format!");
1574 case 0x05: /* Port Number UDH - 16-bit address */
1575 if (len == 4) { /* Port fields */
1576 p_dst = tvb_get_ntohs(tvb, i); i += 2;
1577 p_src = tvb_get_ntohs(tvb, i); i += 2;
1578 proto_item_append_text(subtree,
1579 ": source port %u, destination port %u",
1581 subtree = proto_item_add_subtree(subtree, ett_udh_ie);
1582 proto_tree_add_uint (subtree, hf_smpp_udh_ports_dst,
1583 tvb, i-4, 2, p_dst);
1584 proto_tree_add_uint (subtree, hf_smpp_udh_ports_src,
1585 tvb, i-2, 2, p_src);
1586 ports_available = TRUE;
1588 proto_item_append_text(subtree, " - Invalid format!");
1598 if (tvb_reported_length_remaining(tvb, i) <= 0)
1599 return; /* No more data */
1602 * XXX - where does the "1" come from? If it weren't there,
1603 * "sm_data_len" would, I think, be the same as
1604 * "tvb_reported_length_remaining(tvb, i)".
1606 * I think that the above check ensures that "sm_len" won't
1607 * be less than or equal to "udh_len", so it ensures that
1608 * "sm_len" won't be less than "1 + udh_len", so we don't
1609 * have to worry about "sm_data_len" being negative.
1611 sm_data_len = sm_len - (1 + udh_len);
1612 if (sm_data_len == 0)
1613 return; /* no more data */
1616 * Try reassembling the packets.
1617 * XXX - fragment numbers are 1-origin, but the fragment number
1619 * Should we flag a fragmented message with a fragment number field
1621 * What if the fragment count is 0? Should we flag that as well?
1623 if ( is_fragmented && frag != 0 && frags != 0 &&
1624 tvb_bytes_exist (tvb, i, sm_data_len) ) {
1625 try_sm_reassemble = TRUE;
1626 save_fragmented = pinfo->fragmented;
1627 pinfo->fragmented = TRUE;
1628 fd_sm = fragment_add_seq_check (tvb, i, pinfo,
1629 sm_id, /* guint32 ID for fragments belonging together */
1630 sm_fragment_table, /* list of message fragments */
1631 sm_reassembled_table, /* list of reassembled messages */
1632 frag-1, /* guint32 fragment sequence number */
1633 sm_data_len, /* guint32 fragment length */
1634 (frag != frags)); /* More fragments? */
1637 reassembled_in = fd_sm->reassembled_in;
1639 sm_tvb = process_reassembled_data(tvb, i, pinfo,
1640 "Reassembled Short Message", fd_sm, &sm_frag_items,
1642 if (reassembled) { /* Reassembled */
1643 if (check_col (pinfo->cinfo, COL_INFO))
1644 col_append_str (pinfo->cinfo, COL_INFO,
1645 " (Short Message Reassembled)");
1647 /* Not last packet of reassembled Short Message */
1648 if (check_col (pinfo->cinfo, COL_INFO))
1649 col_append_fstr (pinfo->cinfo, COL_INFO,
1650 " (Short Message fragment %u of %u)", frag, frags);
1652 } /* Else: not fragmented */
1654 if (! sm_tvb) /* One single Short Message, or not reassembled */
1655 sm_tvb = tvb_new_subset (tvb, i, -1, -1);
1656 /* Try calling a subdissector */
1658 if ((reassembled && pinfo->fd->num == reassembled_in)
1659 || frag==0 || (frag==1 && try_dissect_1st_frag)) {
1660 /* Try calling a subdissector only if:
1661 * - the Short Message is reassembled in this very packet,
1662 * - the Short Message consists of only one "fragment",
1663 * - the preference "Always Try Dissection for 1st SM fragment"
1664 * is switched on, and this is the SM's 1st fragment. */
1665 if ( ports_available ) {
1666 if ( port_number_udh_means_wsp ) {
1667 call_dissector (wsp_handle, sm_tvb, pinfo, top_tree);
1669 if (! dissector_try_port(gsm_sms_dissector_table, p_src,
1670 sm_tvb, pinfo, top_tree)) {
1671 if (! dissector_try_port(gsm_sms_dissector_table, p_dst,
1672 sm_tvb, pinfo, top_tree)) {
1673 if (sm_tree) { /* Only display if needed */
1674 proto_tree_add_text (sm_tree, sm_tvb, 0, -1,
1675 "Short Message body");
1680 } else { /* No ports IE */
1681 proto_tree_add_text (sm_tree, sm_tvb, 0, -1,
1682 "Short Message body");
1685 /* The packet is not reassembled,
1686 * or it is reassembled in another packet */
1687 proto_tree_add_text (sm_tree, sm_tvb, 0, -1,
1688 "Unreassembled Short Message fragment %u of %u",
1693 if (try_sm_reassemble) /* Clean up defragmentation */
1694 pinfo->fragmented = save_fragmented;
1699 submit_sm(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
1700 proto_tree *top_tree)
1706 char *src_str = NULL;
1707 char *dst_str = NULL;
1708 address save_src, save_dst;
1710 smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1711 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1712 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1713 src_str = smpp_handle_string_return(tree, tvb, hf_smpp_source_addr, &offset);
1714 smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
1715 smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
1716 dst_str = smpp_handle_string_return(tree, tvb, hf_smpp_destination_addr, &offset);
1717 flag = tvb_get_guint8(tvb, offset);
1719 proto_tree_add_item(tree, hf_smpp_esm_submit_msg_mode,
1720 tvb, offset, 1, flag);
1721 proto_tree_add_item(tree, hf_smpp_esm_submit_msg_type,
1722 tvb, offset, 1, flag);
1723 proto_tree_add_item(tree, hf_smpp_esm_submit_features,
1724 tvb, offset, 1, flag);
1726 smpp_handle_int1(tree, tvb, hf_smpp_protocol_id, &offset);
1727 smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
1728 if (tvb_get_guint8(tvb,offset)) {
1729 smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
1730 hf_smpp_schedule_delivery_time_r, &offset);
1731 } else { /* Time = NULL means Immediate delivery */
1732 proto_tree_add_text(tree, tvb, offset++, 1,
1733 "Scheduled delivery time: Immediate delivery");
1735 if (tvb_get_guint8(tvb,offset)) {
1736 smpp_handle_time(tree, tvb, hf_smpp_validity_period,
1737 hf_smpp_validity_period_r, &offset);
1738 } else { /* Time = NULL means SMSC default validity */
1739 proto_tree_add_text(tree, tvb, offset++, 1,
1740 "Validity period: SMSC default validity period");
1742 flag = tvb_get_guint8(tvb, offset);
1743 proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1744 proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1745 proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1747 smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
1748 smpp_handle_dcs(tree, tvb, &offset);
1749 smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
1750 length = tvb_get_guint8(tvb, offset);
1751 proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
1754 proto_tree_add_item(tree, hf_smpp_short_message,
1755 tvb, offset, length, FALSE);
1756 if (udhi) /* UDHI indicator present */
1758 DebugLog(("UDHI present - set addresses\n"));
1759 /* Save original addresses */
1760 COPY_ADDRESS(&save_src, &(pinfo->src));
1761 COPY_ADDRESS(&save_dst, &(pinfo->dst));
1762 /* Set SMPP source and destination address */
1763 SET_ADDRESS(&(pinfo->src), AT_STRINGZ, 1+strlen(src_str), src_str);
1764 SET_ADDRESS(&(pinfo->dst), AT_STRINGZ, 1+strlen(dst_str), dst_str);
1765 tvb_msg = tvb_new_subset (tvb, offset,
1766 MIN(length, tvb_reported_length(tvb) - offset), length);
1767 call_dissector (gsm_sms_handle, tvb_msg, pinfo, top_tree);
1768 /* Restore original addresses */
1769 COPY_ADDRESS(&(pinfo->src), &save_src);
1770 COPY_ADDRESS(&(pinfo->dst), &save_dst);
1771 /* Get rid of SMPP text string addresses */
1777 smpp_handle_tlv(tree, tvb, &offset);
1780 #define deliver_sm(a, b, c, d) submit_sm(a, b, c, d)
1783 replace_sm(proto_tree *tree, tvbuff_t *tvb)
1789 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1790 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1791 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1792 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1793 if (tvb_get_guint8(tvb,offset)) {
1794 smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
1795 hf_smpp_schedule_delivery_time_r, &offset);
1796 } else { /* Time = NULL */
1797 proto_tree_add_text(tree, tvb, offset++, 1,
1798 "Scheduled delivery time: Keep initial delivery time setting");
1800 if (tvb_get_guint8(tvb,offset)) {
1801 smpp_handle_time(tree, tvb, hf_smpp_validity_period,
1802 hf_smpp_validity_period_r, &offset);
1803 } else { /* Time = NULL */
1804 proto_tree_add_text(tree, tvb, offset++, 1,
1805 "Validity period: Keep initial validity period setting");
1807 flag = tvb_get_guint8(tvb, offset);
1808 proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1809 proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1810 proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1812 smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
1813 length = tvb_get_guint8(tvb, offset);
1814 proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
1816 proto_tree_add_item(tree, hf_smpp_short_message,
1817 tvb, offset, length, FALSE);
1822 cancel_sm(proto_tree *tree, tvbuff_t *tvb)
1826 smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1827 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1828 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1829 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1830 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1831 smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
1832 smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
1833 smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
1837 submit_multi(proto_tree *tree, tvbuff_t *tvb)
1843 smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1844 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1845 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1846 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1848 smpp_handle_dlist(tree, tvb, &offset);
1850 flag = tvb_get_guint8(tvb, offset);
1851 proto_tree_add_item(tree, hf_smpp_esm_submit_msg_mode,
1852 tvb, offset, 1, flag);
1853 proto_tree_add_item(tree, hf_smpp_esm_submit_msg_type,
1854 tvb, offset, 1, flag);
1855 proto_tree_add_item(tree, hf_smpp_esm_submit_features,
1856 tvb, offset, 1, flag);
1858 smpp_handle_int1(tree, tvb, hf_smpp_protocol_id, &offset);
1859 smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
1860 if (tvb_get_guint8(tvb,offset)) {
1861 smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
1862 hf_smpp_schedule_delivery_time_r, &offset);
1863 } else { /* Time = NULL means Immediate delivery */
1864 proto_tree_add_text(tree, tvb, offset++, 1,
1865 "Scheduled delivery time: Immediate delivery");
1867 if (tvb_get_guint8(tvb,offset)) {
1868 smpp_handle_time(tree, tvb, hf_smpp_validity_period,
1869 hf_smpp_validity_period_r, &offset);
1870 } else { /* Time = NULL means SMSC default validity */
1871 proto_tree_add_text(tree, tvb, offset++, 1,
1872 "Validity period: SMSC default validity period");
1874 flag = tvb_get_guint8(tvb, offset);
1875 proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1876 proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1877 proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1879 smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
1880 smpp_handle_dcs(tree, tvb, &offset);
1881 smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
1882 length = tvb_get_guint8(tvb, offset);
1883 proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
1885 proto_tree_add_item(tree, hf_smpp_short_message,
1886 tvb, offset, length, FALSE);
1888 smpp_handle_tlv(tree, tvb, &offset);
1892 alert_notification(proto_tree *tree, tvbuff_t *tvb)
1896 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1897 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1898 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1899 smpp_handle_int1(tree, tvb, hf_smpp_esme_addr_ton, &offset);
1900 smpp_handle_int1(tree, tvb, hf_smpp_esme_addr_npi, &offset);
1901 smpp_handle_string(tree, tvb, hf_smpp_esme_addr, &offset);
1902 smpp_handle_tlv(tree, tvb, &offset);
1906 data_sm(proto_tree *tree, tvbuff_t *tvb)
1911 smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1912 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1913 smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1914 smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1915 smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
1916 smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
1917 smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
1918 flag = tvb_get_guint8(tvb, offset);
1919 proto_tree_add_item(tree, hf_smpp_esm_submit_msg_mode,
1920 tvb, offset, 1, flag);
1921 proto_tree_add_item(tree, hf_smpp_esm_submit_msg_type,
1922 tvb, offset, 1, flag);
1923 proto_tree_add_item(tree, hf_smpp_esm_submit_features,
1924 tvb, offset, 1, flag);
1926 flag = tvb_get_guint8(tvb, offset);
1927 proto_tree_add_item(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1928 proto_tree_add_item(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1929 proto_tree_add_item(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1931 smpp_handle_dcs(tree, tvb, &offset);
1932 smpp_handle_tlv(tree, tvb, &offset);
1936 * The next set of routines handle the different operation-responses,
1937 * associated with SMPP.
1940 bind_receiver_resp(proto_tree *tree, tvbuff_t *tvb)
1944 smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
1945 smpp_handle_tlv(tree, tvb, &offset);
1948 #define bind_transmitter_resp(a, b) bind_receiver_resp(a, b)
1951 query_sm_resp(proto_tree *tree, tvbuff_t *tvb)
1955 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1956 smpp_handle_time(tree, tvb, hf_smpp_final_date,
1957 hf_smpp_final_date_r, &offset);
1958 smpp_handle_int1(tree, tvb, hf_smpp_message_state, &offset);
1959 smpp_handle_int1(tree, tvb, hf_smpp_error_code, &offset);
1962 #define bind_transceiver_resp(a, b) bind_receiver_resp(a, b)
1965 submit_sm_resp(proto_tree *tree, tvbuff_t *tvb)
1969 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1972 #define deliver_sm_resp(a, b) submit_sm_resp(a, b)
1975 submit_multi_resp(proto_tree *tree, tvbuff_t *tvb)
1979 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1980 smpp_handle_dlist_resp(tree, tvb, &offset);
1984 data_sm_resp(proto_tree *tree, tvbuff_t *tvb)
1988 smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1989 smpp_handle_tlv(tree, tvb, &offset);
1993 * A 'heuristic dissector' that attemtps to establish whether we have
1994 * a genuine SMPP PDU here.
1996 * at least the fixed header is there
1997 * it has a correct overall PDU length
1998 * it is a 'well-known' operation
1999 * has a 'well-known' status
2002 dissect_smpp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2004 guint command_id; /* SMPP command */
2005 guint command_status; /* Status code */
2006 guint command_length; /* length of PDU */
2008 if (tvb_reported_length(tvb) < 4 * 4) /* Mandatory header */
2010 command_length = tvb_get_ntohl(tvb, 0);
2011 if (command_length > 64 * 1024)
2013 command_id = tvb_get_ntohl(tvb, 4); /* Only known commands */
2014 if (match_strval(command_id, vals_command_id) == NULL)
2016 command_status = tvb_get_ntohl(tvb, 8); /* ..with known status */
2017 if (match_strval(command_status, vals_command_status) == NULL)
2019 dissect_smpp(tvb, pinfo, tree);
2024 get_smpp_pdu_len(tvbuff_t *tvb, int offset)
2026 return tvb_get_ntohl(tvb, offset);
2030 * This global SMPP variable is used to determine whether the PDU to dissect
2031 * is the first SMPP PDU in the packet (or reassembled buffer), requiring
2032 * different column update code than subsequent SMPP PDUs within this packet
2033 * (or reassembled buffer).
2035 * FIXME - This approach is NOT dissection multi-thread safe!
2037 static gboolean first = TRUE;
2040 dissect_smpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2043 if (pinfo->ptype == PT_TCP) { /* are we running on top of TCP */
2044 tcp_dissect_pdus(tvb, pinfo, tree,
2045 reassemble_over_tcp, /* Do we try to reassemble */
2046 16, /* Length of fixed header */
2047 get_smpp_pdu_len, /* Function returning PDU len */
2048 dissect_smpp_pdu); /* PDU dissector */
2049 } else { /* no? probably X.25 */
2051 while (tvb_reported_length_remaining(tvb, offset) > 0) {
2052 guint16 pdu_len = tvb_get_ntohl(tvb, offset);
2053 gint pdu_real_len = tvb_length_remaining(tvb, offset);
2056 if (pdu_real_len <= 0)
2058 if (pdu_real_len > pdu_len)
2059 pdu_real_len = pdu_len;
2060 pdu_tvb = tvb_new_subset(tvb, offset, pdu_real_len, pdu_len);
2061 dissect_smpp_pdu(pdu_tvb, pinfo, tree);
2069 /* Dissect a single SMPP PDU contained within "tvb". */
2071 dissect_smpp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2073 int offset = 0; /* Offset within tvbuff */
2074 guint command_length; /* length of PDU */
2075 guint command_id; /* SMPP command */
2076 guint command_status; /* Status code */
2077 guint sequence_number; /* ...of command */
2079 gchar *command_status_str = NULL;
2080 /* Set up structures needed to add the protocol subtree and manage it */
2081 proto_item *ti = NULL;
2082 proto_tree *smpp_tree = NULL;
2085 * Safety: don't even try to dissect the PDU
2086 * when the mandatory header isn't present.
2088 if (tvb_reported_length(tvb) < 4 * 4)
2090 command_length = tvb_get_ntohl(tvb, offset);
2092 command_id = tvb_get_ntohl(tvb, offset);
2093 command_str = val_to_str(command_id, vals_command_id,
2094 "(Unknown SMPP Operation 0x%08X)");
2096 command_status = tvb_get_ntohl(tvb, offset);
2097 if (command_id & 0x80000000) {
2098 command_status_str = val_to_str(command_status, vals_command_status,
2099 "(Reserved Error 0x%08X)");
2102 sequence_number = tvb_get_ntohl(tvb, offset);
2106 * Update the protocol column.
2108 if (first == TRUE) {
2109 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2110 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMPP");
2114 * Create display subtree for the protocol
2117 ti = proto_tree_add_item (tree, proto_smpp, tvb, 0, tvb->length, FALSE);
2118 smpp_tree = proto_item_add_subtree (ti, ett_smpp);
2122 * Cycle over the encapsulated PDUs
2128 * Make entries in the Info column on the summary display
2130 if (check_col(pinfo->cinfo, COL_INFO)) {
2131 if (first == TRUE) {
2133 * First PDU - We already computed the fixed header
2135 col_clear(pinfo->cinfo, COL_INFO);
2136 col_add_fstr(pinfo->cinfo, COL_INFO, "SMPP %s", command_str);
2142 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", command_str);
2145 * Display command status of responses in Info column
2147 if (command_id & 0x80000000) {
2148 col_append_fstr(pinfo->cinfo, COL_INFO, ": \"%s\"",
2149 command_status_str);
2154 * Create a tvb for the current PDU.
2155 * Physical length: at most command_length
2156 * Reported length: command_length
2158 if (tvb_length_remaining(tvb, offset - 16 + command_length) > 0) {
2159 pdu_tvb = tvb_new_subset(tvb, offset - 16,
2160 command_length, /* Physical length */
2161 command_length); /* Length reported by the protocol */
2163 pdu_tvb = tvb_new_subset(tvb, offset - 16,
2164 tvb_length_remaining(tvb, offset - 16),/* Physical length */
2165 command_length); /* Length reported by the protocol */
2171 * If "tree" is NULL, Ethereal is only interested in creation
2172 * of conversations, reassembly and subdissection but not in
2173 * the detailed protocol tree.
2174 * In the interest of speed, skip the generation of protocol tree
2175 * items when "tree" is NULL.
2177 * The only PDU which requires subdissection currently is the
2178 * sm_submit PDU (command ID = 0x00000004).
2180 if (tree || (command_id == 4))
2183 * Create display subtree for the PDU
2186 proto_tree_add_uint(smpp_tree, hf_smpp_command_length,
2187 pdu_tvb, 0, 4, command_length);
2188 proto_tree_add_uint(smpp_tree, hf_smpp_command_id,
2189 pdu_tvb, 4, 4, command_id);
2190 proto_item_append_text(ti, ", Command: %s", command_str);
2193 * Status is only meaningful with responses
2195 if (command_id & 0x80000000) {
2196 proto_tree_add_uint(smpp_tree, hf_smpp_command_status,
2197 pdu_tvb, 8, 4, command_status);
2198 proto_item_append_text (ti, ", Status: \"%s\"",
2199 command_status_str);
2201 proto_tree_add_uint(smpp_tree, hf_smpp_sequence_number,
2202 pdu_tvb, 12, 4, sequence_number);
2203 proto_item_append_text(ti, ", Seq: %u, Len: %u",
2204 sequence_number, command_length);
2208 * End of fixed header.
2209 * Don't dissect variable part if it is shortened.
2211 * FIXME - We then do not report a Short Frame or Malformed Packet
2213 if (command_length <= tvb_reported_length(pdu_tvb))
2215 tvbuff_t *tmp_tvb = tvb_new_subset(pdu_tvb, 16,
2216 -1, command_length - 16);
2217 if (command_id & 0x80000000)
2219 switch (command_id & 0x7FFFFFFF) {
2221 * All of these only have a fixed header
2223 case 0: /* Generic nack */
2224 case 6: /* Unbind resp */
2225 case 7: /* Replace SM resp */
2226 case 8: /* Cancel SM resp */
2227 case 21: /* Enquire link resp */
2230 if (!command_status)
2231 bind_receiver_resp(smpp_tree, tmp_tvb);
2234 if (!command_status)
2235 bind_transmitter_resp(smpp_tree, tmp_tvb);
2238 if (!command_status)
2239 query_sm_resp(smpp_tree, tmp_tvb);
2242 if (!command_status)
2243 submit_sm_resp(smpp_tree, tmp_tvb);
2246 if (!command_status)
2247 deliver_sm_resp(smpp_tree, tmp_tvb);
2250 if (!command_status)
2251 bind_transceiver_resp(smpp_tree, tmp_tvb);
2254 if (!command_status)
2255 submit_multi_resp(smpp_tree, tmp_tvb);
2258 if (!command_status)
2259 data_sm_resp(smpp_tree, tmp_tvb);
2263 } /* switch (command_id & 0x7FFFFFFF) */
2267 switch (command_id) {
2269 bind_receiver(smpp_tree, tmp_tvb);
2272 bind_transmitter(smpp_tree, tmp_tvb);
2275 query_sm(smpp_tree, tmp_tvb);
2278 submit_sm(smpp_tree, tmp_tvb, pinfo, tree);
2281 deliver_sm(smpp_tree, tmp_tvb, pinfo, tree);
2283 case 6: /* Unbind */
2284 case 21: /* Enquire link */
2287 replace_sm(smpp_tree, tmp_tvb);
2290 cancel_sm(smpp_tree, tmp_tvb);
2293 bind_transceiver(smpp_tree, tmp_tvb);
2296 outbind(smpp_tree, tmp_tvb);
2299 submit_multi(smpp_tree, tmp_tvb);
2302 alert_notification(smpp_tree, tmp_tvb);
2305 data_sm(smpp_tree, tmp_tvb);
2309 } /* switch (command_id) */
2310 } /* if (command_id & 0x80000000) */
2311 } /* if (command_length <= tvb_reported_length(pdu_tvb)) */
2312 offset += command_length;
2313 } /* if (tree || (command_id == 4)) */
2322 * GSM SMS dissection
2325 dissect_smpp_gsm_sms(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2328 proto_tree *subtree;
2329 DebugLog(("dissect_smpp_gsm_sms() - START\n"));
2330 ti = proto_tree_add_item(tree, proto_smpp_gsm_sms, tvb, 0, -1, TRUE);
2331 subtree = proto_item_add_subtree(ti, ett_gsm_sms);
2332 parse_sm_message(subtree, tvb, pinfo, tree);
2333 DebugLog(("dissect_smpp_gsm_sms() - END\n"));
2336 /* Register the protocol with Ethereal */
2338 proto_register_smpp_gsm_sms(void)
2340 module_t *smpp_gsm_sms_module; /* Preferences for SMPP */
2342 /* Setup list of header fields */
2343 static hf_register_info hf[] = {
2348 { "IE Id", "smpp.gsm-sms.udh.iei",
2349 FT_UINT8, BASE_HEX, VALS(vals_udh_iei), 0x00,
2350 "Name of the User Data Header Information Element.",
2354 { &hf_smpp_udh_length,
2355 { "UDH Length", "smpp.gsm-sms.udh.len",
2356 FT_UINT8, BASE_DEC, NULL, 0x00,
2357 "Length of the User Data Header (bytes)",
2361 { &hf_smpp_udh_multiple_messages,
2362 { "Multiple messages UDH", "smpp.gsm-sms.udh.mm",
2363 FT_NONE, BASE_NONE, NULL, 0x00,
2364 "Multiple messages User Data Header",
2368 { &hf_smpp_udh_multiple_messages_msg_id,
2369 { "Message identifier", "smpp.gsm-sms.udh.mm.msg_id",
2370 FT_UINT16, BASE_DEC, NULL, 0x00,
2371 "Identification of the message",
2375 { &hf_smpp_udh_multiple_messages_msg_parts,
2376 { "Message parts", "smpp.gsm-sms.udh.mm.msg_parts",
2377 FT_UINT8, BASE_DEC, NULL, 0x00,
2378 "Total number of message parts (fragments)",
2382 { &hf_smpp_udh_multiple_messages_msg_part,
2383 { "Message part number", "smpp.gsm-sms.udh.mm.msg_part",
2384 FT_UINT8, BASE_DEC, NULL, 0x00,
2385 "Message part (fragment) sequence number",
2389 { &hf_smpp_udh_ports,
2390 { "Port number UDH", "smpp.gsm-sms.udh.ports",
2391 FT_NONE, BASE_NONE, NULL, 0x00,
2392 "Port number User Data Header",
2396 { &hf_smpp_udh_ports_src,
2397 { "Source port", "smpp.gsm-sms.udh.ports.src",
2398 FT_UINT8, BASE_DEC, NULL, 0x00,
2403 { &hf_smpp_udh_ports_dst,
2404 { "Destination port", "smpp.gsm-sms.udh.ports.dst",
2405 FT_UINT8, BASE_DEC, NULL, 0x00,
2411 * Short Message fragment reassembly
2414 { "Short Message fragments", "smpp.gsm-sms.fragments",
2415 FT_NONE, BASE_NONE, NULL, 0x00,
2416 "SMPP Short Message fragments",
2421 { "Short Message fragment", "smpp.gsm-sms.fragment",
2422 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
2423 "SMPP Short Message fragment",
2427 { &hf_sm_fragment_overlap,
2428 { "Short Message fragment overlap", "smpp.gsm-sms.fragment.overlap",
2429 FT_BOOLEAN, BASE_NONE, NULL, 0x00,
2430 "SMPP Short Message fragment overlaps with other fragment(s)",
2434 { &hf_sm_fragment_overlap_conflicts,
2435 { "Short Message fragment overlapping with conflicting data",
2436 "smpp.gsm-sms.fragment.overlap.conflicts",
2437 FT_BOOLEAN, BASE_NONE, NULL, 0x00,
2438 "SMPP Short Message fragment overlaps with conflicting data",
2442 { &hf_sm_fragment_multiple_tails,
2443 { "Short Message has multiple tail fragments",
2444 "smpp.gsm-sms.fragment.multiple_tails",
2445 FT_BOOLEAN, BASE_NONE, NULL, 0x00,
2446 "SMPP Short Message fragment has multiple tail fragments",
2450 { &hf_sm_fragment_too_long_fragment,
2451 { "Short Message fragment too long",
2452 "smpp.gsm-sms.fragment.too_long_fragment",
2453 FT_BOOLEAN, BASE_NONE, NULL, 0x00,
2454 "SMPP Short Message fragment data goes beyond the packet end",
2458 { &hf_sm_fragment_error,
2459 { "Short Message defragmentation error", "smpp.gsm-sms.fragment.error",
2460 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
2461 "SMPP Short Message defragmentation error due to illegal fragments",
2465 { &hf_sm_reassembled_in,
2467 "smpp.gsm-sms.reassembled.in",
2468 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
2469 "SMPP Short Message has been reassembled in this packet.", HFILL
2474 static gint *ett[] = {
2481 DebugLog(("Registering SMPP GSM SMS dissector\n"));
2482 /* Register the protocol name and description */
2483 proto_smpp_gsm_sms = proto_register_protocol(
2484 "SMPP - GSM Short Message Service", /* Name */
2485 "SMPP GSM SMS", /* Short name */
2486 "smpp-gsm-sms"); /* Filter name */
2488 /* Required function calls to register header fields and subtrees used */
2489 proto_register_field_array(proto_smpp, hf, array_length(hf));
2490 proto_register_subtree_array(ett, array_length(ett));
2492 /* Subdissector code */
2493 gsm_sms_dissector_table = register_dissector_table("smpp.gsm-sms.udh.port",
2494 "GSM SMS port IE in UDH", FT_UINT16, BASE_DEC);
2496 /* Preferences for SMPP */
2497 smpp_gsm_sms_module = prefs_register_protocol (proto_smpp_gsm_sms, NULL);
2498 prefs_register_bool_preference (smpp_gsm_sms_module,
2499 "port_number_udh_means_wsp",
2500 "Port Number IE in UDH always triggers CL-WSP dissection",
2501 "Always decode a GSM Short Message as Connectionless WSP "
2502 "if a Port Number Information Element is present "
2503 "in the SMS User Data Header.",
2504 &port_number_udh_means_wsp);
2505 prefs_register_bool_preference (smpp_gsm_sms_module, "try_dissect_1st_fragment",
2506 "Always try subdissection of 1st Short Message fragment",
2507 "Always try subdissection of the 1st fragment of a fragmented "
2508 "GSM Short Message. If reassembly is possible, the Short Message "
2509 "may be dissected twice (once as a short frame, once in its "
2511 &try_dissect_1st_frag);
2513 register_dissector("smpp-gsm-sms", dissect_smpp_gsm_sms, proto_smpp_gsm_sms);
2515 /* SMPP dissector initialization routines */
2516 register_init_routine (sm_defragment_init);
2520 proto_reg_handoff_smpp_gsm_sms(void)
2522 dissector_handle_t smpp_gsm_sms_handle;
2523 DebugLog(("Creating SMPP GSM SMS dissector handle\n"));
2524 smpp_gsm_sms_handle = create_dissector_handle(dissect_smpp_gsm_sms,
2525 proto_smpp_gsm_sms);
2531 /* Register the protocol with Ethereal */
2533 proto_register_smpp(void)
2535 module_t *smpp_module; /* Preferences for SMPP */
2537 /* Setup list of header fields */
2538 static hf_register_info hf[] = {
2539 { &hf_smpp_command_length,
2540 { "Length ", "smpp.command_length",
2541 FT_UINT32, BASE_DEC, NULL, 0x00,
2542 "Total length of the SMPP PDU.",
2546 { &hf_smpp_command_id,
2547 { "Operation ", "smpp.command_id",
2548 FT_UINT32, BASE_HEX, VALS(vals_command_id), 0x00,
2549 "Defines the SMPP PDU.",
2553 { &hf_smpp_command_status,
2554 { "Result ", "smpp.command_status",
2555 FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
2556 "Indicates success or failure of the SMPP request.",
2560 { &hf_smpp_sequence_number,
2561 { "Sequence #", "smpp.sequence_number",
2562 FT_UINT32, BASE_DEC, NULL, 0x00,
2563 "A number to correlate requests with responses.",
2567 { &hf_smpp_system_id,
2568 { "System ID", "smpp.system_id",
2569 FT_STRING, BASE_NONE, NULL, 0x00,
2570 "Identifies a system.",
2574 { &hf_smpp_password,
2575 { "Password", "smpp.password",
2576 FT_STRING, BASE_NONE, NULL, 0x00,
2577 "Password used for authentication.",
2581 { &hf_smpp_system_type,
2582 { "System type", "smpp.system_type",
2583 FT_STRING, BASE_NONE, NULL, 0x00,
2584 "Categorises the system.",
2588 { &hf_smpp_interface_version,
2589 { "Version (if)", "smpp.interface_version",
2590 FT_STRING, BASE_NONE, NULL, 0x00,
2591 "Version of SMPP interface supported.",
2595 { &hf_smpp_service_type,
2596 { "Service type", "smpp.service_type",
2597 FT_STRING, BASE_NONE, NULL, 0x00,
2598 "SMS application service associated with the message.",
2602 { &hf_smpp_addr_ton,
2603 { "Type of number", "smpp.addr_ton",
2604 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2605 "Indicates the type of number, given in the address.",
2609 { &hf_smpp_source_addr_ton,
2610 { "Type of number (originator)", "smpp.source_addr_ton",
2611 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2612 "Indicates originator type of number, given in the address.",
2616 { &hf_smpp_dest_addr_ton,
2617 { "Type of number (recipient)", "smpp.dest_addr_ton",
2618 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2619 "Indicates recipient type of number, given in the address.",
2623 { &hf_smpp_addr_npi,
2624 { "Numbering plan indicator", "smpp.addr_npi",
2625 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2626 "Gives the numbering plan this address belongs to.",
2630 { &hf_smpp_source_addr_npi,
2631 { "Numbering plan indicator (originator)", "smpp.source_addr_npi",
2632 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2633 "Gives originator numbering plan this address belongs to.",
2637 { &hf_smpp_dest_addr_npi,
2638 { "Numbering plan indicator (recipient)", "smpp.dest_addr_npi",
2639 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2640 "Gives recipient numbering plan this address belongs to.",
2644 { &hf_smpp_address_range,
2645 { "Address", "smpp.address_range",
2646 FT_STRING, BASE_NONE, NULL, 0x00,
2647 "Given address or address range.",
2651 { &hf_smpp_source_addr,
2652 { "Originator address", "smpp.source_addr",
2653 FT_STRING, BASE_NONE, NULL, 0x00,
2654 "Address of SME originating this message.",
2658 { &hf_smpp_destination_addr,
2659 { "Recipient address", "smpp.destination_addr",
2660 FT_STRING, BASE_NONE, NULL, 0x00,
2661 "Address of SME receiving this message.",
2665 { &hf_smpp_esm_submit_msg_mode,
2666 { "Messaging mode", "smpp.esm.submit.msg_mode",
2667 FT_UINT8, BASE_HEX, VALS(vals_esm_submit_msg_mode), 0x03,
2668 "Mode attribute for this message.",
2672 { &hf_smpp_esm_submit_msg_type,
2673 { "Message type ", "smpp.esm.submit.msg_type",
2674 FT_UINT8, BASE_HEX, VALS(vals_esm_submit_msg_type), 0x3C,
2675 "Type attribute for this message.",
2679 { &hf_smpp_esm_submit_features,
2680 { "GSM features ", "smpp.esm.submit.features",
2681 FT_UINT8, BASE_HEX, VALS(vals_esm_submit_features), 0xC0,
2682 "GSM network specific features.",
2686 /*! \todo Get proper values from GSM-spec. */
2687 { &hf_smpp_protocol_id,
2688 { "Protocol id.", "smpp.protocol_id",
2689 FT_UINT8, BASE_HEX, NULL, 0x00,
2690 "Protocol identifier according GSM 03.40.",
2694 { &hf_smpp_priority_flag,
2695 { "Priority level", "smpp.priority_flag",
2696 FT_UINT8, BASE_HEX, VALS(vals_priority_flag), 0x00,
2697 "The priority level of the short message.",
2701 { &hf_smpp_schedule_delivery_time,
2702 { "Scheduled delivery time", "smpp.schedule_delivery_time",
2703 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
2704 "Scheduled time for delivery of short message.",
2708 { &hf_smpp_schedule_delivery_time_r,
2709 { "Scheduled delivery time", "smpp.schedule_delivery_time_r",
2710 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
2711 "Scheduled time for delivery of short message.",
2715 { &hf_smpp_validity_period,
2716 { "Validity period", "smpp.validity_period",
2717 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
2718 "Validity period of this message.",
2722 { &hf_smpp_validity_period_r,
2723 { "Validity period", "smpp.validity_period_r",
2724 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
2725 "Validity period of this message.",
2729 { &hf_smpp_regdel_receipt,
2730 { "Delivery receipt ", "smpp.regdel.receipt",
2731 FT_UINT8, BASE_HEX, VALS(vals_regdel_receipt), 0x03,
2732 "SMSC delivery receipt request.",
2736 { &hf_smpp_regdel_acks,
2737 { "Message type ", "smpp.regdel.acks",
2738 FT_UINT8, BASE_HEX, VALS(vals_regdel_acks), 0x0C,
2739 "SME acknowledgement request.",
2743 { &hf_smpp_regdel_notif,
2744 { "Intermediate notif", "smpp.regdel.notif",
2745 FT_UINT8, BASE_HEX, VALS(vals_regdel_notif), 0x10,
2746 "Intermediate notification request.",
2750 { &hf_smpp_replace_if_present_flag,
2751 { "Replace ", "smpp.replace_if_present_flag",
2752 FT_UINT8, BASE_HEX, VALS(vals_replace_if_present_flag), 0x01,
2753 "Replace the short message with this one or not.",
2757 { &hf_smpp_data_coding,
2758 { "Data coding", "smpp.data_coding",
2759 FT_UINT8, BASE_HEX, NULL, 0x00,
2760 "Defines the encoding scheme of the message.",
2764 { &hf_smpp_sm_default_msg_id,
2765 { "Predefined message", "smpp.sm_default_msg_id",
2766 FT_UINT8, BASE_DEC, NULL, 0x00,
2767 "Index of a predefined ('canned') short message.",
2771 { &hf_smpp_sm_length,
2772 { "Message length", "smpp.sm_length",
2773 FT_UINT8, BASE_DEC, NULL, 0x00,
2774 "Length of the message content.",
2778 { &hf_smpp_short_message,
2779 { "Message", "smpp.message",
2780 FT_NONE, BASE_NONE, NULL, 0x00,
2781 "The actual message or data.",
2785 { &hf_smpp_message_id,
2786 { "Message id.", "smpp.message_id",
2787 FT_STRING, BASE_NONE, NULL, 0x00,
2788 "Identifier of the submitted short message.",
2793 { "Destination list", "smpp.dlist",
2794 FT_NONE, BASE_NONE, NULL, 0x00,
2795 "The list of destinations for a short message.",
2799 { &hf_smpp_dlist_resp,
2800 { "Unsuccesfull delivery list", "smpp.dlist_resp",
2801 FT_NONE, BASE_NONE, NULL, 0x00,
2802 "The list of unsuccesfull deliveries to destinations.",
2807 { "Distr. list name", "smpp.dl_name",
2808 FT_STRING, BASE_NONE, NULL, 0x00,
2809 "The name of the distribution list.",
2813 { &hf_smpp_final_date,
2814 { "Final date", "smpp.final_date",
2815 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
2816 "Date-time when the queried message reached a final state.",
2820 { &hf_smpp_final_date_r,
2821 { "Final date", "smpp.final_date_r",
2822 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
2823 "Date-time when the queried message reached a final state.",
2827 { &hf_smpp_message_state,
2828 { "Message state", "smpp.message_state",
2829 FT_UINT8, BASE_DEC, VALS(vals_message_state), 0x00,
2830 "Specifies the status of the queried short message.",
2834 { &hf_smpp_error_code,
2835 { "Error code", "smpp.error_code",
2836 FT_UINT8, BASE_DEC, NULL, 0x00,
2837 "Network specific error code defining reason for failure.",
2841 { &hf_smpp_error_status_code,
2842 { "Status", "smpp.error_status_code",
2843 FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
2844 "Indicates success/failure of request for this address.",
2848 { &hf_smpp_esme_addr_ton,
2849 { "Type of number (ESME)", "smpp.esme_addr_ton",
2850 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2851 "Indicates recipient type of number, given in the address.",
2855 { &hf_smpp_esme_addr_npi,
2856 { "Numbering plan indicator (ESME)", "smpp.esme_addr_npi",
2857 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2858 "Gives the numbering plan this address belongs to.",
2862 { &hf_smpp_esme_addr,
2863 { "ESME address", "smpp.esme_addr",
2864 FT_STRING, BASE_NONE, NULL, 0x00,
2865 "Address of ESME originating this message.",
2869 { &hf_smpp_dest_addr_subunit,
2870 { "Subunit destination", "smpp.dest_addr_subunit",
2871 FT_UINT8, BASE_HEX, VALS(vals_addr_subunit), 0x00,
2872 "Subunit address within mobile to route message to.",
2876 { &hf_smpp_source_addr_subunit,
2877 { "Subunit origin", "smpp.source_addr_subunit",
2878 FT_UINT8, BASE_HEX, VALS(vals_addr_subunit), 0x00,
2879 "Subunit address within mobile that generated the message.",
2883 { &hf_smpp_dest_network_type,
2884 { "Destination network", "smpp.dest_network_type",
2885 FT_UINT8, BASE_HEX, VALS(vals_network_type), 0x00,
2886 "Network associated with the destination address.",
2890 { &hf_smpp_source_network_type,
2891 { "Originator network", "smpp.source_network_type",
2892 FT_UINT8, BASE_HEX, VALS(vals_network_type), 0x00,
2893 "Network associated with the originator address.",
2897 { &hf_smpp_dest_bearer_type,
2898 { "Destination bearer", "smpp.dest_bearer_type",
2899 FT_UINT8, BASE_HEX, VALS(vals_bearer_type), 0x00,
2900 "Desired bearer for delivery of message.",
2904 { &hf_smpp_source_bearer_type,
2905 { "Originator bearer", "smpp.source_bearer_type",
2906 FT_UINT8, BASE_HEX, VALS(vals_bearer_type), 0x00,
2907 "Bearer over which the message originated.",
2911 { &hf_smpp_dest_telematics_id,
2912 { "Telematic interworking (dest)", "smpp.dest_telematics_id",
2913 FT_UINT16, BASE_HEX, NULL, 0x00,
2914 "Telematic interworking to be used for message delivery.",
2918 { &hf_smpp_source_telematics_id,
2919 { "Telematic interworking (orig)", "smpp.source_telematics_id",
2920 FT_UINT16, BASE_HEX, NULL, 0x00,
2921 "Telematic interworking used for message submission.",
2925 { &hf_smpp_qos_time_to_live,
2926 { "Validity period", "smpp.qos_time_to_live",
2927 FT_UINT32, BASE_DEC, NULL, 0x00,
2928 "Number of seconds to retain message before expiry.",
2932 { &hf_smpp_payload_type,
2933 { "Payload", "smpp.payload_type",
2934 FT_UINT8, BASE_DEC, VALS(vals_payload_type), 0x00,
2935 "PDU type contained in the message payload.",
2939 { &hf_smpp_additional_status_info_text,
2940 { "Information", "smpp.additional_status_info_text",
2941 FT_STRING, BASE_NONE, NULL, 0x00,
2942 "Description of the meaning of a response PDU.",
2946 { &hf_smpp_receipted_message_id,
2947 { "SMSC identifier", "smpp.receipted_message_id",
2948 FT_STRING, BASE_NONE, NULL, 0x00,
2949 "SMSC handle of the message being received.",
2953 { &hf_smpp_privacy_indicator,
2954 { "Privacy indicator", "smpp.privacy_indicator",
2955 FT_UINT8, BASE_DEC, VALS(vals_privacy_indicator), 0x00,
2956 "Indicates the privacy level of the message.",
2960 { &hf_smpp_user_message_reference,
2961 { "Message reference", "smpp.user_message_reference",
2962 FT_UINT16, BASE_HEX, NULL, 0x00,
2963 "Reference to the message, assigned by the user.",
2967 { &hf_smpp_user_response_code,
2968 { "Application response code", "smpp.user_response_code",
2969 FT_UINT8, BASE_HEX, NULL, 0x00,
2970 "A response code set by the user.",
2974 { &hf_smpp_language_indicator,
2975 { "Language", "smpp.language_indicator",
2976 FT_UINT8, BASE_DEC, VALS(vals_language_indicator), 0x00,
2977 "Indicates the language of the short message.",
2981 { &hf_smpp_source_port,
2982 { "Source port", "smpp.source_port",
2983 FT_UINT16, BASE_HEX, NULL, 0x00,
2984 "Application port associated with the source of the message.",
2988 { &hf_smpp_destination_port,
2989 { "Destination port", "smpp.destination_port",
2990 FT_UINT16, BASE_HEX, NULL, 0x00,
2991 "Application port associated with the destination of the message.",
2995 { &hf_smpp_sar_msg_ref_num,
2996 { "SAR reference number", "smpp.sar_msg_ref_num",
2997 FT_UINT16, BASE_DEC, NULL, 0x00,
2998 "Reference number for a concatenated short message.",
3002 { &hf_smpp_sar_total_segments,
3003 { "SAR size", "smpp.sar_total_segments",
3004 FT_UINT16, BASE_DEC, NULL, 0x00,
3005 "Number of segments of a concatenated short message.",
3009 { &hf_smpp_sar_segment_seqnum,
3010 { "SAR sequence number", "smpp.sar_segment_seqnum",
3011 FT_UINT8, BASE_DEC, NULL, 0x00,
3012 "Segment number within a concatenated short message.",
3016 { &hf_smpp_display_time,
3017 { "Display time", "smpp.display_time",
3018 FT_UINT8, BASE_DEC, VALS(vals_display_time), 0x00,
3019 "Associates a display time with the message on the handset.",
3023 { &hf_smpp_ms_validity,
3024 { "Validity info", "smpp.ms_validity",
3025 FT_UINT8, BASE_DEC, VALS(vals_ms_validity), 0x00,
3026 "Associates validity info with the message on the handset.",
3030 { &hf_smpp_dpf_result,
3031 { "Delivery pending set?", "smpp.dpf_result",
3032 FT_UINT8, BASE_DEC, VALS(vals_dpf_result), 0x00,
3033 "Indicates whether Delivery Pending Flag was set.",
3038 { "Request DPF set", "smpp.set_dpf",
3039 FT_UINT8, BASE_DEC, VALS(vals_set_dpf), 0x00,
3040 "Request to set the DPF for certain failure scenario's.",
3044 { &hf_smpp_ms_availability_status,
3045 { "Availability status", "smpp.ms_availability_status",
3046 FT_UINT8, BASE_DEC, VALS(vals_ms_availability_status), 0x00,
3047 "Indicates the availability state of the handset.",
3051 { &hf_smpp_delivery_failure_reason,
3052 { "Delivery failure reason", "smpp.delivery_failure_reason",
3053 FT_UINT8, BASE_DEC, VALS(vals_delivery_failure_reason), 0x00,
3054 "Indicates the reason for a failed delivery attempt.",
3058 { &hf_smpp_more_messages_to_send,
3059 { "More messages?", "smpp.more_messages_to_send",
3060 FT_UINT8, BASE_DEC, VALS(vals_more_messages_to_send), 0x00,
3061 "Indicates more messages pending for the same destination.",
3065 { &hf_smpp_number_of_messages,
3066 { "Number of messages", "smpp.number_of_messages",
3067 FT_UINT8, BASE_DEC, NULL, 0x00,
3068 "Indicates number of messages stored in a mailbox.",
3072 { &hf_smpp_its_reply_type,
3073 { "Reply method", "smpp.its_reply_type",
3074 FT_UINT8, BASE_DEC, VALS(vals_its_reply_type), 0x00,
3075 "Indicates the handset reply method on message receipt.",
3079 { &hf_smpp_ussd_service_op,
3080 { "USSD service operation", "smpp.ussd_service_op",
3081 FT_UINT8, BASE_DEC, VALS(vals_ussd_service_op), 0x00,
3082 "Indicates the USSD service operation.",
3086 { &hf_smpp_vendor_op,
3087 { "Optional parameter - Vendor-specific", "smpp.vendor_op",
3088 FT_NONE, BASE_NONE, NULL, 0x00,
3089 "A supplied optional parameter specific to an SMSC-vendor.",
3093 { &hf_smpp_reserved_op,
3094 { "Optional parameter - Reserved", "smpp.reserved_op",
3095 FT_NONE, BASE_NONE, NULL, 0x00,
3096 "An optional parameter that is reserved in this version.",
3100 { &hf_smpp_msg_wait_ind,
3101 { "Indication", "smpp.msg_wait.ind",
3102 FT_UINT8, BASE_HEX, VALS(vals_msg_wait_ind), 0x80,
3103 "Indicates to the handset that a message is waiting.",
3107 { &hf_smpp_msg_wait_type,
3108 { "Type ", "smpp.msg_wait.type",
3109 FT_UINT8, BASE_HEX, VALS(vals_msg_wait_type), 0x03,
3110 "Indicates type of message that is waiting.",
3114 { &hf_smpp_SC_interface_version,
3115 { "SMSC-supported version", "smpp.SC_interface_version",
3116 FT_STRING, BASE_NONE, NULL, 0x00,
3117 "Version of SMPP interface supported by the SMSC.",
3121 { &hf_smpp_callback_num_pres,
3122 { "Presentation", "smpp.callback_num.pres",
3123 FT_UINT8, BASE_HEX, VALS(vals_callback_num_pres), 0x0C,
3124 "Controls the presentation indication.",
3128 { &hf_smpp_callback_num_scrn,
3129 { "Screening ", "smpp.callback_num.scrn",
3130 FT_UINT8, BASE_HEX, VALS(vals_callback_num_scrn), 0x03,
3131 "Controls screening of the callback-number.",
3135 { &hf_smpp_callback_num_atag,
3136 { "Callback number - alphanumeric display tag",
3137 "smpp.callback_num_atag",
3138 FT_NONE, BASE_NONE, NULL, 0x00,
3139 "Associates an alphanumeric display with call back number.",
3143 { &hf_smpp_callback_num,
3144 { "Callback number", "smpp.callback_num",
3145 FT_NONE, BASE_NONE, NULL, 0x00,
3146 "Associates a call back number with the message.",
3150 { &hf_smpp_network_error_type,
3151 { "Error type", "smpp.network_error.type",
3152 FT_UINT8, BASE_DEC, VALS(vals_network_error_type), 0x00,
3153 "Indicates the network type.",
3157 { &hf_smpp_network_error_code,
3158 { "Error code", "smpp.network_error.code",
3159 FT_UINT16, BASE_HEX, NULL, 0x00,
3160 "Gives the actual network error code.",
3164 { &hf_smpp_message_payload,
3165 { "Payload", "smpp.message_payload",
3166 FT_NONE, BASE_NONE, NULL, 0x00,
3167 "Short message user data.",
3171 { &hf_smpp_alert_on_message_delivery,
3172 { "Alert on delivery", "smpp.alert_on_message_delivery",
3173 FT_NONE, BASE_NONE, NULL, 0x00,
3174 "Instructs the handset to alert user on message delivery.",
3178 { &hf_smpp_its_session_number,
3179 { "Session number", "smpp.its_session.number",
3180 FT_UINT8, BASE_DEC, NULL, 0x00,
3181 "Session number of interactive teleservice.",
3185 { &hf_smpp_its_session_sequence,
3186 { "Sequence number ", "smpp.its_session.sequence",
3187 FT_UINT8, BASE_HEX, NULL, 0xFE,
3188 "Sequence number of the dialogue unit.",
3192 { &hf_smpp_its_session_ind,
3193 { "Session indicator", "smpp.its_session.ind",
3194 FT_UINT8, BASE_HEX, VALS(vals_its_session_ind), 0x01,
3195 "Indicates whether this message is end of conversation.",
3199 { &hf_smpp_opt_param,
3200 { "Optional parameters", "smpp.opt_param",
3201 FT_NONE, BASE_NONE, NULL, 0x00,
3202 "The list of optional parameters in this operation.",
3207 * Data Coding Scheme
3210 { "SMPP Data Coding Scheme", "smpp.dcs",
3211 FT_UINT8, BASE_HEX, VALS(vals_data_coding), 0x00,
3212 "Data Coding Scheme according to SMPP.",
3216 { &hf_smpp_dcs_sms_coding_group,
3217 { "DCS Coding Group for SMS", "smpp.dcs.sms_coding_group",
3218 FT_UINT8, BASE_HEX, VALS(vals_dcs_sms_coding_group), 0xF0,
3219 "Data Coding Scheme coding group for GSM Short Message Service.",
3223 { &hf_smpp_dcs_text_compression,
3224 { "DCS Text compression", "smpp.dcs.text_compression",
3225 FT_BOOLEAN, 8, TFS(&tfs_dcs_text_compression), 0x20,
3226 "Indicates if text compression is used.", HFILL
3229 { &hf_smpp_dcs_class_present,
3230 { "DCS Class present", "smpp.dcs.class_present",
3231 FT_BOOLEAN, 8, TFS(&tfs_dcs_class_present), 0x10,
3232 "Indicates if the message class is present (defined).", HFILL
3235 { &hf_smpp_dcs_charset,
3236 { "DCS Character set", "smpp.dcs.charset",
3237 FT_UINT8, BASE_HEX, VALS(vals_dcs_charset), 0x0C,
3238 "Specifies the character set used in the message.", HFILL
3241 { &hf_smpp_dcs_class,
3242 { "DCS Message class", "smpp.dcs.class",
3243 FT_UINT8, BASE_HEX, VALS(vals_dcs_class), 0x03,
3244 "Specifies the message class.", HFILL
3247 { &hf_smpp_dcs_cbs_coding_group,
3248 { "DCS Coding Group for CBS", "smpp.dcs.cbs_coding_group",
3249 FT_UINT8, BASE_HEX, VALS(vals_dcs_cbs_coding_group), 0xF0,
3250 "Data Coding Scheme coding group for GSM Cell Broadcast Service.",
3254 { &hf_smpp_dcs_cbs_language,
3255 { "DCS CBS Message language", "smpp.dcs.cbs_language",
3256 FT_UINT8, BASE_HEX, VALS(vals_dcs_cbs_language), 0x3F,
3257 "Language of the GSM Cell Broadcast Service message.", HFILL
3260 { &hf_smpp_dcs_cbs_class,
3261 { "DCS CBS Message class", "smpp.dcs.cbs_class",
3262 FT_UINT8, BASE_HEX, VALS(vals_dcs_cbs_class), 0x03,
3263 "Specifies the message class for GSM Cell Broadcast Service, "
3264 "for the Data coding / message handling code group.", HFILL
3267 { &hf_smpp_dcs_wap_charset,
3268 { "DCS Message coding", "smpp.dcs.wap_coding",
3269 FT_UINT8, BASE_HEX, VALS(vals_dcs_wap_charset), 0x0C,
3270 "Specifies the used message encoding, "
3271 "as specified by the WAP Forum (WAP over GSM USSD).", HFILL
3274 { &hf_smpp_dcs_wap_class,
3275 { "DCS CBS Message class", "smpp.dcs.wap_class",
3276 FT_UINT8, BASE_HEX, VALS(vals_dcs_wap_class), 0x03,
3277 "Specifies the message class for GSM Cell Broadcast Service, "
3278 "as specified by the WAP Forum (WAP over GSM USSD).", HFILL
3282 /* Setup protocol subtree array */
3283 static gint *ett[] = {
3290 DebugLog(("Registering SMPP dissector\n"));
3291 /* Register the protocol name and description */
3292 proto_smpp = proto_register_protocol("Short Message Peer to Peer",
3295 /* Required function calls to register header fields and subtrees used */
3296 proto_register_field_array(proto_smpp, hf, array_length(hf));
3297 proto_register_subtree_array(ett, array_length(ett));
3300 smpp_module = prefs_register_protocol (proto_smpp, NULL);
3301 prefs_register_bool_preference (smpp_module,
3302 "reassemble_smpp_over_tcp",
3303 "Reassemble SMPP over TCP",
3304 "Reassemble TCP segments that convey SMPP traffic.",
3305 &reassemble_over_tcp);
3309 * If dissector uses sub-dissector registration add a registration routine.
3310 * This format is required because a script is used to find these routines and
3311 * create the code that calls these routines.
3314 proto_reg_handoff_smpp(void)
3316 dissector_handle_t smpp_handle;
3319 * SMPP can be spoken on any port under TCP or X.25
3320 * ...how *do* we do that under X.25?
3322 * We can register the heuristic SMPP dissector with X.25, for one
3323 * thing. We don't currently have any mechanism to allow the user
3324 * to specify that a given X.25 circuit is to be dissected as SMPP,
3327 smpp_handle = create_dissector_handle(dissect_smpp, proto_smpp);
3328 dissector_add_handle("tcp.port", smpp_handle);
3329 heur_dissector_add("tcp", dissect_smpp_heur, proto_smpp);
3330 heur_dissector_add("x.25", dissect_smpp_heur, proto_smpp);
3332 /* Required for call_dissector() */
3333 wsp_handle = find_dissector ("wsp-cl");
3334 g_assert (wsp_handle);
3335 DebugLog(("Finding smpp-gsm-sms subdissector\n"));
3336 gsm_sms_handle = find_dissector("smpp-gsm-sms");
3337 g_assert (gsm_sms_handle);