/src/wireshark/epan/dissectors/packet-x25.c
Line | Count | Source |
1 | | /* packet-x25.c |
2 | | * Routines for X.25 packet disassembly |
3 | | * Olivier Abad <oabad@noos.fr> |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 |
8 | | * |
9 | | * SPDX-License-Identifier: GPL-2.0-or-later |
10 | | */ |
11 | | |
12 | | #include "config.h" |
13 | | |
14 | | |
15 | | #include <epan/packet.h> |
16 | | #include <epan/conversation.h> |
17 | | #include <epan/reassemble.h> |
18 | | #include <epan/prefs.h> |
19 | | #include <epan/expert.h> |
20 | | #include <epan/tfs.h> |
21 | | #include <wiretap/wtap.h> |
22 | | #include "packet-sflow.h" |
23 | | #include "packet-osi.h" |
24 | | #include "packet-llc.h" |
25 | | #include "packet-ax25.h" |
26 | | #include "packet-lapd.h" |
27 | | |
28 | | void proto_register_x25(void); |
29 | | void proto_reg_handoff_x25(void); |
30 | | |
31 | | /* |
32 | | * Direction of packet. |
33 | | */ |
34 | | typedef enum { |
35 | | X25_FROM_DCE, /* DCE->DTE */ |
36 | | X25_FROM_DTE, /* DTE->DCE */ |
37 | | X25_UNKNOWN /* direction unknown */ |
38 | | } x25_dir_t; |
39 | | |
40 | | /* |
41 | | * 0 for data packets, 1 for non-data packets. |
42 | | */ |
43 | 942 | #define X25_NONDATA_BIT 0x01 |
44 | | |
45 | 1.55k | #define X25_CALL_REQUEST 0x0B |
46 | 1.12k | #define X25_CALL_ACCEPTED 0x0F |
47 | 355 | #define X25_CLEAR_REQUEST 0x13 |
48 | 181 | #define X25_CLEAR_CONFIRMATION 0x17 |
49 | 41 | #define X25_INTERRUPT 0x23 |
50 | 43 | #define X25_INTERRUPT_CONFIRMATION 0x27 |
51 | 8 | #define X25_RESET_REQUEST 0x1B |
52 | 42 | #define X25_RESET_CONFIRMATION 0x1F |
53 | 8 | #define X25_RESTART_REQUEST 0xFB |
54 | 49 | #define X25_RESTART_CONFIRMATION 0xFF |
55 | 9 | #define X25_REGISTRATION_REQUEST 0xF3 |
56 | 9 | #define X25_REGISTRATION_CONFIRMATION 0xF7 |
57 | 3 | #define X25_DIAGNOSTIC 0xF1 |
58 | 17 | #define X25_RR 0x01 |
59 | 3 | #define X25_RNR 0x05 |
60 | 3 | #define X25_REJ 0x09 |
61 | | #define X25_DATA 0x00 |
62 | | |
63 | 942 | #define PACKET_IS_DATA(type) (!(type & X25_NONDATA_BIT)) |
64 | 52 | #define PACKET_TYPE_FC(type) (type & 0x1F) |
65 | | |
66 | 101 | #define X25_MBIT_MOD8 0x10 |
67 | 39 | #define X25_MBIT_MOD128 0x01 |
68 | | |
69 | 344 | #define X25_ABIT 0x8000 |
70 | | |
71 | 70 | #define X25_QBIT 0x8000 |
72 | 15 | #define X25_DBIT 0x4000 |
73 | | |
74 | 9.20k | #define X25_FAC_CLASS_MASK 0xC0 |
75 | | |
76 | 6.47k | #define X25_FAC_CLASS_A 0x00 |
77 | 1.50k | #define X25_FAC_CLASS_B 0x40 |
78 | 683 | #define X25_FAC_CLASS_C 0x80 |
79 | 497 | #define X25_FAC_CLASS_D 0xC0 |
80 | | |
81 | 2.20k | #define X25_FAC_COMP_MARK 0x00 |
82 | 413 | #define X25_FAC_REVERSE 0x01 |
83 | 414 | #define X25_FAC_THROUGHPUT 0x02 |
84 | 279 | #define X25_FAC_CUG 0x03 |
85 | 372 | #define X25_FAC_CHARGING_INFO 0x04 |
86 | 77 | #define X25_FAC_CALLED_MODIF 0x08 |
87 | 100 | #define X25_FAC_CUG_OUTGOING_ACC 0x09 |
88 | 112 | #define X25_FAC_THROUGHPUT_MIN 0x0A |
89 | 456 | #define X25_FAC_EXPRESS_DATA 0x0B |
90 | 58 | #define X25_FAC_BILATERAL_CUG 0x41 |
91 | 60 | #define X25_FAC_PACKET_SIZE 0x42 |
92 | 34 | #define X25_FAC_WINDOW_SIZE 0x43 |
93 | 54 | #define X25_FAC_RPOA_SELECTION 0x44 |
94 | 75 | #define X25_FAC_CUG_EXT 0x47 |
95 | 129 | #define X25_FAC_CUG_OUTGOING_ACC_EXT 0x48 |
96 | 109 | #define X25_FAC_TRANSIT_DELAY 0x49 |
97 | 6 | #define X25_FAC_CALL_DURATION 0xC1 |
98 | 8 | #define X25_FAC_SEGMENT_COUNT 0xC2 |
99 | 19 | #define X25_FAC_CALL_TRANSFER 0xC3 |
100 | 10 | #define X25_FAC_RPOA_SELECTION_EXT 0xC4 |
101 | 5 | #define X25_FAC_MONETARY_UNIT 0xC5 |
102 | 7 | #define X25_FAC_NUI 0xC6 |
103 | 52 | #define X25_FAC_CALLED_ADDR_EXT 0xC9 |
104 | 19 | #define X25_FAC_ETE_TRANSIT_DELAY 0xCA |
105 | 20 | #define X25_FAC_CALLING_ADDR_EXT 0xCB |
106 | 62 | #define X25_FAC_CALL_DEFLECT 0xD1 |
107 | 63 | #define X25_FAC_PRIORITY 0xD2 |
108 | | |
109 | | static int proto_x25; |
110 | | static int hf_x25_facility; |
111 | | static int hf_x25_facilities_length; |
112 | | static int hf_x25_facility_length; |
113 | | static int hf_x25_facility_class; |
114 | | static int hf_x25_facility_classA; |
115 | | static int hf_x25_facility_classA_comp_mark; |
116 | | static int hf_x25_facility_classA_reverse; |
117 | | static int hf_x25_facility_classA_charging_info; |
118 | | static int hf_x25_facility_reverse_charging; |
119 | | static int hf_x25_facility_charging_info; |
120 | | static int hf_x25_facility_throughput_called_dte; |
121 | | static int hf_x25_throughput_called_dte; |
122 | | static int hf_x25_facility_classA_cug; |
123 | | static int hf_x25_facility_classA_called_motif; |
124 | | static int hf_x25_facility_classA_cug_outgoing_acc; |
125 | | static int hf_x25_facility_classA_throughput_min; |
126 | | static int hf_x25_facility_classA_express_data; |
127 | | static int hf_x25_facility_classA_unknown; |
128 | | static int hf_x25_facility_classB; |
129 | | static int hf_x25_facility_classB_bilateral_cug; |
130 | | static int hf_x25_facility_packet_size_called_dte; |
131 | | static int hf_x25_facility_packet_size_calling_dte; |
132 | | static int hf_x25_facility_data_network_id_code; |
133 | | static int hf_x25_facility_cug_ext; |
134 | | static int hf_x25_facility_cug_outgoing_acc_ext; |
135 | | static int hf_x25_facility_transit_delay; |
136 | | static int hf_x25_facility_classB_unknown; |
137 | | static int hf_x25_facility_classC; |
138 | | static int hf_x25_facility_classC_unknown; |
139 | | static int hf_x25_facility_classD; |
140 | | static int hf_x25_gfi; |
141 | | static int hf_x25_abit; |
142 | | static int hf_x25_qbit; |
143 | | static int hf_x25_dbit; |
144 | | static int hf_x25_mod; |
145 | | static int hf_x25_lcn; |
146 | | static int hf_x25_type; |
147 | | static int hf_x25_type_fc_mod8; |
148 | | static int hf_x25_type_data; |
149 | | static int hf_x25_diagnostic; |
150 | | static int hf_x25_p_r_mod8; |
151 | | static int hf_x25_p_r_mod128; |
152 | | static int hf_x25_mbit_mod8; |
153 | | static int hf_x25_mbit_mod128; |
154 | | static int hf_x25_p_s_mod8; |
155 | | static int hf_x25_p_s_mod128; |
156 | | static int hf_x25_window_size_called_dte; |
157 | | static int hf_x25_window_size_calling_dte; |
158 | | static int hf_x25_dte_address_length; |
159 | | static int hf_x25_dce_address_length; |
160 | | static int hf_x25_calling_address_length; |
161 | | static int hf_x25_called_address_length; |
162 | | static int hf_x25_facility_call_transfer_reason; |
163 | | static int hf_x25_facility_monetary_unit; |
164 | | static int hf_x25_facility_nui; |
165 | | static int hf_x25_facility_cumulative_ete_transit_delay; |
166 | | static int hf_x25_facility_requested_ete_transit_delay; |
167 | | static int hf_x25_facility_max_acceptable_ete_transit_delay; |
168 | | static int hf_x25_facility_priority_data; |
169 | | static int hf_x25_facility_priority_estab_conn; |
170 | | static int hf_x25_facility_priority_keep_conn; |
171 | | static int hf_x25_facility_min_acceptable_priority_data; |
172 | | static int hf_x25_facility_min_acceptable_priority_estab_conn; |
173 | | static int hf_x25_facility_min_acceptable_priority_keep_conn; |
174 | | static int hf_x25_facility_classD_unknown; |
175 | | static int hf_x25_facility_call_transfer_num_semi_octets; |
176 | | static int hf_x25_facility_calling_addr_ext_num_semi_octets; |
177 | | static int hf_x25_facility_called_addr_ext_num_semi_octets; |
178 | | static int hf_x25_facility_call_deflect_num_semi_octets; |
179 | | static int hf_x264_length_indicator; |
180 | | static int hf_x264_un_tpdu_id; |
181 | | static int hf_x264_protocol_id; |
182 | | static int hf_x264_sharing_strategy; |
183 | | static int hf_x263_sec_protocol_id; |
184 | | static int hf_x25_reg_request_length; |
185 | | static int hf_x25_reg_confirm_length; |
186 | | |
187 | | /* Generated from convert_proto_tree_add_text.pl */ |
188 | | static int hf_x25_call_duration; |
189 | | static int hf_x25_segments_to_dte; |
190 | | static int hf_x25_segments_from_dte; |
191 | | static int hf_x25_dte_address; |
192 | | static int hf_x25_data_network_identification_code; |
193 | | static int hf_x25_facility_call_deflect_reason; |
194 | | static int hf_x25_alternative_dte_address; |
195 | | static int hf_x25_dce_address; |
196 | | static int hf_x25_called_address; |
197 | | static int hf_x25_calling_address; |
198 | | static int hf_x25_clear_cause; |
199 | | static int hf_x25_reset_cause; |
200 | | static int hf_x25_restart_cause; |
201 | | static int hf_x25_registration; |
202 | | static int hf_x25_user_data; |
203 | | |
204 | | static int ett_x25; |
205 | | static int ett_x25_gfi; |
206 | | static int ett_x25_facilities; |
207 | | static int ett_x25_facility; |
208 | | static int ett_x25_user_data; |
209 | | |
210 | | static int ett_x25_segment; |
211 | | static int ett_x25_segments; |
212 | | static int hf_x25_segments; |
213 | | static int hf_x25_segment; |
214 | | static int hf_x25_segment_overlap; |
215 | | static int hf_x25_segment_overlap_conflict; |
216 | | static int hf_x25_segment_multiple_tails; |
217 | | static int hf_x25_segment_too_long_segment; |
218 | | static int hf_x25_segment_error; |
219 | | static int hf_x25_segment_count; |
220 | | static int hf_x25_reassembled_length; |
221 | | static int hf_x25_fast_select; |
222 | | static int hf_x25_icrd; |
223 | | static int hf_x25_reg_confirm_cause; |
224 | | static int hf_x25_reg_confirm_diagnostic; |
225 | | |
226 | | static expert_field ei_x25_facility_length; |
227 | | |
228 | | static dissector_handle_t x25_handle; |
229 | | |
230 | | static const value_string vals_modulo[] = { |
231 | | { 1, "8" }, |
232 | | { 2, "128" }, |
233 | | { 0, NULL} |
234 | | }; |
235 | | |
236 | | static const value_string vals_x25_type[] = { |
237 | | { X25_CALL_REQUEST, "Call" }, |
238 | | { X25_CALL_ACCEPTED, "Call Accepted" }, |
239 | | { X25_CLEAR_REQUEST, "Clear" }, |
240 | | { X25_CLEAR_CONFIRMATION, "Clear Confirmation" }, |
241 | | { X25_INTERRUPT, "Interrupt" }, |
242 | | { X25_INTERRUPT_CONFIRMATION, "Interrupt Confirmation" }, |
243 | | { X25_RESET_REQUEST, "Reset" }, |
244 | | { X25_RESET_CONFIRMATION, "Reset Confirmation" }, |
245 | | { X25_RESTART_REQUEST, "Restart" }, |
246 | | { X25_RESTART_CONFIRMATION, "Restart Confirmation" }, |
247 | | { X25_REGISTRATION_REQUEST, "Registration" }, |
248 | | { X25_REGISTRATION_CONFIRMATION, "Registration Confirmation" }, |
249 | | { X25_DIAGNOSTIC, "Diagnostic" }, |
250 | | { X25_RR, "RR" }, |
251 | | { X25_RNR, "RNR" }, |
252 | | { X25_REJ, "REJ" }, |
253 | | { X25_DATA, "Data" }, |
254 | | { 0, NULL} |
255 | | }; |
256 | | |
257 | | static struct true_false_string m_bit_tfs = { |
258 | | "More data follows", |
259 | | "End of data" |
260 | | }; |
261 | | |
262 | | static const value_string x25_fast_select_vals[] = { |
263 | | { 0, "Not requested" }, |
264 | | { 1, "Not requested" }, |
265 | | { 2, "No restriction on response" }, |
266 | | { 3, "Restriction on response" }, |
267 | | { 0, NULL} |
268 | | }; |
269 | | |
270 | | static const value_string x25_icrd_vals[] = { |
271 | | { 0, "Status not selected" }, |
272 | | { 1, "Prevention requested" }, |
273 | | { 2, "Allowance requested" }, |
274 | | { 3, "Not allowed" }, |
275 | | { 0, NULL} |
276 | | }; |
277 | | |
278 | | static const value_string x25_clear_diag_vals[] = { |
279 | | { 0, "No additional information" }, |
280 | | { 1, "Invalid P(S)" }, |
281 | | { 2, "Invalid P(R)" }, |
282 | | { 16, "Packet type invalid" }, |
283 | | { 17, "Packet type invalid for state r1" }, |
284 | | { 18, "Packet type invalid for state r2" }, |
285 | | { 19, "Packet type invalid for state r3" }, |
286 | | { 20, "Packet type invalid for state p1" }, |
287 | | { 21, "Packet type invalid for state p2" }, |
288 | | { 22, "Packet type invalid for state p3" }, |
289 | | { 23, "Packet type invalid for state p4" }, |
290 | | { 24, "Packet type invalid for state p5" }, |
291 | | { 25, "Packet type invalid for state p6" }, |
292 | | { 26, "Packet type invalid for state p7" }, |
293 | | { 27, "Packet type invalid for state d1" }, |
294 | | { 28, "Packet type invalid for state d2" }, |
295 | | { 29, "Packet type invalid for state d3" }, |
296 | | { 32, "Packet not allowed" }, |
297 | | { 33, "Unidentifiable packet" }, |
298 | | { 34, "Call on one-way logical channel" }, |
299 | | { 35, "Invalid packet type on a PVC" }, |
300 | | { 36, "Packet on unassigned LC" }, |
301 | | { 37, "Reject not subscribed to" }, |
302 | | { 38, "Packet too short" }, |
303 | | { 39, "Packet too long" }, |
304 | | { 40, "Invalid general format identifier" }, |
305 | | { 41, "Restart/registration packet with nonzero bits" }, |
306 | | { 42, "Packet type not compatible with facility" }, |
307 | | { 43, "Unauthorised interrupt confirmation" }, |
308 | | { 44, "Unauthorised interrupt" }, |
309 | | { 45, "Unauthorised reject" }, |
310 | | { 48, "Time expired" }, |
311 | | { 49, "Time expired for incoming call" }, |
312 | | { 50, "Time expired for clear indication" }, |
313 | | { 51, "Time expired for reset indication" }, |
314 | | { 52, "Time expired for restart indication" }, |
315 | | { 53, "Time expired for call deflection" }, |
316 | | { 64, "Call set-up/clearing or registration pb." }, |
317 | | { 65, "Facility/registration code not allowed" }, |
318 | | { 66, "Facility parameter not allowed" }, |
319 | | { 67, "Invalid called DTE address" }, |
320 | | { 68, "Invalid calling DTE address" }, |
321 | | { 69, "Invalid facility/registration length" }, |
322 | | { 70, "Incoming call barred" }, |
323 | | { 71, "No logical channel available" }, |
324 | | { 72, "Call collision" }, |
325 | | { 73, "Duplicate facility requested" }, |
326 | | { 74, "Non zero address length" }, |
327 | | { 75, "Non zero facility length" }, |
328 | | { 76, "Facility not provided when expected" }, |
329 | | { 77, "Invalid CCITT-specified DTE facility" }, |
330 | | { 78, "Max. nb of call redir/defl. exceeded" }, |
331 | | { 80, "Miscellaneous" }, |
332 | | { 81, "Improper cause code from DTE" }, |
333 | | { 82, "Not aligned octet" }, |
334 | | { 83, "Inconsistent Q bit setting" }, |
335 | | { 84, "NUI problem" }, |
336 | | { 112, "International problem" }, |
337 | | { 113, "Remote network problem" }, |
338 | | { 114, "International protocol problem" }, |
339 | | { 115, "International link out of order" }, |
340 | | { 116, "International link busy" }, |
341 | | { 117, "Transit network facility problem" }, |
342 | | { 118, "Remote network facility problem" }, |
343 | | { 119, "International routing problem" }, |
344 | | { 120, "Temporary routing problem" }, |
345 | | { 121, "Unknown called DNIC" }, |
346 | | { 122, "Maintenance action" }, |
347 | | { 144, "Timer expired or retransmission count surpassed" }, |
348 | | { 145, "Timer expired or retransmission count surpassed for INTERRUPT" }, |
349 | | { 146, "Timer expired or retransmission count surpassed for DATA packet transmission" }, |
350 | | { 147, "Timer expired or retransmission count surpassed for REJECT" }, |
351 | | { 160, "DTE-specific signals" }, |
352 | | { 161, "DTE operational" }, |
353 | | { 162, "DTE not operational" }, |
354 | | { 163, "DTE resource constraint" }, |
355 | | { 164, "Fast select not subscribed" }, |
356 | | { 165, "Invalid partially full DATA packet" }, |
357 | | { 166, "D-bit procedure not supported" }, |
358 | | { 167, "Registration/Cancellation confirmed" }, |
359 | | { 224, "OSI network service problem" }, |
360 | | { 225, "Disconnection (transient condition)" }, |
361 | | { 226, "Disconnection (permanent condition)" }, |
362 | | { 227, "Connection rejection - reason unspecified (transient condition)" }, |
363 | | { 228, "Connection rejection - reason unspecified (permanent condition)" }, |
364 | | { 229, "Connection rejection - quality of service not available (transient condition)" }, |
365 | | { 230, "Connection rejection - quality of service not available (permanent condition)" }, |
366 | | { 231, "Connection rejection - NSAP unreachable (transient condition)" }, |
367 | | { 232, "Connection rejection - NSAP unreachable (permanent condition)" }, |
368 | | { 233, "Reset - reason unspecified" }, |
369 | | { 234, "Reset - congestion" }, |
370 | | { 235, "Connection rejection - NSAP address unknown (permanent condition)" }, |
371 | | { 240, "Higher layer initiated" }, |
372 | | { 241, "Disconnection - normal" }, |
373 | | { 242, "Disconnection - abnormal" }, |
374 | | { 243, "Disconnection - incompatible information in user data" }, |
375 | | { 244, "Connection rejection - reason unspecified (transient condition)" }, |
376 | | { 245, "Connection rejection - reason unspecified (permanent condition)" }, |
377 | | { 246, "Connection rejection - quality of service not available (transient condition)" }, |
378 | | { 247, "Connection rejection - quality of service not available (permanent condition)" }, |
379 | | { 248, "Connection rejection - incompatible information in user data" }, |
380 | | { 249, "Connection rejection - unrecognizable protocol identifier in user data" }, |
381 | | { 250, "Reset - user resynchronization" }, |
382 | | { 0, NULL} |
383 | | }; |
384 | | |
385 | | static value_string_ext x25_clear_diag_vals_ext = VALUE_STRING_EXT_INIT(x25_clear_diag_vals); |
386 | | |
387 | | static const value_string x25_registration_code_vals[] = { |
388 | | { 0x03, "Invalid facility request" }, |
389 | | { 0x05, "Network congestion" }, |
390 | | { 0x13, "Local procedure error" }, |
391 | | { 0x7F, "Registration/cancellation confirmed" }, |
392 | | { 0, NULL} |
393 | | }; |
394 | | |
395 | | static const value_string x25_facilities_class_vals[] = { |
396 | | { X25_FAC_CLASS_A>>6, "A" }, |
397 | | { X25_FAC_CLASS_B>>6, "B" }, |
398 | | { X25_FAC_CLASS_C>>6, "C" }, |
399 | | { X25_FAC_CLASS_D>>6, "D" }, |
400 | | { 0, NULL} |
401 | | }; |
402 | | |
403 | | static const value_string x25_facilities_classA_vals[] = { |
404 | | { X25_FAC_COMP_MARK, "Marker" }, |
405 | | { X25_FAC_REVERSE, "Reverse charging / Fast select" }, |
406 | | { X25_FAC_CHARGING_INFO, "Charging information" }, |
407 | | { X25_FAC_THROUGHPUT, "Throughput class negotiation" }, |
408 | | { X25_FAC_CUG, "Closed user group selection" }, |
409 | | { X25_FAC_CALLED_MODIF, "Called address modified" }, |
410 | | { X25_FAC_CUG_OUTGOING_ACC, "Closed user group with outgoing access selection" }, |
411 | | { X25_FAC_THROUGHPUT_MIN, "Minimum throughput class" }, |
412 | | { X25_FAC_EXPRESS_DATA, "Negotiation of express data" }, |
413 | | { 0, NULL} |
414 | | }; |
415 | | |
416 | | static const value_string x25_facilities_classA_comp_mark_vals[] = { |
417 | | { 0x00, "Network complementary services - calling DTE" }, |
418 | | { 0x0F, "DTE complementary services" }, |
419 | | { 0xFF, "Network complementary services - called DTE" }, |
420 | | { 0, NULL} |
421 | | }; |
422 | | |
423 | | static const value_string x25_facilities_classA_throughput_vals[] = { |
424 | | { 3, "75 bps" }, |
425 | | { 4, "150 bps" }, |
426 | | { 5, "300 bps" }, |
427 | | { 6, "600 bps" }, |
428 | | { 7, "1200 bps" }, |
429 | | { 8, "2400 bps" }, |
430 | | { 9, "4800 bps" }, |
431 | | { 10, "9600 bps" }, |
432 | | { 11, "19200 bps" }, |
433 | | { 12, "48000 bps" }, |
434 | | { 13, "64000 bps" }, |
435 | | { 0, NULL} |
436 | | }; |
437 | | |
438 | | static const value_string x25_facilities_classB_vals[] = { |
439 | | { X25_FAC_BILATERAL_CUG, "Bilateral closed user group selection" }, |
440 | | { X25_FAC_PACKET_SIZE, "Packet size" }, |
441 | | { X25_FAC_WINDOW_SIZE, "Window size" }, |
442 | | { X25_FAC_RPOA_SELECTION, "RPOA selection" }, |
443 | | { X25_FAC_CUG_EXT, "Extended closed user group selection" }, |
444 | | { X25_FAC_CUG_OUTGOING_ACC_EXT, "Extended closed user group with outgoing access selection" }, |
445 | | { X25_FAC_TRANSIT_DELAY, "Transit delay selection and indication" }, |
446 | | { 0, NULL} |
447 | | }; |
448 | | |
449 | | static const value_string x25_facilities_classB_packet_size_vals[] = { |
450 | | { 0x04, "16" }, |
451 | | { 0x05, "32" }, |
452 | | { 0x06, "64" }, |
453 | | { 0x07, "128" }, |
454 | | { 0x08, "256" }, |
455 | | { 0x09, "512" }, |
456 | | { 0x0A, "1024" }, |
457 | | { 0x0B, "2048" }, |
458 | | { 0x0C, "4096" }, |
459 | | { 0, NULL} |
460 | | }; |
461 | | |
462 | | static const value_string x25_facilities_classC_vals[] = { |
463 | | { 0, NULL} |
464 | | }; |
465 | | |
466 | | static const value_string x25_facilities_classD_vals[] = { |
467 | | { X25_FAC_CALL_DURATION, "Call duration" }, |
468 | | { X25_FAC_SEGMENT_COUNT, "Segment count" }, |
469 | | { X25_FAC_CALL_TRANSFER, "Call redirection or deflection notification" }, |
470 | | { X25_FAC_RPOA_SELECTION_EXT, "Extended RPOA selection" }, |
471 | | { X25_FAC_CALLING_ADDR_EXT, "Calling address extension" }, |
472 | | { X25_FAC_MONETARY_UNIT, "Monetary Unit" }, |
473 | | { X25_FAC_NUI, "Network User Identification selection" }, |
474 | | { X25_FAC_CALLED_ADDR_EXT, "Called address extension" }, |
475 | | { X25_FAC_ETE_TRANSIT_DELAY, "End to end transit delay" }, |
476 | | { X25_FAC_CALL_DEFLECT, "Call deflection selection" }, |
477 | | { X25_FAC_PRIORITY, "Priority" }, |
478 | | { 0, NULL} |
479 | | }; |
480 | | |
481 | | static struct true_false_string x25_reverse_charging_val = { |
482 | | "Requested", |
483 | | "Not requested" |
484 | | }; |
485 | | |
486 | | static const value_string x25_facilities_call_transfer_reason_vals[] = { |
487 | | { 0x01, "originally called DTE busy" }, |
488 | | { 0x07, "call dist. within a hunt group" }, |
489 | | { 0x09, "originally called DTE out of order" }, |
490 | | { 0x0F, "systematic call redirection" }, |
491 | | { 0, NULL} |
492 | | }; |
493 | | |
494 | | static const fragment_items x25_frag_items = { |
495 | | &ett_x25_segment, |
496 | | &ett_x25_segments, |
497 | | &hf_x25_segments, |
498 | | &hf_x25_segment, |
499 | | &hf_x25_segment_overlap, |
500 | | &hf_x25_segment_overlap_conflict, |
501 | | &hf_x25_segment_multiple_tails, |
502 | | &hf_x25_segment_too_long_segment, |
503 | | &hf_x25_segment_error, |
504 | | &hf_x25_segment_count, |
505 | | NULL, |
506 | | &hf_x25_reassembled_length, |
507 | | /* Reassembled data field */ |
508 | | NULL, |
509 | | "segments" |
510 | | }; |
511 | | |
512 | | static dissector_handle_t ip_handle; |
513 | | static dissector_handle_t clnp_handle; |
514 | | static dissector_handle_t ositp_handle; |
515 | | static dissector_handle_t qllc_handle; |
516 | | |
517 | | /* Preferences */ |
518 | | static bool payload_is_qllc_sna; |
519 | | static bool call_request_nodata_is_cotp; |
520 | | static bool payload_check_data; |
521 | | static bool reassemble_x25 = true; |
522 | | |
523 | | /* Reassembly of X.25 */ |
524 | | |
525 | | static reassembly_table x25_reassembly_table; |
526 | | |
527 | | static dissector_table_t x25_subdissector_table; |
528 | | static heur_dissector_list_t x25_heur_subdissector_list; |
529 | | |
530 | | static void |
531 | | x25_hash_add_proto_start(uint16_t vc, uint32_t frame, dissector_handle_t dissect) |
532 | 10 | { |
533 | 10 | conversation_t *conv; |
534 | | |
535 | | /* |
536 | | * Is there already a circuit with this VC number? |
537 | | */ |
538 | 10 | conv = find_conversation_by_id(frame, CONVERSATION_X25, vc); |
539 | 10 | if (conv != NULL) { |
540 | | /* |
541 | | * Yes - close it, as we're creating a new one. |
542 | | */ |
543 | 4 | conv->last_frame = frame - 1; |
544 | 4 | } |
545 | | |
546 | | /* |
547 | | * Set up a new circuit. |
548 | | */ |
549 | 10 | conv = conversation_new_by_id(frame, CONVERSATION_X25, vc); |
550 | | |
551 | | /* |
552 | | * Set its dissector. |
553 | | */ |
554 | 10 | conversation_set_dissector(conv, dissect); |
555 | 10 | } |
556 | | |
557 | | static void |
558 | | x25_hash_add_proto_end(uint16_t vc, uint32_t frame) |
559 | 3 | { |
560 | 3 | conversation_t *conv; |
561 | | |
562 | | /* |
563 | | * Try to find the circuit. |
564 | | */ |
565 | 3 | conv = find_conversation_by_id(frame, CONVERSATION_X25, vc); |
566 | | |
567 | | /* |
568 | | * If we succeeded, close it. |
569 | | */ |
570 | 3 | if (conv != NULL) |
571 | 0 | conv->last_frame = frame; |
572 | 3 | } |
573 | | |
574 | | static const range_string clear_code_rvals[] = { |
575 | | { 0x00, 0x00, "DTE Originated" }, |
576 | | { 0x01, 0x01, "Number Busy" }, |
577 | | { 0x03, 0x03, "Invalid Facility Requested" }, |
578 | | { 0x05, 0x05, "Network Congestion" }, |
579 | | { 0x09, 0x09, "Out Of Order" }, |
580 | | { 0x0B, 0x0B, "Access Barred" }, |
581 | | { 0x0D, 0x0D, "Not Obtainable" }, |
582 | | { 0x11, 0x11, "Remote Procedure Error" }, |
583 | | { 0x13, 0x13, "Local Procedure Error" }, |
584 | | { 0x15, 0x15, "RPOA Out Of Order" }, |
585 | | { 0x19, 0x19, "Reverse Charging Acceptance Not Subscribed" }, |
586 | | { 0x21, 0x21, "Incompatible Destination" }, |
587 | | { 0x29, 0x29, "Fast Select Acceptance Not Subscribed" }, |
588 | | { 0x39, 0x39, "Destination Absent" }, |
589 | | { 0x80, 0xff, "DTE Originated" }, |
590 | | { 0, 0, NULL } |
591 | | }; |
592 | | |
593 | | static const range_string reset_code_rvals[] = { |
594 | | { 0x00, 0x00, "DTE Originated" }, |
595 | | { 0x01, 0x01, "Out of order" }, |
596 | | { 0x03, 0x03, "Remote Procedure Error" }, |
597 | | { 0x05, 0x05, "Local Procedure Error" }, |
598 | | { 0x07, 0x07, "Network Congestion" }, |
599 | | { 0x09, 0x09, "Remote DTE operational" }, |
600 | | { 0x0F, 0x0F, "Network operational" }, |
601 | | { 0x11, 0x11, "Incompatible Destination" }, |
602 | | { 0x1D, 0x1D, "Network out of order" }, |
603 | | { 0x80, 0xff, "DTE Originated" }, |
604 | | { 0, 0, NULL } |
605 | | }; |
606 | | |
607 | | static const range_string restart_code_rvals[] = { |
608 | | { 0x00, 0x00, "DTE Originated" }, |
609 | | { 0x01, 0x01, "Local Procedure Error" }, |
610 | | { 0x03, 0x03, "Network Congestion" }, |
611 | | { 0x07, 0x07, "Network Operational" }, |
612 | | { 0x7F, 0x7F, "Registration/cancellation confirmed" }, |
613 | | { 0x80, 0xff, "DTE Originated" }, |
614 | | { 0, 0, NULL } |
615 | | }; |
616 | | |
617 | | static char * |
618 | | dte_address_util(wmem_allocator_t *pool, tvbuff_t *tvb, int offset, uint8_t len) |
619 | 148 | { |
620 | 148 | int i; |
621 | 148 | char *tmpbuf = (char *)wmem_alloc(pool, 258); |
622 | | |
623 | 8.17k | for (i = 0; (i<len)&&(i<256); i++) { |
624 | 8.02k | if (i % 2 == 0) { |
625 | 4.06k | tmpbuf[i] = ((tvb_get_uint8(tvb, offset+i/2) >> 4) & 0x0F) + '0'; |
626 | | /* if > 9, convert to the right hexadecimal letter */ |
627 | 4.06k | if (tmpbuf[i] > '9') |
628 | 1.52k | tmpbuf[i] += ('A' - '0' - 10); |
629 | 4.06k | } else { |
630 | 3.96k | tmpbuf[i] = (tvb_get_uint8(tvb, offset+i/2) & 0x0F) + '0'; |
631 | | /* if > 9, convert to the right hexadecimal letter */ |
632 | 3.96k | if (tmpbuf[i] > '9') |
633 | 1.48k | tmpbuf[i] += ('A' - '0' - 10); |
634 | 3.96k | } |
635 | 8.02k | } |
636 | | |
637 | 148 | tmpbuf[i] = '\0'; |
638 | | |
639 | 148 | return tmpbuf; |
640 | 148 | } |
641 | | |
642 | | static void |
643 | | add_priority(proto_tree *tree, int hf, tvbuff_t *tvb, int offset) |
644 | 246 | { |
645 | 246 | uint8_t priority; |
646 | | |
647 | 246 | priority = tvb_get_uint8(tvb, offset); |
648 | 246 | if (priority == 255) |
649 | 16 | proto_tree_add_uint_format_value(tree, hf, tvb, offset, 1, priority, |
650 | 16 | "Unspecified (255)"); |
651 | 230 | else |
652 | 230 | proto_tree_add_uint(tree, hf, tvb, offset, 1, priority); |
653 | 246 | } |
654 | | |
655 | | static void |
656 | | dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb, packet_info *pinfo) |
657 | 204 | { |
658 | 204 | uint8_t fac, byte1, byte2, byte3; |
659 | 204 | uint32_t len; /* facilities length */ |
660 | 204 | proto_item *ti = NULL; |
661 | 204 | proto_tree *facilities_tree = NULL, *facility_tree = NULL; |
662 | | |
663 | 204 | len = tvb_get_uint8(tvb, *offset); |
664 | 204 | if (len && tree) { |
665 | 192 | facilities_tree = proto_tree_add_subtree(tree, tvb, *offset, len + 1, |
666 | 192 | ett_x25_facilities, NULL, "Facilities"); |
667 | 192 | proto_tree_add_item(facilities_tree, hf_x25_facilities_length, tvb, *offset, 1, ENC_BIG_ENDIAN); |
668 | 192 | } |
669 | 204 | (*offset)++; |
670 | | |
671 | 9.21k | while (len > 0) { |
672 | 9.19k | ti = proto_tree_add_item(facilities_tree, hf_x25_facility, tvb, *offset, -1, ENC_NA); |
673 | 9.19k | fac = tvb_get_uint8(tvb, *offset); |
674 | 9.19k | switch(fac & X25_FAC_CLASS_MASK) { |
675 | 6.47k | case X25_FAC_CLASS_A: |
676 | 6.47k | proto_item_set_len(ti, 2); |
677 | 6.47k | proto_item_append_text(ti, ": %s", |
678 | 6.47k | val_to_str(pinfo->pool, fac, x25_facilities_classA_vals, "Unknown (0x%02X)")); |
679 | 6.47k | facility_tree = proto_item_add_subtree(ti, ett_x25_facility); |
680 | 6.47k | proto_tree_add_item(facility_tree, hf_x25_facility_class, tvb, *offset, 1, ENC_BIG_ENDIAN); |
681 | 6.47k | proto_tree_add_item(facility_tree, hf_x25_facility_classA, tvb, *offset, 1, ENC_BIG_ENDIAN); |
682 | 6.47k | if (facility_tree) { |
683 | 6.47k | switch (fac) { |
684 | 2.20k | case X25_FAC_COMP_MARK: |
685 | 2.20k | proto_tree_add_item(facility_tree, hf_x25_facility_classA_comp_mark, tvb, *offset+1, 1, ENC_BIG_ENDIAN); |
686 | 2.20k | break; |
687 | 413 | case X25_FAC_REVERSE: |
688 | 413 | proto_tree_add_item(facility_tree, hf_x25_facility_classA_reverse, tvb, *offset+1, 1, ENC_BIG_ENDIAN); |
689 | 413 | proto_tree_add_item(facility_tree, hf_x25_fast_select, tvb, *offset+1, 1, ENC_BIG_ENDIAN); |
690 | 413 | proto_tree_add_item(facility_tree, hf_x25_icrd, tvb, *offset+1, 1, ENC_BIG_ENDIAN); |
691 | 413 | proto_tree_add_item(facility_tree, hf_x25_facility_reverse_charging, tvb, *offset+1, 1, ENC_BIG_ENDIAN); |
692 | 413 | break; |
693 | 372 | case X25_FAC_CHARGING_INFO: |
694 | 372 | proto_tree_add_item(facility_tree, hf_x25_facility_classA_charging_info, tvb, *offset+1, 1, ENC_BIG_ENDIAN); |
695 | 372 | proto_tree_add_item(facility_tree, hf_x25_facility_charging_info, tvb, *offset+1, 1, ENC_NA); |
696 | 372 | break; |
697 | 414 | case X25_FAC_THROUGHPUT: |
698 | 414 | proto_tree_add_item(facility_tree, hf_x25_facility_throughput_called_dte, tvb, *offset+1, 1, ENC_BIG_ENDIAN); |
699 | 414 | proto_tree_add_item(facility_tree, hf_x25_throughput_called_dte, tvb, *offset+1, 1, ENC_BIG_ENDIAN); |
700 | 414 | break; |
701 | 279 | case X25_FAC_CUG: |
702 | 279 | proto_tree_add_item(facility_tree, hf_x25_facility_classA_cug, tvb, *offset+1, 1, ENC_BIG_ENDIAN); |
703 | 279 | break; |
704 | 77 | case X25_FAC_CALLED_MODIF: |
705 | 77 | proto_tree_add_item(facility_tree, hf_x25_facility_classA_called_motif, tvb, *offset+1, 1, ENC_BIG_ENDIAN); |
706 | 77 | break; |
707 | 100 | case X25_FAC_CUG_OUTGOING_ACC: |
708 | 100 | proto_tree_add_item(facility_tree, hf_x25_facility_classA_cug_outgoing_acc, tvb, *offset+1, 1, ENC_BIG_ENDIAN); |
709 | 100 | break; |
710 | 112 | case X25_FAC_THROUGHPUT_MIN: |
711 | 112 | proto_tree_add_item(facility_tree, hf_x25_facility_classA_throughput_min, tvb, *offset+1, 1, ENC_BIG_ENDIAN); |
712 | 112 | break; |
713 | 456 | case X25_FAC_EXPRESS_DATA: |
714 | 456 | proto_tree_add_item(facility_tree, hf_x25_facility_classA_express_data, tvb, *offset+1, 1, ENC_BIG_ENDIAN); |
715 | 456 | break; |
716 | 2.04k | default: |
717 | 2.04k | proto_tree_add_item(facility_tree, hf_x25_facility_classA_unknown, tvb, *offset+1, 1, ENC_BIG_ENDIAN); |
718 | 2.04k | break; |
719 | 6.47k | } |
720 | 6.47k | } |
721 | 6.45k | (*offset) += 2; |
722 | 6.45k | len -= 2; |
723 | 6.45k | break; |
724 | 1.50k | case X25_FAC_CLASS_B: |
725 | 1.50k | proto_item_set_len(ti, 3); |
726 | 1.50k | proto_item_append_text(ti, ": %s", |
727 | 1.50k | val_to_str(pinfo->pool, fac, x25_facilities_classB_vals, "Unknown (0x%02X)")); |
728 | 1.50k | facility_tree = proto_item_add_subtree(ti, ett_x25_facility); |
729 | 1.50k | proto_tree_add_item(facility_tree, hf_x25_facility_class, tvb, *offset, 1, ENC_BIG_ENDIAN); |
730 | 1.50k | proto_tree_add_item(facility_tree, hf_x25_facility_classB, tvb, *offset, 1, ENC_BIG_ENDIAN); |
731 | 1.50k | if (facility_tree) { |
732 | 1.50k | switch (fac) { |
733 | 58 | case X25_FAC_BILATERAL_CUG: |
734 | 58 | proto_tree_add_item(facility_tree, hf_x25_facility_classB_bilateral_cug, tvb, *offset+1, 2, ENC_BIG_ENDIAN); |
735 | 58 | break; |
736 | 60 | case X25_FAC_PACKET_SIZE: |
737 | 60 | proto_tree_add_item(facility_tree, hf_x25_facility_packet_size_called_dte, tvb, *offset+1, 1, ENC_BIG_ENDIAN); |
738 | 60 | proto_tree_add_item(facility_tree, hf_x25_facility_packet_size_calling_dte, tvb, *offset+2, 1, ENC_BIG_ENDIAN); |
739 | 60 | break; |
740 | 34 | case X25_FAC_WINDOW_SIZE: |
741 | 34 | proto_tree_add_item(facility_tree, hf_x25_window_size_called_dte, tvb, *offset+1, 1, ENC_BIG_ENDIAN); |
742 | 34 | proto_tree_add_item(facility_tree, hf_x25_window_size_calling_dte, tvb, *offset+2, 1, ENC_BIG_ENDIAN); |
743 | 34 | break; |
744 | 54 | case X25_FAC_RPOA_SELECTION: |
745 | 54 | proto_tree_add_item(facility_tree, hf_x25_facility_data_network_id_code, tvb, *offset+1, 2, ENC_BIG_ENDIAN); |
746 | 54 | break; |
747 | 75 | case X25_FAC_CUG_EXT: |
748 | 75 | proto_tree_add_item(facility_tree, hf_x25_facility_cug_ext, tvb, *offset+1, 2, ENC_BIG_ENDIAN); |
749 | 75 | break; |
750 | 129 | case X25_FAC_CUG_OUTGOING_ACC_EXT: |
751 | 129 | proto_tree_add_item(facility_tree, hf_x25_facility_cug_outgoing_acc_ext, tvb, *offset+1, 2, ENC_BIG_ENDIAN); |
752 | 129 | break; |
753 | 109 | case X25_FAC_TRANSIT_DELAY: |
754 | 109 | proto_tree_add_item(facility_tree, hf_x25_facility_transit_delay, tvb, *offset+1, 2, ENC_BIG_ENDIAN); |
755 | 109 | break; |
756 | 985 | default: |
757 | 985 | proto_tree_add_item(facility_tree, hf_x25_facility_classB_unknown, tvb, *offset+1, 2, ENC_BIG_ENDIAN); |
758 | 985 | break; |
759 | 1.50k | } |
760 | 1.50k | } |
761 | 1.49k | (*offset) += 3; |
762 | 1.49k | len -= 3; |
763 | 1.49k | break; |
764 | 683 | case X25_FAC_CLASS_C: |
765 | 683 | proto_item_set_len(ti, 4); |
766 | 683 | proto_item_append_text(ti, ": %s", |
767 | 683 | val_to_str(pinfo->pool, fac, x25_facilities_classC_vals, "Unknown (0x%02X)")); |
768 | 683 | facility_tree = proto_item_add_subtree(ti, ett_x25_facility); |
769 | 683 | proto_tree_add_item(facility_tree, hf_x25_facility_class, tvb, *offset, 1, ENC_BIG_ENDIAN); |
770 | 683 | proto_tree_add_item(facility_tree, hf_x25_facility_classC, tvb, *offset, 1, ENC_BIG_ENDIAN); |
771 | 683 | if (facility_tree) { |
772 | 683 | proto_tree_add_item(facility_tree, hf_x25_facility_classC_unknown, tvb, *offset+1, 2, ENC_BIG_ENDIAN); |
773 | 683 | } |
774 | 683 | (*offset) += 4; |
775 | 683 | len -= 4; |
776 | 683 | break; |
777 | 497 | case X25_FAC_CLASS_D: |
778 | 497 | proto_item_append_text(ti, ": %s", |
779 | 497 | val_to_str(pinfo->pool, fac, x25_facilities_classD_vals, "Unknown (0x%02X)")); |
780 | 497 | facility_tree = proto_item_add_subtree(ti, ett_x25_facility); |
781 | 497 | proto_tree_add_item(facility_tree, hf_x25_facility_class, tvb, *offset, 1, ENC_BIG_ENDIAN); |
782 | 497 | byte1 = tvb_get_uint8(tvb, *offset+1); |
783 | 497 | proto_item_set_len(ti, byte1+2); |
784 | 497 | proto_tree_add_item(facility_tree, hf_x25_facility_classD, tvb, *offset, 1, ENC_BIG_ENDIAN); |
785 | 497 | proto_tree_add_item(facility_tree, hf_x25_facility_length, tvb, *offset+1, 1, ENC_BIG_ENDIAN); |
786 | 497 | if (facility_tree) { |
787 | 497 | switch (fac) { |
788 | 6 | case X25_FAC_CALL_DURATION: |
789 | 6 | { |
790 | 6 | int i; |
791 | | |
792 | 6 | if ((byte1 < 4) || (byte1 % 4)) { |
793 | 2 | expert_add_info(pinfo, ti, &ei_x25_facility_length); |
794 | 2 | return; |
795 | 2 | } |
796 | 117 | for (i = 0; (i<byte1); i+=4) { |
797 | 113 | proto_tree_add_bytes_format_value(facility_tree, hf_x25_call_duration, tvb, *offset+2+i, 4, |
798 | 113 | NULL, "%u Day(s) %02X:%02X:%02X Hour(s)", |
799 | 113 | tvb_get_uint8(tvb, *offset+2+i), |
800 | 113 | tvb_get_uint8(tvb, *offset+3+i), |
801 | 113 | tvb_get_uint8(tvb, *offset+4+i), |
802 | 113 | tvb_get_uint8(tvb, *offset+5+i)); |
803 | 113 | } |
804 | 4 | } |
805 | 0 | break; |
806 | 8 | case X25_FAC_SEGMENT_COUNT: |
807 | 8 | { |
808 | 8 | int i; |
809 | | |
810 | 8 | if ((byte1 < 8) || (byte1 % 8)) { |
811 | 4 | expert_add_info(pinfo, ti, &ei_x25_facility_length); |
812 | 4 | return; |
813 | 4 | } |
814 | 47 | for (i = 0; (i<byte1); i+=8) { |
815 | 43 | proto_tree_add_item(facility_tree, hf_x25_segments_to_dte, tvb, *offset+2+i, 4, ENC_NA); |
816 | 43 | proto_tree_add_item(facility_tree, hf_x25_segments_from_dte, tvb, *offset+6+i, 4, ENC_NA); |
817 | 43 | } |
818 | 4 | } |
819 | 0 | break; |
820 | 19 | case X25_FAC_CALL_TRANSFER: |
821 | 19 | { |
822 | 19 | char *tmpbuf; |
823 | | |
824 | 19 | if (byte1 < 2) { |
825 | 3 | expert_add_info(pinfo, ti, &ei_x25_facility_length); |
826 | 3 | return; |
827 | 3 | } |
828 | 16 | byte2 = tvb_get_uint8(tvb, *offset+2); |
829 | 16 | if ((byte2 & 0xC0) == 0xC0) { |
830 | 9 | proto_tree_add_uint_format_value(facility_tree, hf_x25_facility_call_transfer_reason, tvb, |
831 | 9 | *offset+2, 1, byte2, "call deflection by the originally called DTE address"); |
832 | 9 | } |
833 | 7 | else { |
834 | 7 | proto_tree_add_uint(facility_tree, hf_x25_facility_call_transfer_reason, tvb, *offset+2, 1, byte2); |
835 | 7 | } |
836 | 16 | byte3 = tvb_get_uint8(tvb, *offset+3); |
837 | 16 | proto_tree_add_uint(facility_tree, hf_x25_facility_call_transfer_num_semi_octets, tvb, *offset+4, 1, byte3); |
838 | 16 | tmpbuf = dte_address_util(pinfo->pool, tvb, *offset + 4, byte3); |
839 | | |
840 | 16 | proto_tree_add_string(facility_tree, hf_x25_dte_address, tvb, *offset+4, byte1 - 2, tmpbuf); |
841 | 16 | } |
842 | 0 | break; |
843 | 10 | case X25_FAC_RPOA_SELECTION_EXT: |
844 | 10 | { |
845 | 10 | int i; |
846 | | |
847 | 10 | if ((byte1 < 2) || (byte1 % 2)) { |
848 | 2 | expert_add_info(pinfo, ti, &ei_x25_facility_length); |
849 | 2 | return; |
850 | 2 | } |
851 | 439 | for (i = 0; (i<byte1); i+=2) { |
852 | 431 | proto_tree_add_item(facility_tree, hf_x25_data_network_identification_code, tvb, *offset+2+i, 2, ENC_BIG_ENDIAN); |
853 | 431 | } |
854 | 8 | } |
855 | 0 | break; |
856 | 20 | case X25_FAC_CALLING_ADDR_EXT: |
857 | 20 | { |
858 | 20 | char *tmpbuf; |
859 | | |
860 | 20 | if (byte1 < 1) { |
861 | 0 | expert_add_info(pinfo, ti, &ei_x25_facility_length); |
862 | 0 | return; |
863 | 0 | } |
864 | 20 | byte2 = tvb_get_uint8(tvb, *offset+2) & 0x3F; |
865 | 20 | proto_tree_add_uint(facility_tree, hf_x25_facility_calling_addr_ext_num_semi_octets, tvb, *offset+2, 1, byte2); |
866 | 20 | tmpbuf = dte_address_util(pinfo->pool, tvb, *offset + 3, byte2); |
867 | 20 | proto_tree_add_string(facility_tree, hf_x25_dte_address, tvb, *offset+3, byte1 - 1, tmpbuf); |
868 | 20 | } |
869 | 0 | break; |
870 | 5 | case X25_FAC_MONETARY_UNIT: |
871 | 5 | proto_tree_add_item(facility_tree, hf_x25_facility_monetary_unit, tvb, *offset+2, byte1, ENC_NA); |
872 | 5 | break; |
873 | 7 | case X25_FAC_NUI: |
874 | 7 | proto_tree_add_item(facility_tree, hf_x25_facility_nui, tvb, *offset+2, byte1, ENC_NA); |
875 | 7 | break; |
876 | 52 | case X25_FAC_CALLED_ADDR_EXT: |
877 | 52 | { |
878 | 52 | char *tmpbuf; |
879 | | |
880 | 52 | if (byte1 < 1) { |
881 | 0 | expert_add_info(pinfo, ti, &ei_x25_facility_length); |
882 | 0 | return; |
883 | 0 | } |
884 | 52 | byte2 = tvb_get_uint8(tvb, *offset+2) & 0x3F; |
885 | 52 | proto_tree_add_uint(facility_tree, hf_x25_facility_called_addr_ext_num_semi_octets, tvb, *offset+2, 1, byte2); |
886 | 52 | tmpbuf = dte_address_util(pinfo->pool, tvb, *offset+3, byte2); |
887 | | |
888 | 52 | proto_tree_add_string(facility_tree, hf_x25_dte_address, tvb, *offset+3, byte1 - 1, tmpbuf); |
889 | 52 | } |
890 | 0 | break; |
891 | 19 | case X25_FAC_ETE_TRANSIT_DELAY: |
892 | 19 | if (byte1 < 2) |
893 | 7 | break; |
894 | 12 | proto_tree_add_item(facility_tree, hf_x25_facility_cumulative_ete_transit_delay, tvb, *offset+2, 2, ENC_BIG_ENDIAN); |
895 | 12 | if (byte1 < 4) |
896 | 3 | break; |
897 | 9 | proto_tree_add_item(facility_tree, hf_x25_facility_requested_ete_transit_delay, tvb, *offset+4, 2, ENC_BIG_ENDIAN); |
898 | 9 | if (byte1 < 6) |
899 | 0 | break; |
900 | 9 | proto_tree_add_item(facility_tree, hf_x25_facility_max_acceptable_ete_transit_delay, tvb, *offset+6, 2, ENC_BIG_ENDIAN); |
901 | 9 | break; |
902 | 62 | case X25_FAC_CALL_DEFLECT: |
903 | 62 | { |
904 | 62 | char *tmpbuf; |
905 | | |
906 | 62 | if (byte1 < 2) { |
907 | 2 | expert_add_info(pinfo, ti, &ei_x25_facility_length); |
908 | 2 | return; |
909 | 2 | } |
910 | 60 | byte2 = tvb_get_uint8(tvb, *offset+2); |
911 | 60 | if ((byte2 & 0xC0) == 0xC0) |
912 | 35 | proto_tree_add_uint_format_value(facility_tree, hf_x25_facility_call_deflect_reason, tvb, *offset+2, 1, |
913 | 35 | byte2, "call DTE originated"); |
914 | 25 | else |
915 | 25 | proto_tree_add_uint_format_value(facility_tree, hf_x25_facility_call_deflect_reason, tvb, *offset+2, 1, |
916 | 25 | byte2, "unknown"); |
917 | 60 | byte3 = tvb_get_uint8(tvb, *offset+3); |
918 | 60 | proto_tree_add_uint(facility_tree, hf_x25_facility_call_deflect_num_semi_octets, tvb, *offset+3, 1, byte3); |
919 | 60 | tmpbuf = dte_address_util(pinfo->pool, tvb, *offset+4, byte3); |
920 | | |
921 | 60 | proto_tree_add_string(facility_tree, hf_x25_alternative_dte_address, tvb, *offset+4, byte1 - 2, tmpbuf); |
922 | 60 | } |
923 | 0 | break; |
924 | 63 | case X25_FAC_PRIORITY: |
925 | 63 | if (byte1 < 1) |
926 | 1 | break; |
927 | 62 | add_priority(facility_tree, hf_x25_facility_priority_data, tvb, *offset+2); |
928 | 62 | if (byte1 < 2) |
929 | 5 | break; |
930 | 57 | add_priority(facility_tree, hf_x25_facility_priority_estab_conn, tvb, *offset+3); |
931 | 57 | if (byte1 < 3) |
932 | 15 | break; |
933 | 42 | add_priority(facility_tree, hf_x25_facility_priority_keep_conn, tvb, *offset+4); |
934 | 42 | if (byte1 < 4) |
935 | 5 | break; |
936 | 37 | add_priority(facility_tree, hf_x25_facility_min_acceptable_priority_data, tvb, *offset+5); |
937 | 37 | if (byte1 < 5) |
938 | 4 | break; |
939 | 33 | add_priority(facility_tree, hf_x25_facility_min_acceptable_priority_estab_conn, tvb, *offset+6); |
940 | 33 | if (byte1 < 6) |
941 | 13 | break; |
942 | 20 | add_priority(facility_tree, hf_x25_facility_min_acceptable_priority_keep_conn, tvb, *offset+7); |
943 | 20 | break; |
944 | 226 | default: |
945 | 226 | proto_tree_add_item(facility_tree, hf_x25_facility_classD_unknown, tvb, *offset+2, byte1, ENC_NA); |
946 | 497 | } |
947 | 497 | } |
948 | 388 | byte1 = tvb_get_uint8(tvb, *offset+1); |
949 | 388 | (*offset) += byte1+2; |
950 | 388 | len -= byte1+2; |
951 | 388 | break; |
952 | 9.19k | } |
953 | 9.19k | } |
954 | 204 | } |
955 | | |
956 | | static void |
957 | | x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb, |
958 | | packet_info *pinfo, bool is_registration) |
959 | 190 | { |
960 | 190 | int len1, len2; |
961 | 190 | int i; |
962 | 190 | char *addr1, *addr2; |
963 | 190 | char *first, *second; |
964 | 190 | uint8_t byte; |
965 | 190 | int localoffset; |
966 | | |
967 | 190 | addr1=(char *)wmem_alloc(pinfo->pool, 16); |
968 | 190 | addr2=(char *)wmem_alloc(pinfo->pool, 16); |
969 | | |
970 | 190 | byte = tvb_get_uint8(tvb, *offset); |
971 | 190 | len1 = (byte >> 0) & 0x0F; |
972 | 190 | len2 = (byte >> 4) & 0x0F; |
973 | | |
974 | 190 | if (tree) { |
975 | 190 | if (is_registration) { |
976 | 6 | proto_tree_add_item(tree, hf_x25_dte_address_length, tvb, *offset, 1, ENC_BIG_ENDIAN); |
977 | 6 | proto_tree_add_item(tree, hf_x25_dce_address_length, tvb, *offset, 1, ENC_BIG_ENDIAN); |
978 | 6 | } |
979 | 184 | else { |
980 | 184 | proto_tree_add_item(tree, hf_x25_calling_address_length, tvb, *offset, 1, ENC_BIG_ENDIAN); |
981 | 184 | proto_tree_add_item(tree, hf_x25_called_address_length, tvb, *offset, 1, ENC_BIG_ENDIAN); |
982 | 184 | } |
983 | 190 | } |
984 | 190 | (*offset)++; |
985 | | |
986 | 190 | localoffset = *offset; |
987 | 190 | byte = tvb_get_uint8(tvb, localoffset); |
988 | | |
989 | 190 | first=addr1; |
990 | 190 | second=addr2; |
991 | 2.52k | for (i = 0; i < (len1 + len2); i++) { |
992 | 2.33k | if (i < len1) { |
993 | 1.39k | if (i % 2 != 0) { |
994 | 644 | *first++ = ((byte >> 0) & 0x0F) + '0'; |
995 | 644 | localoffset++; |
996 | 644 | byte = tvb_get_uint8(tvb, localoffset); |
997 | 755 | } else { |
998 | 755 | *first++ = ((byte >> 4) & 0x0F) + '0'; |
999 | 755 | } |
1000 | 1.39k | } else { |
1001 | 932 | if (i % 2 != 0) { |
1002 | 477 | *second++ = ((byte >> 0) & 0x0F) + '0'; |
1003 | 477 | localoffset++; |
1004 | 477 | byte = tvb_get_uint8(tvb, localoffset); |
1005 | 477 | } else { |
1006 | 455 | *second++ = ((byte >> 4) & 0x0F) + '0'; |
1007 | 455 | } |
1008 | 932 | } |
1009 | 2.33k | } |
1010 | | |
1011 | 190 | *first = '\0'; |
1012 | 190 | *second = '\0'; |
1013 | | |
1014 | 190 | if (len1) { |
1015 | 174 | col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1); |
1016 | 174 | proto_tree_add_string(tree, is_registration ? hf_x25_dce_address : hf_x25_called_address, tvb, *offset, |
1017 | 174 | (len1 + 1) / 2, addr1); |
1018 | 174 | } |
1019 | 190 | if (len2) { |
1020 | 98 | col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2); |
1021 | 98 | proto_tree_add_string(tree, is_registration ? hf_x25_dte_address : hf_x25_calling_address, tvb, *offset + len1/2, |
1022 | 98 | (len2+1)/2+(len1%2+(len2+1)%2)/2, addr2); |
1023 | 98 | } |
1024 | 190 | (*offset) += ((len1 + len2 + 1) / 2); |
1025 | 190 | } |
1026 | | |
1027 | | static void |
1028 | | x25_toa(proto_tree *tree, int *offset, tvbuff_t *tvb, |
1029 | | packet_info *pinfo) |
1030 | 39 | { |
1031 | 39 | int len1, len2; |
1032 | 39 | int i; |
1033 | 39 | char *addr1, *addr2; |
1034 | 39 | char *first, *second; |
1035 | 39 | uint8_t byte; |
1036 | 39 | int localoffset; |
1037 | | |
1038 | 39 | addr1=(char *)wmem_alloc(pinfo->pool, 256); |
1039 | 39 | addr2=(char *)wmem_alloc(pinfo->pool, 256); |
1040 | | |
1041 | 39 | len1 = tvb_get_uint8(tvb, *offset); |
1042 | 39 | proto_tree_add_item(tree, hf_x25_called_address_length, tvb, *offset, 1, ENC_NA); |
1043 | 39 | (*offset)++; |
1044 | | |
1045 | 39 | len2 = tvb_get_uint8(tvb, *offset); |
1046 | 39 | proto_tree_add_item(tree, hf_x25_calling_address_length, tvb, *offset, 1, ENC_NA); |
1047 | 39 | (*offset)++; |
1048 | | |
1049 | 39 | localoffset = *offset; |
1050 | 39 | byte = tvb_get_uint8(tvb, localoffset); |
1051 | | |
1052 | | /* |
1053 | | * XXX - the first two half-octets of the address are the TOA and |
1054 | | * NPI; process them as such and, if the TOA says an address is |
1055 | | * an alternative address, process it correctly (i.e., not as a |
1056 | | * sequence of half-octets containing digit values). |
1057 | | */ |
1058 | 39 | first=addr1; |
1059 | 39 | second=addr2; |
1060 | 2.31k | for (i = 0; i < (len1 + len2); i++) { |
1061 | 2.27k | if (i < len1) { |
1062 | 1.15k | if (i % 2 != 0) { |
1063 | 569 | *first++ = ((byte >> 0) & 0x0F) + '0'; |
1064 | 569 | localoffset++; |
1065 | 569 | byte = tvb_get_uint8(tvb, localoffset); |
1066 | 581 | } else { |
1067 | 581 | *first++ = ((byte >> 4) & 0x0F) + '0'; |
1068 | 581 | } |
1069 | 1.15k | } else { |
1070 | 1.12k | if (i % 2 != 0) { |
1071 | 562 | *second++ = ((byte >> 0) & 0x0F) + '0'; |
1072 | 562 | localoffset++; |
1073 | 562 | byte = tvb_get_uint8(tvb, localoffset); |
1074 | 564 | } else { |
1075 | 564 | *second++ = ((byte >> 4) & 0x0F) + '0'; |
1076 | 564 | } |
1077 | 1.12k | } |
1078 | 2.27k | } |
1079 | | |
1080 | 39 | *first = '\0'; |
1081 | 39 | *second = '\0'; |
1082 | | |
1083 | 39 | if (len1) { |
1084 | 23 | col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1); |
1085 | 23 | proto_tree_add_string(tree, hf_x25_called_address, tvb, *offset, |
1086 | 23 | (len1 + 1) / 2, addr1); |
1087 | 23 | } |
1088 | 39 | if (len2) { |
1089 | 22 | col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2); |
1090 | 22 | proto_tree_add_string(tree, hf_x25_calling_address, tvb, *offset + len1/2, |
1091 | 22 | (len2+1)/2+(len1%2+(len2+1)%2)/2, addr2); |
1092 | 22 | } |
1093 | 39 | (*offset) += ((len1 + len2 + 1) / 2); |
1094 | 39 | } |
1095 | | |
1096 | | static int |
1097 | | get_x25_pkt_len(tvbuff_t *tvb) |
1098 | 329 | { |
1099 | 329 | unsigned length, called_len, calling_len, dte_len, dce_len; |
1100 | 329 | uint8_t byte2, bytex; |
1101 | | |
1102 | 329 | byte2 = tvb_get_uint8(tvb, 2); |
1103 | 329 | switch (byte2) |
1104 | 329 | { |
1105 | 124 | case X25_CALL_REQUEST: |
1106 | 124 | bytex = tvb_get_uint8(tvb, 3); |
1107 | 124 | called_len = (bytex >> 0) & 0x0F; |
1108 | 124 | calling_len = (bytex >> 4) & 0x0F; |
1109 | 124 | length = 4 + (called_len + calling_len + 1) / 2; /* addr */ |
1110 | 124 | if (length < tvb_reported_length(tvb)) |
1111 | 119 | length += (1 + tvb_get_uint8(tvb, length)); /* facilities */ |
1112 | | |
1113 | 124 | return MIN(tvb_reported_length(tvb),length); |
1114 | | |
1115 | 65 | case X25_CALL_ACCEPTED: |
1116 | | /* The calling/called address length byte (following the packet type) |
1117 | | * is not mandatory, so we must check the packet length before trying |
1118 | | * to read it */ |
1119 | 65 | if (tvb_reported_length(tvb) == 3) |
1120 | 1 | return 3; |
1121 | 64 | bytex = tvb_get_uint8(tvb, 3); |
1122 | 64 | called_len = (bytex >> 0) & 0x0F; |
1123 | 64 | calling_len = (bytex >> 4) & 0x0F; |
1124 | 64 | length = 4 + (called_len + calling_len + 1) / 2; /* addr */ |
1125 | 64 | if (length < tvb_reported_length(tvb)) |
1126 | 60 | length += (1 + tvb_get_uint8(tvb, length)); /* facilities */ |
1127 | | |
1128 | 64 | return MIN(tvb_reported_length(tvb),length); |
1129 | | |
1130 | 3 | case X25_CLEAR_REQUEST: |
1131 | 5 | case X25_RESET_REQUEST: |
1132 | 6 | case X25_RESTART_REQUEST: |
1133 | 6 | return MIN(tvb_reported_length(tvb),5); |
1134 | | |
1135 | 1 | case X25_DIAGNOSTIC: |
1136 | 1 | return MIN(tvb_reported_length(tvb),4); |
1137 | | |
1138 | 35 | case X25_CLEAR_CONFIRMATION: |
1139 | 37 | case X25_INTERRUPT: |
1140 | 39 | case X25_INTERRUPT_CONFIRMATION: |
1141 | 40 | case X25_RESET_CONFIRMATION: |
1142 | 43 | case X25_RESTART_CONFIRMATION: |
1143 | 43 | return MIN(tvb_reported_length(tvb),3); |
1144 | | |
1145 | 3 | case X25_REGISTRATION_REQUEST: |
1146 | 3 | bytex = tvb_get_uint8(tvb, 3); |
1147 | 3 | dce_len = (bytex >> 0) & 0x0F; |
1148 | 3 | dte_len = (bytex >> 4) & 0x0F; |
1149 | 3 | length = 4 + (dte_len + dce_len + 1) / 2; /* addr */ |
1150 | 3 | if (length < tvb_reported_length(tvb)) |
1151 | 3 | length += (1 + tvb_get_uint8(tvb, length)); /* registration */ |
1152 | | |
1153 | 3 | return MIN(tvb_reported_length(tvb),length); |
1154 | | |
1155 | 3 | case X25_REGISTRATION_CONFIRMATION: |
1156 | 3 | bytex = tvb_get_uint8(tvb, 5); |
1157 | 3 | dce_len = (bytex >> 0) & 0x0F; |
1158 | 3 | dte_len = (bytex >> 4) & 0x0F; |
1159 | 3 | length = 6 + (dte_len + dce_len + 1) / 2; /* addr */ |
1160 | 3 | if (length < tvb_reported_length(tvb)) |
1161 | 2 | length += (1 + tvb_get_uint8(tvb, length)); /* registration */ |
1162 | | |
1163 | 3 | return MIN(tvb_reported_length(tvb),length); |
1164 | 329 | } |
1165 | | |
1166 | 84 | if (PACKET_IS_DATA(byte2)) |
1167 | 55 | return MIN(tvb_reported_length(tvb),3); |
1168 | | |
1169 | 29 | switch (PACKET_TYPE_FC(byte2)) |
1170 | 29 | { |
1171 | 17 | case X25_RR: |
1172 | 17 | return MIN(tvb_reported_length(tvb),3); |
1173 | | |
1174 | 3 | case X25_RNR: |
1175 | 3 | return MIN(tvb_reported_length(tvb),3); |
1176 | | |
1177 | 3 | case X25_REJ: |
1178 | 3 | return MIN(tvb_reported_length(tvb),3); |
1179 | 29 | } |
1180 | | |
1181 | 6 | return 0; |
1182 | 29 | } |
1183 | | |
1184 | | /* X.264 / ISO 11570 transport protocol ID values. */ |
1185 | | |
1186 | 1 | #define PRT_ID_ISO_8073 0x01 /* X.224/ISO 8073 COTP */ |
1187 | 0 | #define PRT_ID_ISO_8602 0x02 /* X.234/ISO 8602 CLTP */ |
1188 | | #define PRT_ID_ISO_10736_ISO_8073 0x03 /* X.274/ISO 10736 + X.224/ISO 8073 */ |
1189 | | #define PRT_ID_ISO_10736_ISO_8602 0x04 /* X.274/ISO 10736 + X.234/ISO 8602 */ |
1190 | | |
1191 | | static const value_string prt_id_vals[] = { |
1192 | | {PRT_ID_ISO_8073, "ISO 8073 COTP"}, |
1193 | | {PRT_ID_ISO_8602, "ISO 8602 CLTP"}, |
1194 | | {PRT_ID_ISO_10736_ISO_8073, "ISO 10736 in conjunction with ISO 8073 COTP"}, |
1195 | | {PRT_ID_ISO_10736_ISO_8602, "ISO 10736 in conjunction with ISO 8602 CLTP"}, |
1196 | | {0x00, NULL} |
1197 | | }; |
1198 | | |
1199 | | static const value_string sharing_strategy_vals[] = { |
1200 | | {0x00, "No sharing"}, |
1201 | | {0x00, NULL} |
1202 | | }; |
1203 | | |
1204 | | static void |
1205 | | dissect_x25_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, |
1206 | | x25_dir_t dir, bool side) |
1207 | 329 | { |
1208 | 329 | proto_tree *x25_tree=0, *gfi_tree=0, *userdata_tree=0; |
1209 | 329 | proto_item *ti; |
1210 | 329 | unsigned localoffset=0; |
1211 | 329 | unsigned x25_pkt_len; |
1212 | 329 | int modulo; |
1213 | 329 | uint16_t vc; |
1214 | 329 | dissector_handle_t dissect; |
1215 | 329 | bool toa; /* TOA/NPI address format */ |
1216 | 329 | uint16_t bytes0_1; |
1217 | 329 | uint8_t pkt_type; |
1218 | 329 | const char *short_name = NULL, *long_name = NULL; |
1219 | 329 | tvbuff_t *next_tvb = NULL; |
1220 | 329 | bool q_bit_set = false; |
1221 | 329 | bool m_bit_set; |
1222 | 329 | int payload_len; |
1223 | 329 | uint32_t frag_key; |
1224 | 329 | fragment_head *fd_head; |
1225 | 329 | heur_dtbl_entry_t *hdtbl_entry; |
1226 | | |
1227 | | |
1228 | 329 | uint8_t spi; |
1229 | 329 | int is_x_264; |
1230 | 329 | uint8_t prt_id; |
1231 | 329 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "X.25"); |
1232 | 329 | col_clear(pinfo->cinfo, COL_INFO); |
1233 | | |
1234 | 329 | bytes0_1 = tvb_get_ntohs(tvb, 0); |
1235 | | |
1236 | 329 | modulo = ((bytes0_1 & 0x2000) ? 128 : 8); |
1237 | 329 | vc = (int)(bytes0_1 & 0x0FFF); |
1238 | | |
1239 | 329 | conversation_set_elements_by_id(pinfo, CONVERSATION_X25, vc); |
1240 | | |
1241 | 329 | if (bytes0_1 & X25_ABIT) toa = true; |
1242 | 263 | else toa = false; |
1243 | | |
1244 | 329 | x25_pkt_len = get_x25_pkt_len(tvb); |
1245 | 329 | if (x25_pkt_len < 3) /* packet too short */ |
1246 | 6 | { |
1247 | 6 | col_set_str(pinfo->cinfo, COL_INFO, "Invalid/short X.25 packet"); |
1248 | 6 | if (tree) |
1249 | 6 | proto_tree_add_protocol_format(tree, proto_x25, tvb, 0, -1, |
1250 | 6 | "Invalid/short X.25 packet"); |
1251 | 6 | return; |
1252 | 6 | } |
1253 | | |
1254 | 323 | pkt_type = tvb_get_uint8(tvb, 2); |
1255 | 323 | if (PACKET_IS_DATA(pkt_type)) { |
1256 | 55 | if (bytes0_1 & X25_QBIT) |
1257 | 14 | q_bit_set = true; |
1258 | 55 | } |
1259 | | |
1260 | 323 | if (tree) { |
1261 | 323 | ti = proto_tree_add_item(tree, proto_x25, tvb, 0, x25_pkt_len, ENC_NA); |
1262 | 323 | x25_tree = proto_item_add_subtree(ti, ett_x25); |
1263 | 323 | ti = proto_tree_add_item(x25_tree, hf_x25_gfi, tvb, 0, 2, ENC_BIG_ENDIAN); |
1264 | 323 | gfi_tree = proto_item_add_subtree(ti, ett_x25_gfi); |
1265 | | |
1266 | 323 | if (PACKET_IS_DATA(pkt_type)) { |
1267 | 55 | proto_tree_add_boolean(gfi_tree, hf_x25_qbit, tvb, 0, 2, |
1268 | 55 | bytes0_1); |
1269 | 55 | } |
1270 | 268 | else if (pkt_type == X25_CALL_REQUEST || |
1271 | 144 | pkt_type == X25_CALL_ACCEPTED || |
1272 | 79 | pkt_type == X25_CLEAR_REQUEST || |
1273 | 227 | pkt_type == X25_CLEAR_CONFIRMATION) { |
1274 | 227 | proto_tree_add_boolean(gfi_tree, hf_x25_abit, tvb, 0, 2, |
1275 | 227 | bytes0_1); |
1276 | 227 | } |
1277 | | |
1278 | 323 | if (pkt_type == X25_CALL_REQUEST || pkt_type == X25_CALL_ACCEPTED || |
1279 | 244 | PACKET_IS_DATA(pkt_type)) { |
1280 | 244 | proto_tree_add_boolean(gfi_tree, hf_x25_dbit, tvb, 0, 2, |
1281 | 244 | bytes0_1); |
1282 | 244 | } |
1283 | 323 | proto_tree_add_uint(gfi_tree, hf_x25_mod, tvb, 0, 2, bytes0_1); |
1284 | 323 | } |
1285 | | |
1286 | 323 | switch (pkt_type) { |
1287 | 124 | case X25_CALL_REQUEST: |
1288 | 124 | switch (dir) { |
1289 | | |
1290 | 0 | case X25_FROM_DCE: |
1291 | 0 | short_name = "Inc. call"; |
1292 | 0 | long_name = "Incoming call"; |
1293 | 0 | break; |
1294 | | |
1295 | 0 | case X25_FROM_DTE: |
1296 | 0 | short_name = "Call req."; |
1297 | 0 | long_name = "Call request"; |
1298 | 0 | break; |
1299 | | |
1300 | 124 | case X25_UNKNOWN: |
1301 | 124 | short_name = "Inc. call/Call req."; |
1302 | 124 | long_name = "Incoming call/Call request"; |
1303 | 124 | break; |
1304 | 124 | } |
1305 | 124 | col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc); |
1306 | 124 | if (x25_tree) { |
1307 | 124 | proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, |
1308 | 124 | 0, 2, bytes0_1); |
1309 | 124 | proto_tree_add_uint_format_value(x25_tree, hf_x25_type, tvb, 2, 1, |
1310 | 124 | X25_CALL_REQUEST, "%s", long_name); |
1311 | 124 | } |
1312 | 124 | localoffset = 3; |
1313 | 124 | if (localoffset < x25_pkt_len) { /* calling/called addresses */ |
1314 | 124 | if (toa) |
1315 | 21 | x25_toa(x25_tree, (int*)&localoffset, tvb, pinfo); |
1316 | 103 | else |
1317 | 103 | x25_ntoa(x25_tree, (int*)&localoffset, tvb, pinfo, false); |
1318 | 124 | } |
1319 | | |
1320 | 124 | if (localoffset < x25_pkt_len) /* facilities */ |
1321 | 117 | dump_facilities(x25_tree, (int*)&localoffset, tvb, pinfo); |
1322 | | |
1323 | 124 | if (localoffset < tvb_reported_length(tvb)) /* user data */ |
1324 | 27 | { |
1325 | | |
1326 | 27 | userdata_tree = proto_tree_add_subtree(x25_tree, tvb, localoffset, -1, |
1327 | 27 | ett_x25_user_data, &ti, "User data"); |
1328 | | |
1329 | | /* X.263/ISO 9577 says that: |
1330 | | |
1331 | | When CLNP or ESIS are run over X.25, the SPI |
1332 | | is 0x81 or 0x82, respectively; those are the |
1333 | | NLPIDs for those protocol. |
1334 | | |
1335 | | When X.224/ISO 8073 COTP is run over X.25, and |
1336 | | when ISO 11570 explicit identification is being |
1337 | | used, the first octet of the user data field is |
1338 | | a TPDU length field, and the rest is "as defined |
1339 | | in ITU-T Rec. X.225 | ISO/IEC 8073, Annex B, |
1340 | | or ITU-T Rec. X.264 and ISO/IEC 11570". |
1341 | | |
1342 | | When X.264/ISO 11570 default identification is |
1343 | | being used, there is no user data field in the |
1344 | | CALL REQUEST packet. This is for X.225/ISO 8073 |
1345 | | COTP. |
1346 | | |
1347 | | It also says that SPI values from 0x03 through 0x3f are |
1348 | | reserved and are in use by X.224/ISO 8073 Annex B and |
1349 | | X.264/ISO 11570. The note says that those values are |
1350 | | not NLPIDs, they're "used by the respective higher layer |
1351 | | protocol" and "not used for higher layer protocol |
1352 | | identification". I infer from this and from what |
1353 | | X.264/ISO 11570 says that this means that values in those |
1354 | | range are valid values for the first octet of an |
1355 | | X.224/ISO 8073 packet or for X.264/ISO 11570. |
1356 | | |
1357 | | Annex B of X.225/ISO 8073 mentions some additional TPDU |
1358 | | types that can be put in what I presume is the user |
1359 | | data of connect requests. It says that: |
1360 | | |
1361 | | The sending transport entity shall: |
1362 | | |
1363 | | a) either not transmit any TPDU in the NS-user data |
1364 | | parameter of the N-CONNECT request primitive; or |
1365 | | |
1366 | | b) transmit the UN-TPDU (see ITU-T Rec. X.264 and |
1367 | | ISO/IEC 11570) followed by the NCM-TPDU in the |
1368 | | NS-user data parameter of the N-CONNECT request |
1369 | | primitive. |
1370 | | |
1371 | | I don't know if this means that the user data field |
1372 | | will contain a UN TPDU followed by an NCM TPDU or not. |
1373 | | |
1374 | | X.264/ISO 11570 says that: |
1375 | | |
1376 | | When default identification is being used, |
1377 | | X.225/ISO 8073 COTP is identified. No user data |
1378 | | is sent in the network-layer connection request. |
1379 | | |
1380 | | When explicit identification is being used, |
1381 | | the user data is a UN TPDU ("Use of network |
1382 | | connection TPDU"), which specifies the transport |
1383 | | protocol to use over this network connection. |
1384 | | It also says that the length of a UN TPDU shall |
1385 | | not exceed 32 octets, i.e. shall not exceed 0x20; |
1386 | | it says this is "due to the desire not to conflict |
1387 | | with the protocol identifier field carried by X.25 |
1388 | | CALL REQUEST/INCOMING CALL packets", and says that |
1389 | | field has values specified in X.244. X.244 has been |
1390 | | superseded by X.263/ISO 9577, so that presumably |
1391 | | means the goal is to allow a UN TPDU's length |
1392 | | field to be distinguished from an NLPID, allowing |
1393 | | you to tell whether X.264/ISO 11570 explicit |
1394 | | identification is being used or an NLPID is |
1395 | | being used as the SPI. |
1396 | | |
1397 | | I read this as meaning that, if the ISO mechanisms are |
1398 | | used to identify the protocol being carried over X.25: |
1399 | | |
1400 | | if there's no user data in the CALL REQUEST/ |
1401 | | INCOMING CALL packet, it's COTP; |
1402 | | |
1403 | | if there is user data, then: |
1404 | | |
1405 | | if the first octet is less than or equal to |
1406 | | 32, it might be a UN TPDU, and that identifies |
1407 | | the transport protocol being used, and |
1408 | | it may be followed by more data, such |
1409 | | as a COTP NCM TPDU if it's COTP; |
1410 | | |
1411 | | if the first octet is greater than 32, it's |
1412 | | an NLPID, *not* a TPDU length, and the |
1413 | | stuff following it is *not* a TPDU. |
1414 | | |
1415 | | Figure A.2 of X.263/ISO 9577 seems to say that the |
1416 | | first octet of the user data is a TPDU length field, |
1417 | | in the range 0x03 through 0x82, and says they are |
1418 | | for X.225/ISO 8073 Annex B or X.264/ISO 11570. |
1419 | | |
1420 | | However, X.264/ISO 11570 seems to imply that the length |
1421 | | field would be that of a UN TPDU, which must be less |
1422 | | than or equal to 0x20, and X.225/ISO 8073 Annex B seems |
1423 | | to indicate that the user data must begin with |
1424 | | an X.264/ISO 11570 UN TPDU, so I'd say that A.2 should |
1425 | | have said "in the range 0x03 through 0x20", instead |
1426 | | (the length value doesn't include the length field, |
1427 | | and the minimum UN TPDU has length, type, PRT-ID, |
1428 | | and SHARE, so that's 3 bytes without the length). */ |
1429 | 27 | spi = tvb_get_uint8(tvb, localoffset); |
1430 | 27 | if (spi > 32 || spi < 3) { |
1431 | | /* First octet is > 32, or < 3, so the user data isn't an |
1432 | | X.264/ISO 11570 UN TPDU */ |
1433 | 25 | is_x_264 = false; |
1434 | 25 | } else { |
1435 | | /* First octet is >= 3 and <= 32, so the user data *might* |
1436 | | be an X.264/ISO 11570 UN TPDU. Check whether we have |
1437 | | enough data to see if it is. */ |
1438 | 2 | if (tvb_bytes_exist(tvb, localoffset+1, 1)) { |
1439 | | /* We do; check whether the second octet is 1. */ |
1440 | 2 | if (tvb_get_uint8(tvb, localoffset+1) == 0x01) { |
1441 | | /* Yes, the second byte is 1, so it looks like |
1442 | | a UN TPDU. */ |
1443 | 2 | is_x_264 = true; |
1444 | 2 | } else { |
1445 | | /* No, the second byte is not 1, so it's not a |
1446 | | UN TPDU. */ |
1447 | 0 | is_x_264 = false; |
1448 | 0 | } |
1449 | 2 | } else { |
1450 | | /* We can't see the second byte of the putative UN |
1451 | | TPDU, so we don't know if that's what it is. */ |
1452 | 0 | is_x_264 = -1; |
1453 | 0 | } |
1454 | 2 | } |
1455 | 27 | if (is_x_264 == -1) { |
1456 | | /* |
1457 | | * We don't know what it is; just skip it. |
1458 | | */ |
1459 | 0 | localoffset = tvb_reported_length(tvb); |
1460 | 27 | } else if (is_x_264) { |
1461 | | /* It looks like an X.264 UN TPDU, so show it as such. */ |
1462 | 2 | if (userdata_tree) { |
1463 | 2 | proto_tree_add_item( userdata_tree, hf_x264_length_indicator, tvb, localoffset, 1, ENC_BIG_ENDIAN); |
1464 | 2 | proto_tree_add_item( userdata_tree, hf_x264_un_tpdu_id, tvb, localoffset+1, 1, ENC_BIG_ENDIAN); |
1465 | 2 | } |
1466 | 2 | prt_id = tvb_get_uint8(tvb, localoffset+2); |
1467 | 2 | if (userdata_tree) { |
1468 | 2 | proto_tree_add_item( userdata_tree, hf_x264_protocol_id, tvb, localoffset+2, 1, ENC_BIG_ENDIAN); |
1469 | 2 | proto_tree_add_item( userdata_tree, hf_x264_sharing_strategy, tvb, localoffset+3, 1, ENC_BIG_ENDIAN); |
1470 | 2 | } |
1471 | | |
1472 | | /* XXX - dissect the variable part? */ |
1473 | | |
1474 | | /* The length doesn't include the length octet itself. */ |
1475 | 2 | localoffset += spi + 1; |
1476 | | |
1477 | 2 | switch (prt_id) { |
1478 | | |
1479 | 1 | case PRT_ID_ISO_8073: |
1480 | | /* ISO 8073 COTP */ |
1481 | 1 | if (!pinfo->fd->visited) |
1482 | 1 | x25_hash_add_proto_start(vc, pinfo->num, ositp_handle); |
1483 | | /* XXX - dissect the rest of the user data as COTP? |
1484 | | That needs support for NCM TPDUs, etc. */ |
1485 | 1 | break; |
1486 | | |
1487 | 0 | case PRT_ID_ISO_8602: |
1488 | | /* ISO 8602 CLTP */ |
1489 | 0 | if (!pinfo->fd->visited) |
1490 | 0 | x25_hash_add_proto_start(vc, pinfo->num, ositp_handle); |
1491 | 0 | break; |
1492 | 2 | } |
1493 | 25 | } else if (is_x_264 == 0) { |
1494 | | /* It doesn't look like a UN TPDU, so compare the first |
1495 | | octet of the CALL REQUEST packet with various X.263/ |
1496 | | ISO 9577 NLPIDs, as per Annex A of X.263/ISO 9577. */ |
1497 | | |
1498 | 25 | if (userdata_tree) { |
1499 | 25 | proto_tree_add_item( userdata_tree, hf_x263_sec_protocol_id, tvb, localoffset, 1, ENC_BIG_ENDIAN); |
1500 | 25 | } |
1501 | | |
1502 | 25 | if (!pinfo->fd->visited) { |
1503 | | /* |
1504 | | * Is there a dissector handle for this SPI? |
1505 | | * If so, assign it to this virtual circuit. |
1506 | | */ |
1507 | 25 | dissect = dissector_get_uint_handle(x25_subdissector_table, spi); |
1508 | 25 | if (dissect != NULL) |
1509 | 9 | x25_hash_add_proto_start(vc, pinfo->num, dissect); |
1510 | 25 | } |
1511 | | |
1512 | | /* |
1513 | | * If there's only one octet of user data, it's just |
1514 | | * an NLPID; don't try to dissect it. |
1515 | | */ |
1516 | 25 | if (localoffset + 1 == tvb_reported_length(tvb)) |
1517 | 4 | return; |
1518 | | |
1519 | | /* |
1520 | | * There's more than one octet of user data, so we'll |
1521 | | * dissect it; for some protocols, the NLPID is considered |
1522 | | * to be part of the PDU, so, for those cases, we don't |
1523 | | * skip past it. For other protocols, we skip the NLPID. |
1524 | | */ |
1525 | 21 | switch (spi) { |
1526 | | |
1527 | 0 | case NLPID_ISO8473_CLNP: |
1528 | 1 | case NLPID_ISO9542_ESIS: |
1529 | 1 | case NLPID_ISO10589_ISIS: |
1530 | 1 | case NLPID_ISO10747_IDRP: |
1531 | 3 | case NLPID_SNDCF: |
1532 | | /* |
1533 | | * The NLPID is part of the PDU. Don't skip it. |
1534 | | * But if it's all there is to the PDU, don't |
1535 | | * bother dissecting it. |
1536 | | */ |
1537 | 3 | break; |
1538 | | |
1539 | 5 | case NLPID_SPI_X_29: |
1540 | | /* |
1541 | | * The first 4 bytes of the call user data are |
1542 | | * the SPI plus 3 reserved bytes; they are not |
1543 | | * part of the data to be dissected as X.29 data. |
1544 | | */ |
1545 | 5 | localoffset += 4; |
1546 | 5 | break; |
1547 | | |
1548 | 13 | default: |
1549 | | /* |
1550 | | * The NLPID isn't part of the PDU - skip it. |
1551 | | * If that means there's nothing to dissect |
1552 | | */ |
1553 | 13 | localoffset++; |
1554 | 21 | } |
1555 | 21 | } |
1556 | 97 | } else { |
1557 | | /* if there's no user data in the CALL REQUEST/ |
1558 | | INCOMING CALL packet, it's COTP; */ |
1559 | | |
1560 | 97 | if (call_request_nodata_is_cotp){ |
1561 | 0 | x25_hash_add_proto_start(vc, pinfo->num, ositp_handle); |
1562 | 0 | } |
1563 | 97 | } |
1564 | 120 | break; |
1565 | 120 | case X25_CALL_ACCEPTED: |
1566 | 65 | switch (dir) { |
1567 | | |
1568 | 0 | case X25_FROM_DCE: |
1569 | 0 | short_name = "Call conn."; |
1570 | 0 | long_name = "Call connected"; |
1571 | 0 | break; |
1572 | | |
1573 | 0 | case X25_FROM_DTE: |
1574 | 0 | short_name = "Call acc."; |
1575 | 0 | long_name = "Call accepted"; |
1576 | 0 | break; |
1577 | | |
1578 | 65 | case X25_UNKNOWN: |
1579 | 65 | short_name = "Call conn./Call acc."; |
1580 | 65 | long_name = "Call connected/Call accepted"; |
1581 | 65 | break; |
1582 | 65 | } |
1583 | 65 | col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc); |
1584 | 65 | if (x25_tree) { |
1585 | 65 | proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1); |
1586 | 65 | proto_tree_add_uint_format_value(x25_tree, hf_x25_type, tvb, 2, 1, |
1587 | 65 | X25_CALL_ACCEPTED, "%s", long_name); |
1588 | 65 | } |
1589 | 65 | localoffset = 3; |
1590 | 65 | if (localoffset < x25_pkt_len) { /* calling/called addresses */ |
1591 | 64 | if (toa) |
1592 | 13 | x25_toa(x25_tree, (int*)&localoffset, tvb, pinfo); |
1593 | 51 | else |
1594 | 51 | x25_ntoa(x25_tree, (int*)&localoffset, tvb, pinfo, false); |
1595 | 64 | } |
1596 | | |
1597 | 65 | if (localoffset < x25_pkt_len) /* facilities */ |
1598 | 57 | dump_facilities(x25_tree, (int*)&localoffset, tvb, pinfo); |
1599 | 65 | break; |
1600 | 3 | case X25_CLEAR_REQUEST: |
1601 | 3 | switch (dir) { |
1602 | | |
1603 | 0 | case X25_FROM_DCE: |
1604 | 0 | short_name = "Clear ind."; |
1605 | 0 | long_name = "Clear indication"; |
1606 | 0 | break; |
1607 | | |
1608 | 0 | case X25_FROM_DTE: |
1609 | 0 | short_name = "Clear req."; |
1610 | 0 | long_name = "Clear request"; |
1611 | 0 | break; |
1612 | | |
1613 | 3 | case X25_UNKNOWN: |
1614 | 3 | short_name = "Clear ind./Clear req."; |
1615 | 3 | long_name = "Clear indication/Clear request"; |
1616 | 3 | break; |
1617 | 3 | } |
1618 | 3 | col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - %s", short_name, |
1619 | 3 | vc, rval_to_str_wmem(pinfo->pool, tvb_get_uint8(tvb, 3), clear_code_rvals, "Unknown (0x%02x)"), |
1620 | 3 | val_to_str_ext(pinfo->pool, tvb_get_uint8(tvb, 4), &x25_clear_diag_vals_ext, "Unknown (0x%02x)")); |
1621 | 3 | x25_hash_add_proto_end(vc, pinfo->num); |
1622 | 3 | if (x25_tree) { |
1623 | 2 | proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1); |
1624 | 2 | proto_tree_add_uint_format_value(x25_tree, hf_x25_type, tvb, |
1625 | 2 | localoffset+2, 1, X25_CLEAR_REQUEST, "%s", |
1626 | 2 | long_name); |
1627 | 2 | proto_tree_add_item(x25_tree, hf_x25_clear_cause, tvb, 3, 1, ENC_NA); |
1628 | 2 | proto_tree_add_item(x25_tree, hf_x25_diagnostic, tvb, 4, 1, ENC_BIG_ENDIAN); |
1629 | 2 | } |
1630 | 3 | localoffset = x25_pkt_len; |
1631 | 3 | break; |
1632 | 35 | case X25_CLEAR_CONFIRMATION: |
1633 | 35 | col_add_fstr(pinfo->cinfo, COL_INFO, "Clear Conf. VC:%d", vc); |
1634 | 35 | if (x25_tree) { |
1635 | 35 | proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1); |
1636 | 35 | proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1, |
1637 | 35 | X25_CLEAR_CONFIRMATION); |
1638 | 35 | } |
1639 | 35 | localoffset = x25_pkt_len; |
1640 | | |
1641 | 35 | if (localoffset < tvb_reported_length(tvb)) { /* extended clear conf format */ |
1642 | 35 | if (toa) |
1643 | 5 | x25_toa(x25_tree, (int*)&localoffset, tvb, pinfo); |
1644 | 30 | else |
1645 | 30 | x25_ntoa(x25_tree,(int*)&localoffset, tvb, pinfo, false); |
1646 | 35 | } |
1647 | | |
1648 | 35 | if (localoffset < tvb_reported_length(tvb)) /* facilities */ |
1649 | 30 | dump_facilities(x25_tree, (int*)&localoffset, tvb, pinfo); |
1650 | 35 | break; |
1651 | 1 | case X25_DIAGNOSTIC: |
1652 | 1 | col_add_fstr(pinfo->cinfo, COL_INFO, "Diag. %d", |
1653 | 1 | (int)tvb_get_uint8(tvb, 3)); |
1654 | 1 | if (x25_tree) { |
1655 | 1 | proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1, |
1656 | 1 | X25_DIAGNOSTIC); |
1657 | 1 | proto_tree_add_item(x25_tree, hf_x25_diagnostic, tvb, 3, 1, ENC_NA); |
1658 | 1 | } |
1659 | 1 | localoffset = x25_pkt_len; |
1660 | 1 | break; |
1661 | 2 | case X25_INTERRUPT: |
1662 | 2 | col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt VC:%d", vc); |
1663 | 2 | if (x25_tree) { |
1664 | 2 | proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1); |
1665 | 2 | proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1, |
1666 | 2 | X25_INTERRUPT); |
1667 | 2 | } |
1668 | 2 | localoffset = x25_pkt_len; |
1669 | 2 | break; |
1670 | 2 | case X25_INTERRUPT_CONFIRMATION: |
1671 | 2 | col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt Conf. VC:%d", vc); |
1672 | 2 | if (x25_tree) { |
1673 | 2 | proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1); |
1674 | 2 | proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1, |
1675 | 2 | X25_INTERRUPT_CONFIRMATION); |
1676 | 2 | } |
1677 | 2 | localoffset = x25_pkt_len; |
1678 | 2 | break; |
1679 | 2 | case X25_RESET_REQUEST: |
1680 | 2 | switch (dir) { |
1681 | | |
1682 | 0 | case X25_FROM_DCE: |
1683 | 0 | short_name = "Reset ind."; |
1684 | 0 | long_name = "Reset indication"; |
1685 | 0 | break; |
1686 | | |
1687 | 0 | case X25_FROM_DTE: |
1688 | 0 | short_name = "Reset req."; |
1689 | 0 | long_name = "Reset request"; |
1690 | 0 | break; |
1691 | | |
1692 | 2 | case X25_UNKNOWN: |
1693 | 2 | short_name = "Reset ind./Reset req."; |
1694 | 2 | long_name = "Reset indication/Reset request"; |
1695 | 2 | break; |
1696 | 2 | } |
1697 | 2 | col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - Diag.:%d", |
1698 | 2 | short_name, vc, rval_to_str_wmem(pinfo->pool, tvb_get_uint8(tvb, 3), reset_code_rvals, "Unknown (0x%02x)"), |
1699 | 2 | (int)tvb_get_uint8(tvb, 4)); |
1700 | 2 | x25_hash_add_proto_end(vc, pinfo->num); |
1701 | 2 | if (x25_tree) { |
1702 | 1 | proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1); |
1703 | 1 | proto_tree_add_uint_format_value(x25_tree, hf_x25_type, tvb, 2, 1, |
1704 | 1 | X25_RESET_REQUEST, "%s", long_name); |
1705 | 1 | proto_tree_add_item(x25_tree, hf_x25_reset_cause, tvb, 3, 1, ENC_NA); |
1706 | 1 | proto_tree_add_item(x25_tree, hf_x25_diagnostic, tvb, 4, 1, ENC_NA); |
1707 | 1 | } |
1708 | 2 | localoffset = x25_pkt_len; |
1709 | 2 | break; |
1710 | 1 | case X25_RESET_CONFIRMATION: |
1711 | 1 | col_add_fstr(pinfo->cinfo, COL_INFO, "Reset conf. VC:%d", vc); |
1712 | 1 | if (x25_tree) { |
1713 | 1 | proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1); |
1714 | 1 | proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1, |
1715 | 1 | X25_RESET_CONFIRMATION); |
1716 | 1 | } |
1717 | 1 | localoffset = x25_pkt_len; |
1718 | 1 | break; |
1719 | 1 | case X25_RESTART_REQUEST: |
1720 | 1 | switch (dir) { |
1721 | | |
1722 | 0 | case X25_FROM_DCE: |
1723 | 0 | short_name = "Restart ind."; |
1724 | 0 | long_name = "Restart indication"; |
1725 | 0 | break; |
1726 | | |
1727 | 0 | case X25_FROM_DTE: |
1728 | 0 | short_name = "Restart req."; |
1729 | 0 | long_name = "Restart request"; |
1730 | 0 | break; |
1731 | | |
1732 | 1 | case X25_UNKNOWN: |
1733 | 1 | short_name = "Restart ind./Restart req."; |
1734 | 1 | long_name = "Restart indication/Restart request"; |
1735 | 1 | break; |
1736 | 1 | } |
1737 | 1 | col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s - Diag.:%d", |
1738 | 1 | short_name, |
1739 | 1 | rval_to_str_wmem(pinfo->pool, tvb_get_uint8(tvb, 3), restart_code_rvals, "Unknown (0x%02x)"), |
1740 | 1 | (int)tvb_get_uint8(tvb, 4)); |
1741 | 1 | if (x25_tree) { |
1742 | 1 | proto_tree_add_uint_format_value(x25_tree, hf_x25_type, tvb, 2, 1, |
1743 | 1 | X25_RESTART_REQUEST, "%s", long_name); |
1744 | 1 | proto_tree_add_item(x25_tree, hf_x25_restart_cause, tvb, 3, 1, ENC_NA); |
1745 | 1 | proto_tree_add_item(x25_tree, hf_x25_diagnostic, tvb, 4, 1, ENC_NA); |
1746 | 1 | } |
1747 | 1 | localoffset = x25_pkt_len; |
1748 | 1 | break; |
1749 | 3 | case X25_RESTART_CONFIRMATION: |
1750 | 3 | col_set_str(pinfo->cinfo, COL_INFO, "Restart conf."); |
1751 | 3 | if (x25_tree) |
1752 | 3 | proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1, |
1753 | 3 | X25_RESTART_CONFIRMATION); |
1754 | 3 | localoffset = x25_pkt_len; |
1755 | 3 | break; |
1756 | 3 | case X25_REGISTRATION_REQUEST: |
1757 | 3 | col_set_str(pinfo->cinfo, COL_INFO, "Registration req."); |
1758 | 3 | if (x25_tree) |
1759 | 3 | proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1, |
1760 | 3 | X25_REGISTRATION_REQUEST); |
1761 | 3 | localoffset = 3; |
1762 | 3 | if (localoffset < x25_pkt_len) |
1763 | 3 | x25_ntoa(x25_tree, (int*)&localoffset, tvb, pinfo, true); |
1764 | | |
1765 | 3 | if (x25_tree) { |
1766 | 3 | if (localoffset < x25_pkt_len) |
1767 | 3 | proto_tree_add_item( x25_tree, hf_x25_reg_request_length, tvb, localoffset, 1, ENC_BIG_ENDIAN); |
1768 | 3 | if (localoffset+1 < x25_pkt_len) |
1769 | 3 | proto_tree_add_item(x25_tree, hf_x25_registration, tvb, localoffset+1, tvb_get_uint8(tvb, localoffset) & 0x7F, ENC_NA); |
1770 | 3 | } |
1771 | 3 | localoffset = tvb_reported_length(tvb); |
1772 | 3 | break; |
1773 | 3 | case X25_REGISTRATION_CONFIRMATION: |
1774 | 3 | col_set_str(pinfo->cinfo, COL_INFO, "Registration conf."); |
1775 | 3 | if (x25_tree) { |
1776 | 3 | proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1, |
1777 | 3 | X25_REGISTRATION_CONFIRMATION); |
1778 | 3 | proto_tree_add_item(x25_tree, hf_x25_reg_confirm_cause, tvb, 3, 1, ENC_BIG_ENDIAN); |
1779 | 3 | proto_tree_add_item(x25_tree, hf_x25_reg_confirm_diagnostic, tvb, 4, 1, ENC_BIG_ENDIAN); |
1780 | 3 | } |
1781 | 3 | localoffset = 5; |
1782 | 3 | if (localoffset < x25_pkt_len) |
1783 | 3 | x25_ntoa(x25_tree, (int*)&localoffset, tvb, pinfo, true); |
1784 | | |
1785 | 3 | if (x25_tree) { |
1786 | 2 | if (localoffset < x25_pkt_len) |
1787 | 2 | proto_tree_add_item( x25_tree, hf_x25_reg_confirm_length, tvb, localoffset, 1, ENC_BIG_ENDIAN); |
1788 | 2 | if (localoffset+1 < x25_pkt_len) |
1789 | 2 | proto_tree_add_item(x25_tree, hf_x25_registration, tvb, localoffset+1, tvb_get_uint8(tvb, localoffset) & 0x7F, ENC_NA); |
1790 | 2 | } |
1791 | 3 | localoffset = tvb_reported_length(tvb); |
1792 | 3 | break; |
1793 | 78 | default: |
1794 | 78 | localoffset = 2; |
1795 | 78 | if (x25_tree) { |
1796 | 78 | proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2, |
1797 | 78 | 2, bytes0_1); |
1798 | 78 | } |
1799 | 78 | if (PACKET_IS_DATA(pkt_type)) { |
1800 | 55 | if (modulo == 8) |
1801 | 43 | col_add_fstr(pinfo->cinfo, COL_INFO, |
1802 | 43 | "Data VC:%d P(S):%d P(R):%d %s", vc, |
1803 | 43 | (pkt_type >> 1) & 0x07, |
1804 | 43 | (pkt_type >> 5) & 0x07, |
1805 | 43 | (pkt_type & X25_MBIT_MOD8) ? " M" : ""); |
1806 | 12 | else |
1807 | 12 | col_add_fstr(pinfo->cinfo, COL_INFO, |
1808 | 12 | "Data VC:%d P(R):%d P(S):%d %s", vc, |
1809 | 12 | tvb_get_uint8(tvb, localoffset+1) >> 1, |
1810 | 12 | pkt_type >> 1, |
1811 | 12 | (tvb_get_uint8(tvb, localoffset+1) & X25_MBIT_MOD128) ? " M" : ""); |
1812 | 55 | if (x25_tree) { |
1813 | 55 | if (modulo == 8) { |
1814 | 43 | proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb, |
1815 | 43 | localoffset, 1, pkt_type); |
1816 | 43 | proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod8, tvb, |
1817 | 43 | localoffset, 1, pkt_type); |
1818 | 43 | proto_tree_add_uint(x25_tree, hf_x25_p_s_mod8, tvb, |
1819 | 43 | localoffset, 1, pkt_type); |
1820 | 43 | proto_tree_add_uint(x25_tree, hf_x25_type_data, tvb, |
1821 | 43 | localoffset, 1, pkt_type); |
1822 | 43 | } |
1823 | 12 | else { |
1824 | 12 | proto_tree_add_uint(x25_tree, hf_x25_p_s_mod128, tvb, |
1825 | 12 | localoffset, 1, pkt_type); |
1826 | 12 | proto_tree_add_uint(x25_tree, hf_x25_type_data, tvb, |
1827 | 12 | localoffset, 1, pkt_type); |
1828 | 12 | proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb, |
1829 | 12 | localoffset+1, 1, ENC_NA); |
1830 | 12 | proto_tree_add_item(x25_tree, hf_x25_mbit_mod128, tvb, |
1831 | 12 | localoffset+1, 1, ENC_NA); |
1832 | 12 | } |
1833 | 55 | } |
1834 | 55 | if (modulo == 8) { |
1835 | 43 | m_bit_set = pkt_type & X25_MBIT_MOD8; |
1836 | 43 | localoffset += 1; |
1837 | 43 | } else { |
1838 | 12 | m_bit_set = tvb_get_uint8(tvb, localoffset+1) & X25_MBIT_MOD128; |
1839 | 12 | localoffset += 2; |
1840 | 12 | } |
1841 | 55 | payload_len = tvb_reported_length_remaining(tvb, localoffset); |
1842 | 55 | if (reassemble_x25) { |
1843 | | /* |
1844 | | * Reassemble received and sent traffic separately. |
1845 | | * We don't reassemble traffic with an unknown direction |
1846 | | * at all. |
1847 | | */ |
1848 | 55 | frag_key = vc; |
1849 | 55 | if (side) { |
1850 | | /* |
1851 | | * OR in an extra bit to distinguish from traffic |
1852 | | * in the other direction. |
1853 | | */ |
1854 | 39 | frag_key |= 0x10000; |
1855 | 39 | } |
1856 | 55 | fd_head = fragment_add_seq_next(&x25_reassembly_table, |
1857 | 55 | tvb, localoffset, |
1858 | 55 | pinfo, frag_key, NULL, |
1859 | 55 | payload_len, m_bit_set); |
1860 | 55 | pinfo->fragmented = m_bit_set; |
1861 | | |
1862 | | /* Fragment handling is not adapted to handle several x25 |
1863 | | * packets in the same frame. This is common with XOT and |
1864 | | * shorter packet sizes. |
1865 | | * Therefore, fragment_add_seq_next seem to always return fd_head |
1866 | | * A fix to use m_bit_set to only show fragments for last pkt |
1867 | | */ |
1868 | 55 | if (!m_bit_set && fd_head) { |
1869 | 51 | if (fd_head->next) { |
1870 | 0 | proto_item *frag_tree_item; |
1871 | | |
1872 | | /* This is the last packet */ |
1873 | 0 | next_tvb = tvb_new_chain(tvb, fd_head->tvb_data); |
1874 | 0 | add_new_data_source(pinfo, next_tvb, "Reassembled X.25"); |
1875 | 0 | if (x25_tree) { |
1876 | 0 | show_fragment_seq_tree(fd_head, |
1877 | 0 | &x25_frag_items, |
1878 | 0 | x25_tree, |
1879 | 0 | pinfo, next_tvb, &frag_tree_item); |
1880 | 0 | } |
1881 | 0 | } |
1882 | 51 | } |
1883 | | |
1884 | 55 | if (m_bit_set && next_tvb == NULL) { |
1885 | | /* |
1886 | | * This isn't the last packet, so just |
1887 | | * show it as X.25 user data. |
1888 | | */ |
1889 | 4 | proto_tree_add_item(x25_tree, hf_x25_user_data, tvb, localoffset, -1, ENC_NA); |
1890 | 4 | return; |
1891 | 4 | } |
1892 | 55 | } |
1893 | 55 | } else { |
1894 | | /* |
1895 | | * Non-data packets (RR, RNR, REJ). |
1896 | | */ |
1897 | 23 | if (modulo == 8) { |
1898 | 12 | if (x25_tree) { |
1899 | 12 | proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb, |
1900 | 12 | localoffset, 1, pkt_type); |
1901 | 12 | proto_tree_add_item(x25_tree, hf_x25_type_fc_mod8, tvb, |
1902 | 12 | localoffset, 1, ENC_BIG_ENDIAN); |
1903 | 12 | } |
1904 | 12 | col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d P(R):%d", |
1905 | 12 | val_to_str(pinfo->pool, PACKET_TYPE_FC(pkt_type), vals_x25_type, "Unknown (0x%02X)"), |
1906 | 12 | vc, (pkt_type >> 5) & 0x07); |
1907 | 12 | localoffset += 1; |
1908 | 12 | } else { |
1909 | 11 | if (x25_tree) { |
1910 | 11 | proto_tree_add_item(x25_tree, hf_x25_type, tvb, |
1911 | 11 | localoffset, 1, ENC_BIG_ENDIAN); |
1912 | 11 | proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb, |
1913 | 11 | localoffset+1, 1, ENC_BIG_ENDIAN); |
1914 | 11 | } |
1915 | 11 | col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d P(R):%d", |
1916 | 11 | val_to_str(pinfo->pool, PACKET_TYPE_FC(pkt_type), vals_x25_type, "Unknown (0x%02X)"), |
1917 | 11 | vc, tvb_get_uint8(tvb, localoffset+1) >> 1); |
1918 | 11 | localoffset += 2; |
1919 | 11 | } |
1920 | 23 | } |
1921 | 74 | break; |
1922 | 323 | } |
1923 | | |
1924 | 125 | if (localoffset >= tvb_reported_length(tvb)) |
1925 | 6 | return; |
1926 | 119 | if (pinfo->fragmented) |
1927 | 6 | return; |
1928 | | |
1929 | 113 | if (!next_tvb) |
1930 | 113 | next_tvb = tvb_new_subset_remaining(tvb, localoffset); |
1931 | | |
1932 | | /* See if there's already a dissector for this circuit. */ |
1933 | 113 | if (try_conversation_dissector_by_id(CONVERSATION_X25, vc, next_tvb, pinfo, |
1934 | 113 | tree, &q_bit_set)) { |
1935 | 19 | return; /* found it and dissected it */ |
1936 | 19 | } |
1937 | | |
1938 | | /* Did the user suggest QLLC/SNA? */ |
1939 | 94 | if (payload_is_qllc_sna) { |
1940 | | /* Yes - dissect it as QLLC/SNA. */ |
1941 | 0 | if (!pinfo->fd->visited) |
1942 | 0 | x25_hash_add_proto_start(vc, pinfo->num, qllc_handle); |
1943 | 0 | call_dissector_with_data(qllc_handle, next_tvb, pinfo, tree, &q_bit_set); |
1944 | 0 | return; |
1945 | 0 | } |
1946 | | |
1947 | 94 | if (payload_check_data){ |
1948 | | /* If the Call Req. has not been captured, let's look at the first |
1949 | | two bytes of the payload to see if this looks like COTP. */ |
1950 | 0 | if (tvb_get_uint8(next_tvb, 0) == tvb_reported_length(next_tvb)-1) { |
1951 | | /* First byte contains the length of the remaining buffer */ |
1952 | 0 | if ((tvb_get_uint8(next_tvb, 1) & 0x0F) == 0) { |
1953 | | /* Second byte contains a valid COTP TPDU */ |
1954 | 0 | if (!pinfo->fd->visited) |
1955 | 0 | x25_hash_add_proto_start(vc, pinfo->num, ositp_handle); |
1956 | 0 | call_dissector(ositp_handle, next_tvb, pinfo, tree); |
1957 | 0 | return; |
1958 | 0 | } |
1959 | 0 | } |
1960 | | |
1961 | | /* Then let's look at the first byte of the payload to see if this |
1962 | | looks like IP or CLNP. */ |
1963 | 0 | switch (tvb_get_uint8(next_tvb, 0)) { |
1964 | | |
1965 | 0 | case 0x45: |
1966 | | /* Looks like an IP header */ |
1967 | 0 | if (!pinfo->fd->visited) |
1968 | 0 | x25_hash_add_proto_start(vc, pinfo->num, ip_handle); |
1969 | 0 | call_dissector(ip_handle, next_tvb, pinfo, tree); |
1970 | 0 | return; |
1971 | | |
1972 | 0 | case NLPID_ISO8473_CLNP: |
1973 | 0 | if (!pinfo->fd->visited) |
1974 | 0 | x25_hash_add_proto_start(vc, pinfo->num, clnp_handle); |
1975 | 0 | call_dissector(clnp_handle, next_tvb, pinfo, tree); |
1976 | 0 | return; |
1977 | 0 | } |
1978 | 0 | } |
1979 | | |
1980 | | /* Try the heuristic dissectors. */ |
1981 | 94 | if (dissector_try_heuristic(x25_heur_subdissector_list, next_tvb, pinfo, |
1982 | 94 | tree, &hdtbl_entry, NULL)) { |
1983 | 2 | return; |
1984 | 2 | } |
1985 | | |
1986 | | /* All else failed; dissect it as raw data */ |
1987 | 92 | call_data_dissector(next_tvb, pinfo, tree); |
1988 | 92 | } |
1989 | | |
1990 | | /* |
1991 | | * X.25 dissector for use when "pinfo->pseudo_header" points to a |
1992 | | * "struct x25_phdr". |
1993 | | */ |
1994 | | static int |
1995 | | dissect_x25_dir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
1996 | 0 | { |
1997 | 0 | dissect_x25_common(tvb, pinfo, tree, |
1998 | 0 | (pinfo->pseudo_header->dte_dce.flags & FROM_DCE) ? X25_FROM_DCE : |
1999 | 0 | X25_FROM_DTE, |
2000 | 0 | pinfo->pseudo_header->dte_dce.flags & FROM_DCE); |
2001 | 0 | return tvb_captured_length(tvb); |
2002 | 0 | } |
2003 | | |
2004 | | /* |
2005 | | * X.25 dissector for use when "pinfo->pseudo_header" doesn't point to a |
2006 | | * "struct x25_phdr". |
2007 | | */ |
2008 | | static int |
2009 | | dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
2010 | 329 | { |
2011 | 329 | int direction; |
2012 | | |
2013 | | /* |
2014 | | * We don't know if this packet is DTE->DCE or DCE->DCE. |
2015 | | * However, we can, at least, distinguish between the two |
2016 | | * sides of the conversation, based on the addresses and |
2017 | | * ports. |
2018 | | */ |
2019 | 329 | direction = cmp_address(&pinfo->src, &pinfo->dst); |
2020 | 329 | if (direction == 0) |
2021 | 147 | direction = (pinfo->srcport > pinfo->destport)*2 - 1; |
2022 | 329 | dissect_x25_common(tvb, pinfo, tree, X25_UNKNOWN, direction > 0); |
2023 | 329 | return tvb_captured_length(tvb); |
2024 | 329 | } |
2025 | | |
2026 | | void |
2027 | | proto_register_x25(void) |
2028 | 15 | { |
2029 | 15 | static hf_register_info hf[] = { |
2030 | 15 | { &hf_x25_facility, |
2031 | 15 | { "Facility", "x25.facility", FT_NONE, BASE_NONE, NULL, 0, |
2032 | 15 | NULL, HFILL }}, |
2033 | 15 | { &hf_x25_facilities_length, |
2034 | 15 | { "Facilities Length", "x25.facilities_length", FT_UINT8, BASE_DEC, NULL, 0, |
2035 | 15 | NULL, HFILL }}, |
2036 | 15 | { &hf_x25_facility_length, |
2037 | 15 | { "Length", "x25.facility_length", FT_UINT8, BASE_DEC, NULL, 0, |
2038 | 15 | NULL, HFILL }}, |
2039 | 15 | { &hf_x25_facility_class, |
2040 | 15 | { "Facility Class", "x25.facility.class", FT_UINT8, BASE_HEX, VALS(x25_facilities_class_vals), X25_FAC_CLASS_MASK, |
2041 | 15 | NULL, HFILL }}, |
2042 | 15 | { &hf_x25_facility_classA, |
2043 | 15 | { "Code", "x25.facility.classA", FT_UINT8, BASE_HEX, VALS(x25_facilities_classA_vals), 0, |
2044 | 15 | "Facility ClassA Code", HFILL }}, |
2045 | 15 | { &hf_x25_facility_classA_comp_mark, |
2046 | 15 | { "Parameter", "x25.facility.comp_mark", FT_UINT8, BASE_DEC, VALS(x25_facilities_classA_comp_mark_vals), 0, |
2047 | 15 | "Facility Marker Parameter", HFILL }}, |
2048 | 15 | { &hf_x25_facility_classA_reverse, |
2049 | 15 | { "Parameter", "x25.facility.reverse", FT_UINT8, BASE_HEX, NULL, 0, |
2050 | 15 | "Facility Reverse Charging Parameter", HFILL }}, |
2051 | 15 | { &hf_x25_facility_classA_charging_info, |
2052 | 15 | { "Parameter", "x25.facility.charging_info", FT_UINT8, BASE_HEX, NULL, 0, |
2053 | 15 | "Facility Charging Information Parameter", HFILL }}, |
2054 | 15 | { &hf_x25_facility_reverse_charging, |
2055 | 15 | { "Reverse charging", "x25.reverse_charging", FT_BOOLEAN, 8, TFS(&x25_reverse_charging_val), 0x01, |
2056 | 15 | NULL, HFILL }}, |
2057 | 15 | { &hf_x25_facility_charging_info, |
2058 | 15 | { "Charging information", "x25.charging_info", FT_BOOLEAN, 8, TFS(&tfs_requested_not_requested), 0x01, |
2059 | 15 | NULL, HFILL }}, |
2060 | 15 | { &hf_x25_facility_throughput_called_dte, |
2061 | 15 | { "From the called DTE", "x25.facility.throughput.called_dte", FT_UINT8, BASE_DEC, VALS(x25_facilities_classA_throughput_vals), 0xF0, |
2062 | 15 | "Facility Throughput called DTE", HFILL }}, |
2063 | 15 | { &hf_x25_throughput_called_dte, |
2064 | 15 | { "From the calling DTE", "x25.facility.throughput.calling_dte", FT_UINT8, BASE_DEC, VALS(x25_facilities_classA_throughput_vals), 0x0F, |
2065 | 15 | "Facility Throughput calling DTE", HFILL }}, |
2066 | 15 | { &hf_x25_facility_classA_cug, |
2067 | 15 | { "Closed user group", "x25.facility.cug", FT_UINT8, BASE_HEX, NULL, 0, |
2068 | 15 | "Facility Closed user group", HFILL }}, |
2069 | 15 | { &hf_x25_facility_classA_called_motif, |
2070 | 15 | { "Parameter", "x25.facility.called_motif", FT_UINT8, BASE_HEX, NULL, 0, |
2071 | 15 | "Facility Called address modified parameter", HFILL }}, |
2072 | 15 | { &hf_x25_facility_classA_cug_outgoing_acc, |
2073 | 15 | { "Closed user group", "x25.facility.cug_outgoing_acc", FT_UINT8, BASE_HEX, NULL, 0, |
2074 | 15 | "Facility Closed user group with outgoing access selection", HFILL }}, |
2075 | 15 | { &hf_x25_facility_classA_throughput_min, |
2076 | 15 | { "Parameter", "x25.facility.throughput_min", FT_UINT8, BASE_HEX, NULL, 0, |
2077 | 15 | "Facility Minimum throughput class parameter", HFILL }}, |
2078 | 15 | { &hf_x25_facility_classA_express_data, |
2079 | 15 | { "Parameter", "x25.facility.express_data", FT_UINT8, BASE_HEX, NULL, 0, |
2080 | 15 | "Facility Negotiation of express data parameter", HFILL }}, |
2081 | 15 | { &hf_x25_facility_classA_unknown, |
2082 | 15 | { "Parameter", "x25.facility.classA_unknown", FT_UINT8, BASE_HEX, NULL, 0, |
2083 | 15 | "Facility Class A unknown parameter", HFILL }}, |
2084 | 15 | { &hf_x25_facility_classB, |
2085 | 15 | { "Code", "x25.facility.classB", FT_UINT8, BASE_HEX, VALS(x25_facilities_classB_vals), 0, |
2086 | 15 | "Facility ClassB Code", HFILL }}, |
2087 | 15 | { &hf_x25_facility_classB_bilateral_cug, |
2088 | 15 | { "Bilateral CUG", "x25.facility.bilateral_cug", FT_UINT16, BASE_HEX, NULL, 0, |
2089 | 15 | "Facility Bilateral CUG", HFILL }}, |
2090 | 15 | { &hf_x25_facility_packet_size_called_dte, |
2091 | 15 | { "From the called DTE", "x25.facility.packet_size.called_dte", FT_UINT8, BASE_DEC, VALS(x25_facilities_classB_packet_size_vals), 0, |
2092 | 15 | "Facility Packet size from the called DTE", HFILL }}, |
2093 | 15 | { &hf_x25_facility_packet_size_calling_dte, |
2094 | 15 | { "From the calling DTE", "x25.facility.packet_size.calling_dte", FT_UINT8, BASE_DEC, VALS(x25_facilities_classB_packet_size_vals), 0, |
2095 | 15 | "Facility Packet size from the calling DTE", HFILL }}, |
2096 | 15 | { &hf_x25_facility_data_network_id_code, |
2097 | 15 | { "Data network identification code", "x25.facility.data_network_id_code", FT_UINT16, BASE_HEX, NULL, 0, |
2098 | 15 | "Facility RPOA selection data network identification code", HFILL }}, |
2099 | 15 | { &hf_x25_facility_cug_ext, |
2100 | 15 | { "Closed user group", "x25.facility.cug_ext", FT_UINT16, BASE_HEX, NULL, 0, |
2101 | 15 | "Facility Extended closed user group selection", HFILL }}, |
2102 | 15 | { &hf_x25_facility_cug_outgoing_acc_ext, |
2103 | 15 | { "Closed user group", "x25.facility.cug_outgoing_acc_ext", FT_UINT16, BASE_HEX, NULL, 0, |
2104 | 15 | "Facility Extended closed user group with outgoing access selection", HFILL }}, |
2105 | 15 | { &hf_x25_facility_transit_delay, |
2106 | 15 | { "Transit delay (ms)", "x25.facility.transit_delay", FT_UINT16, BASE_DEC, NULL, 0, |
2107 | 15 | "Facility Transit delay selection and indication", HFILL }}, |
2108 | 15 | { &hf_x25_facility_classB_unknown, |
2109 | 15 | { "Parameter", "x25.facility.classB_unknown", FT_UINT16, BASE_HEX, NULL, 0, |
2110 | 15 | "Facility Class B unknown parameter", HFILL }}, |
2111 | 15 | { &hf_x25_facility_classC_unknown, |
2112 | 15 | { "Parameter", "x25.facility.classC_unknown", FT_UINT24, BASE_HEX, NULL, 0, |
2113 | 15 | "Facility Class C unknown parameter", HFILL }}, |
2114 | 15 | { &hf_x25_facility_classC, |
2115 | 15 | { "Code", "x25.facility.classC", FT_UINT8, BASE_HEX, VALS(x25_facilities_classC_vals), 0, |
2116 | 15 | "Facility ClassC Code", HFILL }}, |
2117 | 15 | { &hf_x25_facility_classD, |
2118 | 15 | { "Code", "x25.facility.classD", FT_UINT8, BASE_HEX, VALS(x25_facilities_classD_vals), 0, |
2119 | 15 | "Facility ClassD Code", HFILL }}, |
2120 | 15 | { &hf_x25_gfi, |
2121 | 15 | { "GFI", "x25.gfi", FT_UINT16, BASE_DEC, NULL, 0xF000, |
2122 | 15 | "General format identifier", HFILL }}, |
2123 | 15 | { &hf_x25_abit, |
2124 | 15 | { "A Bit", "x25.a", FT_BOOLEAN, 16, NULL, X25_ABIT, |
2125 | 15 | "Address Bit", HFILL }}, |
2126 | 15 | { &hf_x25_qbit, |
2127 | 15 | { "Q Bit", "x25.q", FT_BOOLEAN, 16, NULL, X25_QBIT, |
2128 | 15 | "Qualifier Bit", HFILL }}, |
2129 | 15 | { &hf_x25_dbit, |
2130 | 15 | { "D Bit", "x25.d", FT_BOOLEAN, 16, NULL, X25_DBIT, |
2131 | 15 | "Delivery Confirmation Bit", HFILL }}, |
2132 | 15 | { &hf_x25_mod, |
2133 | 15 | { "Modulo", "x25.mod", FT_UINT16, BASE_DEC, VALS(vals_modulo), 0x3000, |
2134 | 15 | "Specifies whether the frame is modulo 8 or 128", HFILL }}, |
2135 | 15 | { &hf_x25_lcn, |
2136 | 15 | { "Logical Channel", "x25.lcn", FT_UINT16, BASE_DEC, NULL, 0x0FFF, |
2137 | 15 | "Logical Channel Number", HFILL }}, |
2138 | 15 | { &hf_x25_type, |
2139 | 15 | { "Packet Type", "x25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x0, |
2140 | 15 | NULL, HFILL }}, |
2141 | 15 | { &hf_x25_type_fc_mod8, |
2142 | 15 | { "Packet Type", "x25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x1F, |
2143 | 15 | NULL, HFILL }}, |
2144 | 15 | { &hf_x25_type_data, |
2145 | 15 | { "Packet Type", "x25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x01, |
2146 | 15 | NULL, HFILL }}, |
2147 | 15 | { &hf_x25_diagnostic, |
2148 | 15 | { "Diagnostic", "x25.diagnostic", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &x25_clear_diag_vals_ext, 0, |
2149 | 15 | NULL, HFILL }}, |
2150 | 15 | { &hf_x25_p_r_mod8, |
2151 | 15 | { "P(R)", "x25.p_r", FT_UINT8, BASE_DEC, NULL, 0xE0, |
2152 | 15 | "Packet Receive Sequence Number", HFILL }}, |
2153 | 15 | { &hf_x25_p_r_mod128, |
2154 | 15 | { "P(R)", "x25.p_r", FT_UINT8, BASE_DEC, NULL, 0xFE, |
2155 | 15 | "Packet Receive Sequence Number", HFILL }}, |
2156 | 15 | { &hf_x25_mbit_mod8, |
2157 | 15 | { "M Bit", "x25.m", FT_BOOLEAN, 8, TFS(&m_bit_tfs), X25_MBIT_MOD8, |
2158 | 15 | "More Bit", HFILL }}, |
2159 | 15 | { &hf_x25_mbit_mod128, |
2160 | 15 | { "M Bit", "x25.m", FT_BOOLEAN, 8, TFS(&m_bit_tfs), X25_MBIT_MOD128, |
2161 | 15 | "More Bit", HFILL }}, |
2162 | 15 | { &hf_x25_p_s_mod8, |
2163 | 15 | { "P(S)", "x25.p_s", FT_UINT8, BASE_DEC, NULL, 0x0E, |
2164 | 15 | "Packet Send Sequence Number", HFILL }}, |
2165 | 15 | { &hf_x25_p_s_mod128, |
2166 | 15 | { "P(S)", "x25.p_s", FT_UINT8, BASE_DEC, NULL, 0xFE, |
2167 | 15 | "Packet Send Sequence Number", HFILL }}, |
2168 | 15 | { &hf_x25_window_size_called_dte, |
2169 | 15 | { "From the called DTE", "x25.window_size.called_dte", FT_UINT8, BASE_DEC, NULL, 0x7F, |
2170 | 15 | NULL, HFILL }}, |
2171 | 15 | { &hf_x25_window_size_calling_dte, |
2172 | 15 | { "From the calling DTE", "x25.window_size.calling_dte", FT_UINT8, BASE_DEC, NULL, 0x7F, |
2173 | 15 | NULL, HFILL }}, |
2174 | 15 | { &hf_x25_dte_address_length, |
2175 | 15 | { "DTE address length", "x25.dte_address_length", FT_UINT8, BASE_DEC, NULL, 0xF0, |
2176 | 15 | NULL, HFILL }}, |
2177 | 15 | { &hf_x25_dce_address_length, |
2178 | 15 | { "DCE address length", "x25.dce_address_length", FT_UINT8, BASE_DEC, NULL, 0x0F, |
2179 | 15 | NULL, HFILL }}, |
2180 | 15 | { &hf_x25_calling_address_length, |
2181 | 15 | { "Calling address length", "x25.calling_address_length", FT_UINT8, BASE_DEC, NULL, 0xF0, |
2182 | 15 | NULL, HFILL }}, |
2183 | 15 | { &hf_x25_called_address_length, |
2184 | 15 | { "Called address length", "x25.called_address_length", FT_UINT8, BASE_DEC, NULL, 0x0F, |
2185 | 15 | NULL, HFILL }}, |
2186 | 15 | { &hf_x25_facility_call_transfer_reason, |
2187 | 15 | { "Reason", "x25.facility.call_transfer_reason", FT_UINT8, BASE_DEC, VALS(x25_facilities_call_transfer_reason_vals), 0, |
2188 | 15 | NULL, HFILL }}, |
2189 | 15 | { &hf_x25_facility_monetary_unit, |
2190 | 15 | { "Monetary unit", "x25.facility.monetary_unit", FT_BYTES, BASE_NONE, NULL, 0, |
2191 | 15 | NULL, HFILL }}, |
2192 | 15 | { &hf_x25_facility_nui, |
2193 | 15 | { "NUI", "x25.facility.nui", FT_BYTES, BASE_NONE, NULL, 0, |
2194 | 15 | NULL, HFILL }}, |
2195 | 15 | { &hf_x25_facility_cumulative_ete_transit_delay, |
2196 | 15 | { "Cumulative end-to-end transit delay (ms)", "x25.facility.cumulative_ete_transit_delay", FT_UINT16, BASE_DEC, NULL, 0, |
2197 | 15 | NULL, HFILL }}, |
2198 | 15 | { &hf_x25_facility_requested_ete_transit_delay, |
2199 | 15 | { "Requested end-to-end transit delay (ms)", "x25.facility.requested_ete_transit_delay", FT_UINT16, BASE_DEC, NULL, 0, |
2200 | 15 | NULL, HFILL }}, |
2201 | 15 | { &hf_x25_facility_max_acceptable_ete_transit_delay, |
2202 | 15 | { "Maximum acceptable end-to-end transit delay (ms)", "x25.facility.mac_acceptable_ete_transit_delay", FT_UINT16, BASE_DEC, NULL, 0, |
2203 | 15 | NULL, HFILL }}, |
2204 | 15 | { &hf_x25_facility_priority_data, |
2205 | 15 | { "Priority for data", "x25.facility.priority_data", FT_UINT8, BASE_DEC, NULL, 0, |
2206 | 15 | NULL, HFILL }}, |
2207 | 15 | { &hf_x25_facility_priority_estab_conn, |
2208 | 15 | { "Priority for establishing connection", "x25.facility.priority_estab_conn", FT_UINT8, BASE_DEC, NULL, 0, |
2209 | 15 | NULL, HFILL }}, |
2210 | 15 | { &hf_x25_facility_priority_keep_conn, |
2211 | 15 | { "Priority for keeping connection", "x25.facility.priority_keep_conn", FT_UINT8, BASE_DEC, NULL, 0, |
2212 | 15 | NULL, HFILL }}, |
2213 | 15 | { &hf_x25_facility_min_acceptable_priority_data, |
2214 | 15 | { "Minimum acceptable priority for data", "x25.facility.min_acceptable_priority_data", FT_UINT8, BASE_DEC, NULL, 0, |
2215 | 15 | NULL, HFILL }}, |
2216 | 15 | { &hf_x25_facility_min_acceptable_priority_estab_conn, |
2217 | 15 | { "Minimum acceptable priority for establishing connection", "x25.facility.min_acceptable_priority_estab_conn", FT_UINT8, BASE_DEC, NULL, 0, |
2218 | 15 | NULL, HFILL }}, |
2219 | 15 | { &hf_x25_facility_min_acceptable_priority_keep_conn, |
2220 | 15 | { "Minimum acceptable priority for keeping connection", "x25.facility.min_acceptable_priority_keep_conn", FT_UINT8, BASE_DEC, NULL, 0, |
2221 | 15 | NULL, HFILL }}, |
2222 | 15 | { &hf_x25_facility_classD_unknown, |
2223 | 15 | { "Parameter", "x25.facility.classD_unknown", FT_BYTES, BASE_NONE, NULL, 0, |
2224 | 15 | "Facility Class D unknown parameter", HFILL }}, |
2225 | 15 | { &hf_x25_facility_call_transfer_num_semi_octets, |
2226 | 15 | { "Number of semi-octets in DTE address", "x25.facility.call_transfer_num_semi_octets", FT_UINT8, BASE_DEC, NULL, 0, |
2227 | 15 | NULL, HFILL }}, |
2228 | 15 | { &hf_x25_facility_calling_addr_ext_num_semi_octets, |
2229 | 15 | { "Number of semi-octets in DTE address", "x25.facility.calling_addr_ext_num_semi_octets", FT_UINT8, BASE_DEC, NULL, 0, |
2230 | 15 | NULL, HFILL }}, |
2231 | 15 | { &hf_x25_facility_called_addr_ext_num_semi_octets, |
2232 | 15 | { "Number of semi-octets in DTE address", "x25.facility.called_addr_ext_num_semi_octets", FT_UINT8, BASE_DEC, NULL, 0, |
2233 | 15 | NULL, HFILL }}, |
2234 | 15 | { &hf_x25_facility_call_deflect_num_semi_octets, |
2235 | 15 | { "Number of semi-octets in the alternative DTE address", "x25.facility.call_deflect_num_semi_octets", FT_UINT8, BASE_DEC, NULL, 0, |
2236 | 15 | NULL, HFILL }}, |
2237 | 15 | { &hf_x264_length_indicator, |
2238 | 15 | { "X.264 length indicator", "x25.x264_length_indicator", FT_UINT8, BASE_DEC, NULL, 0, |
2239 | 15 | NULL, HFILL }}, |
2240 | 15 | { &hf_x264_un_tpdu_id, |
2241 | 15 | { "X.264 UN TPDU identifier", "x25.x264_un_tpdu_id", FT_UINT8, BASE_HEX, NULL, 0, |
2242 | 15 | NULL, HFILL }}, |
2243 | 15 | { &hf_x264_protocol_id, |
2244 | 15 | { "X.264 protocol identifier", "x25.x264_protocol_id", FT_UINT8, BASE_HEX, VALS(prt_id_vals), 0, |
2245 | 15 | NULL, HFILL }}, |
2246 | 15 | { &hf_x264_sharing_strategy, |
2247 | 15 | { "X.264 sharing strategy", "x25.x264_sharing_strategy", FT_UINT8, BASE_HEX, VALS(sharing_strategy_vals), 0, |
2248 | 15 | NULL, HFILL }}, |
2249 | 15 | { &hf_x263_sec_protocol_id, |
2250 | 15 | { "X.263 secondary protocol ID", "x25.x263_sec_protocol_id", FT_UINT8, BASE_HEX, VALS(nlpid_vals), 0, |
2251 | 15 | NULL, HFILL }}, |
2252 | 15 | { &hf_x25_reg_request_length, |
2253 | 15 | { "Registration length", "x25.reg_request_length", FT_UINT8, BASE_DEC, NULL, 0x7F, |
2254 | 15 | NULL, HFILL }}, |
2255 | 15 | { &hf_x25_reg_confirm_length, |
2256 | 15 | { "Registration length", "x25.reg_confirm_length", FT_UINT8, BASE_DEC, NULL, 0x7F, |
2257 | 15 | NULL, HFILL }}, |
2258 | | |
2259 | 15 | { &hf_x25_segment_overlap, |
2260 | 15 | { "Fragment overlap", "x25.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
2261 | 15 | "Fragment overlaps with other fragments", HFILL }}, |
2262 | | |
2263 | 15 | { &hf_x25_segment_overlap_conflict, |
2264 | 15 | { "Conflicting data in fragment overlap", "x25.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
2265 | 15 | "Overlapping fragments contained conflicting data", HFILL }}, |
2266 | | |
2267 | 15 | { &hf_x25_segment_multiple_tails, |
2268 | 15 | { "Multiple tail fragments found", "x25.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
2269 | 15 | "Several tails were found when defragmenting the packet", HFILL }}, |
2270 | | |
2271 | 15 | { &hf_x25_segment_too_long_segment, |
2272 | 15 | { "Fragment too long", "x25.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
2273 | 15 | "Fragment contained data past end of packet", HFILL }}, |
2274 | | |
2275 | 15 | { &hf_x25_segment_error, |
2276 | 15 | { "Defragmentation error", "x25.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0, |
2277 | 15 | "Defragmentation error due to illegal fragments", HFILL }}, |
2278 | | |
2279 | 15 | { &hf_x25_segment_count, |
2280 | 15 | { "Fragment count", "x25.fragment.count", FT_UINT32, BASE_DEC, NULL, 0x0, |
2281 | 15 | NULL, HFILL }}, |
2282 | | |
2283 | 15 | { &hf_x25_reassembled_length, |
2284 | 15 | { "Reassembled X.25 length", "x25.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x0, |
2285 | 15 | "The total length of the reassembled payload", HFILL }}, |
2286 | | |
2287 | 15 | { &hf_x25_segment, |
2288 | 15 | { "X.25 Fragment", "x25.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0, |
2289 | 15 | NULL, HFILL }}, |
2290 | | |
2291 | 15 | { &hf_x25_segments, |
2292 | 15 | { "X.25 Fragments", "x25.fragments", FT_NONE, BASE_NONE, NULL, 0x0, |
2293 | 15 | NULL, HFILL }}, |
2294 | | |
2295 | 15 | { &hf_x25_fast_select, |
2296 | 15 | { "Fast select", "x25.fast_select", FT_UINT8, BASE_DEC, VALS(x25_fast_select_vals), 0xC0, |
2297 | 15 | NULL, HFILL }}, |
2298 | | |
2299 | 15 | { &hf_x25_icrd, |
2300 | 15 | { "ICRD", "x25.icrd", FT_UINT8, BASE_DEC, VALS(x25_icrd_vals), 0x30, |
2301 | 15 | NULL, HFILL }}, |
2302 | | |
2303 | 15 | { &hf_x25_reg_confirm_cause, |
2304 | 15 | { "Cause", "x25.reg_confirm.cause", FT_UINT8, BASE_DEC, VALS(x25_registration_code_vals), 0, |
2305 | 15 | NULL, HFILL }}, |
2306 | | |
2307 | 15 | { &hf_x25_reg_confirm_diagnostic, |
2308 | 15 | { "Diagnostic", "x25.reg_confirm.diagnostic", FT_UINT8, BASE_DEC, VALS(x25_registration_code_vals), 0, |
2309 | 15 | NULL, HFILL }}, |
2310 | | |
2311 | | /* Generated from convert_proto_tree_add_text.pl */ |
2312 | 15 | { &hf_x25_call_duration, { "Call duration", "x25.call_duration", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
2313 | 15 | { &hf_x25_segments_to_dte, { "Segments sent to DTE", "x25.segments_to_dte", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
2314 | 15 | { &hf_x25_segments_from_dte, { "Segments received from DTE", "x25.segments_from_dte", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
2315 | 15 | { &hf_x25_dte_address, { "DTE address", "x25.dte_address", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
2316 | 15 | { &hf_x25_data_network_identification_code, { "Data network identification code", "x25.data_network_identification_code", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
2317 | 15 | { &hf_x25_facility_call_deflect_reason, { "Reason", "x25.facility.call_deflect_reason", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
2318 | 15 | { &hf_x25_alternative_dte_address, { "Alternative DTE address", "x25.alternative_dte_address", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
2319 | 15 | { &hf_x25_dce_address, { "DCE address", "x25.dce_address", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
2320 | 15 | { &hf_x25_called_address, { "Called address", "x25.called_address", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
2321 | 15 | { &hf_x25_calling_address, { "Calling address", "x25.calling_address", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
2322 | 15 | { &hf_x25_clear_cause, { "Cause", "x25.clear_cause", FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(clear_code_rvals), 0x0, NULL, HFILL }}, |
2323 | 15 | { &hf_x25_reset_cause, { "Cause", "x25.reset_cause", FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(reset_code_rvals), 0x0, NULL, HFILL }}, |
2324 | 15 | { &hf_x25_restart_cause, { "Cause", "x25.restart_cause", FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(restart_code_rvals), 0x0, NULL, HFILL }}, |
2325 | 15 | { &hf_x25_registration, { "Registration", "x25.registration", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
2326 | 15 | { &hf_x25_user_data, { "User data", "x25.user_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
2327 | 15 | }; |
2328 | | |
2329 | 15 | static int *ett[] = { |
2330 | 15 | &ett_x25, |
2331 | 15 | &ett_x25_gfi, |
2332 | 15 | &ett_x25_facilities, |
2333 | 15 | &ett_x25_facility, |
2334 | 15 | &ett_x25_user_data, |
2335 | 15 | &ett_x25_segment, |
2336 | 15 | &ett_x25_segments |
2337 | 15 | }; |
2338 | | |
2339 | 15 | static ei_register_info ei[] = { |
2340 | 15 | { &ei_x25_facility_length, { "x25.facility_length.bogus", PI_PROTOCOL, PI_WARN, "Bogus length", EXPFILL }}, |
2341 | 15 | }; |
2342 | | |
2343 | 15 | module_t *x25_module; |
2344 | 15 | expert_module_t* expert_x25; |
2345 | | |
2346 | 15 | proto_x25 = proto_register_protocol ("X.25", "X.25", "x25"); |
2347 | 15 | proto_register_field_array (proto_x25, hf, array_length(hf)); |
2348 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
2349 | 15 | expert_x25 = expert_register_protocol(proto_x25); |
2350 | 15 | expert_register_field_array(expert_x25, ei, array_length(ei)); |
2351 | | |
2352 | 15 | x25_subdissector_table = register_dissector_table("x.25.spi", |
2353 | 15 | "X.25 secondary protocol identifier", proto_x25, FT_UINT8, BASE_HEX); |
2354 | 15 | x25_heur_subdissector_list = register_heur_dissector_list_with_description("x.25", "X.25 payload", proto_x25); |
2355 | | |
2356 | 15 | register_dissector("x.25_dir", dissect_x25_dir, proto_x25); |
2357 | 15 | x25_handle = register_dissector("x.25", dissect_x25, proto_x25); |
2358 | | |
2359 | | /* Preferences */ |
2360 | 15 | x25_module = prefs_register_protocol(proto_x25, NULL); |
2361 | | /* For reading older preference files with "x.25." preferences */ |
2362 | 15 | prefs_register_module_alias("x.25", x25_module); |
2363 | 15 | prefs_register_obsolete_preference(x25_module, "non_q_bit_is_sna"); |
2364 | 15 | prefs_register_bool_preference(x25_module, "payload_is_qllc_sna", |
2365 | 15 | "Default to QLLC/SNA", |
2366 | 15 | "If CALL REQUEST not seen or didn't specify protocol, dissect as QLLC/SNA", |
2367 | 15 | &payload_is_qllc_sna); |
2368 | 15 | prefs_register_bool_preference(x25_module, "call_request_nodata_is_cotp", |
2369 | 15 | "Assume COTP for Call Request without data", |
2370 | 15 | "If CALL REQUEST has no data, assume the protocol handled is COTP", |
2371 | 15 | &call_request_nodata_is_cotp); |
2372 | 15 | prefs_register_bool_preference(x25_module, "payload_check_data", |
2373 | 15 | "Check data for COTP/IP/CLNP", |
2374 | 15 | "If CALL REQUEST not seen or didn't specify protocol, check user data before checking heuristic dissectors", |
2375 | 15 | &payload_check_data); |
2376 | 15 | prefs_register_bool_preference(x25_module, "reassemble", |
2377 | 15 | "Reassemble fragmented X.25 packets", |
2378 | 15 | "Reassemble fragmented X.25 packets", |
2379 | 15 | &reassemble_x25); |
2380 | 15 | reassembly_table_register(&x25_reassembly_table, |
2381 | 15 | &addresses_reassembly_table_functions); |
2382 | 15 | } |
2383 | | |
2384 | | void |
2385 | | proto_reg_handoff_x25(void) |
2386 | 15 | { |
2387 | | /* |
2388 | | * Get handles for various dissectors. |
2389 | | */ |
2390 | 15 | ip_handle = find_dissector_add_dependency("ip", proto_x25); |
2391 | 15 | clnp_handle = find_dissector_add_dependency("clnp", proto_x25); |
2392 | 15 | ositp_handle = find_dissector_add_dependency("ositp", proto_x25); |
2393 | 15 | qllc_handle = find_dissector_add_dependency("qllc", proto_x25); |
2394 | | |
2395 | 15 | dissector_add_uint("llc.dsap", SAP_X25, x25_handle); |
2396 | 15 | dissector_add_uint("lapd.sapi", LAPD_SAPI_X25, x25_handle); |
2397 | 15 | dissector_add_uint("ax25.pid", AX25_P_ROSE, x25_handle); |
2398 | 15 | dissector_add_uint("sflow_245.header_protocol", SFLOW_245_HEADER_X25, x25_handle); |
2399 | 15 | } |
2400 | | |
2401 | | /* |
2402 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
2403 | | * |
2404 | | * Local variables: |
2405 | | * c-basic-offset: 4 |
2406 | | * tab-width: 8 |
2407 | | * indent-tabs-mode: nil |
2408 | | * End: |
2409 | | * |
2410 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
2411 | | * :indentSize=4:tabSize=8:noTabs=true: |
2412 | | */ |