2 * Routines for Universal Computer Protocol dissection
3 * Copyright 2001, Tom Uijldert <tom.uijldert@cmg.nl>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 * Dissector of a UCP (Universal Computer Protocol) PDU, as defined for the
13 * ERMES paging system in ETS 300 133-3 (2nd final draft, September 1997,
15 * Includes the extension of EMI-UCP interface
16 * (V4.0, May 2001, www.advox.se/download/protocols/EMI_UCP.pdf)
18 * Support for statistics using the Stats Tree API added by
19 * Abhik Sarkar <sarkar.abhik@gmail.com>
27 #include <epan/packet.h>
28 #include <epan/prefs.h>
29 #include <epan/expert.h>
30 #include <epan/stats_tree.h>
31 #include <epan/charsets.h>
33 #include <wsutil/strtoi.h>
35 #include "packet-tcp.h"
37 void proto_register_ucp(void);
38 void proto_reg_handoff_ucp(void);
41 typedef struct _ucp_tap_rec_t
{
42 unsigned message_type
; /* 0 = Operation; 1 = Result */
43 unsigned operation
; /* Operation Type */
44 unsigned result
; /* 0 = Success; Non 0 = Error Code */
48 static bool ucp_desegment
= true;
50 /* STX + TRN(2 num. char.) + / + LEN(5 num. char.) + / + 'O'/'R' + / + OT(2 num. char.) + / */
51 #define UCP_HEADER_SIZE 15
54 * Convert ASCII-hex character to binary equivalent. No checks, assume
55 * is valid hex character.
57 #define AHex2Bin(n) (((n) & 0x40) ? ((n) & 0x0F) + 9 : ((n) & 0x0F))
59 #define UCP_STX 0x02 /* Start of UCP PDU */
60 #define UCP_ETX 0x03 /* End of UCP PDU */
62 #define UCP_MALFORMED -1 /* Not a valid PDU */
63 #define UCP_INV_CHK -2 /* Incorrect checksum */
65 #define UCP_TRN_OFFSET 1
66 #define UCP_LEN_OFFSET 4
67 #define UCP_O_R_OFFSET 10 /* Location of O/R field */
68 #define UCP_OT_OFFSET 12 /* Location of OT field */
70 #define UCP_TRN_LEN 2 /* Length of TRN-field */
71 #define UCP_LEN_LEN 5 /* Length of LEN-field */
72 #define UCP_O_R_LEN 1 /* Length of O/R-field */
73 #define UCP_OT_LEN 2 /* Length of OT-field */
76 static dissector_handle_t ucp_handle
;
79 * Initialize the protocol and registered fields
81 * Header (fixed) section
85 static int hf_ucp_hdr_TRN
;
86 static int hf_ucp_hdr_LEN
;
87 static int hf_ucp_hdr_O_R
;
88 static int hf_ucp_hdr_OT
;
93 static int st_ucp_messages
= -1;
94 static int st_ucp_ops
= -1;
95 static int st_ucp_res
= -1;
96 static int st_ucp_results
= -1;
97 static int st_ucp_results_pos
= -1;
98 static int st_ucp_results_neg
= -1;
100 static const char st_str_ucp
[] = "UCP Messages";
101 static const char st_str_ops
[] = "Operations";
102 static const char st_str_res
[] = "Results";
103 static const char st_str_ucp_res
[] = "UCP Results Acks/Nacks";
104 static const char st_str_pos
[] = "Positive";
105 static const char st_str_neg
[] = "Negative";
108 * Data (variable) section
110 static int hf_ucp_oper_section
;
111 static int hf_ucp_parm_AdC
;
112 static int hf_ucp_parm_OAdC
;
113 static int hf_ucp_parm_DAdC
;
114 static int hf_ucp_parm_AC
;
115 static int hf_ucp_parm_OAC
;
116 static int hf_ucp_parm_BAS
;
117 static int hf_ucp_parm_LAR
;
118 static int hf_ucp_parm_LAC
;
119 static int hf_ucp_parm_L1R
;
120 static int hf_ucp_parm_L1P
;
121 static int hf_ucp_parm_L3R
;
122 static int hf_ucp_parm_L3P
;
123 static int hf_ucp_parm_LCR
;
124 static int hf_ucp_parm_LUR
;
125 static int hf_ucp_parm_LRR
;
126 static int hf_ucp_parm_RT
;
127 static int hf_ucp_parm_NoN
;
128 static int hf_ucp_parm_NoA
;
129 static int hf_ucp_parm_NoB
;
130 static int hf_ucp_parm_NAC
;
131 static int hf_ucp_parm_PNC
;
132 static int hf_ucp_parm_AMsg
;
133 static int hf_ucp_parm_LNo
;
134 static int hf_ucp_parm_LST
;
135 static int hf_ucp_parm_TNo
;
136 static int hf_ucp_parm_CS
;
137 static int hf_ucp_parm_PID
;
138 static int hf_ucp_parm_NPL
;
139 static int hf_ucp_parm_GA
;
140 static int hf_ucp_parm_RP
;
141 static int hf_ucp_parm_LRP
;
142 static int hf_ucp_parm_PR
;
143 static int hf_ucp_parm_LPR
;
144 static int hf_ucp_parm_UM
;
145 static int hf_ucp_parm_LUM
;
146 static int hf_ucp_parm_RC
;
147 static int hf_ucp_parm_LRC
;
148 static int hf_ucp_parm_NRq
;
149 static int hf_ucp_parm_GAdC
;
150 static int hf_ucp_parm_A_D
;
151 static int hf_ucp_parm_CT
;
152 static int hf_ucp_parm_AAC
;
153 static int hf_ucp_parm_MNo
;
154 static int hf_ucp_parm_R_T
;
155 static int hf_ucp_parm_IVR5x
;
156 static int hf_ucp_parm_REQ_OT
;
157 static int hf_ucp_parm_SSTAT
;
158 static int hf_ucp_parm_LMN
;
159 static int hf_ucp_parm_NMESS
;
160 static int hf_ucp_parm_NAdC
;
161 static int hf_ucp_parm_NT
;
162 static int hf_ucp_parm_NPID
;
163 static int hf_ucp_parm_LRq
;
164 static int hf_ucp_parm_LRAd
;
165 static int hf_ucp_parm_LPID
;
166 static int hf_ucp_parm_DD
;
167 static int hf_ucp_parm_DDT
;
168 static int hf_ucp_parm_STx
;
169 static int hf_ucp_parm_ST
;
170 static int hf_ucp_parm_SP
;
171 static int hf_ucp_parm_VP
;
172 static int hf_ucp_parm_RPID
;
173 static int hf_ucp_parm_SCTS
;
174 static int hf_ucp_parm_Dst
;
175 static int hf_ucp_parm_Rsn
;
176 static int hf_ucp_parm_DSCTS
;
177 static int hf_ucp_parm_MT
;
178 static int hf_ucp_parm_NB
;
179 static int hf_ucp_data_section
;
180 static int hf_ucp_parm_MMS
;
181 static int hf_ucp_parm_DCs
;
182 static int hf_ucp_parm_MCLs
;
183 static int hf_ucp_parm_RPI
;
184 static int hf_ucp_parm_CPg
;
185 static int hf_ucp_parm_RPLy
;
186 static int hf_ucp_parm_OTOA
;
187 static int hf_ucp_parm_HPLMN
;
188 static int hf_ucp_parm_RES4
;
189 static int hf_ucp_parm_RES5
;
190 static int hf_ucp_parm_OTON
;
191 static int hf_ucp_parm_ONPI
;
192 static int hf_ucp_parm_STYP0
;
193 static int hf_ucp_parm_STYP1
;
194 static int hf_ucp_parm_ACK
;
195 static int hf_ucp_parm_PWD
;
196 static int hf_ucp_parm_NPWD
;
197 static int hf_ucp_parm_VERS
;
198 static int hf_ucp_parm_LAdC
;
199 static int hf_ucp_parm_LTON
;
200 static int hf_ucp_parm_LNPI
;
201 static int hf_ucp_parm_OPID
;
202 static int hf_ucp_parm_RES1
;
203 static int hf_ucp_parm_RES2
;
204 static int hf_ucp_parm_MVP
;
205 static int hf_ucp_parm_EC
;
206 static int hf_ucp_parm_SM
;
207 static int hf_ucp_not_subscribed
;
208 static int hf_ucp_ga_roaming
;
209 static int hf_ucp_call_barring
;
210 static int hf_ucp_deferred_delivery
;
211 static int hf_ucp_diversion
;
213 static int hf_ucp_parm_XSer
;
214 static int hf_xser_service
;
215 static int hf_xser_length
;
216 static int hf_xser_data
;
218 /* Initialize the subtree pointers */
223 static expert_field ei_ucp_stx_missing
;
224 static expert_field ei_ucp_intstring_invalid
;
225 static expert_field ei_ucp_hexstring_invalid
;
226 static expert_field ei_ucp_short_data
;
232 * Value-arrays for certain field-contents
234 static const value_string vals_hdr_O_R
[] = {
235 { 'O', "Operation" },
240 static const value_string vals_hdr_OT
[] = { /* Operation type */
243 { 2, "Call input (multiple address)" },
244 { 3, "Call input (supplementary services included)" },
245 { 4, "Address list information" },
246 { 5, "Change address list" },
247 { 6, "Advice of accumulated charges" },
248 { 7, "Password management" },
249 { 8, "Legitimisation code management" },
250 { 9, "Standard text information" },
251 { 10, "Change standard text" },
252 { 11, "Request roaming information" },
253 { 12, "Change roaming information" },
254 { 13, "Roaming reset" },
255 { 14, "Message retrieval" },
256 { 15, "Request call barring" },
257 { 16, "Cancel call barring" },
258 { 17, "Request call diversion" },
259 { 18, "Cancel call diversion" },
260 { 19, "Request deferred delivery" },
261 { 20, "Cancel deferred delivery" },
262 { 21, "All features reset" },
263 { 22, "Call input (with specific character set)" },
264 { 23, "UCP version status request" },
265 { 24, "Mobile subscriber feature status request" },
266 { 30, "SMS message transfer" },
268 { 32, "(proprietary)" },
269 { 34, "(proprietary)" },
270 { 36, "(proprietary)" },
271 { 38, "(proprietary)" },
272 { 40, "(proprietary)" },
273 { 41, "(proprietary)" },
274 { 42, "(proprietary)" },
275 { 43, "(proprietary)" },
276 { 44, "(proprietary)" },
277 { 45, "(proprietary)" },
278 { 51, "Submit short message" },
279 { 52, "Deliver short message" },
280 { 53, "Deliver notification" },
281 { 54, "Modify message" },
282 { 55, "Inquiry message" },
283 { 56, "Delete message" },
284 { 57, "Inquiry response message" },
285 { 58, "Delete response message" },
286 { 60, "Session management" },
287 { 61, "List management" },
288 { 95, "(proprietary)" },
289 { 96, "(proprietary)" },
290 { 97, "(proprietary)" },
291 { 98, "(proprietary)" },
292 { 99, "(proprietary)" },
295 static value_string_ext vals_hdr_OT_ext
= VALUE_STRING_EXT_INIT(vals_hdr_OT
);
297 static const value_string vals_parm_EC
[] = { /* Error code */
298 { 1, "Checksum error" },
299 { 2, "Syntax error" },
300 { 3, "Operation not supported by system" },
301 { 4, "Operation not allowed" },
302 { 5, "Call barring active" },
303 { 6, "AdC invalid" },
304 { 7, "Authentication failure" },
305 { 8, "Legitimisation code for all calls, failure" },
306 { 9, "GA not valid" },
307 { 10, "Repetition not allowed" },
308 { 11, "Legitimisation code for repetition, failure" },
309 { 12, "Priority call not allowed" },
310 { 13, "Legitimisation code for priority call, failure" },
311 { 14, "Urgent message not allowed" },
312 { 15, "Legitimisation code for urgent message, failure" },
313 { 16, "Reverse charging not allowed" },
314 { 17, "Legitimisation code for rev. charging, failure" },
315 { 18, "Deferred delivery not allowed" },
316 { 19, "New AC not valid" },
317 { 20, "New legitimisation code not valid" },
318 { 21, "Standard text not valid" },
319 { 22, "Time period not valid" },
320 { 23, "Message type not supported by system" },
321 { 24, "Message too long" },
322 { 25, "Requested standard text not valid" },
323 { 26, "Message type not valid for the pager type" },
324 { 27, "Message not found in SMSC" },
325 { 28, "Invalid character set" },
326 { 30, "Subscriber hang-up" },
327 { 31, "Fax group not supported" },
328 { 32, "Fax message type not supported" },
329 { 33, "Address already in list (60-series)" },
330 { 34, "Address not in list (60-series)" },
331 { 35, "List full, cannot add address to list (60-series)" },
332 { 36, "RPID already in use" },
333 { 37, "Delivery in progress" },
334 { 38, "Message forwarded" },
335 { 50, "Low network status" },
336 { 51, "Legitimisation code for standard text, failure" },
337 { 53, "Operation partially successful" },
338 { 54, "Operation not successful" },
339 { 55, "System error" },
340 { 57, "AdC already a member of GAdC address list" },
341 { 58, "AdC not a member of GAdC address list" },
342 { 59, "Requested standard text list invalid" },
343 { 61, "Not controller of GAdC address list" },
344 { 62, "Standard text too large" },
345 { 63, "Not owner of standard text list" },
346 { 64, "Address list full" },
347 { 65, "GAdC invalid" },
348 { 66, "Operation restricted to mobile subscribers" },
349 { 68, "Invalid AdC type" },
350 { 69, "Cannot add AdC to GAdC address list" },
351 { 90, "(proprietary error code)" },
352 { 91, "(proprietary error code)" },
353 { 92, "(proprietary error code)" },
354 { 93, "(proprietary error code)" },
355 { 94, "(proprietary error code)" },
356 { 95, "(proprietary error code)" },
357 { 96, "(proprietary error code)" },
358 { 97, "(proprietary error code)" },
359 { 98, "(proprietary error code)" },
360 { 99, "(proprietary error code)" },
363 static value_string_ext vals_parm_EC_ext
= VALUE_STRING_EXT_INIT(vals_parm_EC
);
365 static const value_string vals_parm_NRq
[] = {
366 { '0', "NAdC not used" },
367 { '1', "NAdC used" },
371 static const value_string vals_parm_NT
[] = {
372 { '0', "Default value" },
373 { '1', "Delivery notification" },
374 { '2', "Non-delivery notification" },
375 { '3', "Delivery and Non-delivery notification" },
376 { '4', "Buffered message notification" },
377 { '5', "Buffered and Delivery notification" },
378 { '6', "Buffered and Non-delivery notification" },
379 { '7', "All notifications" },
383 static const value_string vals_parm_PID
[] = {
384 { 100, "Mobile station" },
385 { 122, "Fax Group 3" },
387 { 138, "Menu over PSTN" },
388 { 139, "PC appl. over PSTN (E.164)" },
389 { 339, "PC appl. over X.25 (X.121)" },
390 { 439, "PC appl. over ISDN (E.164)" },
391 { 539, "PC appl. over TCP/IP" },
392 { 639, "PC appl. via abbreviated number" },
396 static const value_string vals_parm_LRq
[] = {
397 { '0', "LRAd not used" },
398 { '1', "LRAd used" },
402 static const value_string vals_parm_DD
[] = {
403 { '0', "DDT not used" },
408 static const value_string vals_parm_Dst
[] = {
409 { '0', "delivered" },
410 { '1', "buffered (see Rsn)" },
411 { '2', "not delivered (see Rsn)" },
415 static const value_string vals_parm_Rsn
[] = {
416 { 0, "Unknown subscriber" },
417 { 1, "Service temporary not available" },
418 { 2, "Service temporary not available" },
419 { 3, "Service temporary not available" },
420 { 4, "Service temporary not available" },
421 { 5, "Service temporary not available" },
422 { 6, "Service temporary not available" },
423 { 7, "Service temporary not available" },
424 { 8, "Service temporary not available" },
425 { 9, "Illegal error code" },
426 { 10, "Network time-out" },
427 { 100, "Facility not supported" },
428 { 101, "Unknown subscriber" },
429 { 102, "Facility not provided" },
430 { 103, "Call barred" },
431 { 104, "Operation barred" },
432 { 105, "SC congestion" },
433 { 106, "Facility not supported" },
434 { 107, "Absent subscriber" },
435 { 108, "Delivery fail" },
436 { 109, "Sc congestion" },
437 { 110, "Protocol error" },
438 { 111, "MS not equipped" },
439 { 112, "Unknown SC" },
440 { 113, "SC congestion" },
441 { 114, "Illegal MS" },
442 { 115, "MS nota subscriber" },
443 { 116, "Error in MS" },
444 { 117, "SMS lower layer not provisioned" },
445 { 118, "System fail" },
446 { 119, "PLMN system failure" },
447 { 120, "HLR system failure" },
448 { 121, "VLR system failure" },
449 { 122, "Previous VLR system failure" },
450 { 123, "Controlling MSC system failure" },
451 { 124, "VMSC system failure" },
452 { 125, "EIR system failure" },
453 { 126, "System failure" },
454 { 127, "Unexpected data value" },
455 { 200, "Error in address service centre" },
456 { 201, "Invalid absolute validity period" },
457 { 202, "Short message exceeds maximum" },
458 { 203, "Unable to unpack GSM message" },
459 { 204, "Unable to convert to IRA alphabet" },
460 { 205, "Invalid validity period format" },
461 { 206, "Invalid destination address" },
462 { 207, "Duplicate message submit" },
463 { 208, "Invalid message type indicator" },
466 static value_string_ext vals_parm_Rsn_ext
= VALUE_STRING_EXT_INIT(vals_parm_Rsn
);
468 static const value_string vals_parm_MT
[] = {
469 { '2', "Numeric message" },
470 { '3', "Alphanumeric message" },
471 { '4', "Transparent data" },
475 static const value_string vals_parm_DCs
[] = {
476 { '0', "default alphabet" },
477 { '1', "User defined data (8 bit)" },
481 static const value_string vals_parm_MCLs
[] = {
482 { '0', "message class 0" },
483 { '1', "message class 1" },
484 { '2', "message class 2" },
485 { '3', "message class 3" },
489 static const value_string vals_parm_RPI
[] = {
495 static const value_string vals_parm_ACK
[] = {
501 static const value_string vals_parm_RP
[] = {
502 { '1', "Repetition requested" },
506 static const value_string vals_parm_UM
[] = {
507 { '1', "Urgent message" },
511 static const value_string vals_parm_RC
[] = {
512 { '1', "Reverse charging request" },
516 static const value_string vals_parm_OTOA
[] = {
517 { 1139, "The OAdC is set to NPI telephone and TON international" },
518 { 5039, "The OAdC contains an alphanumeric address" },
522 static const value_string vals_parm_OTON
[] = {
523 { '1', "International number" },
524 { '2', "National number" },
525 { '6', "Abbreviated number (short number alias)" },
529 static const value_string vals_parm_ONPI
[] = {
530 { '1', "E.164 address" },
531 { '3', "X.121 address" },
532 { '5', "Private -TCP/IP or abbreviated number- address" },
536 static const value_string vals_parm_STYP0
[] = {
537 { '1', "open session" },
539 { '3', "change password" },
540 { '4', "open provisioning session" },
542 { '6', "change provisioning password" },
546 static const value_string vals_parm_STYP1
[] = {
547 { '1', "add item to mo-list" },
548 { '2', "remove item from mo-list" },
549 { '3', "verify item mo-list" },
550 { '4', "add item to mt-list" },
551 { '5', "remove item from mt-list" },
552 { '6', "verify item mt-list" },
556 static const value_string vals_parm_OPID
[] = {
557 { 0, "Mobile station" },
558 { 39, "PC application" },
562 static const value_string vals_parm_BAS
[] = {
567 static const value_string vals_parm_LAR
[] = {
568 { '1', "Leg. code for all calls requested" },
572 static const value_string vals_parm_L1R
[] = {
573 { '1', "Leg. code for priority 1 requested" },
577 static const value_string vals_parm_L3R
[] = {
578 { '1', "Leg. code for priority 3 requested" },
582 static const value_string vals_parm_LCR
[] = {
583 { '1', "Leg. code for reverse charging requested" },
587 static const value_string vals_parm_LUR
[] = {
588 { '1', "Leg. code for urgent message requested" },
592 static const value_string vals_parm_LRR
[] = {
593 { '1', "Leg. code for repetition requested" },
597 static const value_string vals_parm_RT
[] = {
598 { '1', "Tone only" },
600 { '3', "Alphanumeric" },
601 { '4', "Transparent data" },
605 static const value_string vals_parm_PNC
[] = {
607 { 'I', "Input PNC" },
611 static const value_string vals_parm_A_D
[] = {
617 static const value_string vals_parm_R_T
[] = {
618 { 'R', "Retrieval Ok" },
619 { 'T', "Retransmit on radio channel" },
623 static const value_string vals_parm_REQ_OT
[] = {
624 { 'S', "Send used operation types" },
625 { 'N', "Don't send used operation types" },
629 static const value_string vals_parm_SSTAT
[] = {
630 { '0', "All services" },
631 { '1', "All in the moment active services" },
632 { '2', "Call diversion" },
633 { '3', "Roaming information status" },
634 { '4', "Call barring status" },
635 { '5', "Deferred delivery status" },
636 { '6', "Number of stored messages" },
640 static const value_string vals_xser_service
[] = {
642 { 1, "GSM UDH information" },
643 { 2, "GSM DCS information" },
644 { 3, "[Message Type] TDMA information exchange" },
645 { 4, "[Message Reference] TDMA information exchange" },
646 { 5, "[Privacy Indicator] TDMA information exchange" },
647 { 6, "[Urgency Indicator] TDMA information exchange" },
648 { 7, "[Acknowledgement Request] TDMA information exchange" },
649 { 8, "[Message Updating] TDMA information exchange" },
650 { 9, "[Call Back Number] TDMA information exchange" },
651 { 10, "[Response Code] TDMA information exchange" },
652 { 11, "[Teleservice ID] TDMA information exchange" },
653 { 12, "Billing identifier" },
654 { 13, "Single shot indicator" },
655 { 14, "Originator TON" },
656 { 15, "Originator NPI" },
657 { 16, "Recipient TON" },
658 { 17, "Recipient NPI" },
659 { 18, "Message Original Submission Time" },
660 { 19, "Destination Network Type" },
663 static value_string_ext vals_xser_service_ext
= VALUE_STRING_EXT_INIT(vals_xser_service
);
667 ucp_stats_tree_init(stats_tree
* st
)
669 st_ucp_messages
= stats_tree_create_node(st
, st_str_ucp
, 0, STAT_DT_INT
, true);
670 st_ucp_ops
= stats_tree_create_node(st
, st_str_ops
, st_ucp_messages
, STAT_DT_INT
, true);
671 st_ucp_res
= stats_tree_create_node(st
, st_str_res
, st_ucp_messages
, STAT_DT_INT
, true);
672 st_ucp_results
= stats_tree_create_node(st
, st_str_ucp_res
, 0, STAT_DT_INT
, true);
673 st_ucp_results_pos
= stats_tree_create_node(st
, st_str_pos
, st_ucp_results
, STAT_DT_INT
, true);
674 st_ucp_results_neg
= stats_tree_create_node(st
, st_str_neg
, st_ucp_results
, STAT_DT_INT
, true);
677 static tap_packet_status
678 ucp_stats_tree_per_packet(stats_tree
*st
, /* st as it was passed to us */
679 packet_info
*pinfo _U_
,
680 epan_dissect_t
*edt _U_
,
682 tap_flags_t flags _U_
) /* Used for getting UCP stats */
684 const ucp_tap_rec_t
*tap_rec
= (const ucp_tap_rec_t
*)p
;
686 tick_stat_node(st
, st_str_ucp
, 0, true);
688 if (tap_rec
->message_type
== 0) /* Operation */
690 tick_stat_node(st
, st_str_ops
, st_ucp_messages
, true);
691 tick_stat_node(st
, val_to_str_ext(tap_rec
->operation
, &vals_hdr_OT_ext
,
692 "Unknown OT: %d"), st_ucp_ops
, false);
696 tick_stat_node(st
, st_str_res
, st_ucp_messages
, true);
697 tick_stat_node(st
, val_to_str_ext(tap_rec
->operation
, &vals_hdr_OT_ext
,
698 "Unknown OT: %d"), st_ucp_res
, false);
700 tick_stat_node(st
, st_str_ucp_res
, 0, true);
702 if (tap_rec
->result
== 0) /* Positive Result */
704 tick_stat_node(st
, st_str_pos
, st_ucp_results
, false);
706 else /* Negative Result */
708 tick_stat_node(st
, st_str_neg
, st_ucp_results
, true);
709 tick_stat_node(st
, val_to_str_ext(tap_rec
->result
, &vals_parm_EC_ext
,
710 "Unknown EC: %d"), st_ucp_results_neg
, false);
714 return TAP_PACKET_REDRAW
;
718 * Checks whether the PDU looks a bit like UCP and checks the checksum
720 * Note: check_ucp is called only with a buffer of at least LEN+2 bytes.
721 * IOW: The buffer should contain a complete UCP PDU [STX ... ETX]
723 * \param tvb The buffer with PDU-data
724 * \param endpkt Returns pointer, indicating the end of the PDU
726 * \return The state of this PDU
729 * UCP_INV_CHK Nice packet, but checksum doesn't add up...
732 check_ucp(tvbuff_t
*tvb
, int *endpkt
)
735 unsigned checksum
= 0;
739 length
= tvb_find_uint8(tvb
, offset
, -1, UCP_ETX
);
741 *endpkt
= tvb_reported_length_remaining(tvb
, offset
);
742 return UCP_MALFORMED
;
744 for (; offset
< (unsigned) (length
- 2); offset
++)
745 checksum
+= tvb_get_uint8(tvb
, offset
);
747 tmp
= tvb_get_uint8(tvb
, offset
++);
748 pkt_check
= AHex2Bin(tmp
);
749 tmp
= tvb_get_uint8(tvb
, offset
++);
750 pkt_check
= 16 * pkt_check
+ AHex2Bin(tmp
);
751 *endpkt
= offset
+ 1;
752 if (checksum
== (unsigned) pkt_check
)
759 * UCP equivalent of mktime() (3). Convert date to standard 'time_t' format
761 * \param len The length of datestr
762 * \param datestr The UCP-formatted date to convert
764 * \return The date in standard 'time_t' format.
767 ucp_mktime(const int len
, const char *datestr
)
771 r_time
.tm_mday
= (10 * (datestr
[0] - '0') + (datestr
[1] - '0'));
774 r_time
.tm_mon
= (10 * (datestr
[2] - '0') + (datestr
[3] - '0')) - 1;
779 r_time
.tm_year
= (10 * (datestr
[4] - '0') + (datestr
[5] - '0'));
782 if (r_time
.tm_year
< 90)
783 r_time
.tm_year
+= 100;
786 r_time
.tm_hour
= (10 * (datestr
[6] - '0') + (datestr
[7] - '0'));
791 r_time
.tm_min
= (10 * (datestr
[8] - '0') + (datestr
[9] - '0'));
796 r_time
.tm_sec
= (10 * (datestr
[10] - '0') + (datestr
[11] - '0'));
800 r_time
.tm_isdst
= -1;
802 return mktime(&r_time
);
806 * Scanning routines to add standard types (byte, int, string, data)
807 * to the protocol-tree. Each field is separated with a slash ('/').
809 * \param tree The protocol tree to add to
810 * \param tvb Buffer containing the data
811 * \param field The actual field, whose value needs displaying
812 * \param offset Location of field within the buffer, returns location
817 ucp_handle_string(proto_tree
*tree
, tvbuff_t
*tvb
, int field
, int *offset
)
819 proto_item
*ti
= NULL
;
822 idx
= tvb_find_uint8(tvb
, *offset
, -1, '/');
824 /* Force the appropriate exception to be thrown. */
825 len
= tvb_captured_length_remaining(tvb
, *offset
);
826 tvb_ensure_bytes_exist(tvb
, *offset
, len
+ 1);
830 ti
= proto_tree_add_item(tree
, field
, tvb
, *offset
, len
, ENC_ASCII
|ENC_NA
);
833 *offset
+= 1; /* skip terminating '/' */
838 ucp_handle_IRAstring(proto_tree
*tree
, tvbuff_t
*tvb
, int field
, int *offset
)
841 wmem_strbuf_t
*strbuf
;
846 idx
= tvb_find_uint8(tvb
, *offset
, -1, '/');
848 /* Force the appropriate exception to be thrown. */
849 len
= tvb_captured_length_remaining(tvb
, *offset
);
850 tvb_ensure_bytes_exist(tvb
, *offset
, len
+ 1);
854 bytes
= g_byte_array_sized_new(len
);
855 if (tvb_get_string_bytes(tvb
, *offset
, len
, ENC_ASCII
|ENC_STR_HEX
|ENC_SEP_NONE
, bytes
, &tmpoff
)) {
856 strval
= get_ts_23_038_7bits_string_unpacked(wmem_packet_scope(), bytes
->data
, bytes
->len
);
858 strbuf
= wmem_strbuf_new(wmem_packet_scope(), strval
);
859 while ((tmpoff
+ 1) < idx
) {
860 wmem_strbuf_append_unichar_repl(strbuf
);
862 if ((tmpoff
+ 1) >= idx
) break;
863 bytes
= g_byte_array_set_size(bytes
, 0);
864 if (tvb_get_string_bytes(tvb
, tmpoff
, idx
-tmpoff
, ENC_ASCII
|ENC_STR_HEX
|ENC_SEP_NONE
, bytes
, &tmpoff
)) {
865 strval
= get_ts_23_038_7bits_string_unpacked(wmem_packet_scope(), bytes
->data
, bytes
->len
);
866 wmem_strbuf_append(strbuf
, strval
);
870 /* Odd string length, which is impossible and indicates an error. */
871 wmem_strbuf_append_unichar_repl(strbuf
);
873 g_byte_array_free(bytes
, true);
875 proto_tree_add_string(tree
, field
, tvb
, *offset
,
876 len
, wmem_strbuf_finalize(strbuf
));
880 *offset
+= 1; /* skip terminating '/' */
884 ucp_handle_byte(proto_tree
*tree
, tvbuff_t
*tvb
, int field
, int *offset
)
888 if ((intval
= tvb_get_uint8(tvb
, (*offset
)++)) != '/') {
889 proto_tree_add_uint(tree
, field
, tvb
, *offset
- 1, 1, intval
);
896 ucp_handle_int(proto_tree
*tree
, packet_info
* pinfo
, tvbuff_t
*tvb
, int field
, int *offset
)
904 idx
= tvb_find_uint8(tvb
, *offset
, -1, '/');
906 /* Force the appropriate exception to be thrown. */
907 len
= tvb_captured_length_remaining(tvb
, *offset
);
908 tvb_ensure_bytes_exist(tvb
, *offset
, len
+ 1);
911 strval
= tvb_get_string_enc(wmem_packet_scope(), tvb
, *offset
, len
, ENC_ASCII
);
913 intval_valid
= ws_strtou32(strval
, NULL
, &intval
);
914 pi
= proto_tree_add_uint(tree
, field
, tvb
, *offset
, len
, intval
);
916 expert_add_info_format(pinfo
, pi
, &ei_ucp_intstring_invalid
,
917 "Invalid integer string: %s", strval
);
921 *offset
+= 1; /* skip terminating '/' */
926 ucp_handle_time(proto_tree
*tree
, tvbuff_t
*tvb
, int field
, int *offset
)
933 idx
= tvb_find_uint8(tvb
, *offset
, -1, '/');
935 /* Force the appropriate exception to be thrown. */
936 len
= tvb_captured_length_remaining(tvb
, *offset
);
937 tvb_ensure_bytes_exist(tvb
, *offset
, len
+ 1);
940 strval
= tvb_get_string_enc(wmem_packet_scope(), tvb
, *offset
, len
, ENC_ASCII
);
942 tval
= ucp_mktime(len
, strval
);
945 proto_tree_add_time(tree
, field
, tvb
, *offset
, len
, &tmptime
);
949 *offset
+= 1; /* skip terminating '/' */
953 ucp_handle_data(proto_tree
*tree
, tvbuff_t
*tvb
, int field
, int *offset
)
955 int tmpoff
= *offset
;
957 while (tvb_get_uint8(tvb
, tmpoff
++) != '/')
959 if ((tmpoff
- *offset
) > 1)
960 proto_tree_add_item(tree
, field
, tvb
, *offset
,
961 tmpoff
- *offset
- 1, ENC_NA
);
966 ucp_handle_data_string(proto_tree
*tree
, tvbuff_t
*tvb
, int field
, int *offset
)
968 int tmpoff
= *offset
;
970 while (tvb_get_uint8(tvb
, tmpoff
++) != '/')
972 if ((tmpoff
- *offset
) > 1)
973 proto_tree_add_item(tree
, field
, tvb
, *offset
,
974 tmpoff
- *offset
- 1, ENC_ASCII
|ENC_NA
);
979 * Handle the data-field within the UCP-message, according the Message Type
981 * - 2 Numeric message
982 * - 3 Alphanumeric message
983 * - 4 Transparent (binary) data
984 * - 5 Standard text handling
985 * - 6 Alphanumeric message in specified character set
987 * \param tree The protocol tree to add to
988 * \param tvb Buffer containing the data
989 * \param offset Location of field within the buffer, returns location
993 ucp_handle_mt(proto_tree
*tree
, packet_info
* pinfo
, tvbuff_t
*tvb
, int *offset
)
997 intval
= ucp_handle_byte(tree
, tvb
, hf_ucp_parm_MT
, offset
);
999 case '1': /* Tone only, no data */
1001 case '4': /* TMsg, no of bits */
1002 ucp_handle_string(tree
, tvb
, hf_ucp_parm_NB
, offset
);
1003 /* fall through here for the data piece */
1006 ucp_handle_data(tree
, tvb
, hf_ucp_data_section
, offset
);
1009 ucp_handle_IRAstring(tree
, tvb
, hf_ucp_parm_AMsg
, offset
);
1012 ucp_handle_byte(tree
, tvb
, hf_ucp_parm_PNC
, offset
);
1013 ucp_handle_string(tree
, tvb
, hf_ucp_parm_LNo
, offset
);
1014 ucp_handle_string(tree
, tvb
, hf_ucp_parm_LST
, offset
);
1015 ucp_handle_string(tree
, tvb
, hf_ucp_parm_TNo
, offset
);
1018 ucp_handle_data(tree
, tvb
, hf_ucp_data_section
, offset
);
1019 ucp_handle_int(tree
, pinfo
, tvb
, hf_ucp_parm_CS
, offset
);
1022 break; /* No data so ? */
1027 * Handle the data within the 'Extended services' field. Each field having the
1028 * format TTLLDD..., TT being the type of service, LL giving the length of the
1029 * field, DD... containing the actual data
1031 * \param tree The protocol tree to add to
1032 * \param tvb Buffer containing the extended services data
1035 ucp_handle_XSer(proto_tree
*tree
, tvbuff_t
*tvb
)
1042 while ((intval
= tvb_get_uint8(tvb
, offset
)) != '/') {
1043 service
= AHex2Bin(intval
);
1044 intval
= tvb_get_uint8(tvb
, offset
+1);
1045 service
= service
* 16 + AHex2Bin(intval
);
1046 intval
= tvb_get_uint8(tvb
, offset
+2);
1047 len
= AHex2Bin(intval
);
1048 intval
= tvb_get_uint8(tvb
, offset
+3);
1049 len
= len
* 16 + AHex2Bin(intval
);
1050 proto_tree_add_uint(tree
, hf_xser_service
, tvb
, offset
, 2, service
);
1051 proto_tree_add_uint(tree
, hf_xser_length
, tvb
, offset
+2, 2, len
);
1052 proto_tree_add_item(tree
, hf_xser_data
, tvb
, offset
+4, len
*2, ENC_ASCII
);
1053 offset
+= 4 + (2 * len
);
1058 ucp_handle_alphanum_OAdC(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
, int field
, int *offset
)
1060 proto_item
*ti
= NULL
;
1062 char *strval
= NULL
;
1066 idx
= tvb_find_uint8(tvb
, *offset
, -1, '/');
1068 /* Force the appropriate exception to be thrown. */
1069 len
= tvb_captured_length_remaining(tvb
, *offset
);
1070 tvb_ensure_bytes_exist(tvb
, *offset
, len
+ 1);
1072 len
= idx
- *offset
;
1077 *offset
+= 1; /* skip terminating '/' */
1081 bytes
= g_byte_array_sized_new(len
);
1082 if (tvb_get_string_bytes(tvb
, *offset
, len
, ENC_ASCII
|ENC_STR_HEX
|ENC_SEP_NONE
, bytes
, &tmpoff
)) {
1083 /* If this returns true, there's at least one byte */
1084 unsigned addrlength
= bytes
->data
[0]; // expected number of semi-octets/nibbles
1085 unsigned numdigocts
= (addrlength
+ 1) / 2;
1086 int no_of_chars
= (addrlength
<< 2) / 7;
1087 if (bytes
->len
+ 1 < numdigocts
) {
1089 proto_tree_add_expert(tree
, pinfo
, &ei_ucp_short_data
, tvb
, *offset
, len
);
1090 no_of_chars
= ((bytes
->len
- 1) << 3) / 7;
1092 strval
= get_ts_23_038_7bits_string_packed(pinfo
->pool
, &bytes
->data
[1], 0, no_of_chars
);
1094 g_byte_array_free(bytes
, true);
1095 ti
= proto_tree_add_string(tree
, field
, tvb
, *offset
,
1097 if (tmpoff
< *offset
+ len
) {
1098 /* We didn't consume all the bytes, so either a failed conversion
1099 * from ASCII hex bytes, or an odd number of bytes.
1101 expert_add_info(pinfo
, ti
, &ei_ucp_hexstring_invalid
);
1105 *offset
+= 1; /* skip terminating '/' */
1110 /* Next definitions are just a convenient shorthand to make the coding a
1111 * bit more readable instead of summing up all these parameters.
1113 #define UcpHandleString(field) ucp_handle_string(tree, tvb, (field), &offset)
1115 #define UcpHandleIRAString(field) \
1116 ucp_handle_IRAstring(tree, tvb, (field), &offset)
1118 #define UcpHandleByte(field) ucp_handle_byte(tree, tvb, (field), &offset)
1120 #define UcpHandleInt(field) ucp_handle_int(tree, pinfo, tvb, (field), &offset)
1122 #define UcpHandleTime(field) ucp_handle_time(tree, tvb, (field), &offset)
1124 #define UcpHandleData(field) ucp_handle_data(tree, tvb, (field), &offset)
1126 #define UcpHandleDataString(field)\
1127 ucp_handle_data_string(tree, tvb, (field), &offset)
1130 * The next set of routines handle the different operation types,
1131 * associated with UCP.
1134 add_00O(proto_tree
*tree
, tvbuff_t
*tvb
)
1138 UcpHandleString(hf_ucp_parm_AdC
);
1139 UcpHandleString(hf_ucp_parm_OAdC
);
1140 UcpHandleString(hf_ucp_parm_OAC
);
1144 add_00R(proto_tree
*tree
, packet_info
* pinfo
, tvbuff_t
*tvb
, ucp_tap_rec_t
*tap_rec
)
1149 intval
= UcpHandleByte(hf_ucp_parm_ACK
);
1152 UcpHandleByte(hf_ucp_parm_BAS
);
1153 UcpHandleByte(hf_ucp_parm_LAR
);
1154 UcpHandleByte(hf_ucp_parm_L1R
);
1155 UcpHandleByte(hf_ucp_parm_L3R
);
1156 UcpHandleByte(hf_ucp_parm_LCR
);
1157 UcpHandleByte(hf_ucp_parm_LUR
);
1158 UcpHandleByte(hf_ucp_parm_LRR
);
1159 UcpHandleByte(hf_ucp_parm_RT
);
1160 UcpHandleInt(hf_ucp_parm_NoN
);
1161 UcpHandleInt(hf_ucp_parm_NoA
);
1162 UcpHandleInt(hf_ucp_parm_NoB
);
1164 tap_rec
->result
= 0;
1166 tap_rec
->result
= UcpHandleInt(hf_ucp_parm_EC
);
1167 UcpHandleString(hf_ucp_parm_SM
);
1172 add_01O(proto_tree
*tree
, packet_info
* pinfo
, tvbuff_t
*tvb
)
1176 UcpHandleString(hf_ucp_parm_AdC
);
1177 UcpHandleString(hf_ucp_parm_OAdC
);
1178 UcpHandleString(hf_ucp_parm_OAC
);
1179 ucp_handle_mt(tree
, pinfo
, tvb
, &offset
);
1183 add_01R(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
, ucp_tap_rec_t
*tap_rec
)
1188 intval
= UcpHandleByte(hf_ucp_parm_ACK
);
1190 tap_rec
->result
= UcpHandleInt(hf_ucp_parm_EC
);
1192 tap_rec
->result
= 0;
1193 UcpHandleString(hf_ucp_parm_SM
);
1197 add_02O(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
)
1198 { /* Multiple address call input*/
1203 intval
= UcpHandleInt(hf_ucp_parm_NPL
);
1204 for (idx
= 0; idx
< intval
; idx
++)
1205 UcpHandleString(hf_ucp_parm_AdC
);
1207 UcpHandleString(hf_ucp_parm_OAdC
);
1208 UcpHandleString(hf_ucp_parm_OAC
);
1209 ucp_handle_mt(tree
, pinfo
, tvb
, &offset
);
1212 #define add_02R(a, b, c, d) add_01R(a, b, c, d)
1215 add_03O(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
)
1216 { /* Call input with SS */
1221 UcpHandleString(hf_ucp_parm_AdC
);
1222 UcpHandleString(hf_ucp_parm_OAdC
);
1223 UcpHandleString(hf_ucp_parm_OAC
);
1224 intval
= UcpHandleInt(hf_ucp_parm_NPL
);
1225 for (idx
= 0; idx
< intval
; idx
++)
1226 UcpHandleString(hf_ucp_parm_GA
);
1228 UcpHandleByte(hf_ucp_parm_RP
);
1229 UcpHandleString(hf_ucp_parm_LRP
);
1230 UcpHandleByte(hf_ucp_parm_PR
);
1231 UcpHandleString(hf_ucp_parm_LPR
);
1232 UcpHandleByte(hf_ucp_parm_UM
);
1233 UcpHandleString(hf_ucp_parm_LUM
);
1234 UcpHandleByte(hf_ucp_parm_RC
);
1235 UcpHandleString(hf_ucp_parm_LRC
);
1236 UcpHandleByte(hf_ucp_parm_DD
);
1237 UcpHandleTime(hf_ucp_parm_DDT
); /* DDMMYYHHmm */
1238 ucp_handle_mt(tree
, pinfo
, tvb
, &offset
);
1241 #define add_03R(a, b, c, d) add_01R(a, b, c, d)
1244 add_04O(proto_tree
*tree
, tvbuff_t
*tvb
)
1245 { /* Address list information */
1248 UcpHandleString(hf_ucp_parm_GAdC
);
1249 UcpHandleString(hf_ucp_parm_AC
);
1250 UcpHandleString(hf_ucp_parm_OAdC
);
1251 UcpHandleString(hf_ucp_parm_OAC
);
1255 add_04R(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
, ucp_tap_rec_t
*tap_rec
)
1261 intval
= UcpHandleByte(hf_ucp_parm_ACK
);
1262 if (intval
== 'A') {
1263 intval
= UcpHandleInt(hf_ucp_parm_NPL
);
1264 for (idx
= 0; idx
< intval
; idx
++)
1265 UcpHandleString(hf_ucp_parm_AdC
);
1266 UcpHandleString(hf_ucp_parm_GAdC
);
1267 tap_rec
->result
= 0;
1269 tap_rec
->result
= UcpHandleInt(hf_ucp_parm_EC
);
1270 UcpHandleString(hf_ucp_parm_SM
);
1274 add_05O(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
)
1275 { /* Change address list */
1280 UcpHandleString(hf_ucp_parm_GAdC
);
1281 UcpHandleString(hf_ucp_parm_AC
);
1282 UcpHandleString(hf_ucp_parm_OAdC
);
1283 UcpHandleString(hf_ucp_parm_OAC
);
1284 intval
= UcpHandleInt(hf_ucp_parm_NPL
);
1285 for (idx
= 0; idx
< intval
; idx
++)
1286 UcpHandleString(hf_ucp_parm_AdC
);
1287 UcpHandleByte(hf_ucp_parm_A_D
);
1290 #define add_05R(a, b, c, d) add_01R(a, b, c, d)
1293 add_06O(proto_tree
*tree
, tvbuff_t
*tvb
)
1294 { /* Advice of accum. charges */
1297 UcpHandleString(hf_ucp_parm_AdC
);
1298 UcpHandleString(hf_ucp_parm_AC
);
1302 add_06R(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
, ucp_tap_rec_t
*tap_rec
)
1307 intval
= UcpHandleByte(hf_ucp_parm_ACK
);
1308 if (intval
== 'A') {
1309 UcpHandleTime(hf_ucp_parm_CT
);
1310 UcpHandleString(hf_ucp_parm_AAC
);
1311 tap_rec
->result
= 0;
1313 tap_rec
->result
= UcpHandleInt(hf_ucp_parm_EC
);
1314 UcpHandleString(hf_ucp_parm_SM
);
1318 add_07O(proto_tree
*tree
, tvbuff_t
*tvb
)
1319 { /* Password management */
1322 UcpHandleString(hf_ucp_parm_AdC
);
1323 UcpHandleString(hf_ucp_parm_AC
);
1324 UcpHandleString(hf_ucp_parm_NAC
);
1327 #define add_07R(a, b, c, d) add_01R(a, b, c, d)
1330 add_08O(proto_tree
*tree
, tvbuff_t
*tvb
)
1331 { /* Leg. code management */
1334 UcpHandleString(hf_ucp_parm_AdC
);
1335 UcpHandleString(hf_ucp_parm_AC
);
1336 UcpHandleString(hf_ucp_parm_LAC
);
1337 UcpHandleString(hf_ucp_parm_L1P
);
1338 UcpHandleString(hf_ucp_parm_L3P
);
1339 UcpHandleString(hf_ucp_parm_LRC
);
1340 UcpHandleString(hf_ucp_parm_LUM
);
1341 UcpHandleString(hf_ucp_parm_LRP
);
1342 UcpHandleString(hf_ucp_parm_LST
);
1345 #define add_08R(a, b, c, d) add_01R(a, b, c, d)
1348 add_09O(proto_tree
*tree
, tvbuff_t
*tvb
)
1349 { /* Standard text information */
1352 UcpHandleString(hf_ucp_parm_LNo
);
1353 UcpHandleString(hf_ucp_parm_LST
);
1357 add_09R(proto_tree
*tree
, packet_info
*pinfo
,tvbuff_t
*tvb
, ucp_tap_rec_t
*tap_rec
)
1363 intval
= UcpHandleByte(hf_ucp_parm_ACK
);
1364 if (intval
== 'A') {
1365 intval
= UcpHandleInt(hf_ucp_parm_NPL
);
1366 for (idx
= 0; idx
< intval
; idx
++)
1367 UcpHandleString(hf_ucp_parm_LST
);
1368 tap_rec
->result
= 0;
1370 tap_rec
->result
= UcpHandleInt(hf_ucp_parm_EC
);
1371 UcpHandleString(hf_ucp_parm_SM
);
1375 add_10O(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
)
1376 { /* Change standard text */
1379 UcpHandleString(hf_ucp_parm_AdC
);
1380 UcpHandleString(hf_ucp_parm_AC
);
1381 UcpHandleString(hf_ucp_parm_LNo
);
1382 UcpHandleString(hf_ucp_parm_TNo
);
1383 UcpHandleData(hf_ucp_parm_STx
);
1384 UcpHandleInt(hf_ucp_parm_CS
);
1387 #define add_10R(a, b, c, d) add_01R(a, b, c, d)
1389 #define add_11O(a, b) add_06O(a, b) /* Request roaming info */
1392 add_11R(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
, ucp_tap_rec_t
*tap_rec
)
1398 intval
= UcpHandleByte(hf_ucp_parm_ACK
);
1399 if (intval
== 'A') {
1400 intval
= UcpHandleInt(hf_ucp_parm_NPL
);
1401 for (idx
= 0; idx
< intval
; idx
++)
1402 UcpHandleString(hf_ucp_parm_GA
);
1403 tap_rec
->result
= 0;
1405 tap_rec
->result
= UcpHandleInt(hf_ucp_parm_EC
);
1406 UcpHandleString(hf_ucp_parm_SM
);
1410 add_12O(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
)
1411 { /* Change roaming */
1416 UcpHandleString(hf_ucp_parm_AdC
);
1417 UcpHandleString(hf_ucp_parm_AC
);
1418 intval
= UcpHandleInt(hf_ucp_parm_NPL
);
1419 for (idx
= 0; idx
< intval
; idx
++)
1420 UcpHandleString(hf_ucp_parm_GA
);
1423 #define add_12R(a, b, c, d) add_01R(a, b, c, d)
1425 #define add_13O(a, c) add_06O(a, c) /* Roaming reset */
1427 #define add_13R(a, b, c, d) add_01R(a, b, c, d)
1430 add_14O(proto_tree
*tree
, tvbuff_t
*tvb
)
1431 { /* Message retrieval */
1434 UcpHandleString(hf_ucp_parm_AdC
);
1435 UcpHandleString(hf_ucp_parm_AC
);
1436 UcpHandleString(hf_ucp_parm_MNo
);
1437 UcpHandleByte(hf_ucp_parm_R_T
);
1441 add_14R(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
, ucp_tap_rec_t
*tap_rec
)
1447 intval
= UcpHandleByte(hf_ucp_parm_ACK
);
1448 if (intval
== 'A') {
1449 intval
= UcpHandleInt(hf_ucp_parm_NPL
);
1451 * Spec is unclear here. Is 'SM' part of the Msg:s field or not?
1452 * For now, assume it is part of it...
1454 for (idx
= 0; idx
< intval
; idx
++)
1455 UcpHandleData(hf_ucp_data_section
);
1456 tap_rec
->result
= 0;
1458 tap_rec
->result
= UcpHandleInt(hf_ucp_parm_EC
);
1459 UcpHandleString(hf_ucp_parm_SM
);
1464 add_15O(proto_tree
*tree
, tvbuff_t
*tvb
)
1465 { /* Request call barring */
1468 UcpHandleString(hf_ucp_parm_AdC
);
1469 UcpHandleString(hf_ucp_parm_AC
);
1470 UcpHandleTime(hf_ucp_parm_ST
);
1471 UcpHandleTime(hf_ucp_parm_SP
);
1474 #define add_15R(a, b, c, d) add_01R(a, b, c, d)
1476 #define add_16O(a, b) add_06O(a, b) /* Cancel call barring */
1478 #define add_16R(a, b, c, d) add_01R(a, b, c, d)
1481 add_17O(proto_tree
*tree
, tvbuff_t
*tvb
)
1482 { /* Request call diversion */
1485 UcpHandleString(hf_ucp_parm_AdC
);
1486 UcpHandleString(hf_ucp_parm_AC
);
1487 UcpHandleString(hf_ucp_parm_DAdC
);
1488 UcpHandleTime(hf_ucp_parm_ST
);
1489 UcpHandleTime(hf_ucp_parm_SP
);
1492 #define add_17R(a, b, c, d) add_01R(a, b, c, d)
1494 #define add_18O(a, b) add_06O(a, b) /* Cancel call diversion */
1496 #define add_18R(a, b, c, d) add_01R(a, b, c, d)
1499 add_19O(proto_tree
*tree
, tvbuff_t
*tvb
)
1500 { /* Request deferred delivery*/
1503 UcpHandleString(hf_ucp_parm_AdC
);
1504 UcpHandleString(hf_ucp_parm_AC
);
1505 UcpHandleTime(hf_ucp_parm_ST
);
1506 UcpHandleTime(hf_ucp_parm_SP
);
1509 #define add_19R(a, b, c, d) add_01R(a, b, c, d)
1511 #define add_20O(a, b) add_06O(a, b) /* Cancel deferred delivery */
1513 #define add_20R(a, b, c, d) add_01R(a, b, c, d)
1515 #define add_21O(a, b) add_06O(a, b) /* All features reset */
1517 #define add_21R(a, b, c, d) add_01R(a, b, c, d)
1520 add_22O(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
)
1521 { /* Call input w. add. CS */
1524 UcpHandleString(hf_ucp_parm_AdC
);
1525 UcpHandleString(hf_ucp_parm_OAdC
);
1526 UcpHandleString(hf_ucp_parm_OAC
);
1527 UcpHandleData(hf_ucp_data_section
);
1528 UcpHandleInt(hf_ucp_parm_CS
);
1531 #define add_22R(a, b, c, d) add_01R(a, b, c, d)
1534 add_23O(proto_tree
*tree
, tvbuff_t
*tvb
)
1535 { /* UCP version status */
1538 UcpHandleString(hf_ucp_parm_IVR5x
);
1539 UcpHandleByte(hf_ucp_parm_REQ_OT
);
1543 add_23R(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
, ucp_tap_rec_t
*tap_rec
)
1549 intval
= UcpHandleByte(hf_ucp_parm_ACK
);
1550 if (intval
== 'A') {
1551 UcpHandleByte(hf_ucp_parm_IVR5x
);
1552 intval
= UcpHandleInt(hf_ucp_parm_NPL
);
1553 for (idx
= 0; idx
< intval
; idx
++)
1554 UcpHandleInt(hf_ucp_hdr_OT
);
1555 tap_rec
->result
= 0;
1557 tap_rec
->result
= UcpHandleInt(hf_ucp_parm_EC
);
1558 UcpHandleString(hf_ucp_parm_SM
);
1562 add_24O(proto_tree
*tree
, tvbuff_t
*tvb
)
1563 { /* Mobile subs. feature stat*/
1566 UcpHandleString(hf_ucp_parm_AdC
);
1567 UcpHandleString(hf_ucp_parm_AC
);
1568 UcpHandleByte(hf_ucp_parm_SSTAT
);
1572 add_24R(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
, ucp_tap_rec_t
*tap_rec
)
1578 intval
= UcpHandleByte(hf_ucp_parm_ACK
);
1579 if (intval
== 'A') {
1580 if ((intval
= tvb_get_uint8(tvb
, offset
++)) != '/') {
1581 proto_tree_add_item(tree
, hf_ucp_ga_roaming
, tvb
, offset
- 1, 1, ENC_NA
);
1582 if (intval
== 'N') {
1583 proto_tree_add_item(tree
, hf_ucp_not_subscribed
, tvb
, offset
-1, 1, ENC_NA
);
1587 intval
= UcpHandleInt(hf_ucp_parm_NPL
);
1588 for (idx
= 0; idx
< intval
; idx
++)
1589 UcpHandleData(hf_ucp_data_section
);
1592 if ((intval
= tvb_get_uint8(tvb
, offset
++)) != '/') {
1593 proto_tree_add_item(tree
, hf_ucp_call_barring
, tvb
, offset
- 1, 1, ENC_NA
);
1594 if (intval
== 'N') {
1595 proto_tree_add_item(tree
, hf_ucp_not_subscribed
, tvb
, offset
-1, 1, ENC_NA
);
1599 intval
= UcpHandleInt(hf_ucp_parm_NPL
);
1600 for (idx
= 0; idx
< intval
; idx
++)
1601 UcpHandleData(hf_ucp_data_section
);
1604 if ((intval
= tvb_get_uint8(tvb
, offset
++)) != '/') {
1605 proto_tree_add_item(tree
, hf_ucp_deferred_delivery
, tvb
, offset
- 1, 1, ENC_NA
);
1606 if (intval
== 'N') {
1607 proto_tree_add_item(tree
, hf_ucp_not_subscribed
, tvb
, offset
-1, 1, ENC_NA
);
1611 intval
= UcpHandleInt(hf_ucp_parm_NPL
);
1612 for (idx
= 0; idx
< intval
; idx
++)
1613 UcpHandleData(hf_ucp_data_section
);
1616 if ((intval
= tvb_get_uint8(tvb
, offset
++)) != '/') {
1617 proto_tree_add_item(tree
, hf_ucp_diversion
, tvb
, offset
- 1, 1, ENC_NA
);
1618 if (intval
== 'N') {
1619 proto_tree_add_item(tree
, hf_ucp_not_subscribed
, tvb
, offset
-1, 1, ENC_NA
);
1623 intval
= UcpHandleInt(hf_ucp_parm_NPL
);
1624 for (idx
= 0; idx
< intval
; idx
++)
1625 UcpHandleData(hf_ucp_data_section
);
1628 UcpHandleInt(hf_ucp_parm_LMN
);
1629 if ((intval
= tvb_get_uint8(tvb
, offset
++)) != '/') {
1630 if (intval
== 'N') {
1631 proto_tree_add_item(tree
, hf_ucp_not_subscribed
, tvb
, offset
-1, 1, ENC_NA
);
1635 UcpHandleInt(hf_ucp_parm_NMESS
);
1638 tap_rec
->result
= 0;
1640 tap_rec
->result
= UcpHandleInt(hf_ucp_parm_EC
);
1641 UcpHandleString(hf_ucp_parm_SM
);
1645 add_30O(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
)
1646 { /* SMS message transfer */
1649 UcpHandleString(hf_ucp_parm_AdC
);
1650 UcpHandleString(hf_ucp_parm_OAdC
);
1651 UcpHandleString(hf_ucp_parm_AC
);
1652 UcpHandleByte(hf_ucp_parm_NRq
);
1653 UcpHandleString(hf_ucp_parm_NAdC
);
1654 UcpHandleInt(hf_ucp_parm_NPID
);
1655 UcpHandleByte(hf_ucp_parm_DD
);
1656 UcpHandleTime(hf_ucp_parm_DDT
); /* DDMMYYHHmm */
1657 UcpHandleTime(hf_ucp_parm_VP
); /* DDMMYYHHmm */
1658 UcpHandleIRAString(hf_ucp_parm_AMsg
);
1662 add_30R(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
, ucp_tap_rec_t
*tap_rec
)
1667 intval
= UcpHandleByte(hf_ucp_parm_ACK
);
1668 if (intval
== 'A') {
1669 UcpHandleTime(hf_ucp_parm_MVP
); /* DDMMYYHHmm */
1670 tap_rec
->result
= 0;
1672 tap_rec
->result
= UcpHandleInt(hf_ucp_parm_EC
);
1674 UcpHandleString(hf_ucp_parm_SM
);
1678 add_31O(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
)
1682 UcpHandleString(hf_ucp_parm_AdC
);
1683 UcpHandleInt(hf_ucp_parm_PID
);
1686 #define add_31R(a, b, c, d) add_01R(a, b, c, d)
1689 add_5xO(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
)
1690 { /* 50-series operations */
1693 int tmpoff
, oadc_offset
;
1694 proto_item
*ti
, *oadc_item
;
1697 UcpHandleString(hf_ucp_parm_AdC
);
1698 oadc_offset
= offset
;
1699 oadc_item
= UcpHandleString(hf_ucp_parm_OAdC
);
1700 UcpHandleString(hf_ucp_parm_AC
);
1701 UcpHandleByte(hf_ucp_parm_NRq
);
1702 UcpHandleString(hf_ucp_parm_NAdC
);
1703 UcpHandleByte(hf_ucp_parm_NT
);
1704 UcpHandleInt(hf_ucp_parm_NPID
);
1705 UcpHandleByte(hf_ucp_parm_LRq
);
1706 UcpHandleString(hf_ucp_parm_LRAd
);
1707 UcpHandleInt(hf_ucp_parm_LPID
);
1708 UcpHandleByte(hf_ucp_parm_DD
);
1709 UcpHandleTime(hf_ucp_parm_DDT
); /* DDMMYYHHmm */
1710 UcpHandleTime(hf_ucp_parm_VP
); /* DDMMYYHHmm */
1711 UcpHandleString(hf_ucp_parm_RPID
);
1712 UcpHandleTime(hf_ucp_parm_SCTS
); /* DDMMYYhhmmss */
1713 UcpHandleByte(hf_ucp_parm_Dst
);
1714 UcpHandleInt(hf_ucp_parm_Rsn
);
1715 UcpHandleTime(hf_ucp_parm_DSCTS
); /* DDMMYYhhmmss */
1716 intval
= UcpHandleByte(hf_ucp_parm_MT
);
1717 UcpHandleString(hf_ucp_parm_NB
);
1719 UcpHandleData(hf_ucp_data_section
);
1721 UcpHandleIRAString(hf_ucp_parm_AMsg
);
1722 UcpHandleByte(hf_ucp_parm_MMS
);
1723 UcpHandleByte(hf_ucp_parm_PR
);
1724 UcpHandleByte(hf_ucp_parm_DCs
);
1725 UcpHandleByte(hf_ucp_parm_MCLs
);
1726 UcpHandleByte(hf_ucp_parm_RPI
);
1727 if (tvb_get_uint8(tvb
, offset
++) != '/') {
1728 proto_tree_add_string(tree
, hf_ucp_parm_CPg
, tvb
, offset
- 1,1,
1729 "(reserved for Code Page)");
1732 if (tvb_get_uint8(tvb
, offset
++) != '/') {
1733 proto_tree_add_string(tree
, hf_ucp_parm_RPLy
, tvb
, offset
- 1,1,
1734 "(reserved for Reply type)");
1737 intval
= UcpHandleInt(hf_ucp_parm_OTOA
);
1738 if (intval
== 5039) {
1739 ti
= ucp_handle_alphanum_OAdC(tree
, pinfo
, tvb
, hf_ucp_parm_OAdC
, &oadc_offset
);
1740 if (ti
&& oadc_item
) {
1741 proto_tree_move_item(tree
, oadc_item
, ti
);
1742 proto_item_set_hidden(oadc_item
);
1745 UcpHandleString(hf_ucp_parm_HPLMN
);
1746 tmpoff
= offset
; /* Extra services */
1747 while (tvb_get_uint8(tvb
, tmpoff
++) != '/')
1749 if ((tmpoff
- offset
) > 1) {
1750 int len
= tmpoff
- offset
- 1;
1751 proto_tree
*subtree
;
1753 ti
= proto_tree_add_item(tree
, hf_ucp_parm_XSer
, tvb
, offset
, len
, ENC_NA
);
1754 tmptvb
= tvb_new_subset_length(tvb
, offset
, len
+ 1);
1755 subtree
= proto_item_add_subtree(ti
, ett_XSer
);
1756 ucp_handle_XSer(subtree
, tmptvb
);
1759 UcpHandleDataString(hf_ucp_parm_RES4
);
1760 UcpHandleDataString(hf_ucp_parm_RES5
);
1763 #define add_5xR(a, b, c, d) add_30R(a, b, c, d)
1766 add_6xO(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
, uint8_t OT
)
1767 { /* 60-series operations */
1770 UcpHandleString(hf_ucp_parm_OAdC
);
1771 UcpHandleByte(hf_ucp_parm_OTON
);
1772 UcpHandleByte(hf_ucp_parm_ONPI
);
1774 UcpHandleByte(hf_ucp_parm_STYP0
);
1776 UcpHandleByte(hf_ucp_parm_STYP1
);
1778 UcpHandleIRAString(hf_ucp_parm_PWD
);
1779 UcpHandleIRAString(hf_ucp_parm_NPWD
);
1780 UcpHandleString(hf_ucp_parm_VERS
);
1781 UcpHandleString(hf_ucp_parm_LAdC
);
1782 UcpHandleByte(hf_ucp_parm_LTON
);
1783 UcpHandleByte(hf_ucp_parm_LNPI
);
1785 UcpHandleInt(hf_ucp_parm_OPID
);
1787 UcpHandleDataString(hf_ucp_parm_RES1
);
1789 UcpHandleDataString(hf_ucp_parm_RES2
);
1793 #define add_6xR(a, b, c, d) add_01R(a, b, c, d)
1796 * End of convenient shorthands
1798 #undef UcpHandleString
1799 #undef UcpHandleIRAString
1800 #undef UcpHandleByte
1802 #undef UcpHandleTime
1803 #undef UcpHandleData
1806 get_ucp_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
, void *data _U_
)
1811 offset
= offset
+ 4;
1812 for (i
= 0; i
< UCP_LEN_LEN
; i
++) { /* Length */
1813 intval
= 10 * intval
+
1814 (tvb_get_uint8(tvb
, offset
) - '0');
1822 * The actual dissector
1825 /* We get here only with at least LEN+2 bytes in the buffer */
1828 dissect_ucp_common(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
1830 int offset
= 0; /* Offset in packet within tvbuff */
1831 uint8_t O_R
; /* Request or response */
1832 uint8_t OT
; /* Operation type */
1837 ucp_tap_rec_t
*tap_rec
; /* Tap record */
1839 /* Set up structures needed to add the protocol subtree and manage it */
1842 proto_tree
*ucp_tree
;
1843 proto_tree
*sub_tree
;
1846 /* Make entries in Protocol column */
1847 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "UCP");
1848 col_clear(pinfo
->cinfo
, COL_INFO
);
1850 if (tvb_get_uint8(tvb
, 0) != UCP_STX
){
1851 proto_tree_add_expert(tree
, pinfo
, &ei_ucp_stx_missing
, tvb
, 0, -1);
1852 return tvb_captured_length(tvb
);
1855 /* Get data needed for dissect_ucp_common */
1856 result
= check_ucp(tvb
, &endpkt
);
1858 O_R
= tvb_get_uint8(tvb
, UCP_O_R_OFFSET
);
1859 OT
= tvb_get_uint8(tvb
, UCP_OT_OFFSET
) - '0';
1860 OT
= 10 * OT
+ (tvb_get_uint8(tvb
, UCP_OT_OFFSET
+ 1) - '0');
1862 /* Create Tap record */
1863 tap_rec
= wmem_new0(wmem_packet_scope(), ucp_tap_rec_t
);
1864 tap_rec
->message_type
= (O_R
== 'O' ? 0 : 1);
1865 tap_rec
->operation
= OT
;
1867 /* Make entries in Info column on summary display */
1868 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s (%s)",
1869 val_to_str_ext_const(OT
, &vals_hdr_OT_ext
, "unknown operation"),
1870 val_to_str(O_R
, vals_hdr_O_R
, "Unknown (%d)"));
1871 if (result
== UCP_INV_CHK
)
1872 col_append_str(pinfo
->cinfo
, COL_INFO
, " [checksum invalid]");
1874 /* In the interest of speed, if "tree" is NULL, don't do any work not
1875 necessary to generate protocol tree items. */
1878 /* create display subtree for the protocol */
1879 ti
= proto_tree_add_item(tree
, proto_ucp
, tvb
, 0, -1, ENC_NA
);
1881 ucp_tree
= proto_item_add_subtree(ti
, ett_ucp
);
1883 * Process the packet here.
1884 * Transaction number
1886 offset
++; /* Skip <stx> */
1887 intval
= tvb_get_uint8(tvb
, offset
+0) - '0';
1888 intval
= 10 * intval
+ (tvb_get_uint8(tvb
, offset
+1) - '0');
1889 proto_tree_add_uint(ucp_tree
, hf_ucp_hdr_TRN
, tvb
, offset
,
1890 UCP_TRN_LEN
, intval
);
1891 offset
+= UCP_TRN_LEN
+ 1; /* Skip TN/ */
1894 for (i
= 0; i
< UCP_LEN_LEN
; i
++) { /* Length */
1895 intval
= 10 * intval
+
1896 (tvb_get_uint8(tvb
, offset
+i
) - '0');
1898 proto_tree_add_uint(ucp_tree
, hf_ucp_hdr_LEN
, tvb
, offset
,
1899 UCP_LEN_LEN
, intval
);
1900 offset
+= UCP_LEN_LEN
+ 1; /* skip LEN/ */
1902 proto_tree_add_uint(ucp_tree
, hf_ucp_hdr_O_R
, tvb
, offset
,
1905 offset
+= UCP_O_R_LEN
+ 1; /* skip Operation_type/ */
1907 proto_tree_add_uint(ucp_tree
, hf_ucp_hdr_OT
, tvb
, offset
,
1909 offset
+= UCP_OT_LEN
;
1912 * Variable part starts here.
1915 tmp_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1916 sub_ti
= proto_tree_add_item(ucp_tree
, hf_ucp_oper_section
, tvb
,
1917 offset
, endpkt
- offset
, ENC_NA
);
1918 sub_tree
= proto_item_add_subtree(sub_ti
, ett_sub
);
1922 O_R
== 'O' ? add_00O(sub_tree
, tmp_tvb
) : add_00R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1925 O_R
== 'O' ? add_01O(sub_tree
, pinfo
, tmp_tvb
) : add_01R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1928 O_R
== 'O' ? add_02O(sub_tree
, pinfo
, tmp_tvb
) : add_02R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1931 O_R
== 'O' ? add_03O(sub_tree
, pinfo
, tmp_tvb
) : add_03R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1934 O_R
== 'O' ? add_04O(sub_tree
, tmp_tvb
) : add_04R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1937 O_R
== 'O' ? add_05O(sub_tree
, pinfo
, tmp_tvb
) : add_05R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1940 O_R
== 'O' ? add_06O(sub_tree
, tmp_tvb
) : add_06R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1943 O_R
== 'O' ? add_07O(sub_tree
,tmp_tvb
) : add_07R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1946 O_R
== 'O' ? add_08O(sub_tree
,tmp_tvb
) : add_08R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1949 O_R
== 'O' ? add_09O(sub_tree
,tmp_tvb
) : add_09R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1952 O_R
== 'O' ? add_10O(sub_tree
, pinfo
, tmp_tvb
) : add_10R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1955 O_R
== 'O' ? add_11O(sub_tree
,tmp_tvb
) : add_11R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1958 O_R
== 'O' ? add_12O(sub_tree
, pinfo
, tmp_tvb
) : add_12R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1961 O_R
== 'O' ? add_13O(sub_tree
, tmp_tvb
) : add_13R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1964 O_R
== 'O' ? add_14O(sub_tree
,tmp_tvb
) : add_14R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1967 O_R
== 'O' ? add_15O(sub_tree
,tmp_tvb
) : add_15R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1970 O_R
== 'O' ? add_16O(sub_tree
,tmp_tvb
) : add_16R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1973 O_R
== 'O' ? add_17O(sub_tree
,tmp_tvb
) : add_17R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1976 O_R
== 'O' ? add_18O(sub_tree
,tmp_tvb
) : add_18R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1979 O_R
== 'O' ? add_19O(sub_tree
,tmp_tvb
) : add_19R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1982 O_R
== 'O' ? add_20O(sub_tree
,tmp_tvb
) : add_20R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1985 O_R
== 'O' ? add_21O(sub_tree
,tmp_tvb
) : add_21R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1988 O_R
== 'O' ? add_22O(sub_tree
, pinfo
, tmp_tvb
) : add_22R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1991 O_R
== 'O' ? add_23O(sub_tree
,tmp_tvb
) : add_23R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1994 O_R
== 'O' ? add_24O(sub_tree
,tmp_tvb
) : add_24R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
1997 O_R
== 'O' ? add_30O(sub_tree
, pinfo
, tmp_tvb
) : add_30R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
2000 O_R
== 'O' ? add_31O(sub_tree
, pinfo
, tmp_tvb
) : add_31R(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
2002 case 51: case 52: case 53: case 54: case 55: case 56: case 57:
2004 O_R
== 'O' ? add_5xO(sub_tree
, pinfo
, tmp_tvb
) : add_5xR(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
2007 O_R
== 'O' ? add_6xO(sub_tree
, pinfo
, tmp_tvb
,OT
) : add_6xR(sub_tree
, pinfo
, tmp_tvb
, tap_rec
);
2014 /* Queue packet for Tap */
2015 tap_queue_packet(ucp_tap
, pinfo
, tap_rec
);
2017 return tvb_captured_length(tvb
);
2021 dissect_ucp_tcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
2023 tcp_dissect_pdus(tvb
, pinfo
, tree
, ucp_desegment
, UCP_HEADER_SIZE
,
2024 get_ucp_pdu_len
, dissect_ucp_common
, data
);
2025 return tvb_captured_length(tvb
);
2029 * The heuristic dissector
2033 dissect_ucp_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
2035 conversation_t
*conversation
;
2039 if (tvb_captured_length(tvb
) < UCP_HEADER_SIZE
)
2042 if ((tvb_get_uint8(tvb
, 0) != UCP_STX
) ||
2043 (tvb_get_uint8(tvb
, UCP_TRN_OFFSET
+ UCP_TRN_LEN
) != '/') ||
2044 (tvb_get_uint8(tvb
, UCP_LEN_OFFSET
+ UCP_LEN_LEN
) != '/') ||
2045 (tvb_get_uint8(tvb
, UCP_O_R_OFFSET
+ UCP_O_R_LEN
) != '/') ||
2046 (tvb_get_uint8(tvb
, UCP_OT_OFFSET
+ UCP_OT_LEN
) != '/'))
2049 if (try_val_to_str(tvb_get_uint8(tvb
, UCP_O_R_OFFSET
), vals_hdr_O_R
) == NULL
)
2053 * Ok, looks like a valid packet
2056 /* Set up a conversation with attached dissector so dissect_ucp_heur
2057 * won't be called any more for this TCP connection.
2060 conversation
= find_or_create_conversation(pinfo
);
2061 conversation_set_dissector(conversation
, ucp_handle
);
2063 dissect_ucp_tcp(tvb
, pinfo
, tree
, data
);
2068 /* Register the protocol with Wireshark */
2070 proto_register_ucp(void)
2073 /* Setup list of fields */
2074 static hf_register_info hf
[] = {
2076 { "Transaction Reference Number", "ucp.hdr.TRN",
2077 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2078 "Transaction number for this command, used in windowing.",
2083 { "Length", "ucp.hdr.LEN",
2084 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2085 "Total number of characters between <stx>...<etx>.",
2090 { "Type", "ucp.hdr.O_R",
2091 FT_CHAR
, BASE_HEX
, VALS(vals_hdr_O_R
), 0x00,
2092 "Your basic 'is a request or response'.",
2097 { "Operation", "ucp.hdr.OT",
2098 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
, &vals_hdr_OT_ext
, 0x00,
2099 "The operation that is requested with this message.",
2103 { &hf_ucp_oper_section
,
2104 { "Data", "ucp.parm",
2105 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2106 "The actual content of the operation.",
2111 { "AdC", "ucp.parm.AdC",
2112 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2113 "Address code recipient.",
2117 { &hf_ucp_parm_OAdC
,
2118 { "OAdC", "ucp.parm.OAdC",
2119 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2120 "Address code originator.",
2124 { &hf_ucp_parm_DAdC
,
2125 { "DAdC", "ucp.parm.DAdC",
2126 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2127 "Diverted address code.",
2132 { "AC", "ucp.parm.AC",
2133 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2134 "Authentication code.",
2139 { "OAC", "ucp.parm.OAC",
2140 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2141 "Authentication code, originator.",
2146 { "NAC", "ucp.parm.NAC",
2147 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2148 "New authentication code.",
2153 { "BAS", "ucp.parm.BAS",
2154 FT_CHAR
, BASE_HEX
, VALS(vals_parm_BAS
), 0x00,
2155 "Barring status flag.",
2160 { "LAR", "ucp.parm.LAR",
2161 FT_CHAR
, BASE_HEX
, VALS(vals_parm_LAR
), 0x00,
2162 "Leg. code for all calls flag.",
2167 { "LAC", "ucp.parm.LAC",
2168 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2169 "New leg. code for all calls.",
2174 { "L1R", "ucp.parm.L1R",
2175 FT_CHAR
, BASE_HEX
, VALS(vals_parm_L1R
), 0x00,
2176 "Leg. code for priority 1 flag.",
2181 { "L1P", "ucp.parm.L1P",
2182 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2183 "New leg. code for level 1 priority.",
2188 { "L3R", "ucp.parm.L3R",
2189 FT_CHAR
, BASE_HEX
, VALS(vals_parm_L3R
), 0x00,
2190 "Leg. code for priority 3 flag.",
2195 { "L3P", "ucp.parm.L3P",
2196 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2197 "New leg. code for level 3 priority.",
2202 { "LCR", "ucp.parm.LCR",
2203 FT_CHAR
, BASE_HEX
, VALS(vals_parm_LCR
), 0x00,
2204 "Leg. code for reverse charging flag.",
2209 { "LUR", "ucp.parm.LUR",
2210 FT_CHAR
, BASE_HEX
, VALS(vals_parm_LUR
), 0x00,
2211 "Leg. code for urgent message flag.",
2216 { "LRR", "ucp.parm.LRR",
2217 FT_CHAR
, BASE_HEX
, VALS(vals_parm_LRR
), 0x00,
2218 "Leg. code for repetition flag.",
2223 { "RT", "ucp.parm.RT",
2224 FT_CHAR
, BASE_HEX
, VALS(vals_parm_RT
), 0x00,
2230 { "NoN", "ucp.parm.NoN",
2231 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2232 "Maximum number of numerical characters accepted.",
2237 { "NoA", "ucp.parm.NoA",
2238 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2239 "Maximum number of alphanumerical characters accepted.",
2244 { "NoB", "ucp.parm.NoB",
2245 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2246 "Maximum number of data bits accepted.",
2251 { "PNC", "ucp.parm.PNC",
2252 FT_CHAR
, BASE_HEX
, VALS(vals_parm_PNC
), 0x00,
2253 "Paging network controller.",
2257 { &hf_ucp_parm_AMsg
,
2258 { "AMsg", "ucp.parm.AMsg",
2259 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2260 "The alphanumeric message that is being sent.",
2265 { "LNo", "ucp.parm.LNo",
2266 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2267 "Standard text list number requested by calling party.",
2272 { "LST", "ucp.parm.LST",
2273 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2274 "Legitimisation code for standard text.",
2279 { "TNo", "ucp.parm.TNo",
2280 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2281 "Standard text number requested by calling party.",
2286 { "CS", "ucp.parm.CS",
2287 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2288 "Additional character set number.",
2293 { "PID", "ucp.parm.PID",
2294 FT_UINT16
, BASE_DEC
, VALS(vals_parm_PID
), 0x00,
2300 { "NPL", "ucp.parm.NPL",
2301 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2302 "Number of parameters in the following list.",
2307 { "GA", "ucp.parm.GA",
2308 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2309 "GA?? haven't got a clue.",
2314 { "RP", "ucp.parm.RP",
2315 FT_CHAR
, BASE_HEX
, VALS(vals_parm_RP
), 0x00,
2316 "Repetition requested.",
2321 { "LRP", "ucp.parm.LRP",
2322 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2323 "Legitimisation code for repetition.",
2328 { "PR", "ucp.parm.PR",
2329 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2330 "Priority requested.",
2335 { "LPR", "ucp.parm.LPR",
2336 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2337 "Legitimisation code for priority requested.",
2342 { "UM", "ucp.parm.UM",
2343 FT_CHAR
, BASE_HEX
, VALS(vals_parm_UM
), 0x00,
2344 "Urgent message indicator.",
2349 { "LUM", "ucp.parm.LUM",
2350 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2351 "Legitimisation code for urgent message.",
2356 { "RC", "ucp.parm.RC",
2357 FT_CHAR
, BASE_HEX
, VALS(vals_parm_RC
), 0x00,
2358 "Reverse charging request.",
2363 { "LRC", "ucp.parm.LRC",
2364 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2365 "Legitimisation code for reverse charging.",
2370 { "NRq", "ucp.parm.NRq",
2371 FT_CHAR
, BASE_HEX
, VALS(vals_parm_NRq
), 0x00,
2372 "Notification request.",
2376 { &hf_ucp_parm_GAdC
,
2377 { "GAdC", "ucp.parm.GAdC",
2378 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2379 "Group address code.",
2384 { "A_D", "ucp.parm.A_D",
2385 FT_CHAR
, BASE_HEX
, VALS(vals_parm_A_D
), 0x00,
2386 "Add to/delete from fixed subscriber address list record.",
2391 { "CT", "ucp.parm.CT",
2392 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x00,
2393 "Accumulated charges timestamp.",
2398 { "AAC", "ucp.parm.AAC",
2399 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2400 "Accumulated charges.",
2405 { "MNo", "ucp.parm.MNo",
2406 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2412 { "R_T", "ucp.parm.R_T",
2413 FT_CHAR
, BASE_HEX
, VALS(vals_parm_R_T
), 0x00,
2418 { &hf_ucp_parm_NAdC
,
2419 { "NAdC", "ucp.parm.NAdC",
2420 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2421 "Notification address.",
2426 { "NT", "ucp.parm.NT",
2427 FT_CHAR
, BASE_HEX
, VALS(vals_parm_NT
), 0x00,
2428 "Notification type.",
2432 { &hf_ucp_parm_IVR5x
,
2433 { "IVR5x", "ucp.parm.IVR5x",
2434 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2435 "UCP release number supported/accepted.",
2439 { &hf_ucp_parm_REQ_OT
,
2440 { "REQ_OT", "ucp.parm.REQ_OT",
2441 FT_CHAR
, BASE_HEX
, VALS(vals_parm_REQ_OT
), 0x00,
2442 "UCP release number supported/accepted.",
2446 { &hf_ucp_parm_SSTAT
,
2447 { "SSTAT", "ucp.parm.SSTAT",
2448 FT_CHAR
, BASE_HEX
, VALS(vals_parm_SSTAT
), 0x00,
2449 "Supplementary services for which status is requested.",
2454 { "LMN", "ucp.parm.LMN",
2455 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2456 "Last message number.",
2460 { &hf_ucp_parm_NMESS
,
2461 { "NMESS", "ucp.parm.NMESS",
2462 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2463 "Number of stored messages.",
2467 { &hf_ucp_parm_NPID
,
2468 { "NPID", "ucp.parm.NPID",
2469 FT_UINT16
, BASE_DEC
, VALS(vals_parm_PID
), 0x00,
2470 "Notification PID value.",
2475 { "LRq", "ucp.parm.LRq",
2476 FT_CHAR
, BASE_HEX
, VALS(vals_parm_LRq
), 0x00,
2477 "Last resort address request.",
2481 { &hf_ucp_parm_LRAd
,
2482 { "LRAd", "ucp.parm.LRAd",
2483 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2484 "Last resort address.",
2488 { &hf_ucp_parm_LPID
,
2489 { "LPID", "ucp.parm.LPID",
2490 FT_UINT16
, BASE_DEC
, VALS(vals_parm_PID
), 0x00,
2491 "Last resort PID value.",
2496 { "DD", "ucp.parm.DD",
2497 FT_CHAR
, BASE_HEX
, VALS(vals_parm_DD
), 0x00,
2498 "Deferred delivery requested.",
2503 { "DDT", "ucp.parm.DDT",
2504 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x00,
2505 "Deferred delivery time.",
2510 { "STx", "ucp.parm.STx",
2511 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2517 { "ST", "ucp.parm.ST",
2518 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x00,
2524 { "SP", "ucp.parm.SP",
2525 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x00,
2531 { "VP", "ucp.parm.VP",
2532 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x00,
2537 { &hf_ucp_parm_RPID
,
2538 { "RPID", "ucp.parm.RPID",
2539 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2544 { &hf_ucp_parm_SCTS
,
2545 { "SCTS", "ucp.parm.SCTS",
2546 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x00,
2547 "Service Centre timestamp.",
2552 { "Dst", "ucp.parm.Dst",
2553 FT_CHAR
, BASE_HEX
, VALS(vals_parm_Dst
), 0x00,
2559 { "Rsn", "ucp.parm.Rsn",
2560 FT_UINT16
, BASE_DEC
| BASE_EXT_STRING
, &vals_parm_Rsn_ext
, 0x00,
2565 { &hf_ucp_parm_DSCTS
,
2566 { "DSCTS", "ucp.parm.DSCTS",
2567 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x00,
2568 "Delivery timestamp.",
2573 { "MT", "ucp.parm.MT",
2574 FT_CHAR
, BASE_HEX
, VALS(vals_parm_MT
), 0x00,
2580 { "NB", "ucp.parm.NB",
2581 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2582 "No. of bits in Transparent Data (TD) message.",
2586 { &hf_ucp_data_section
,
2587 { "Data", "ucp.message",
2588 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2589 "The actual message or data.",
2594 { "MMS", "ucp.parm.MMS",
2595 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2596 "More messages to send.",
2601 { "DCs", "ucp.parm.DCs",
2602 FT_CHAR
, BASE_HEX
, VALS(vals_parm_DCs
), 0x00,
2603 "Data coding scheme (deprecated).",
2607 { &hf_ucp_parm_MCLs
,
2608 { "MCLs", "ucp.parm.MCLs",
2609 FT_CHAR
, BASE_HEX
, VALS(vals_parm_MCLs
), 0x00,
2615 { "RPI", "ucp.parm.RPI",
2616 FT_CHAR
, BASE_HEX
, VALS(vals_parm_RPI
), 0x00,
2622 { "CPg", "ucp.parm.CPg",
2623 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2624 "Reserved for Code Page.",
2628 { &hf_ucp_parm_RPLy
,
2629 { "RPLy", "ucp.parm.RPLy",
2630 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2631 "Reserved for Reply type.",
2635 { &hf_ucp_parm_OTOA
,
2636 { "OTOA", "ucp.parm.OTOA",
2637 FT_UINT16
, BASE_DEC
, VALS(vals_parm_OTOA
), 0x00,
2638 "Originator Type Of Address.",
2642 { &hf_ucp_parm_HPLMN
,
2643 { "HPLMN", "ucp.parm.HPLMN",
2644 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2645 "Home PLMN address.",
2649 { &hf_ucp_parm_XSer
,
2650 { "Extra services:", "ucp.parm.XSer",
2651 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2656 { &hf_ucp_parm_RES4
,
2657 { "RES4", "ucp.parm.RES4",
2658 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2659 "Reserved for future use.",
2663 { &hf_ucp_parm_RES5
,
2664 { "RES5", "ucp.parm.RES5",
2665 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2666 "Reserved for future use.",
2670 { &hf_ucp_parm_OTON
,
2671 { "OTON", "ucp.parm.OTON",
2672 FT_CHAR
, BASE_HEX
, VALS(vals_parm_OTON
), 0x00,
2673 "Originator type of number.",
2677 { &hf_ucp_parm_ONPI
,
2678 { "ONPI", "ucp.parm.ONPI",
2679 FT_CHAR
, BASE_HEX
, VALS(vals_parm_ONPI
), 0x00,
2680 "Originator numbering plan id.",
2684 { &hf_ucp_parm_STYP0
,
2685 { "STYP0", "ucp.parm.STYP0",
2686 FT_CHAR
, BASE_HEX
, VALS(vals_parm_STYP0
), 0x00,
2687 "Subtype of operation.",
2691 { &hf_ucp_parm_STYP1
,
2692 { "STYP1", "ucp.parm.STYP1",
2693 FT_CHAR
, BASE_HEX
, VALS(vals_parm_STYP1
), 0x00,
2694 "Subtype of operation.",
2699 { "PWD", "ucp.parm.PWD",
2700 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2701 "Current password.",
2705 { &hf_ucp_parm_NPWD
,
2706 { "NPWD", "ucp.parm.NPWD",
2707 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2712 { &hf_ucp_parm_VERS
,
2713 { "VERS", "ucp.parm.VERS",
2714 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2719 { &hf_ucp_parm_LAdC
,
2720 { "LAdC", "ucp.parm.LAdC",
2721 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2722 "Address for VSMSC list operation.",
2726 { &hf_ucp_parm_LTON
,
2727 { "LTON", "ucp.parm.LTON",
2728 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2729 "Type of number list address.",
2733 { &hf_ucp_parm_LNPI
,
2734 { "LNPI", "ucp.parm.LNPI",
2735 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2736 "Numbering plan id. list address.",
2740 { &hf_ucp_parm_OPID
,
2741 { "OPID", "ucp.parm.OPID",
2742 FT_UINT8
, BASE_DEC
, VALS(vals_parm_OPID
), 0x00,
2743 "Originator protocol identifier.",
2747 { &hf_ucp_parm_RES1
,
2748 { "RES1", "ucp.parm.RES1",
2749 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2750 "Reserved for future use.",
2754 { &hf_ucp_parm_RES2
,
2755 { "RES2", "ucp.parm.RES2",
2756 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2757 "Reserved for future use.",
2762 { "(N)Ack", "ucp.parm.ACK",
2763 FT_CHAR
, BASE_HEX
, VALS(vals_parm_ACK
), 0x00,
2764 "Positive or negative acknowledge of the operation.",
2769 { "MVP", "ucp.parm.MVP",
2770 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x00,
2771 "Modified validity period.",
2776 { "Error code", "ucp.parm.EC",
2777 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
, &vals_parm_EC_ext
, 0x00,
2778 "The result of the requested operation.",
2783 { "SM", "ucp.parm.SM",
2784 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2789 { &hf_ucp_ga_roaming
,
2790 { "GA roaming definitions", "ucp.parm.ga_roaming",
2791 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2796 { &hf_ucp_call_barring
,
2797 { "Call barring definitions", "ucp.parm.call_barring",
2798 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2803 { &hf_ucp_deferred_delivery
,
2804 { "Deferred delivery definitions", "ucp.parm.deferred_delivery",
2805 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2810 { &hf_ucp_diversion
,
2811 { "Diversion definitions", "ucp.parm.diversion",
2812 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2817 { &hf_ucp_not_subscribed
,
2818 { "Not subscribed/not allowed", "ucp.parm.not_subscribed",
2819 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2825 { "Type of service", "ucp.xser.service",
2826 FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &vals_xser_service_ext
, 0x00,
2827 "The type of service specified.",
2832 { "Length", "ucp.xser.length",
2833 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2839 { "Data", "ucp.xser.data",
2840 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2846 /* Setup protocol subtree array */
2847 static int *ett
[] = {
2853 static ei_register_info ei
[] = {
2854 { &ei_ucp_stx_missing
, { "ucp.stx_missing", PI_MALFORMED
, PI_ERROR
, "UCP_STX missing, this is not a new packet", EXPFILL
}},
2855 { &ei_ucp_intstring_invalid
, { "ucp.intstring.invalid", PI_MALFORMED
, PI_ERROR
, "Invalid integer string", EXPFILL
}},
2856 { &ei_ucp_hexstring_invalid
, { "ucp.hexstring.invalid", PI_PROTOCOL
, PI_WARN
, "Invalid hex string", EXPFILL
}},
2857 { &ei_ucp_short_data
, { "ucp.short_data", PI_PROTOCOL
, PI_WARN
, "Short Data (?)", EXPFILL
}}
2860 module_t
*ucp_module
;
2861 expert_module_t
* expert_ucp
;
2863 /* Register the protocol name and description */
2864 proto_ucp
= proto_register_protocol("Universal Computer Protocol",
2867 /* Required function calls to register header fields and subtrees used */
2868 proto_register_field_array(proto_ucp
, hf
, array_length(hf
));
2869 proto_register_subtree_array(ett
, array_length(ett
));
2870 expert_ucp
= expert_register_protocol(proto_ucp
);
2871 expert_register_field_array(expert_ucp
, ei
, array_length(ei
));
2873 /* Register the dissector handle */
2874 ucp_handle
= register_dissector("ucp", dissect_ucp_tcp
, proto_ucp
);
2876 /* Register for tapping */
2877 ucp_tap
= register_tap("ucp");
2879 /* register preferences */
2880 ucp_module
= prefs_register_protocol(proto_ucp
, NULL
);
2881 prefs_register_bool_preference(ucp_module
, "desegment_ucp_messages",
2882 "Reassemble UCP messages spanning multiple TCP segments",
2883 "Whether the UCP dissector should reassemble messages spanning"
2884 " multiple TCP segments."
2885 " To use this option, you must also enable "
2886 "\"Allow subdissectors to reassemble TCP streams\" in the "
2887 "TCP protocol settings.",
2892 proto_reg_handoff_ucp(void)
2895 * UCP can be spoken on any port so, when not on a specific port, try heuristic
2896 * whenever TCP is spoken.
2898 heur_dissector_add("tcp", dissect_ucp_heur
, "UCP over TCP", "ucp_tcp", proto_ucp
, HEURISTIC_ENABLE
);
2901 * Also register as a dissector that can be selected by a TCP port number via "decode as".
2903 dissector_add_for_decode_as_with_preference("tcp.port", ucp_handle
);
2906 stats_tree_cfg
*st_config
= stats_tree_register("ucp", "ucp_messages", "_UCP Messages", 0,
2907 ucp_stats_tree_per_packet
, ucp_stats_tree_init
, NULL
);
2908 stats_tree_set_group(st_config
, REGISTER_TELEPHONY_GROUP_UNSORTED
);
2912 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2917 * indent-tabs-mode: nil
2920 * vi: set shiftwidth=4 tabstop=8 expandtab:
2921 * :indentSize=4:tabSize=8:noTabs=true: