2 * Routines for X.25 packet disassembly
3 * Olivier Abad <oabad@noos.fr>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #include <epan/packet.h>
33 #include <epan/ax25_pids.h>
34 #include <epan/llcsaps.h>
35 #include <epan/circuit.h>
36 #include <epan/reassemble.h>
37 #include <epan/prefs.h>
38 #include <epan/wmem/wmem.h>
39 #include <epan/expert.h>
40 #include <epan/nlpid.h>
41 #include <epan/x264_prt_id.h>
42 #include <epan/lapd_sapi.h>
45 * Direction of packet.
48 X25_FROM_DCE
, /* DCE->DTE */
49 X25_FROM_DTE
, /* DTE->DCE */
50 X25_UNKNOWN
/* direction unknown */
54 * 0 for data packets, 1 for non-data packets.
56 #define X25_NONDATA_BIT 0x01
58 #define X25_CALL_REQUEST 0x0B
59 #define X25_CALL_ACCEPTED 0x0F
60 #define X25_CLEAR_REQUEST 0x13
61 #define X25_CLEAR_CONFIRMATION 0x17
62 #define X25_INTERRUPT 0x23
63 #define X25_INTERRUPT_CONFIRMATION 0x27
64 #define X25_RESET_REQUEST 0x1B
65 #define X25_RESET_CONFIRMATION 0x1F
66 #define X25_RESTART_REQUEST 0xFB
67 #define X25_RESTART_CONFIRMATION 0xFF
68 #define X25_REGISTRATION_REQUEST 0xF3
69 #define X25_REGISTRATION_CONFIRMATION 0xF7
70 #define X25_DIAGNOSTIC 0xF1
76 #define PACKET_IS_DATA(type) (!(type & X25_NONDATA_BIT))
77 #define PACKET_TYPE_FC(type) (type & 0x1F)
79 #define X25_MBIT_MOD8 0x10
80 #define X25_MBIT_MOD128 0x01
82 #define X25_ABIT 0x8000
84 #define X25_QBIT 0x8000
85 #define X25_DBIT 0x4000
87 #define X25_FAC_CLASS_MASK 0xC0
89 #define X25_FAC_CLASS_A 0x00
90 #define X25_FAC_CLASS_B 0x40
91 #define X25_FAC_CLASS_C 0x80
92 #define X25_FAC_CLASS_D 0xC0
94 #define X25_FAC_COMP_MARK 0x00
95 #define X25_FAC_REVERSE 0x01
96 #define X25_FAC_THROUGHPUT 0x02
97 #define X25_FAC_CUG 0x03
98 #define X25_FAC_CHARGING_INFO 0x04
99 #define X25_FAC_CALLED_MODIF 0x08
100 #define X25_FAC_CUG_OUTGOING_ACC 0x09
101 #define X25_FAC_THROUGHPUT_MIN 0x0A
102 #define X25_FAC_EXPRESS_DATA 0x0B
103 #define X25_FAC_BILATERAL_CUG 0x41
104 #define X25_FAC_PACKET_SIZE 0x42
105 #define X25_FAC_WINDOW_SIZE 0x43
106 #define X25_FAC_RPOA_SELECTION 0x44
107 #define X25_FAC_CUG_EXT 0x47
108 #define X25_FAC_CUG_OUTGOING_ACC_EXT 0x48
109 #define X25_FAC_TRANSIT_DELAY 0x49
110 #define X25_FAC_CALL_DURATION 0xC1
111 #define X25_FAC_SEGMENT_COUNT 0xC2
112 #define X25_FAC_CALL_TRANSFER 0xC3
113 #define X25_FAC_RPOA_SELECTION_EXT 0xC4
114 #define X25_FAC_MONETARY_UNIT 0xC5
115 #define X25_FAC_NUI 0xC6
116 #define X25_FAC_CALLED_ADDR_EXT 0xC9
117 #define X25_FAC_ETE_TRANSIT_DELAY 0xCA
118 #define X25_FAC_CALLING_ADDR_EXT 0xCB
119 #define X25_FAC_CALL_DEFLECT 0xD1
120 #define X25_FAC_PRIORITY 0xD2
122 static int proto_x25
= -1;
123 static int hf_x25_facility
= -1;
124 static int hf_x25_facilities_length
= -1;
125 static int hf_x25_facility_length
= -1;
126 static int hf_x25_facility_class
= -1;
127 static int hf_x25_facility_classA
= -1;
128 static int hf_x25_facility_classA_comp_mark
= -1;
129 static int hf_x25_facility_classA_reverse
= -1;
130 static int hf_x25_facility_classA_charging_info
= -1;
131 static int hf_x25_facility_reverse_charging
= -1;
132 static int hf_x25_facility_charging_info
= -1;
133 static int hf_x25_facility_throughput_called_dte
= -1;
134 static int hf_x25_throughput_called_dte
= -1;
135 static int hf_x25_facility_classA_cug
= -1;
136 static int hf_x25_facility_classA_called_motif
= -1;
137 static int hf_x25_facility_classA_cug_outgoing_acc
= -1;
138 static int hf_x25_facility_classA_throughput_min
= -1;
139 static int hf_x25_facility_classA_express_data
= -1;
140 static int hf_x25_facility_classA_unknown
= -1;
141 static int hf_x25_facility_classB
= -1;
142 static int hf_x25_facility_classB_bilateral_cug
= -1;
143 static int hf_x25_facility_packet_size_called_dte
= -1;
144 static int hf_x25_facility_packet_size_calling_dte
= -1;
145 static int hf_x25_facility_data_network_id_code
= -1;
146 static int hf_x25_facility_cug_ext
= -1;
147 static int hf_x25_facility_cug_outgoing_acc_ext
= -1;
148 static int hf_x25_facility_transit_delay
= -1;
149 static int hf_x25_facility_classB_unknown
= -1;
150 static int hf_x25_facility_classC
= -1;
151 static int hf_x25_facility_classC_unknown
= -1;
152 static int hf_x25_facility_classD
= -1;
153 static int hf_x25_gfi
= -1;
154 static int hf_x25_abit
= -1;
155 static int hf_x25_qbit
= -1;
156 static int hf_x25_dbit
= -1;
157 static int hf_x25_mod
= -1;
158 static int hf_x25_lcn
= -1;
159 static int hf_x25_type
= -1;
160 static int hf_x25_type_fc_mod8
= -1;
161 static int hf_x25_type_data
= -1;
162 static int hf_x25_diagnostic
= -1;
163 static int hf_x25_p_r_mod8
= -1;
164 static int hf_x25_p_r_mod128
= -1;
165 static int hf_x25_mbit_mod8
= -1;
166 static int hf_x25_mbit_mod128
= -1;
167 static int hf_x25_p_s_mod8
= -1;
168 static int hf_x25_p_s_mod128
= -1;
169 static int hf_x25_window_size_called_dte
= -1;
170 static int hf_x25_window_size_calling_dte
= -1;
171 static int hf_x25_dte_address_length
= -1;
172 static int hf_x25_dce_address_length
= -1;
173 static int hf_x25_calling_address_length
= -1;
174 static int hf_x25_called_address_length
= -1;
175 static int hf_x25_facility_call_transfer_reason
= -1;
176 static int hf_x25_facility_monetary_unit
= -1;
177 static int hf_x25_facility_nui
= -1;
178 static int hf_x25_facility_cumulative_ete_transit_delay
= -1;
179 static int hf_x25_facility_requested_ete_transit_delay
= -1;
180 static int hf_x25_facility_max_acceptable_ete_transit_delay
= -1;
181 static int hf_x25_facility_priority_data
= -1;
182 static int hf_x25_facility_priority_estab_conn
= -1;
183 static int hf_x25_facility_priority_keep_conn
= -1;
184 static int hf_x25_facility_min_acceptable_priority_data
= -1;
185 static int hf_x25_facility_min_acceptable_priority_estab_conn
= -1;
186 static int hf_x25_facility_min_acceptable_priority_keep_conn
= -1;
187 static int hf_x25_facility_classD_unknown
= -1;
188 static int hf_x25_facility_call_transfer_num_semi_octets
= -1;
189 static int hf_x25_facility_calling_addr_ext_num_semi_octets
= -1;
190 static int hf_x25_facility_called_addr_ext_num_semi_octets
= -1;
191 static int hf_x25_facility_call_deflect_num_semi_octets
= -1;
192 static int hf_x264_length_indicator
= -1;
193 static int hf_x264_un_tpdu_id
= -1;
194 static int hf_x264_protocol_id
= -1;
195 static int hf_x264_sharing_strategy
= -1;
196 static int hf_x263_sec_protocol_id
= -1;
197 static int hf_x25_reg_request_length
= -1;
198 static int hf_x25_reg_confirm_length
= -1;
201 static gint ett_x25
= -1;
202 static gint ett_x25_gfi
= -1;
203 static gint ett_x25_facilities
= -1;
204 static gint ett_x25_facility
= -1;
205 static gint ett_x25_user_data
= -1;
207 static gint ett_x25_segment
= -1;
208 static gint ett_x25_segments
= -1;
209 static gint hf_x25_segments
= -1;
210 static gint hf_x25_segment
= -1;
211 static gint hf_x25_segment_overlap
= -1;
212 static gint hf_x25_segment_overlap_conflict
= -1;
213 static gint hf_x25_segment_multiple_tails
= -1;
214 static gint hf_x25_segment_too_long_segment
= -1;
215 static gint hf_x25_segment_error
= -1;
216 static gint hf_x25_segment_count
= -1;
217 static gint hf_x25_reassembled_length
= -1;
218 static gint hf_x25_fast_select
= -1;
219 static gint hf_x25_icrd
= -1;
220 static gint hf_x25_reg_confirm_cause
= -1;
221 static gint hf_x25_reg_confirm_diagnostic
= -1;
223 static expert_field ei_x25_facility_length
= EI_INIT
;
225 static const value_string vals_modulo
[] = {
231 static const value_string vals_x25_type
[] = {
232 { X25_CALL_REQUEST
, "Call" },
233 { X25_CALL_ACCEPTED
, "Call Accepted" },
234 { X25_CLEAR_REQUEST
, "Clear" },
235 { X25_CLEAR_CONFIRMATION
, "Clear Confirmation" },
236 { X25_INTERRUPT
, "Interrupt" },
237 { X25_INTERRUPT_CONFIRMATION
, "Interrupt Confirmation" },
238 { X25_RESET_REQUEST
, "Reset" },
239 { X25_RESET_CONFIRMATION
, "Reset Confirmation" },
240 { X25_RESTART_REQUEST
, "Restart" },
241 { X25_RESTART_CONFIRMATION
, "Restart Confirmation" },
242 { X25_REGISTRATION_REQUEST
, "Registration" },
243 { X25_REGISTRATION_CONFIRMATION
, "Registration Confirmation" },
244 { X25_DIAGNOSTIC
, "Diagnostic" },
248 { X25_DATA
, "Data" },
252 static struct true_false_string m_bit_tfs
= {
257 static const value_string x25_fast_select_vals
[] = {
258 { 0, "Not requested" },
259 { 1, "Not requested" },
260 { 2, "No restriction on response" },
261 { 3, "Restriction on response" },
265 static const value_string x25_icrd_vals
[] = {
266 { 0, "Status not selected" },
267 { 1, "Prevention requested" },
268 { 2, "Allowance requested" },
269 { 3, "Not allowed" },
273 static const value_string x25_clear_diag_vals
[] = {
274 { 0, "No additional information" },
275 { 1, "Invalid P(S)" },
276 { 2, "Invalid P(R)" },
277 { 16, "Packet type invalid" },
278 { 17, "Packet type invalid for state r1" },
279 { 18, "Packet type invalid for state r2" },
280 { 19, "Packet type invalid for state r3" },
281 { 20, "Packet type invalid for state p1" },
282 { 21, "Packet type invalid for state p2" },
283 { 22, "Packet type invalid for state p3" },
284 { 23, "Packet type invalid for state p4" },
285 { 24, "Packet type invalid for state p5" },
286 { 25, "Packet type invalid for state p6" },
287 { 26, "Packet type invalid for state p7" },
288 { 27, "Packet type invalid for state d1" },
289 { 28, "Packet type invalid for state d2" },
290 { 29, "Packet type invalid for state d3" },
291 { 32, "Packet not allowed" },
292 { 33, "Unidentifiable packet" },
293 { 34, "Call on one-way logical channel" },
294 { 35, "Invalid packet type on a PVC" },
295 { 36, "Packet on unassigned LC" },
296 { 37, "Reject not subscribed to" },
297 { 38, "Packet too short" },
298 { 39, "Packet too long" },
299 { 40, "Invalid general format identifier" },
300 { 41, "Restart/registration packet with nonzero bits" },
301 { 42, "Packet type not compatible with facility" },
302 { 43, "Unauthorised interrupt confirmation" },
303 { 44, "Unauthorised interrupt" },
304 { 45, "Unauthorised reject" },
305 { 48, "Time expired" },
306 { 49, "Time expired for incoming call" },
307 { 50, "Time expired for clear indication" },
308 { 51, "Time expired for reset indication" },
309 { 52, "Time expired for restart indication" },
310 { 53, "Time expired for call deflection" },
311 { 64, "Call set-up/clearing or registration pb." },
312 { 65, "Facility/registration code not allowed" },
313 { 66, "Facility parameter not allowed" },
314 { 67, "Invalid called DTE address" },
315 { 68, "Invalid calling DTE address" },
316 { 69, "Invalid facility/registration length" },
317 { 70, "Incoming call barred" },
318 { 71, "No logical channel available" },
319 { 72, "Call collision" },
320 { 73, "Duplicate facility requested" },
321 { 74, "Non zero address length" },
322 { 75, "Non zero facility length" },
323 { 76, "Facility not provided when expected" },
324 { 77, "Invalid CCITT-specified DTE facility" },
325 { 78, "Max. nb of call redir/defl. exceeded" },
326 { 80, "Miscellaneous" },
327 { 81, "Improper cause code from DTE" },
328 { 82, "Not aligned octet" },
329 { 83, "Inconsistent Q bit setting" },
330 { 84, "NUI problem" },
331 { 112, "International problem" },
332 { 113, "Remote network problem" },
333 { 114, "International protocol problem" },
334 { 115, "International link out of order" },
335 { 116, "International link busy" },
336 { 117, "Transit network facility problem" },
337 { 118, "Remote network facility problem" },
338 { 119, "International routing problem" },
339 { 120, "Temporary routing problem" },
340 { 121, "Unknown called DNIC" },
341 { 122, "Maintenance action" },
342 { 144, "Timer expired or retransmission count surpassed" },
343 { 145, "Timer expired or retransmission count surpassed for INTERRUPT" },
344 { 146, "Timer expired or retransmission count surpassed for DATA packet transmission" },
345 { 147, "Timer expired or retransmission count surpassed for REJECT" },
346 { 160, "DTE-specific signals" },
347 { 161, "DTE operational" },
348 { 162, "DTE not operational" },
349 { 163, "DTE resource constraint" },
350 { 164, "Fast select not subscribed" },
351 { 165, "Invalid partially full DATA packet" },
352 { 166, "D-bit procedure not supported" },
353 { 167, "Registration/Cancellation confirmed" },
354 { 224, "OSI network service problem" },
355 { 225, "Disconnection (transient condition)" },
356 { 226, "Disconnection (permanent condition)" },
357 { 227, "Connection rejection - reason unspecified (transient condition)" },
358 { 228, "Connection rejection - reason unspecified (permanent condition)" },
359 { 229, "Connection rejection - quality of service not available (transient condition)" },
360 { 230, "Connection rejection - quality of service not available (permanent condition)" },
361 { 231, "Connection rejection - NSAP unreachable (transient condition)" },
362 { 232, "Connection rejection - NSAP unreachable (permanent condition)" },
363 { 233, "reset - reason unspecified" },
364 { 234, "reset - congestion" },
365 { 235, "Connection rejection - NSAP address unknown (permanent condition)" },
366 { 240, "Higher layer initiated" },
367 { 241, "Disconnection - normal" },
368 { 242, "Disconnection - abnormal" },
369 { 243, "Disconnection - incompatible information in user data" },
370 { 244, "Connection rejection - reason unspecified (transient condition)" },
371 { 245, "Connection rejection - reason unspecified (permanent condition)" },
372 { 246, "Connection rejection - quality of service not available (transient condition)" },
373 { 247, "Connection rejection - quality of service not available (permanent condition)" },
374 { 248, "Connection rejection - incompatible information in user data" },
375 { 249, "Connection rejection - unrecognizable protocol identifier in user data" },
376 { 250, "Reset - user resynchronization" },
380 value_string_ext x25_clear_diag_vals_ext
= VALUE_STRING_EXT_INIT(x25_clear_diag_vals
);
382 static const value_string x25_registration_code_vals
[] = {
383 { 0x03, "Invalid facility request" },
384 { 0x05, "Network congestion" },
385 { 0x13, "Local procedure error" },
386 { 0x7F, "Registration/cancellation confirmed" },
390 static const value_string x25_facilities_class_vals
[] = {
391 { X25_FAC_CLASS_A
>>6, "A" },
392 { X25_FAC_CLASS_B
>>6, "B" },
393 { X25_FAC_CLASS_C
>>6, "C" },
394 { X25_FAC_CLASS_D
>>6, "D" },
398 static const value_string x25_facilities_classA_vals
[] = {
399 { X25_FAC_COMP_MARK
, "Marker" },
400 { X25_FAC_REVERSE
, "Reverse charging / Fast select" },
401 { X25_FAC_CHARGING_INFO
, "Charging information" },
402 { X25_FAC_THROUGHPUT
, "Throughput class negotiation" },
403 { X25_FAC_CUG
, "Closed user group selection" },
404 { X25_FAC_CALLED_MODIF
, "Called address modified" },
405 { X25_FAC_CUG_OUTGOING_ACC
, "Closed user group with outgoing access selection" },
406 { X25_FAC_THROUGHPUT_MIN
, "Minimum throughput class" },
407 { X25_FAC_EXPRESS_DATA
, "Negotiation of express data" },
411 static const value_string x25_facilities_classA_comp_mark_vals
[] = {
412 { 0x00, "Network complementary services - calling DTE" },
413 { 0x0F, "DTE complementary services" },
414 { 0xFF, "Network complementary services - called DTE" },
418 static const value_string x25_facilities_classA_throughput_vals
[] = {
433 static const value_string x25_facilities_classB_vals
[] = {
434 { X25_FAC_BILATERAL_CUG
, "Bilateral closed user group selection" },
435 { X25_FAC_PACKET_SIZE
, "Packet size" },
436 { X25_FAC_WINDOW_SIZE
, "Window size" },
437 { X25_FAC_RPOA_SELECTION
, "RPOA selection" },
438 { X25_FAC_CUG_EXT
, "Extended closed user group selection" },
439 { X25_FAC_CUG_OUTGOING_ACC_EXT
, "Extended closed user group with outgoing access selection" },
440 { X25_FAC_TRANSIT_DELAY
, "Transit delay selection and indication" },
444 static const value_string x25_facilities_classB_packet_size_vals
[] = {
457 static const value_string x25_facilities_classC_vals
[] = {
461 static const value_string x25_facilities_classD_vals
[] = {
462 { X25_FAC_CALL_DURATION
, "Call duration" },
463 { X25_FAC_SEGMENT_COUNT
, "Segment count" },
464 { X25_FAC_CALL_TRANSFER
, "Call redirection or deflection notification" },
465 { X25_FAC_RPOA_SELECTION_EXT
, "Extended RPOA selection" },
466 { X25_FAC_CALLING_ADDR_EXT
, "Calling address extension" },
467 { X25_FAC_MONETARY_UNIT
, "Monetary Unit" },
468 { X25_FAC_NUI
, "Network User Identification selection" },
469 { X25_FAC_CALLED_ADDR_EXT
, "Called address extension" },
470 { X25_FAC_ETE_TRANSIT_DELAY
, "End to end transit delay" },
471 { X25_FAC_CALL_DEFLECT
, "Call deflection selection" },
472 { X25_FAC_PRIORITY
, "Priority" },
476 static struct true_false_string x25_reverse_charging_val
= {
481 static const value_string x25_facilities_call_transfer_reason_vals
[] = {
482 { 0x01, "originally called DTE busy" },
483 { 0x07, "call dist. within a hunt group" },
484 { 0x09, "originally called DTE out of order" },
485 { 0x0F, "systematic call redirection" },
489 static const fragment_items x25_frag_items
= {
494 &hf_x25_segment_overlap
,
495 &hf_x25_segment_overlap_conflict
,
496 &hf_x25_segment_multiple_tails
,
497 &hf_x25_segment_too_long_segment
,
498 &hf_x25_segment_error
,
499 &hf_x25_segment_count
,
501 &hf_x25_reassembled_length
,
502 /* Reassembled data field */
507 static dissector_handle_t ip_handle
;
508 static dissector_handle_t clnp_handle
;
509 static dissector_handle_t ositp_handle
;
510 static dissector_handle_t qllc_handle
;
511 static dissector_handle_t data_handle
;
514 static gboolean payload_is_qllc_sna
= FALSE
;
515 static gboolean call_request_nodata_is_cotp
= FALSE
;
516 static gboolean payload_check_data
= FALSE
;
517 static gboolean reassemble_x25
= TRUE
;
519 /* Reassembly of X.25 */
521 static reassembly_table x25_reassembly_table
;
523 static dissector_table_t x25_subdissector_table
;
524 static heur_dissector_list_t x25_heur_subdissector_list
;
527 x25_hash_add_proto_start(guint16 vc
, guint32 frame
, dissector_handle_t dissect
)
532 * Is there already a circuit with this VC number?
534 circuit
= find_circuit(CT_X25
, vc
, frame
);
535 if (circuit
!= NULL
) {
537 * Yes - close it, as we're creating a new one.
539 close_circuit(circuit
, frame
- 1);
543 * Set up a new circuit.
545 circuit
= circuit_new(CT_X25
, vc
, frame
);
550 circuit_set_dissector(circuit
, dissect
);
554 x25_hash_add_proto_end(guint16 vc
, guint32 frame
)
559 * Try to find the circuit.
561 circuit
= find_circuit(CT_X25
, vc
, frame
);
564 * If we succeeded, close it.
567 close_circuit(circuit
, frame
);
570 static const char *clear_code(unsigned char code
)
572 if (code
== 0x00 || (code
& 0x80) == 0x80)
573 return "DTE Originated";
578 return "Number Busy";
580 return "Invalid Facility Requested";
582 return "Network Congestion";
584 return "Out Of Order";
586 return "Access Barred";
588 return "Not Obtainable";
590 return "Remote Procedure Error";
592 return "Local Procedure Error";
594 return "RPOA Out Of Order";
596 return "Reverse Charging Acceptance Not Subscribed";
598 return "Incompatible Destination";
600 return "Fast Select Acceptance Not Subscribed";
602 return "Destination Absent";
605 return wmem_strdup_printf(wmem_packet_scope(),"Unknown %02X", code
);
608 static const char *reset_code(unsigned char code
)
610 if (code
== 0x00 || (code
& 0x80) == 0x80)
611 return "DTE Originated";
616 return "Out of order";
618 return "Remote Procedure Error";
620 return "Local Procedure Error";
622 return "Network Congestion";
624 return "Remote DTE operational";
626 return "Network operational";
628 return "Incompatible Destination";
630 return "Network out of order";
633 return wmem_strdup_printf(wmem_packet_scope(),"Unknown %02X", code
);
636 static const char *restart_code(unsigned char code
)
638 if (code
== 0x00 || (code
& 0x80) == 0x80)
639 return "DTE Originated";
644 return "Local Procedure Error";
646 return "Network Congestion";
648 return "Network Operational";
650 return "Registration/cancellation confirmed";
653 return wmem_strdup_printf(wmem_packet_scope(),"Unknown %02X", code
);
657 dte_address_util(tvbuff_t
*tvb
, int offset
, guint8 len
)
660 char *tmpbuf
= (char *)wmem_alloc(wmem_packet_scope(), 258);
662 for (i
= 0; (i
<len
)&&(i
<256); i
++) {
664 tmpbuf
[i
] = ((tvb_get_guint8(tvb
, offset
+i
/2) >> 4) & 0x0F) + '0';
665 /* if > 9, convert to the right hexadecimal letter */
667 tmpbuf
[i
] += ('A' - '0' - 10);
669 tmpbuf
[i
] = (tvb_get_guint8(tvb
, offset
+i
/2) & 0x0F) + '0';
670 /* if > 9, convert to the right hexadecimal letter */
672 tmpbuf
[i
] += ('A' - '0' - 10);
682 add_priority(proto_tree
*tree
, int hf
, tvbuff_t
*tvb
, int offset
)
686 priority
= tvb_get_guint8(tvb
, offset
);
688 proto_tree_add_uint_format_value(tree
, hf
, tvb
, offset
, 1, priority
,
689 "Unspecified (255)");
691 proto_tree_add_uint(tree
, hf
, tvb
, offset
, 1, priority
);
695 dump_facilities(proto_tree
*tree
, int *offset
, tvbuff_t
*tvb
, packet_info
*pinfo
)
697 guint8 fac
, byte1
, byte2
, byte3
;
698 guint32 len
; /* facilities length */
699 proto_item
*ti
= NULL
;
700 proto_tree
*facilities_tree
= NULL
, *facility_tree
= NULL
;
702 len
= tvb_get_guint8(tvb
, *offset
);
704 ti
= proto_tree_add_text(tree
, tvb
, *offset
, len
+ 1,
706 facilities_tree
= proto_item_add_subtree(ti
, ett_x25_facilities
);
707 proto_tree_add_item(facilities_tree
, hf_x25_facilities_length
, tvb
, *offset
, 1, ENC_NA
);
712 ti
= proto_tree_add_item(facilities_tree
, hf_x25_facility
, tvb
, *offset
, -1, ENC_NA
);
713 fac
= tvb_get_guint8(tvb
, *offset
);
714 switch(fac
& X25_FAC_CLASS_MASK
) {
715 case X25_FAC_CLASS_A
:
716 proto_item_set_len(ti
, 2);
717 proto_item_append_text(ti
, ": %s",
718 val_to_str(fac
, x25_facilities_classA_vals
, "Unknown (0x%02X)"));
719 facility_tree
= proto_item_add_subtree(ti
, ett_x25_facility
);
720 proto_tree_add_item(facility_tree
, hf_x25_facility_class
, tvb
, *offset
, 1, ENC_NA
);
721 proto_tree_add_item(facility_tree
, hf_x25_facility_classA
, tvb
, *offset
, 1, ENC_NA
);
724 case X25_FAC_COMP_MARK
:
725 proto_tree_add_item(facility_tree
, hf_x25_facility_classA_comp_mark
, tvb
, *offset
+1, 1, ENC_NA
);
727 case X25_FAC_REVERSE
:
728 proto_tree_add_item(facility_tree
, hf_x25_facility_classA_reverse
, tvb
, *offset
+1, 1, ENC_NA
);
729 proto_tree_add_item(facility_tree
, hf_x25_fast_select
, tvb
, *offset
+1, 1, ENC_BIG_ENDIAN
);
730 proto_tree_add_item(facility_tree
, hf_x25_icrd
, tvb
, *offset
+1, 1, ENC_BIG_ENDIAN
);
731 proto_tree_add_item(facility_tree
, hf_x25_facility_reverse_charging
, tvb
, *offset
+1, 1, ENC_BIG_ENDIAN
);
733 case X25_FAC_CHARGING_INFO
:
734 proto_tree_add_item(facility_tree
, hf_x25_facility_classA_charging_info
, tvb
, *offset
+1, 1, ENC_NA
);
735 proto_tree_add_item(facility_tree
, hf_x25_facility_charging_info
, tvb
, *offset
+1, 1, ENC_NA
);
737 case X25_FAC_THROUGHPUT
:
738 proto_tree_add_item(facility_tree
, hf_x25_facility_throughput_called_dte
, tvb
, *offset
+1, 1, ENC_NA
);
739 proto_tree_add_item(facility_tree
, hf_x25_throughput_called_dte
, tvb
, *offset
+1, 1, ENC_NA
);
742 proto_tree_add_item(facility_tree
, hf_x25_facility_classA_cug
, tvb
, *offset
+1, 1, ENC_NA
);
744 case X25_FAC_CALLED_MODIF
:
745 proto_tree_add_item(facility_tree
, hf_x25_facility_classA_called_motif
, tvb
, *offset
+1, 1, ENC_NA
);
747 case X25_FAC_CUG_OUTGOING_ACC
:
748 proto_tree_add_item(facility_tree
, hf_x25_facility_classA_cug_outgoing_acc
, tvb
, *offset
+1, 1, ENC_NA
);
750 case X25_FAC_THROUGHPUT_MIN
:
751 proto_tree_add_item(facility_tree
, hf_x25_facility_classA_throughput_min
, tvb
, *offset
+1, 1, ENC_NA
);
753 case X25_FAC_EXPRESS_DATA
:
754 proto_tree_add_item(facility_tree
, hf_x25_facility_classA_express_data
, tvb
, *offset
+1, 1, ENC_NA
);
757 proto_tree_add_item(facility_tree
, hf_x25_facility_classA_unknown
, tvb
, *offset
+1, 1, ENC_NA
);
764 case X25_FAC_CLASS_B
:
765 proto_item_set_len(ti
, 3);
766 proto_item_append_text(ti
, ": %s",
767 val_to_str(fac
, x25_facilities_classB_vals
, "Unknown (0x%02X)"));
768 facility_tree
= proto_item_add_subtree(ti
, ett_x25_facility
);
769 proto_tree_add_item(facility_tree
, hf_x25_facility_class
, tvb
, *offset
, 1, ENC_NA
);
770 proto_tree_add_item(facility_tree
, hf_x25_facility_classB
, tvb
, *offset
, 1, ENC_NA
);
773 case X25_FAC_BILATERAL_CUG
:
774 proto_tree_add_item(facility_tree
, hf_x25_facility_classB_bilateral_cug
, tvb
, *offset
+1, 2, ENC_BIG_ENDIAN
);
776 case X25_FAC_PACKET_SIZE
:
777 proto_tree_add_item(facility_tree
, hf_x25_facility_packet_size_called_dte
, tvb
, *offset
+1, 1, ENC_BIG_ENDIAN
);
778 proto_tree_add_item(facility_tree
, hf_x25_facility_packet_size_calling_dte
, tvb
, *offset
+2, 1, ENC_BIG_ENDIAN
);
780 case X25_FAC_WINDOW_SIZE
:
781 proto_tree_add_item(facility_tree
, hf_x25_window_size_called_dte
, tvb
, *offset
+1, 1, ENC_NA
);
782 proto_tree_add_item(facility_tree
, hf_x25_window_size_calling_dte
, tvb
, *offset
+2, 1, ENC_NA
);
784 case X25_FAC_RPOA_SELECTION
:
785 proto_tree_add_item(facility_tree
, hf_x25_facility_data_network_id_code
, tvb
, *offset
+1, 2, ENC_BIG_ENDIAN
);
787 case X25_FAC_CUG_EXT
:
788 proto_tree_add_item(facility_tree
, hf_x25_facility_cug_ext
, tvb
, *offset
+1, 2, ENC_BIG_ENDIAN
);
790 case X25_FAC_CUG_OUTGOING_ACC_EXT
:
791 proto_tree_add_item(facility_tree
, hf_x25_facility_cug_outgoing_acc_ext
, tvb
, *offset
+1, 2, ENC_BIG_ENDIAN
);
793 case X25_FAC_TRANSIT_DELAY
:
794 proto_tree_add_item(facility_tree
, hf_x25_facility_transit_delay
, tvb
, *offset
+1, 2, ENC_BIG_ENDIAN
);
797 proto_tree_add_item(facility_tree
, hf_x25_facility_classB_unknown
, tvb
, *offset
+1, 2, ENC_BIG_ENDIAN
);
804 case X25_FAC_CLASS_C
:
805 proto_item_set_len(ti
, 4);
806 proto_item_append_text(ti
, ": %s",
807 val_to_str(fac
, x25_facilities_classC_vals
, "Unknown (0x%02X)"));
808 facility_tree
= proto_item_add_subtree(ti
, ett_x25_facility
);
809 proto_tree_add_item(facility_tree
, hf_x25_facility_class
, tvb
, *offset
, 1, ENC_NA
);
810 proto_tree_add_item(facility_tree
, hf_x25_facility_classC
, tvb
, *offset
, 1, ENC_NA
);
812 proto_tree_add_item(facility_tree
, hf_x25_facility_classC_unknown
, tvb
, *offset
+1, 2, ENC_BIG_ENDIAN
);
817 case X25_FAC_CLASS_D
:
818 proto_item_append_text(ti
, ": %s",
819 val_to_str(fac
, x25_facilities_classD_vals
, "Unknown (0x%02X)"));
820 facility_tree
= proto_item_add_subtree(ti
, ett_x25_facility
);
821 proto_tree_add_item(facility_tree
, hf_x25_facility_class
, tvb
, *offset
, 1, ENC_NA
);
822 byte1
= tvb_get_guint8(tvb
, *offset
+1);
823 proto_item_set_len(ti
, byte1
+2);
824 proto_tree_add_item(facility_tree
, hf_x25_facility_classD
, tvb
, *offset
, 1, ENC_NA
);
825 proto_tree_add_item(facility_tree
, hf_x25_facility_length
, tvb
, *offset
+1, 1, ENC_NA
);
828 case X25_FAC_CALL_DURATION
:
832 if ((byte1
< 4) || (byte1
% 4)) {
833 expert_add_info(pinfo
, ti
, &ei_x25_facility_length
);
836 for (i
= 0; (i
<byte1
); i
+=4) {
837 proto_tree_add_text(facility_tree
, tvb
, *offset
+2+i
, 4,
838 "Call duration: %u Day(s) %02X:%02X:%02X Hour(s)",
839 tvb_get_guint8(tvb
, *offset
+2+i
),
840 tvb_get_guint8(tvb
, *offset
+3+i
),
841 tvb_get_guint8(tvb
, *offset
+4+i
),
842 tvb_get_guint8(tvb
, *offset
+5+i
));
846 case X25_FAC_SEGMENT_COUNT
:
850 if ((byte1
< 8) || (byte1
% 8)) {
851 expert_add_info(pinfo
, ti
, &ei_x25_facility_length
);
854 for (i
= 0; (i
<byte1
); i
+=8) {
855 proto_tree_add_text(facility_tree
, tvb
, *offset
+2+i
, 4,
856 "Segments sent to DTE: %02X%02X%02X%02X",
857 tvb_get_guint8(tvb
, *offset
+2+i
),
858 tvb_get_guint8(tvb
, *offset
+3+i
),
859 tvb_get_guint8(tvb
, *offset
+4+i
),
860 tvb_get_guint8(tvb
, *offset
+5+i
));
861 proto_tree_add_text(facility_tree
, tvb
, *offset
+6+i
, 4,
862 "Segments received from DTE: %02X%02X%02X%02X",
863 tvb_get_guint8(tvb
, *offset
+6+i
),
864 tvb_get_guint8(tvb
, *offset
+7+i
),
865 tvb_get_guint8(tvb
, *offset
+8+i
),
866 tvb_get_guint8(tvb
, *offset
+9+i
));
870 case X25_FAC_CALL_TRANSFER
:
875 expert_add_info(pinfo
, ti
, &ei_x25_facility_length
);
878 byte2
= tvb_get_guint8(tvb
, *offset
+2);
879 if ((byte2
& 0xC0) == 0xC0) {
880 proto_tree_add_uint_format_value(facility_tree
, hf_x25_facility_call_transfer_reason
, tvb
,
881 *offset
+2, 1, byte2
, "call deflection by the originally called DTE address");
884 proto_tree_add_uint(facility_tree
, hf_x25_facility_call_transfer_reason
, tvb
, *offset
+2, 1, byte2
);
886 byte3
= tvb_get_guint8(tvb
, *offset
+3);
887 proto_tree_add_uint(facility_tree
, hf_x25_facility_call_transfer_num_semi_octets
, tvb
, *offset
+4, 1, byte3
);
888 tmpbuf
= dte_address_util(tvb
, *offset
+ 4, byte3
);
890 proto_tree_add_text(facility_tree
, tvb
, *offset
+4, byte1
- 2,
891 "DTE address: %s", tmpbuf
);
894 case X25_FAC_RPOA_SELECTION_EXT
:
898 if ((byte1
< 2) || (byte1
% 2)) {
899 expert_add_info(pinfo
, ti
, &ei_x25_facility_length
);
902 for (i
= 0; (i
<byte1
); i
+=2) {
903 proto_tree_add_text(facility_tree
, tvb
, *offset
+2+i
, 2,
904 "Data network identification code: %04X",
905 tvb_get_ntohs(tvb
, *offset
+2+i
));
909 case X25_FAC_CALLING_ADDR_EXT
:
914 expert_add_info(pinfo
, ti
, &ei_x25_facility_length
);
917 byte2
= tvb_get_guint8(tvb
, *offset
+2) & 0x3F;
918 proto_tree_add_uint(facility_tree
, hf_x25_facility_calling_addr_ext_num_semi_octets
, tvb
, *offset
+2, 1, byte2
);
919 tmpbuf
= dte_address_util(tvb
, *offset
+ 3, byte2
);
920 proto_tree_add_text(facility_tree
, tvb
, *offset
+3, byte1
- 1,
921 "DTE address: %s", tmpbuf
);
924 case X25_FAC_MONETARY_UNIT
:
925 proto_tree_add_item(facility_tree
, hf_x25_facility_monetary_unit
, tvb
, *offset
+2, byte1
, ENC_NA
);
928 proto_tree_add_item(facility_tree
, hf_x25_facility_nui
, tvb
, *offset
+2, byte1
, ENC_NA
);
930 case X25_FAC_CALLED_ADDR_EXT
:
935 expert_add_info(pinfo
, ti
, &ei_x25_facility_length
);
938 byte2
= tvb_get_guint8(tvb
, *offset
+2) & 0x3F;
939 proto_tree_add_uint(facility_tree
, hf_x25_facility_called_addr_ext_num_semi_octets
, tvb
, *offset
+2, 1, byte2
);
940 tmpbuf
= dte_address_util(tvb
, *offset
+3, byte2
);
942 proto_tree_add_text(facility_tree
, tvb
, *offset
+3, byte1
- 1,
943 "DTE address: %s", tmpbuf
);
946 case X25_FAC_ETE_TRANSIT_DELAY
:
949 proto_tree_add_item(facility_tree
, hf_x25_facility_cumulative_ete_transit_delay
, tvb
, *offset
+2, 2, ENC_BIG_ENDIAN
);
952 proto_tree_add_item(facility_tree
, hf_x25_facility_requested_ete_transit_delay
, tvb
, *offset
+4, 2, ENC_BIG_ENDIAN
);
955 proto_tree_add_item(facility_tree
, hf_x25_facility_max_acceptable_ete_transit_delay
, tvb
, *offset
+6, 2, ENC_BIG_ENDIAN
);
957 case X25_FAC_CALL_DEFLECT
:
962 expert_add_info(pinfo
, ti
, &ei_x25_facility_length
);
965 byte2
= tvb_get_guint8(tvb
, *offset
+2);
966 if ((byte2
& 0xC0) == 0xC0)
967 proto_tree_add_text(facility_tree
, tvb
, *offset
+2, 1,
968 "Reason: call DTE originated");
970 proto_tree_add_text(facility_tree
, tvb
, *offset
+2, 1,
972 byte3
= tvb_get_guint8(tvb
, *offset
+3);
973 proto_tree_add_uint(facility_tree
, hf_x25_facility_call_deflect_num_semi_octets
, tvb
, *offset
+3, 1, byte3
);
974 tmpbuf
= dte_address_util(tvb
, *offset
+4, byte3
);
976 proto_tree_add_text(facility_tree
, tvb
, *offset
+4, byte1
- 2,
977 "Alternative DTE address: %s", tmpbuf
);
980 case X25_FAC_PRIORITY
:
983 add_priority(facility_tree
, hf_x25_facility_priority_data
, tvb
, *offset
+2);
986 add_priority(facility_tree
, hf_x25_facility_priority_estab_conn
, tvb
, *offset
+3);
989 add_priority(facility_tree
, hf_x25_facility_priority_keep_conn
, tvb
, *offset
+4);
992 add_priority(facility_tree
, hf_x25_facility_min_acceptable_priority_data
, tvb
, *offset
+5);
995 add_priority(facility_tree
, hf_x25_facility_min_acceptable_priority_estab_conn
, tvb
, *offset
+6);
998 add_priority(facility_tree
, hf_x25_facility_min_acceptable_priority_keep_conn
, tvb
, *offset
+7);
1001 proto_tree_add_item(facility_tree
, hf_x25_facility_classD_unknown
, tvb
, *offset
+2, byte1
, ENC_NA
);
1004 byte1
= tvb_get_guint8(tvb
, *offset
+1);
1005 (*offset
) += byte1
+2;
1013 x25_ntoa(proto_tree
*tree
, int *offset
, tvbuff_t
*tvb
,
1014 packet_info
*pinfo
, gboolean is_registration
)
1018 char *addr1
, *addr2
;
1019 char *first
, *second
;
1023 addr1
=(char *)wmem_alloc(wmem_packet_scope(), 16);
1024 addr2
=(char *)wmem_alloc(wmem_packet_scope(), 16);
1026 byte
= tvb_get_guint8(tvb
, *offset
);
1027 len1
= (byte
>> 0) & 0x0F;
1028 len2
= (byte
>> 4) & 0x0F;
1031 if (is_registration
) {
1032 proto_tree_add_item(tree
, hf_x25_dte_address_length
, tvb
, *offset
, 1, ENC_NA
);
1033 proto_tree_add_item(tree
, hf_x25_dce_address_length
, tvb
, *offset
, 1, ENC_NA
);
1036 proto_tree_add_item(tree
, hf_x25_calling_address_length
, tvb
, *offset
, 1, ENC_NA
);
1037 proto_tree_add_item(tree
, hf_x25_called_address_length
, tvb
, *offset
, 1, ENC_NA
);
1042 localoffset
= *offset
;
1043 byte
= tvb_get_guint8(tvb
, localoffset
);
1047 for (i
= 0; i
< (len1
+ len2
); i
++) {
1050 *first
++ = ((byte
>> 0) & 0x0F) + '0';
1052 byte
= tvb_get_guint8(tvb
, localoffset
);
1054 *first
++ = ((byte
>> 4) & 0x0F) + '0';
1058 *second
++ = ((byte
>> 0) & 0x0F) + '0';
1060 byte
= tvb_get_guint8(tvb
, localoffset
);
1062 *second
++ = ((byte
>> 4) & 0x0F) + '0';
1071 col_add_str(pinfo
->cinfo
, COL_RES_DL_DST
, addr1
);
1073 proto_tree_add_text(tree
, tvb
, *offset
,
1077 "Called address: %s",
1081 col_add_str(pinfo
->cinfo
, COL_RES_DL_SRC
, addr2
);
1083 proto_tree_add_text(tree
, tvb
, *offset
+ len1
/2,
1084 (len2
+1)/2+(len1
%2+(len2
+1)%2)/2,
1087 "Calling address: %s",
1090 (*offset
) += ((len1
+ len2
+ 1) / 2);
1094 x25_toa(proto_tree
*tree
, int *offset
, tvbuff_t
*tvb
,
1099 char *addr1
, *addr2
;
1100 char *first
, *second
;
1104 addr1
=(char *)wmem_alloc(wmem_packet_scope(), 256);
1105 addr2
=(char *)wmem_alloc(wmem_packet_scope(), 256);
1107 len1
= tvb_get_guint8(tvb
, *offset
);
1109 proto_tree_add_text(tree
, tvb
, *offset
, 1,
1110 "Called address length: %u",
1115 len2
= tvb_get_guint8(tvb
, *offset
);
1117 proto_tree_add_text(tree
, tvb
, *offset
, 1,
1118 "Calling address length: %u",
1123 localoffset
= *offset
;
1124 byte
= tvb_get_guint8(tvb
, localoffset
);
1127 * XXX - the first two half-octets of the address are the TOA and
1128 * NPI; process them as such and, if the TOA says an address is
1129 * an alternative address, process it correctly (i.e., not as a
1130 * sequence of half-octets containing digit values).
1134 for (i
= 0; i
< (len1
+ len2
); i
++) {
1137 *first
++ = ((byte
>> 0) & 0x0F) + '0';
1139 byte
= tvb_get_guint8(tvb
, localoffset
);
1141 *first
++ = ((byte
>> 4) & 0x0F) + '0';
1145 *second
++ = ((byte
>> 0) & 0x0F) + '0';
1147 byte
= tvb_get_guint8(tvb
, localoffset
);
1149 *second
++ = ((byte
>> 4) & 0x0F) + '0';
1158 col_add_str(pinfo
->cinfo
, COL_RES_DL_DST
, addr1
);
1160 proto_tree_add_text(tree
, tvb
, *offset
,
1162 "Called address: %s",
1166 col_add_str(pinfo
->cinfo
, COL_RES_DL_SRC
, addr2
);
1168 proto_tree_add_text(tree
, tvb
, *offset
+ len1
/2,
1169 (len2
+1)/2+(len1
%2+(len2
+1)%2)/2,
1170 "Calling address: %s",
1173 (*offset
) += ((len1
+ len2
+ 1) / 2);
1177 get_x25_pkt_len(tvbuff_t
*tvb
)
1179 guint length
, called_len
, calling_len
, dte_len
, dce_len
;
1180 guint8 byte2
, bytex
;
1182 byte2
= tvb_get_guint8(tvb
, 2);
1185 case X25_CALL_REQUEST
:
1186 bytex
= tvb_get_guint8(tvb
, 3);
1187 called_len
= (bytex
>> 0) & 0x0F;
1188 calling_len
= (bytex
>> 4) & 0x0F;
1189 length
= 4 + (called_len
+ calling_len
+ 1) / 2; /* addr */
1190 if (length
< tvb_reported_length(tvb
))
1191 length
+= (1 + tvb_get_guint8(tvb
, length
)); /* facilities */
1193 return MIN(tvb_reported_length(tvb
),length
);
1195 case X25_CALL_ACCEPTED
:
1196 /* The calling/called address length byte (following the packet type)
1197 * is not mandatory, so we must check the packet length before trying
1199 if (tvb_reported_length(tvb
) == 3)
1201 bytex
= tvb_get_guint8(tvb
, 3);
1202 called_len
= (bytex
>> 0) & 0x0F;
1203 calling_len
= (bytex
>> 4) & 0x0F;
1204 length
= 4 + (called_len
+ calling_len
+ 1) / 2; /* addr */
1205 if (length
< tvb_reported_length(tvb
))
1206 length
+= (1 + tvb_get_guint8(tvb
, length
)); /* facilities */
1208 return MIN(tvb_reported_length(tvb
),length
);
1210 case X25_CLEAR_REQUEST
:
1211 case X25_RESET_REQUEST
:
1212 case X25_RESTART_REQUEST
:
1213 return MIN(tvb_reported_length(tvb
),5);
1215 case X25_DIAGNOSTIC
:
1216 return MIN(tvb_reported_length(tvb
),4);
1218 case X25_CLEAR_CONFIRMATION
:
1220 case X25_INTERRUPT_CONFIRMATION
:
1221 case X25_RESET_CONFIRMATION
:
1222 case X25_RESTART_CONFIRMATION
:
1223 return MIN(tvb_reported_length(tvb
),3);
1225 case X25_REGISTRATION_REQUEST
:
1226 bytex
= tvb_get_guint8(tvb
, 3);
1227 dce_len
= (bytex
>> 0) & 0x0F;
1228 dte_len
= (bytex
>> 4) & 0x0F;
1229 length
= 4 + (dte_len
+ dce_len
+ 1) / 2; /* addr */
1230 if (length
< tvb_reported_length(tvb
))
1231 length
+= (1 + tvb_get_guint8(tvb
, length
)); /* registration */
1233 return MIN(tvb_reported_length(tvb
),length
);
1235 case X25_REGISTRATION_CONFIRMATION
:
1236 bytex
= tvb_get_guint8(tvb
, 5);
1237 dce_len
= (bytex
>> 0) & 0x0F;
1238 dte_len
= (bytex
>> 4) & 0x0F;
1239 length
= 6 + (dte_len
+ dce_len
+ 1) / 2; /* addr */
1240 if (length
< tvb_reported_length(tvb
))
1241 length
+= (1 + tvb_get_guint8(tvb
, length
)); /* registration */
1243 return MIN(tvb_reported_length(tvb
),length
);
1246 if (PACKET_IS_DATA(byte2
))
1247 return MIN(tvb_reported_length(tvb
),3);
1249 switch (PACKET_TYPE_FC(byte2
))
1252 return MIN(tvb_reported_length(tvb
),3);
1255 return MIN(tvb_reported_length(tvb
),3);
1258 return MIN(tvb_reported_length(tvb
),3);
1264 static const value_string prt_id_vals
[] = {
1265 {PRT_ID_ISO_8073
, "ISO 8073 COTP"},
1266 {PRT_ID_ISO_8602
, "ISO 8602 CLTP"},
1267 {PRT_ID_ISO_10736_ISO_8073
, "ISO 10736 in conjunction with ISO 8073 COTP"},
1268 {PRT_ID_ISO_10736_ISO_8602
, "ISO 10736 in conjunction with ISO 8602 CLTP"},
1272 static const value_string sharing_strategy_vals
[] = {
1273 {0x00, "No sharing"},
1278 dissect_x25_common(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1279 x25_dir_t dir
, gboolean side
)
1281 proto_tree
*x25_tree
=0, *gfi_tree
=0, *userdata_tree
=0;
1283 guint localoffset
=0;
1287 dissector_handle_t dissect
;
1288 gboolean toa
; /* TOA/NPI address format */
1291 const char *short_name
= NULL
, *long_name
= NULL
;
1292 tvbuff_t
*next_tvb
= NULL
;
1293 gboolean q_bit_set
= FALSE
;
1297 fragment_head
*fd_head
;
1303 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "X.25");
1304 col_clear(pinfo
->cinfo
, COL_INFO
);
1306 bytes0_1
= tvb_get_ntohs(tvb
, 0);
1308 modulo
= ((bytes0_1
& 0x2000) ? 128 : 8);
1309 vc
= (int)(bytes0_1
& 0x0FFF);
1311 pinfo
->ctype
= CT_X25
;
1312 pinfo
->circuit_id
= vc
;
1314 if (bytes0_1
& X25_ABIT
) toa
= TRUE
;
1317 x25_pkt_len
= get_x25_pkt_len(tvb
);
1318 if (x25_pkt_len
< 3) /* packet too short */
1320 col_set_str(pinfo
->cinfo
, COL_INFO
, "Invalid/short X.25 packet");
1322 proto_tree_add_protocol_format(tree
, proto_x25
, tvb
, 0, -1,
1323 "Invalid/short X.25 packet");
1327 pkt_type
= tvb_get_guint8(tvb
, 2);
1328 if (PACKET_IS_DATA(pkt_type
)) {
1329 if (bytes0_1
& X25_QBIT
)
1334 ti
= proto_tree_add_item(tree
, proto_x25
, tvb
, 0, x25_pkt_len
, ENC_NA
);
1335 x25_tree
= proto_item_add_subtree(ti
, ett_x25
);
1336 ti
= proto_tree_add_item(x25_tree
, hf_x25_gfi
, tvb
, 0, 2, ENC_BIG_ENDIAN
);
1337 gfi_tree
= proto_item_add_subtree(ti
, ett_x25_gfi
);
1339 if (PACKET_IS_DATA(pkt_type
)) {
1340 proto_tree_add_boolean(gfi_tree
, hf_x25_qbit
, tvb
, 0, 2,
1343 else if (pkt_type
== X25_CALL_REQUEST
||
1344 pkt_type
== X25_CALL_ACCEPTED
||
1345 pkt_type
== X25_CLEAR_REQUEST
||
1346 pkt_type
== X25_CLEAR_CONFIRMATION
) {
1347 proto_tree_add_boolean(gfi_tree
, hf_x25_abit
, tvb
, 0, 2,
1351 if (pkt_type
== X25_CALL_REQUEST
|| pkt_type
== X25_CALL_ACCEPTED
||
1352 PACKET_IS_DATA(pkt_type
)) {
1353 proto_tree_add_boolean(gfi_tree
, hf_x25_dbit
, tvb
, 0, 2,
1356 proto_tree_add_uint(gfi_tree
, hf_x25_mod
, tvb
, 0, 2, bytes0_1
);
1360 case X25_CALL_REQUEST
:
1364 short_name
= "Inc. call";
1365 long_name
= "Incoming call";
1369 short_name
= "Call req.";
1370 long_name
= "Call request";
1374 short_name
= "Inc. call/Call req.";
1375 long_name
= "Incoming call/Call request";
1378 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s VC:%d", short_name
, vc
);
1380 proto_tree_add_uint(x25_tree
, hf_x25_lcn
, tvb
,
1382 proto_tree_add_uint_format_value(x25_tree
, hf_x25_type
, tvb
, 2, 1,
1383 X25_CALL_REQUEST
, "%s", long_name
);
1386 if (localoffset
< x25_pkt_len
) { /* calling/called addresses */
1388 x25_toa(x25_tree
, (gint
*)&localoffset
, tvb
, pinfo
);
1390 x25_ntoa(x25_tree
, (gint
*)&localoffset
, tvb
, pinfo
, FALSE
);
1393 if (localoffset
< x25_pkt_len
) /* facilities */
1394 dump_facilities(x25_tree
, (gint
*)&localoffset
, tvb
, pinfo
);
1396 if (localoffset
< tvb_reported_length(tvb
)) /* user data */
1400 ti
= proto_tree_add_text(x25_tree
, tvb
, localoffset
, -1,
1402 userdata_tree
= proto_item_add_subtree(ti
, ett_x25_user_data
);
1405 /* X.263/ISO 9577 says that:
1407 When CLNP or ESIS are run over X.25, the SPI
1408 is 0x81 or 0x82, respectively; those are the
1409 NLPIDs for those protocol.
1411 When X.224/ISO 8073 COTP is run over X.25, and
1412 when ISO 11570 explicit identification is being
1413 used, the first octet of the user data field is
1414 a TPDU length field, and the rest is "as defined
1415 in ITU-T Rec. X.225 | ISO/IEC 8073, Annex B,
1416 or ITU-T Rec. X.264 and ISO/IEC 11570".
1418 When X.264/ISO 11570 default identification is
1419 being used, there is no user data field in the
1420 CALL REQUEST packet. This is for X.225/ISO 8073
1423 It also says that SPI values from 0x03 through 0x3f are
1424 reserved and are in use by X.224/ISO 8073 Annex B and
1425 X.264/ISO 11570. The note says that those values are
1426 not NLPIDs, they're "used by the respective higher layer
1427 protocol" and "not used for higher layer protocol
1428 identification". I infer from this and from what
1429 X.264/ISO 11570 says that this means that values in those
1430 range are valid values for the first octet of an
1431 X.224/ISO 8073 packet or for X.264/ISO 11570.
1433 Annex B of X.225/ISO 8073 mentions some additional TPDU
1434 types that can be put in what I presume is the user
1435 data of connect requests. It says that:
1437 The sending transport entity shall:
1439 a) either not transmit any TPDU in the NS-user data
1440 parameter of the N-CONNECT request primitive; or
1442 b) transmit the UN-TPDU (see ITU-T Rec. X.264 and
1443 ISO/IEC 11570) followed by the NCM-TPDU in the
1444 NS-user data parameter of the N-CONNECT request
1447 I don't know if this means that the user data field
1448 will contain a UN TPDU followed by an NCM TPDU or not.
1450 X.264/ISO 11570 says that:
1452 When default identification is being used,
1453 X.225/ISO 8073 COTP is identified. No user data
1454 is sent in the network-layer connection request.
1456 When explicit identification is being used,
1457 the user data is a UN TPDU ("Use of network
1458 connection TPDU"), which specifies the transport
1459 protocol to use over this network connection.
1460 It also says that the length of a UN TPDU shall
1461 not exceed 32 octets, i.e. shall not exceed 0x20;
1462 it says this is "due to the desire not to conflict
1463 with the protocol identifier field carried by X.25
1464 CALL REQUEST/INCOMING CALL packets", and says that
1465 field has values specified in X.244. X.244 has been
1466 superseded by X.263/ISO 9577, so that presumably
1467 means the goal is to allow a UN TPDU's length
1468 field to be distinguished from an NLPID, allowing
1469 you to tell whether X.264/ISO 11570 explicit
1470 identification is being used or an NLPID is
1471 being used as the SPI.
1473 I read this as meaning that, if the ISO mechanisms are
1474 used to identify the protocol being carried over X.25:
1476 if there's no user data in the CALL REQUEST/
1477 INCOMING CALL packet, it's COTP;
1479 if there is user data, then:
1481 if the first octet is less than or equal to
1482 32, it might be a UN TPDU, and that identifies
1483 the transport protocol being used, and
1484 it may be followed by more data, such
1485 as a COTP NCM TPDU if it's COTP;
1487 if the first octet is greater than 32, it's
1488 an NLPID, *not* a TPDU length, and the
1489 stuff following it is *not* a TPDU.
1491 Figure A.2 of X.263/ISO 9577 seems to say that the
1492 first octet of the user data is a TPDU length field,
1493 in the range 0x03 through 0x82, and says they are
1494 for X.225/ISO 8073 Annex B or X.264/ISO 11570.
1496 However, X.264/ISO 11570 seems to imply that the length
1497 field would be that of a UN TPDU, which must be less
1498 than or equal to 0x20, and X.225/ISO 8073 Annex B seems
1499 to indicate that the user data must begin with
1500 an X.264/ISO 11570 UN TPDU, so I'd say that A.2 should
1501 have said "in the range 0x03 through 0x20", instead
1502 (the length value doesn't include the length field,
1503 and the minimum UN TPDU has length, type, PRT-ID,
1504 and SHARE, so that's 3 bytes without the length). */
1505 spi
= tvb_get_guint8(tvb
, localoffset
);
1506 if (spi
> 32 || spi
< 3) {
1507 /* First octet is > 32, or < 3, so the user data isn't an
1508 X.264/ISO 11570 UN TPDU */
1511 /* First octet is >= 3 and <= 32, so the user data *might*
1512 be an X.264/ISO 11570 UN TPDU. Check whether we have
1513 enough data to see if it is. */
1514 if (tvb_bytes_exist(tvb
, localoffset
+1, 1)) {
1515 /* We do; check whether the second octet is 1. */
1516 if (tvb_get_guint8(tvb
, localoffset
+1) == 0x01) {
1517 /* Yes, the second byte is 1, so it looks like
1521 /* No, the second byte is not 1, so it's not a
1526 /* We can't see the second byte of the putative UN
1527 TPDU, so we don't know if that's what it is. */
1531 if (is_x_264
== -1) {
1533 * We don't know what it is; just skip it.
1535 localoffset
= tvb_length(tvb
);
1536 } else if (is_x_264
) {
1537 /* It looks like an X.264 UN TPDU, so show it as such. */
1538 if (userdata_tree
) {
1539 proto_tree_add_item( userdata_tree
, hf_x264_length_indicator
, tvb
, localoffset
, 1, ENC_NA
);
1540 proto_tree_add_item( userdata_tree
, hf_x264_un_tpdu_id
, tvb
, localoffset
+1, 1, ENC_NA
);
1542 prt_id
= tvb_get_guint8(tvb
, localoffset
+2);
1543 if (userdata_tree
) {
1544 proto_tree_add_item( userdata_tree
, hf_x264_protocol_id
, tvb
, localoffset
+2, 1, ENC_NA
);
1545 proto_tree_add_item( userdata_tree
, hf_x264_sharing_strategy
, tvb
, localoffset
+3, 1, ENC_NA
);
1548 /* XXX - dissect the variable part? */
1550 /* The length doesn't include the length octet itself. */
1551 localoffset
+= spi
+ 1;
1555 case PRT_ID_ISO_8073
:
1557 if (!pinfo
->fd
->flags
.visited
)
1558 x25_hash_add_proto_start(vc
, pinfo
->fd
->num
, ositp_handle
);
1559 /* XXX - dissect the rest of the user data as COTP?
1560 That needs support for NCM TPDUs, etc. */
1563 case PRT_ID_ISO_8602
:
1565 if (!pinfo
->fd
->flags
.visited
)
1566 x25_hash_add_proto_start(vc
, pinfo
->fd
->num
, ositp_handle
);
1569 } else if (is_x_264
== 0) {
1570 /* It doesn't look like a UN TPDU, so compare the first
1571 octet of the CALL REQUEST packet with various X.263/
1572 ISO 9577 NLPIDs, as per Annex A of X.263/ISO 9577. */
1574 if (userdata_tree
) {
1575 proto_tree_add_item( userdata_tree
, hf_x263_sec_protocol_id
, tvb
, localoffset
, 1, ENC_NA
);
1578 if (!pinfo
->fd
->flags
.visited
) {
1580 * Is there a dissector handle for this SPI?
1581 * If so, assign it to this virtual circuit.
1583 dissect
= dissector_get_uint_handle(x25_subdissector_table
, spi
);
1584 if (dissect
!= NULL
)
1585 x25_hash_add_proto_start(vc
, pinfo
->fd
->num
, dissect
);
1589 * If there's only one octet of user data, it's just
1590 * an NLPID; don't try to dissect it.
1592 if (localoffset
+ 1 == tvb_reported_length(tvb
))
1596 * There's more than one octet of user data, so we'll
1597 * dissect it; for some protocols, the NLPID is considered
1598 * to be part of the PDU, so, for those cases, we don't
1599 * skip past it. For other protocols, we skip the NLPID.
1603 case NLPID_ISO8473_CLNP
:
1604 case NLPID_ISO9542_ESIS
:
1605 case NLPID_ISO10589_ISIS
:
1606 case NLPID_ISO10747_IDRP
:
1609 * The NLPID is part of the PDU. Don't skip it.
1610 * But if it's all there is to the PDU, don't
1611 * bother dissecting it.
1615 case NLPID_SPI_X_29
:
1617 * The first 4 bytes of the call user data are
1618 * the SPI plus 3 reserved bytes; they are not
1619 * part of the data to be dissected as X.29 data.
1626 * The NLPID isn't part of the PDU - skip it.
1627 * If that means there's nothing to dissect
1633 /* if there's no user data in the CALL REQUEST/
1634 INCOMING CALL packet, it's COTP; */
1636 if (call_request_nodata_is_cotp
){
1637 x25_hash_add_proto_start(vc
, pinfo
->fd
->num
, ositp_handle
);
1641 case X25_CALL_ACCEPTED
:
1645 short_name
= "Call conn.";
1646 long_name
= "Call connected";
1650 short_name
= "Call acc.";
1651 long_name
= "Call accepted";
1655 short_name
= "Call conn./Call acc.";
1656 long_name
= "Call connected/Call accepted";
1659 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s VC:%d", short_name
, vc
);
1661 proto_tree_add_uint(x25_tree
, hf_x25_lcn
, tvb
, 0, 2, bytes0_1
);
1662 proto_tree_add_uint_format_value(x25_tree
, hf_x25_type
, tvb
, 2, 1,
1663 X25_CALL_ACCEPTED
, "%s", long_name
);
1666 if (localoffset
< x25_pkt_len
) { /* calling/called addresses */
1668 x25_toa(x25_tree
, (gint
*)&localoffset
, tvb
, pinfo
);
1670 x25_ntoa(x25_tree
, (gint
*)&localoffset
, tvb
, pinfo
, FALSE
);
1673 if (localoffset
< x25_pkt_len
) /* facilities */
1674 dump_facilities(x25_tree
, (gint
*)&localoffset
, tvb
, pinfo
);
1676 case X25_CLEAR_REQUEST
:
1680 short_name
= "Clear ind.";
1681 long_name
= "Clear indication";
1685 short_name
= "Clear req.";
1686 long_name
= "Clear request";
1690 short_name
= "Clear ind./Clear req.";
1691 long_name
= "Clear indication/Clear request";
1694 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s VC:%d %s - %s", short_name
,
1695 vc
, clear_code(tvb_get_guint8(tvb
, 3)),
1696 val_to_str_ext(tvb_get_guint8(tvb
, 4), &x25_clear_diag_vals_ext
, "Unknown (0x%02x)"));
1697 x25_hash_add_proto_end(vc
, pinfo
->fd
->num
);
1699 proto_tree_add_uint(x25_tree
, hf_x25_lcn
, tvb
, 0, 2, bytes0_1
);
1700 proto_tree_add_uint_format_value(x25_tree
, hf_x25_type
, tvb
,
1701 localoffset
+2, 1, X25_CLEAR_REQUEST
, "%s",
1703 proto_tree_add_text(x25_tree
, tvb
, 3, 1,
1704 "Cause: %s", clear_code(tvb_get_guint8(tvb
, 3)));
1705 proto_tree_add_item(x25_tree
, hf_x25_diagnostic
, tvb
, 4, 1, ENC_NA
);
1707 localoffset
= x25_pkt_len
;
1709 case X25_CLEAR_CONFIRMATION
:
1710 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Clear Conf. VC:%d", vc
);
1712 proto_tree_add_uint(x25_tree
, hf_x25_lcn
, tvb
, 0, 2, bytes0_1
);
1713 proto_tree_add_uint(x25_tree
, hf_x25_type
, tvb
, 2, 1,
1714 X25_CLEAR_CONFIRMATION
);
1716 localoffset
= x25_pkt_len
;
1718 if (localoffset
< tvb_reported_length(tvb
)) { /* extended clear conf format */
1720 x25_toa(x25_tree
, (gint
*)&localoffset
, tvb
, pinfo
);
1722 x25_ntoa(x25_tree
,(gint
*)&localoffset
, tvb
, pinfo
, FALSE
);
1725 if (localoffset
< tvb_reported_length(tvb
)) /* facilities */
1726 dump_facilities(x25_tree
, (gint
*)&localoffset
, tvb
, pinfo
);
1728 case X25_DIAGNOSTIC
:
1729 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Diag. %d",
1730 (int)tvb_get_guint8(tvb
, 3));
1732 proto_tree_add_uint(x25_tree
, hf_x25_type
, tvb
, 2, 1,
1734 proto_tree_add_text(x25_tree
, tvb
, 3, 1,
1735 "Diagnostic: %d", (int)tvb_get_guint8(tvb
, 3));
1737 localoffset
= x25_pkt_len
;
1740 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Interrupt VC:%d", vc
);
1742 proto_tree_add_uint(x25_tree
, hf_x25_lcn
, tvb
, 0, 2, bytes0_1
);
1743 proto_tree_add_uint(x25_tree
, hf_x25_type
, tvb
, 2, 1,
1746 localoffset
= x25_pkt_len
;
1748 case X25_INTERRUPT_CONFIRMATION
:
1749 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Interrupt Conf. VC:%d", vc
);
1751 proto_tree_add_uint(x25_tree
, hf_x25_lcn
, tvb
, 0, 2, bytes0_1
);
1752 proto_tree_add_uint(x25_tree
, hf_x25_type
, tvb
, 2, 1,
1753 X25_INTERRUPT_CONFIRMATION
);
1755 localoffset
= x25_pkt_len
;
1757 case X25_RESET_REQUEST
:
1761 short_name
= "Reset ind.";
1762 long_name
= "Reset indication";
1766 short_name
= "Reset req.";
1767 long_name
= "Reset request";
1771 short_name
= "Reset ind./Reset req.";
1772 long_name
= "Reset indication/Reset request";
1775 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s VC:%d %s - Diag.:%d",
1776 short_name
, vc
, reset_code(tvb_get_guint8(tvb
, 3)),
1777 (int)tvb_get_guint8(tvb
, 4));
1778 x25_hash_add_proto_end(vc
, pinfo
->fd
->num
);
1780 proto_tree_add_uint(x25_tree
, hf_x25_lcn
, tvb
, 0, 2, bytes0_1
);
1781 proto_tree_add_uint_format_value(x25_tree
, hf_x25_type
, tvb
, 2, 1,
1782 X25_RESET_REQUEST
, "%s", long_name
);
1783 proto_tree_add_text(x25_tree
, tvb
, 3, 1,
1784 "Cause: %s", reset_code(tvb_get_guint8(tvb
, 3)));
1785 proto_tree_add_text(x25_tree
, tvb
, 4, 1,
1786 "Diagnostic: %d", (int)tvb_get_guint8(tvb
, 4));
1788 localoffset
= x25_pkt_len
;
1790 case X25_RESET_CONFIRMATION
:
1791 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Reset conf. VC:%d", vc
);
1793 proto_tree_add_uint(x25_tree
, hf_x25_lcn
, tvb
, 0, 2, bytes0_1
);
1794 proto_tree_add_uint(x25_tree
, hf_x25_type
, tvb
, 2, 1,
1795 X25_RESET_CONFIRMATION
);
1797 localoffset
= x25_pkt_len
;
1799 case X25_RESTART_REQUEST
:
1803 short_name
= "Restart ind.";
1804 long_name
= "Restart indication";
1808 short_name
= "Restart req.";
1809 long_name
= "Restart request";
1813 short_name
= "Restart ind./Restart req.";
1814 long_name
= "Restart indication/Restart request";
1817 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s %s - Diag.:%d",
1819 restart_code(tvb_get_guint8(tvb
, 3)),
1820 (int)tvb_get_guint8(tvb
, 4));
1822 proto_tree_add_uint_format_value(x25_tree
, hf_x25_type
, tvb
, 2, 1,
1823 X25_RESTART_REQUEST
, "%s", long_name
);
1824 proto_tree_add_text(x25_tree
, tvb
, 3, 1,
1825 "Cause: %s", restart_code(tvb_get_guint8(tvb
, 3)));
1826 proto_tree_add_text(x25_tree
, tvb
, 4, 1,
1827 "Diagnostic: %d", (int)tvb_get_guint8(tvb
, 4));
1829 localoffset
= x25_pkt_len
;
1831 case X25_RESTART_CONFIRMATION
:
1832 col_set_str(pinfo
->cinfo
, COL_INFO
, "Restart conf.");
1834 proto_tree_add_uint(x25_tree
, hf_x25_type
, tvb
, 2, 1,
1835 X25_RESTART_CONFIRMATION
);
1836 localoffset
= x25_pkt_len
;
1838 case X25_REGISTRATION_REQUEST
:
1839 col_set_str(pinfo
->cinfo
, COL_INFO
, "Registration req.");
1841 proto_tree_add_uint(x25_tree
, hf_x25_type
, tvb
, 2, 1,
1842 X25_REGISTRATION_REQUEST
);
1844 if (localoffset
< x25_pkt_len
)
1845 x25_ntoa(x25_tree
, (gint
*)&localoffset
, tvb
, pinfo
, TRUE
);
1848 if (localoffset
< x25_pkt_len
)
1849 proto_tree_add_item( x25_tree
, hf_x25_reg_request_length
, tvb
, localoffset
, 1, ENC_NA
);
1850 if (localoffset
+1 < x25_pkt_len
)
1851 proto_tree_add_text(x25_tree
, tvb
, localoffset
+1,
1852 tvb_get_guint8(tvb
, localoffset
) & 0x7F,
1855 localoffset
= tvb_reported_length(tvb
);
1857 case X25_REGISTRATION_CONFIRMATION
:
1858 col_set_str(pinfo
->cinfo
, COL_INFO
, "Registration conf.");
1860 proto_tree_add_uint(x25_tree
, hf_x25_type
, tvb
, 2, 1,
1861 X25_REGISTRATION_CONFIRMATION
);
1862 proto_tree_add_item(x25_tree
, hf_x25_reg_confirm_cause
, tvb
, 3, 1, ENC_NA
);
1863 proto_tree_add_item(x25_tree
, hf_x25_reg_confirm_diagnostic
, tvb
, 4, 1, ENC_NA
);
1866 if (localoffset
< x25_pkt_len
)
1867 x25_ntoa(x25_tree
, (gint
*)&localoffset
, tvb
, pinfo
, TRUE
);
1870 if (localoffset
< x25_pkt_len
)
1871 proto_tree_add_item( x25_tree
, hf_x25_reg_confirm_length
, tvb
, localoffset
, 1, ENC_NA
);
1872 if (localoffset
+1 < x25_pkt_len
)
1873 proto_tree_add_text(x25_tree
, tvb
, localoffset
+1,
1874 tvb_get_guint8(tvb
, localoffset
) & 0x7F,
1877 localoffset
= tvb_reported_length(tvb
);
1882 proto_tree_add_uint(x25_tree
, hf_x25_lcn
, tvb
, localoffset
-2,
1885 if (PACKET_IS_DATA(pkt_type
)) {
1887 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
1888 "Data VC:%d P(S):%d P(R):%d %s", vc
,
1889 (pkt_type
>> 1) & 0x07,
1890 (pkt_type
>> 5) & 0x07,
1891 (pkt_type
& X25_MBIT_MOD8
) ? " M" : "");
1893 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
1894 "Data VC:%d P(S):%d P(R):%d %s", vc
,
1895 tvb_get_guint8(tvb
, localoffset
+1) >> 1,
1897 (tvb_get_guint8(tvb
, localoffset
+1) & X25_MBIT_MOD128
) ? " M" : "");
1900 proto_tree_add_uint(x25_tree
, hf_x25_p_r_mod8
, tvb
,
1901 localoffset
, 1, pkt_type
);
1902 proto_tree_add_boolean(x25_tree
, hf_x25_mbit_mod8
, tvb
,
1903 localoffset
, 1, pkt_type
);
1904 proto_tree_add_uint(x25_tree
, hf_x25_p_s_mod8
, tvb
,
1905 localoffset
, 1, pkt_type
);
1906 proto_tree_add_uint(x25_tree
, hf_x25_type_data
, tvb
,
1907 localoffset
, 1, pkt_type
);
1910 proto_tree_add_uint(x25_tree
, hf_x25_p_r_mod128
, tvb
,
1911 localoffset
, 1, pkt_type
);
1912 proto_tree_add_uint(x25_tree
, hf_x25_type_data
, tvb
,
1913 localoffset
, 1, pkt_type
);
1914 proto_tree_add_uint(x25_tree
, hf_x25_p_s_mod128
, tvb
,
1916 tvb_get_guint8(tvb
, localoffset
+1));
1917 proto_tree_add_boolean(x25_tree
, hf_x25_mbit_mod128
, tvb
,
1919 tvb_get_guint8(tvb
, localoffset
+1));
1923 m_bit_set
= pkt_type
& X25_MBIT_MOD8
;
1926 m_bit_set
= tvb_get_guint8(tvb
, localoffset
+1) & X25_MBIT_MOD128
;
1929 payload_len
= tvb_reported_length_remaining(tvb
, localoffset
);
1930 if (reassemble_x25
) {
1932 * Reassemble received and sent traffic separately.
1933 * We don't reassemble traffic with an unknown direction
1939 * OR in an extra bit to distinguish from traffic
1940 * in the other direction.
1942 frag_key
|= 0x10000;
1944 fd_head
= fragment_add_seq_next(&x25_reassembly_table
,
1946 pinfo
, frag_key
, NULL
,
1947 payload_len
, m_bit_set
);
1948 pinfo
->fragmented
= m_bit_set
;
1950 /* Fragment handling is not adapted to handle several x25
1951 * packets in the same frame. This is common with XOT and
1952 * shorter packet sizes.
1953 * Therefore, fragment_add_seq_next seem to always return fd_head
1954 * A fix to use m_bit_set to only show fragments for last pkt
1956 if (!m_bit_set
&& fd_head
) {
1957 if (fd_head
->next
) {
1958 proto_item
*frag_tree_item
;
1960 /* This is the last packet */
1961 next_tvb
= tvb_new_chain(tvb
, fd_head
->tvb_data
);
1962 add_new_data_source(pinfo
, next_tvb
, "Reassembled X.25");
1964 show_fragment_seq_tree(fd_head
,
1967 pinfo
, next_tvb
, &frag_tree_item
);
1972 if (m_bit_set
&& next_tvb
== NULL
) {
1974 * This isn't the last packet, so just
1975 * show it as X.25 user data.
1977 proto_tree_add_text(x25_tree
, tvb
, localoffset
, -1,
1978 "User data (%u byte%s)", payload_len
,
1979 plurality(payload_len
, "", "s"));
1985 * Non-data packets (RR, RNR, REJ).
1989 proto_tree_add_uint(x25_tree
, hf_x25_p_r_mod8
, tvb
,
1990 localoffset
, 1, pkt_type
);
1991 proto_tree_add_item(x25_tree
, hf_x25_type_fc_mod8
, tvb
,
1992 localoffset
, 1, ENC_NA
);
1994 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s VC:%d P(R):%d",
1995 val_to_str(PACKET_TYPE_FC(pkt_type
), vals_x25_type
, "Unknown (0x%02X)"),
1996 vc
, (pkt_type
>> 5) & 0x07);
2000 proto_tree_add_item(x25_tree
, hf_x25_type
, tvb
,
2001 localoffset
, 1, ENC_NA
);
2002 proto_tree_add_item(x25_tree
, hf_x25_p_r_mod128
, tvb
,
2003 localoffset
+1, 1, ENC_NA
);
2005 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s VC:%d P(R):%d",
2006 val_to_str(PACKET_TYPE_FC(pkt_type
), vals_x25_type
, "Unknown (0x%02X)"),
2007 vc
, tvb_get_guint8(tvb
, localoffset
+1) >> 1);
2014 if (localoffset
>= tvb_reported_length(tvb
))
2016 if (pinfo
->fragmented
)
2020 next_tvb
= tvb_new_subset_remaining(tvb
, localoffset
);
2022 /* See if there's already a dissector for this circuit. */
2023 if (try_circuit_dissector(CT_X25
, vc
, pinfo
->fd
->num
, next_tvb
, pinfo
,
2024 tree
, &q_bit_set
)) {
2025 return; /* found it and dissected it */
2028 /* Did the user suggest QLLC/SNA? */
2029 if (payload_is_qllc_sna
) {
2030 /* Yes - dissect it as QLLC/SNA. */
2031 if (!pinfo
->fd
->flags
.visited
)
2032 x25_hash_add_proto_start(vc
, pinfo
->fd
->num
, qllc_handle
);
2033 call_dissector_with_data(qllc_handle
, next_tvb
, pinfo
, tree
, &q_bit_set
);
2037 if (payload_check_data
){
2038 /* If the Call Req. has not been captured, let's look at the first
2039 two bytes of the payload to see if this looks like COTP. */
2040 if (tvb_get_guint8(tvb
, localoffset
) == tvb_length(next_tvb
)-1) {
2041 /* First byte contains the length of the remaining buffer */
2042 if ((tvb_get_guint8(tvb
, localoffset
+1) & 0x0F) == 0) {
2043 /* Second byte contains a valid COTP TPDU */
2044 if (!pinfo
->fd
->flags
.visited
)
2045 x25_hash_add_proto_start(vc
, pinfo
->fd
->num
, ositp_handle
);
2046 call_dissector(ositp_handle
, next_tvb
, pinfo
, tree
);
2051 /* Then let's look at the first byte of the payload to see if this
2052 looks like IP or CLNP. */
2053 switch (tvb_get_guint8(tvb
, localoffset
)) {
2056 /* Looks like an IP header */
2057 if (!pinfo
->fd
->flags
.visited
)
2058 x25_hash_add_proto_start(vc
, pinfo
->fd
->num
, ip_handle
);
2059 call_dissector(ip_handle
, next_tvb
, pinfo
, tree
);
2062 case NLPID_ISO8473_CLNP
:
2063 if (!pinfo
->fd
->flags
.visited
)
2064 x25_hash_add_proto_start(vc
, pinfo
->fd
->num
, clnp_handle
);
2065 call_dissector(clnp_handle
, next_tvb
, pinfo
, tree
);
2070 /* Try the heuristic dissectors. */
2071 if (dissector_try_heuristic(x25_heur_subdissector_list
, next_tvb
, pinfo
,
2076 /* All else failed; dissect it as raw data */
2077 call_dissector(data_handle
, next_tvb
, pinfo
, tree
);
2081 * X.25 dissector for use when "pinfo->pseudo_header" points to a
2082 * "struct x25_phdr".
2085 dissect_x25_dir(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
2087 dissect_x25_common(tvb
, pinfo
, tree
,
2088 (pinfo
->pseudo_header
->x25
.flags
& FROM_DCE
) ? X25_FROM_DCE
:
2090 pinfo
->pseudo_header
->x25
.flags
& FROM_DCE
);
2094 * X.25 dissector for use when "pinfo->pseudo_header" doesn't point to a
2095 * "struct x25_phdr".
2098 dissect_x25(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
2103 * We don't know if this packet is DTE->DCE or DCE->DCE.
2104 * However, we can, at least, distinguish between the two
2105 * sides of the conversation, based on the addresses and
2108 direction
= CMP_ADDRESS(&pinfo
->src
, &pinfo
->dst
);
2110 direction
= (pinfo
->srcport
> pinfo
->destport
)*2 - 1;
2111 dissect_x25_common(tvb
, pinfo
, tree
, X25_UNKNOWN
, direction
> 0);
2115 x25_reassemble_init(void)
2117 reassembly_table_init(&x25_reassembly_table
,
2118 &addresses_reassembly_table_functions
);
2122 proto_register_x25(void)
2124 static hf_register_info hf
[] = {
2126 { "Facility", "x25.facility", FT_NONE
, BASE_NONE
, NULL
, 0,
2128 { &hf_x25_facilities_length
,
2129 { "Facilities Length", "x25.facilities_length", FT_UINT8
, BASE_DEC
, NULL
, 0,
2131 { &hf_x25_facility_length
,
2132 { "Length", "x25.facility_length", FT_UINT8
, BASE_DEC
, NULL
, 0,
2134 { &hf_x25_facility_class
,
2135 { "Facility Class", "x25.facility.class", FT_UINT8
, BASE_HEX
, VALS(x25_facilities_class_vals
), X25_FAC_CLASS_MASK
,
2137 { &hf_x25_facility_classA
,
2138 { "Code", "x25.facility.classA", FT_UINT8
, BASE_HEX
, VALS(x25_facilities_classA_vals
), 0,
2139 "Facility ClassA Code", HFILL
}},
2140 { &hf_x25_facility_classA_comp_mark
,
2141 { "Parameter", "x25.facility.comp_mark", FT_UINT8
, BASE_DEC
, VALS(x25_facilities_classA_comp_mark_vals
), 0,
2142 "Facility Marker Parameter", HFILL
}},
2143 { &hf_x25_facility_classA_reverse
,
2144 { "Parameter", "x25.facility.reverse", FT_UINT8
, BASE_HEX
, NULL
, 0,
2145 "Facility Reverse Charging Parameter", HFILL
}},
2146 { &hf_x25_facility_classA_charging_info
,
2147 { "Parameter", "x25.facility.charging_info", FT_UINT8
, BASE_HEX
, NULL
, 0,
2148 "Facility Charging Information Parameter", HFILL
}},
2149 { &hf_x25_facility_reverse_charging
,
2150 { "Reverse charging", "x25.reverse_charging", FT_BOOLEAN
, 8, TFS(&x25_reverse_charging_val
), 0x01,
2152 { &hf_x25_facility_charging_info
,
2153 { "Charging information", "x25.charging_info", FT_BOOLEAN
, 8, TFS(&tfs_requested_not_requested
), 0x01,
2155 { &hf_x25_facility_throughput_called_dte
,
2156 { "From the called DTE", "x25.facility.throughput.called_dte", FT_UINT8
, BASE_DEC
, VALS(x25_facilities_classA_throughput_vals
), 0xF0,
2157 "Facility Throughput called DTE", HFILL
}},
2158 { &hf_x25_throughput_called_dte
,
2159 { "From the calling DTE", "x25.facility.throughput.called_dte", FT_UINT8
, BASE_DEC
, VALS(x25_facilities_classA_throughput_vals
), 0x0F,
2160 "Facility Throughput called DTE", HFILL
}},
2161 { &hf_x25_facility_classA_cug
,
2162 { "Closed user group", "x25.facility.cug", FT_UINT8
, BASE_HEX
, NULL
, 0,
2163 "Facility Closed user group", HFILL
}},
2164 { &hf_x25_facility_classA_called_motif
,
2165 { "Parameter", "x25.facility.called_motif", FT_UINT8
, BASE_HEX
, NULL
, 0,
2166 "Facility Called address modified parameter", HFILL
}},
2167 { &hf_x25_facility_classA_cug_outgoing_acc
,
2168 { "Closed user group", "x25.facility.cug_outgoing_acc", FT_UINT8
, BASE_HEX
, NULL
, 0,
2169 "Facility Closed user group with outgoing access selection", HFILL
}},
2170 { &hf_x25_facility_classA_throughput_min
,
2171 { "Parameter", "x25.facility.throughput_min", FT_UINT8
, BASE_HEX
, NULL
, 0,
2172 "Facility Minimum throughput class parameter", HFILL
}},
2173 { &hf_x25_facility_classA_express_data
,
2174 { "Parameter", "x25.facility.express_data", FT_UINT8
, BASE_HEX
, NULL
, 0,
2175 "Facility Negotiation of express data parameter", HFILL
}},
2176 { &hf_x25_facility_classA_unknown
,
2177 { "Parameter", "x25.facility.classA_unknown", FT_UINT8
, BASE_HEX
, NULL
, 0,
2178 "Facility Class A unknown parameter", HFILL
}},
2179 { &hf_x25_facility_classB
,
2180 { "Code", "x25.facility.classB", FT_UINT8
, BASE_HEX
, VALS(x25_facilities_classB_vals
), 0,
2181 "Facility ClassB Code", HFILL
}},
2182 { &hf_x25_facility_classB_bilateral_cug
,
2183 { "Bilateral CUG", "x25.facility.bilateral_cug", FT_UINT16
, BASE_HEX
, NULL
, 0,
2184 "Facility Bilateral CUG", HFILL
}},
2185 { &hf_x25_facility_packet_size_called_dte
,
2186 { "From the called DTE", "x25.facility.packet_size.called_dte", FT_UINT8
, BASE_DEC
, VALS(x25_facilities_classB_packet_size_vals
), 0,
2187 "Facility Packet size from the called DTE", HFILL
}},
2188 { &hf_x25_facility_packet_size_calling_dte
,
2189 { "From the calling DTE", "x25.facility.packet_size.calling_dte", FT_UINT8
, BASE_DEC
, VALS(x25_facilities_classB_packet_size_vals
), 0,
2190 "Facility Packet size from the calling DTE", HFILL
}},
2191 { &hf_x25_facility_data_network_id_code
,
2192 { "Data network identification code", "x25.facility.data_network_id_code", FT_UINT16
, BASE_HEX
, NULL
, 0,
2193 "Facility RPOA selection data network identification code", HFILL
}},
2194 { &hf_x25_facility_cug_ext
,
2195 { "Closed user group", "x25.facility.cug_ext", FT_UINT16
, BASE_HEX
, NULL
, 0,
2196 "Facility Extended closed user group selection", HFILL
}},
2197 { &hf_x25_facility_cug_outgoing_acc_ext
,
2198 { "Closed user group", "x25.facility.cug_outgoing_acc_ext", FT_UINT16
, BASE_HEX
, NULL
, 0,
2199 "Facility Extended closed user group with outgoing access selection", HFILL
}},
2200 { &hf_x25_facility_transit_delay
,
2201 { "Transit delay (ms)", "x25.facility.transit_delay", FT_UINT16
, BASE_DEC
, NULL
, 0,
2202 "Facility Transit delay selection and indication", HFILL
}},
2203 { &hf_x25_facility_classB_unknown
,
2204 { "Parameter", "x25.facility.classB_unknown", FT_UINT16
, BASE_HEX
, NULL
, 0,
2205 "Facility Class B unknown parameter", HFILL
}},
2206 { &hf_x25_facility_classC_unknown
,
2207 { "Parameter", "x25.facility.classC_unknown", FT_UINT24
, BASE_HEX
, NULL
, 0,
2208 "Facility Class C unknown parameter", HFILL
}},
2209 { &hf_x25_facility_classC
,
2210 { "Code", "x25.facility.classC", FT_UINT8
, BASE_HEX
, VALS(x25_facilities_classC_vals
), 0,
2211 "Facility ClassC Code", HFILL
}},
2212 { &hf_x25_facility_classD
,
2213 { "Code", "x25.facility.classD", FT_UINT8
, BASE_HEX
, VALS(x25_facilities_classD_vals
), 0,
2214 "Facility ClassD Code", HFILL
}},
2216 { "GFI", "x25.gfi", FT_UINT16
, BASE_DEC
, NULL
, 0xF000,
2217 "General format identifier", HFILL
}},
2219 { "A Bit", "x25.a", FT_BOOLEAN
, 16, NULL
, X25_ABIT
,
2220 "Address Bit", HFILL
}},
2222 { "Q Bit", "x25.q", FT_BOOLEAN
, 16, NULL
, X25_QBIT
,
2223 "Qualifier Bit", HFILL
}},
2225 { "D Bit", "x25.d", FT_BOOLEAN
, 16, NULL
, X25_DBIT
,
2226 "Delivery Confirmation Bit", HFILL
}},
2228 { "Modulo", "x25.mod", FT_UINT16
, BASE_DEC
, VALS(vals_modulo
), 0x3000,
2229 "Specifies whether the frame is modulo 8 or 128", HFILL
}},
2231 { "Logical Channel", "x25.lcn", FT_UINT16
, BASE_DEC
, NULL
, 0x0FFF,
2232 "Logical Channel Number", HFILL
}},
2234 { "Packet Type", "x25.type", FT_UINT8
, BASE_HEX
, VALS(vals_x25_type
), 0x0,
2236 { &hf_x25_type_fc_mod8
,
2237 { "Packet Type", "x25.type", FT_UINT8
, BASE_HEX
, VALS(vals_x25_type
), 0x1F,
2239 { &hf_x25_type_data
,
2240 { "Packet Type", "x25.type", FT_UINT8
, BASE_HEX
, VALS(vals_x25_type
), 0x01,
2242 { &hf_x25_diagnostic
,
2243 { "Diagnostic", "x25.diagnostic", FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &x25_clear_diag_vals_ext
, 0,
2246 { "P(R)", "x25.p_r", FT_UINT8
, BASE_DEC
, NULL
, 0xE0,
2247 "Packet Receive Sequence Number", HFILL
}},
2248 { &hf_x25_p_r_mod128
,
2249 { "P(R)", "x25.p_r", FT_UINT8
, BASE_DEC
, NULL
, 0xFE,
2250 "Packet Receive Sequence Number", HFILL
}},
2251 { &hf_x25_mbit_mod8
,
2252 { "M Bit", "x25.m", FT_BOOLEAN
, 8, TFS(&m_bit_tfs
), X25_MBIT_MOD8
,
2253 "More Bit", HFILL
}},
2254 { &hf_x25_mbit_mod128
,
2255 { "M Bit", "x25.m", FT_BOOLEAN
, 8, TFS(&m_bit_tfs
), X25_MBIT_MOD128
,
2256 "More Bit", HFILL
}},
2258 { "P(S)", "x25.p_s", FT_UINT8
, BASE_DEC
, NULL
, 0x0E,
2259 "Packet Send Sequence Number", HFILL
}},
2260 { &hf_x25_p_s_mod128
,
2261 { "P(S)", "x25.p_s", FT_UINT8
, BASE_DEC
, NULL
, 0xFE,
2262 "Packet Send Sequence Number", HFILL
}},
2263 { &hf_x25_window_size_called_dte
,
2264 { "From the called DTE", "x25.window_size.called_dte", FT_UINT8
, BASE_DEC
, NULL
, 0x7F,
2266 { &hf_x25_window_size_calling_dte
,
2267 { "From the calling DTE", "x25.window_size.calling_dte", FT_UINT8
, BASE_DEC
, NULL
, 0x7F,
2269 { &hf_x25_dte_address_length
,
2270 { "DTE address length", "x25.dte_address_length", FT_UINT8
, BASE_DEC
, NULL
, 0xF0,
2272 { &hf_x25_dce_address_length
,
2273 { "DCE address length", "x25.dce_address_length", FT_UINT8
, BASE_DEC
, NULL
, 0x0F,
2275 { &hf_x25_calling_address_length
,
2276 { "Calling address length", "x25.calling_address_length", FT_UINT8
, BASE_DEC
, NULL
, 0xF0,
2278 { &hf_x25_called_address_length
,
2279 { "Called address length", "x25.called_address_length", FT_UINT8
, BASE_DEC
, NULL
, 0x0F,
2281 { &hf_x25_facility_call_transfer_reason
,
2282 { "Reason", "x25.facility.call_transfer_reason", FT_UINT8
, BASE_DEC
, VALS(x25_facilities_call_transfer_reason_vals
), 0,
2284 { &hf_x25_facility_monetary_unit
,
2285 { "Monetary unit", "x25.facility.monetary_unit", FT_BYTES
, BASE_NONE
, NULL
, 0,
2287 { &hf_x25_facility_nui
,
2288 { "NUI", "x25.facility.nui", FT_BYTES
, BASE_NONE
, NULL
, 0,
2290 { &hf_x25_facility_cumulative_ete_transit_delay
,
2291 { "Cumulative end-to-end transit delay (ms)", "x25.facility.cumulative_ete_transit_delay", FT_UINT16
, BASE_DEC
, NULL
, 0,
2293 { &hf_x25_facility_requested_ete_transit_delay
,
2294 { "Requested end-to-end transit delay (ms)", "x25.facility.requested_ete_transit_delay", FT_UINT16
, BASE_DEC
, NULL
, 0,
2296 { &hf_x25_facility_max_acceptable_ete_transit_delay
,
2297 { "Maximum acceptable end-to-end transit delay (ms)", "x25.facility.mac_acceptable_ete_transit_delay", FT_UINT16
, BASE_DEC
, NULL
, 0,
2299 { &hf_x25_facility_priority_data
,
2300 { "Priority for data", "x25.facility.priority_data", FT_UINT8
, BASE_DEC
, NULL
, 0,
2302 { &hf_x25_facility_priority_estab_conn
,
2303 { "Priority for establishing connection", "x25.facility.priority_estab_conn", FT_UINT8
, BASE_DEC
, NULL
, 0,
2305 { &hf_x25_facility_priority_keep_conn
,
2306 { "Priority for keeping connection", "x25.facility.priority_keep_conn", FT_UINT8
, BASE_DEC
, NULL
, 0,
2308 { &hf_x25_facility_min_acceptable_priority_data
,
2309 { "Minimum acceptable priority for data", "x25.facility.min_acceptable_priority_data", FT_UINT8
, BASE_DEC
, NULL
, 0,
2311 { &hf_x25_facility_min_acceptable_priority_estab_conn
,
2312 { "Minimum acceptable priority for establishing connection", "x25.facility.min_acceptable_priority_estab_conn", FT_UINT8
, BASE_DEC
, NULL
, 0,
2314 { &hf_x25_facility_min_acceptable_priority_keep_conn
,
2315 { "Minimum acceptable priority for keeping connection", "x25.facility.min_acceptable_priority_keep_conn", FT_UINT8
, BASE_DEC
, NULL
, 0,
2317 { &hf_x25_facility_classD_unknown
,
2318 { "Parameter", "x25.facility.classD_unknown", FT_BYTES
, BASE_NONE
, NULL
, 0,
2319 "Facility Class D unknown parameter", HFILL
}},
2320 { &hf_x25_facility_call_transfer_num_semi_octets
,
2321 { "Number of semi-octets in DTE address", "x25.facility.call_transfer_num_semi_octets", FT_UINT8
, BASE_DEC
, NULL
, 0,
2323 { &hf_x25_facility_calling_addr_ext_num_semi_octets
,
2324 { "Number of semi-octets in DTE address", "x25.facility.calling_addr_ext_num_semi_octets", FT_UINT8
, BASE_DEC
, NULL
, 0,
2326 { &hf_x25_facility_called_addr_ext_num_semi_octets
,
2327 { "Number of semi-octets in DTE address", "x25.facility.called_addr_ext_num_semi_octets", FT_UINT8
, BASE_DEC
, NULL
, 0,
2329 { &hf_x25_facility_call_deflect_num_semi_octets
,
2330 { "Number of semi-octets in the alternative DTE address", "x25.facility.call_deflect_num_semi_octets", FT_UINT8
, BASE_DEC
, NULL
, 0,
2332 { &hf_x264_length_indicator
,
2333 { "X.264 length indicator", "x25.x264_length_indicator", FT_UINT8
, BASE_DEC
, NULL
, 0,
2335 { &hf_x264_un_tpdu_id
,
2336 { "X.264 UN TPDU identifier", "x25.x264_un_tpdu_id", FT_UINT8
, BASE_HEX
, NULL
, 0,
2338 { &hf_x264_protocol_id
,
2339 { "X.264 protocol identifier", "x25.x264_protocol_id", FT_UINT8
, BASE_HEX
, VALS(prt_id_vals
), 0,
2341 { &hf_x264_sharing_strategy
,
2342 { "X.264 sharing strategy", "x25.x264_sharing_strategy", FT_UINT8
, BASE_HEX
, VALS(sharing_strategy_vals
), 0,
2344 { &hf_x263_sec_protocol_id
,
2345 { "X.263 secondary protocol ID", "x25.x263_sec_protocol_id", FT_UINT8
, BASE_HEX
, VALS(nlpid_vals
), 0,
2347 { &hf_x25_reg_request_length
,
2348 { "Registration length", "x25.reg_request_length", FT_UINT8
, BASE_DEC
, NULL
, 0x7F,
2350 { &hf_x25_reg_confirm_length
,
2351 { "Registration length", "x25.reg_confirm_length", FT_UINT8
, BASE_DEC
, NULL
, 0x7F,
2354 { &hf_x25_segment_overlap
,
2355 { "Fragment overlap", "x25.fragment.overlap", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
2356 "Fragment overlaps with other fragments", HFILL
}},
2358 { &hf_x25_segment_overlap_conflict
,
2359 { "Conflicting data in fragment overlap", "x25.fragment.overlap.conflict", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
2360 "Overlapping fragments contained conflicting data", HFILL
}},
2362 { &hf_x25_segment_multiple_tails
,
2363 { "Multiple tail fragments found", "x25.fragment.multipletails", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
2364 "Several tails were found when defragmenting the packet", HFILL
}},
2366 { &hf_x25_segment_too_long_segment
,
2367 { "Fragment too long", "x25.fragment.toolongfragment", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
2368 "Fragment contained data past end of packet", HFILL
}},
2370 { &hf_x25_segment_error
,
2371 { "Defragmentation error", "x25.fragment.error", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
2372 "Defragmentation error due to illegal fragments", HFILL
}},
2374 { &hf_x25_segment_count
,
2375 { "Fragment count", "x25.fragment.count", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2378 { &hf_x25_reassembled_length
,
2379 { "Reassembled X.25 length", "x25.reassembled.length", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2380 "The total length of the reassembled payload", HFILL
}},
2383 { "X.25 Fragment", "x25.fragment", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
2384 "X25 Fragment", HFILL
}},
2387 { "X.25 Fragments", "x25.fragments", FT_NONE
, BASE_NONE
, NULL
, 0x0,
2390 { &hf_x25_fast_select
,
2391 { "Fast select", "x25.fast_select", FT_UINT8
, BASE_DEC
, VALS(x25_fast_select_vals
), 0xC0,
2395 { "ICRD", "x25.icrd", FT_UINT8
, BASE_DEC
, VALS(x25_icrd_vals
), 0x30,
2398 { &hf_x25_reg_confirm_cause
,
2399 { "Cause", "x25.reg_confirm.cause", FT_UINT8
, BASE_DEC
, VALS(x25_registration_code_vals
), 0,
2402 { &hf_x25_reg_confirm_diagnostic
,
2403 { "Diagnostic", "x25.reg_confirm.diagnostic", FT_UINT8
, BASE_DEC
, VALS(x25_registration_code_vals
), 0,
2407 static gint
*ett
[] = {
2410 &ett_x25_facilities
,
2417 static ei_register_info ei
[] = {
2418 { &ei_x25_facility_length
, { "x25.facility_length.bogus", PI_PROTOCOL
, PI_WARN
, "Bogus length", EXPFILL
}},
2421 module_t
*x25_module
;
2422 expert_module_t
* expert_x25
;
2424 proto_x25
= proto_register_protocol ("X.25", "X.25", "x25");
2425 proto_register_field_array (proto_x25
, hf
, array_length(hf
));
2426 proto_register_subtree_array(ett
, array_length(ett
));
2427 expert_x25
= expert_register_protocol(proto_x25
);
2428 expert_register_field_array(expert_x25
, ei
, array_length(ei
));
2430 x25_subdissector_table
= register_dissector_table("x.25.spi",
2431 "X.25 secondary protocol identifier", FT_UINT8
, BASE_HEX
);
2432 register_heur_dissector_list("x.25", &x25_heur_subdissector_list
);
2434 register_dissector("x.25_dir", dissect_x25_dir
, proto_x25
);
2435 register_dissector("x.25", dissect_x25
, proto_x25
);
2438 x25_module
= prefs_register_protocol(proto_x25
, NULL
);
2439 prefs_register_obsolete_preference(x25_module
, "non_q_bit_is_sna");
2440 prefs_register_bool_preference(x25_module
, "payload_is_qllc_sna",
2441 "Default to QLLC/SNA",
2442 "If CALL REQUEST not seen or didn't specify protocol, dissect as QLLC/SNA",
2443 &payload_is_qllc_sna
);
2444 prefs_register_bool_preference(x25_module
, "call_request_nodata_is_cotp",
2445 "Assume COTP for Call Request without data",
2446 "If CALL REQUEST has no data, assume the protocol handled is COTP",
2447 &call_request_nodata_is_cotp
);
2448 prefs_register_bool_preference(x25_module
, "payload_check_data",
2449 "Check data for COTP/IP/CLNP",
2450 "If CALL REQUEST not seen or didn't specify protocol, check user data before checking heuristic dissectors",
2451 &payload_check_data
);
2452 prefs_register_bool_preference(x25_module
, "reassemble",
2453 "Reassemble fragmented X.25 packets",
2454 "Reassemble fragmented X.25 packets",
2456 register_init_routine(&x25_reassemble_init
);
2460 proto_reg_handoff_x25(void)
2462 dissector_handle_t x25_handle
;
2465 * Get handles for various dissectors.
2467 ip_handle
= find_dissector("ip");
2468 clnp_handle
= find_dissector("clnp");
2469 ositp_handle
= find_dissector("ositp");
2470 qllc_handle
= find_dissector("qllc");
2471 data_handle
= find_dissector("data");
2473 x25_handle
= find_dissector("x.25");
2474 dissector_add_uint("llc.dsap", SAP_X25
, x25_handle
);
2475 dissector_add_uint("lapd.sapi", LAPD_SAPI_X25
, x25_handle
);
2476 dissector_add_uint("ax25.pid", AX25_P_ROSE
, x25_handle
);