662ea531ba2f363d20e66b51024624f195eee704
[metze/wireshark/wip.git] / epan / dissectors / packet-x25.c
1 /* packet-x25.c
2  * Routines for X.25 packet disassembly
3  * Olivier Abad <oabad@noos.fr>
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998
10  *
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.
15  *
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.
20  *
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.
24  */
25
26 #include "config.h"
27
28 #include <string.h>
29
30 #include <glib.h>
31
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>
43
44 /*
45  * Direction of packet.
46  */
47 typedef enum {
48         X25_FROM_DCE,           /* DCE->DTE */
49         X25_FROM_DTE,           /* DTE->DCE */
50         X25_UNKNOWN             /* direction unknown */
51 } x25_dir_t;
52
53 /*
54  * 0 for data packets, 1 for non-data packets.
55  */
56 #define X25_NONDATA_BIT                 0x01
57
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
71 #define X25_RR                          0x01
72 #define X25_RNR                         0x05
73 #define X25_REJ                         0x09
74 #define X25_DATA                        0x00
75
76 #define PACKET_IS_DATA(type)            (!(type & X25_NONDATA_BIT))
77 #define PACKET_TYPE_FC(type)            (type & 0x1F)
78
79 #define X25_MBIT_MOD8                   0x10
80 #define X25_MBIT_MOD128                 0x01
81
82 #define X25_ABIT                        0x8000
83
84 #define X25_QBIT                        0x8000
85 #define X25_DBIT                        0x4000
86
87 #define X25_FAC_CLASS_MASK              0xC0
88
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
93
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
121
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;
199
200
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;
206
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;
222
223 static expert_field ei_x25_facility_length = EI_INIT;
224
225 static const value_string vals_modulo[] = {
226         { 1, "8" },
227         { 2, "128" },
228         { 0, NULL}
229 };
230
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" },
245         { X25_RR, "RR" },
246         { X25_RNR, "RNR" },
247         { X25_REJ, "REJ" },
248         { X25_DATA, "Data" },
249         { 0,   NULL}
250 };
251
252 static struct true_false_string m_bit_tfs = {
253         "More data follows",
254         "End of data"
255 };
256
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" },
262         { 0, NULL}
263 };
264
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" },
270         { 0, NULL}
271 };
272
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" },
377         { 0, NULL}
378 };
379
380 value_string_ext x25_clear_diag_vals_ext = VALUE_STRING_EXT_INIT(x25_clear_diag_vals);
381
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" },
387         { 0, NULL}
388 };
389
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" },
395         { 0, NULL}
396 };
397
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" },
408         { 0, NULL}
409 };
410
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" },
415         { 0, NULL}
416 };
417
418 static const value_string x25_facilities_classA_throughput_vals[] = {
419         { 3, "75 bps" },
420         { 4, "150 bps" },
421         { 5, "300 bps" },
422         { 6, "600 bps" },
423         { 7, "1200 bps" },
424         { 8, "2400 bps" },
425         { 9, "4800 bps" },
426         { 10, "9600 bps" },
427         { 11, "19200 bps" },
428         { 12, "48000 bps" },
429         { 13, "64000 bps" },
430         { 0, NULL}
431 };
432
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" },
441         { 0, NULL}
442 };
443
444 static const value_string x25_facilities_classB_packet_size_vals[] = {
445         { 0x04, "16" },
446         { 0x05, "32" },
447         { 0x06, "64" },
448         { 0x07, "128" },
449         { 0x08, "256" },
450         { 0x09, "512" },
451         { 0x0A, "1024" },
452         { 0x0B, "2048" },
453         { 0x0C, "4096" },
454         { 0, NULL}
455 };
456
457 static const value_string x25_facilities_classC_vals[] = {
458         { 0, NULL}
459 };
460
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" },
473         { 0, NULL}
474 };
475
476 static struct true_false_string x25_reverse_charging_val = {
477         "Requested",
478         "Not requested"
479 };
480
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" },
486         { 0, NULL}
487 };
488
489 static const fragment_items x25_frag_items = {
490         &ett_x25_segment,
491         &ett_x25_segments,
492         &hf_x25_segments,
493         &hf_x25_segment,
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,
500         NULL,
501         &hf_x25_reassembled_length,
502         /* Reassembled data field */
503         NULL,
504         "segments"
505 };
506
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;
512
513 /* Preferences */
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;
518
519 /* Reassembly of X.25 */
520
521 static reassembly_table x25_reassembly_table;
522
523 static dissector_table_t x25_subdissector_table;
524 static heur_dissector_list_t x25_heur_subdissector_list;
525
526 static void
527 x25_hash_add_proto_start(guint16 vc, guint32 frame, dissector_handle_t dissect)
528 {
529   circuit_t *circuit;
530
531   /*
532    * Is there already a circuit with this VC number?
533    */
534   circuit = find_circuit(CT_X25, vc, frame);
535   if (circuit != NULL) {
536     /*
537      * Yes - close it, as we're creating a new one.
538      */
539     close_circuit(circuit, frame - 1);
540   }
541
542   /*
543    * Set up a new circuit.
544    */
545   circuit = circuit_new(CT_X25, vc, frame);
546
547   /*
548    * Set its dissector.
549    */
550   circuit_set_dissector(circuit, dissect);
551 }
552
553 static void
554 x25_hash_add_proto_end(guint16 vc, guint32 frame)
555 {
556   circuit_t *circuit;
557
558   /*
559    * Try to find the circuit.
560    */
561   circuit = find_circuit(CT_X25, vc, frame);
562
563   /*
564    * If we succeeded, close it.
565    */
566   if (circuit != NULL)
567     close_circuit(circuit, frame);
568 }
569
570 static const char *clear_code(unsigned char code)
571 {
572         if (code == 0x00 || (code & 0x80) == 0x80)
573                 return "DTE Originated";
574
575         switch(code)
576         {
577         case  0x01:
578                 return "Number Busy";
579         case  0x03:
580                 return "Invalid Facility Requested";
581         case  0x05:
582                 return "Network Congestion";
583         case  0x09:
584                 return "Out Of Order";
585         case  0x0B:
586                 return "Access Barred";
587         case  0x0D:
588                 return "Not Obtainable";
589         case  0x11:
590                 return "Remote Procedure Error";
591         case  0x13:
592                 return "Local Procedure Error";
593         case  0x15:
594                 return "RPOA Out Of Order";
595         case  0x19:
596                 return "Reverse Charging Acceptance Not Subscribed";
597         case  0x21:
598                 return "Incompatible Destination";
599         case  0x29:
600                 return "Fast Select Acceptance Not Subscribed";
601         case  0x39:
602                 return "Destination Absent";
603         }
604
605         return wmem_strdup_printf(wmem_packet_scope(),"Unknown %02X", code);
606 }
607
608 static const char *reset_code(unsigned char code)
609 {
610         if (code == 0x00 || (code & 0x80) == 0x80)
611                 return "DTE Originated";
612
613         switch(code)
614         {
615         case 0x01:
616                 return "Out of order";
617         case 0x03:
618                 return "Remote Procedure Error";
619         case 0x05:
620                 return "Local Procedure Error";
621         case 0x07:
622                 return "Network Congestion";
623         case 0x09:
624                 return "Remote DTE operational";
625         case 0x0F:
626                 return "Network operational";
627         case 0x11:
628                 return "Incompatible Destination";
629         case 0x1D:
630                 return "Network out of order";
631         }
632
633         return wmem_strdup_printf(wmem_packet_scope(),"Unknown %02X", code);
634 }
635
636 static const char *restart_code(unsigned char code)
637 {
638         if (code == 0x00 || (code & 0x80) == 0x80)
639                 return "DTE Originated";
640
641         switch(code)
642         {
643         case 0x01:
644                 return "Local Procedure Error";
645         case 0x03:
646                 return "Network Congestion";
647         case 0x07:
648                 return "Network Operational";
649         case 0x7F:
650                 return "Registration/cancellation confirmed";
651         }
652
653         return wmem_strdup_printf(wmem_packet_scope(),"Unknown %02X", code);
654 }
655
656 static char *
657 dte_address_util(tvbuff_t *tvb, int offset, guint8 len)
658 {
659         int i;
660         char *tmpbuf = (char *)wmem_alloc(wmem_packet_scope(), 258);
661
662         for (i = 0; (i<len)&&(i<256); i++) {
663                 if (i % 2 == 0) {
664                         tmpbuf[i] = ((tvb_get_guint8(tvb, offset+i/2) >> 4) & 0x0F) + '0';
665                         /* if > 9, convert to the right hexadecimal letter */
666                         if (tmpbuf[i] > '9')
667                                 tmpbuf[i] += ('A' - '0' - 10);
668                 } else {
669                         tmpbuf[i] = (tvb_get_guint8(tvb, offset+i/2) & 0x0F) + '0';
670                         /* if > 9, convert to the right hexadecimal letter */
671                         if (tmpbuf[i] > '9')
672                                 tmpbuf[i] += ('A' - '0' - 10);
673                 }
674         }
675
676         tmpbuf[i] = '\0';
677
678         return tmpbuf;
679 }
680
681 static void
682 add_priority(proto_tree *tree, int hf, tvbuff_t *tvb, int offset)
683 {
684         guint8 priority;
685
686         priority = tvb_get_guint8(tvb, offset);
687         if (priority == 255)
688                 proto_tree_add_uint_format_value(tree, hf, tvb, offset, 1, priority,
689                     "Unspecified (255)");
690         else
691                 proto_tree_add_uint(tree, hf, tvb, offset, 1, priority);
692 }
693
694 static void
695 dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb, packet_info *pinfo)
696 {
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;
701
702         len = tvb_get_guint8(tvb, *offset);
703         if (len && tree) {
704                 ti = proto_tree_add_text(tree, tvb, *offset, len + 1,
705                                                          "Facilities");
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);
708         }
709         (*offset)++;
710
711         while (len > 0) {
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);
722                         if (facility_tree) {
723                                 switch (fac) {
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);
726                                         break;
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);
732                                         break;
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);
736                                         break;
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);
740                                         break;
741                                 case X25_FAC_CUG:
742                                         proto_tree_add_item(facility_tree, hf_x25_facility_classA_cug, tvb, *offset+1, 1, ENC_NA);
743                                         break;
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);
746                                         break;
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);
749                                         break;
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);
752                                         break;
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);
755                                         break;
756                                 default:
757                                         proto_tree_add_item(facility_tree, hf_x25_facility_classA_unknown, tvb, *offset+1, 1, ENC_NA);
758                                         break;
759                                 }
760                         }
761                         (*offset) += 2;
762                         len -= 2;
763                         break;
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);
771                         if (facility_tree) {
772                                 switch (fac) {
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);
775                                         break;
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);
779                                         break;
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);
783                                         break;
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);
786                                         break;
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);
789                                         break;
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);
792                                         break;
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);
795                                         break;
796                                 default:
797                                         proto_tree_add_item(facility_tree, hf_x25_facility_classB_unknown, tvb, *offset+1, 2, ENC_BIG_ENDIAN);
798                                         break;
799                                 }
800                         }
801                         (*offset) += 3;
802                         len -= 3;
803                         break;
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);
811                         if (facility_tree) {
812                                 proto_tree_add_item(facility_tree, hf_x25_facility_classC_unknown, tvb, *offset+1, 2, ENC_BIG_ENDIAN);
813                         }
814                         (*offset) += 4;
815                         len -= 4;
816                         break;
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);
826                         if (facility_tree) {
827                                 switch (fac) {
828                                 case X25_FAC_CALL_DURATION:
829                                         {
830                                         int i;
831
832                                         if ((byte1 < 4) || (byte1 % 4)) {
833                                                 expert_add_info(pinfo, ti, &ei_x25_facility_length);
834                                                 return;
835                                         }
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));
843                                         }
844                                         }
845                                         break;
846                                 case X25_FAC_SEGMENT_COUNT:
847                                         {
848                                         int i;
849
850                                         if ((byte1 < 8) || (byte1 % 8)) {
851                                                 expert_add_info(pinfo, ti, &ei_x25_facility_length);
852                                                 return;
853                                         }
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));
867                                         }
868                                         }
869                                         break;
870                                 case X25_FAC_CALL_TRANSFER:
871                                         {
872                                         char *tmpbuf;
873
874                                         if (byte1 < 2) {
875                                                 expert_add_info(pinfo, ti, &ei_x25_facility_length);
876                                                 return;
877                                         }
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");
882                                         }
883                                         else {
884                                                 proto_tree_add_uint(facility_tree, hf_x25_facility_call_transfer_reason, tvb, *offset+2, 1, byte2);
885                                         }
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);
889
890                                         proto_tree_add_text(facility_tree, tvb, *offset+4, byte1 - 2,
891                                                 "DTE address: %s", tmpbuf);
892                                         }
893                                         break;
894                                 case X25_FAC_RPOA_SELECTION_EXT:
895                                         {
896                                         int i;
897
898                                         if ((byte1 < 2) || (byte1 % 2)) {
899                                                 expert_add_info(pinfo, ti, &ei_x25_facility_length);
900                                                 return;
901                                         }
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));
906                                         }
907                                         }
908                                         break;
909                                 case X25_FAC_CALLING_ADDR_EXT:
910                                         {
911                                         char *tmpbuf;
912
913                                         if (byte1 < 1) {
914                                                 expert_add_info(pinfo, ti, &ei_x25_facility_length);
915                                                 return;
916                                         }
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);
922                                         }
923                                         break;
924                                 case X25_FAC_MONETARY_UNIT:
925                                         proto_tree_add_item(facility_tree, hf_x25_facility_monetary_unit, tvb, *offset+2, byte1, ENC_NA);
926                                         break;
927                                 case X25_FAC_NUI:
928                                         proto_tree_add_item(facility_tree, hf_x25_facility_nui, tvb, *offset+2, byte1, ENC_NA);
929                                         break;
930                                 case X25_FAC_CALLED_ADDR_EXT:
931                                         {
932                                         char *tmpbuf;
933
934                                         if (byte1 < 1) {
935                                                 expert_add_info(pinfo, ti, &ei_x25_facility_length);
936                                                 return;
937                                         }
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);
941
942                                         proto_tree_add_text(facility_tree, tvb, *offset+3, byte1 - 1,
943                                                 "DTE address: %s", tmpbuf);
944                                         }
945                                         break;
946                                 case X25_FAC_ETE_TRANSIT_DELAY:
947                                         if (byte1 < 2)
948                                                 break;
949                                         proto_tree_add_item(facility_tree, hf_x25_facility_cumulative_ete_transit_delay, tvb, *offset+2, 2, ENC_BIG_ENDIAN);
950                                         if (byte1 < 4)
951                                                 break;
952                                         proto_tree_add_item(facility_tree, hf_x25_facility_requested_ete_transit_delay, tvb, *offset+4, 2, ENC_BIG_ENDIAN);
953                                         if (byte1 < 6)
954                                                 break;
955                                         proto_tree_add_item(facility_tree, hf_x25_facility_max_acceptable_ete_transit_delay, tvb, *offset+6, 2, ENC_BIG_ENDIAN);
956                                         break;
957                                 case X25_FAC_CALL_DEFLECT:
958                                         {
959                                         char *tmpbuf;
960
961                                         if (byte1 < 2) {
962                                                 expert_add_info(pinfo, ti, &ei_x25_facility_length);
963                                                 return;
964                                         }
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");
969                                         else
970                                                 proto_tree_add_text(facility_tree, tvb, *offset+2, 1,
971                                                         "Reason: unknown");
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);
975
976                                         proto_tree_add_text(facility_tree, tvb, *offset+4, byte1 - 2,
977                                                 "Alternative DTE address: %s", tmpbuf);
978                                         }
979                                         break;
980                                 case X25_FAC_PRIORITY:
981                                         if (byte1 < 1)
982                                                 break;
983                                         add_priority(facility_tree, hf_x25_facility_priority_data, tvb, *offset+2);
984                                         if (byte1 < 2)
985                                                 break;
986                                         add_priority(facility_tree, hf_x25_facility_priority_estab_conn, tvb, *offset+3);
987                                         if (byte1 < 3)
988                                                 break;
989                                         add_priority(facility_tree, hf_x25_facility_priority_keep_conn, tvb, *offset+4);
990                                         if (byte1 < 4)
991                                                 break;
992                                         add_priority(facility_tree, hf_x25_facility_min_acceptable_priority_data, tvb, *offset+5);
993                                         if (byte1 < 5)
994                                                 break;
995                                         add_priority(facility_tree, hf_x25_facility_min_acceptable_priority_estab_conn, tvb, *offset+6);
996                                         if (byte1 < 6)
997                                                 break;
998                                         add_priority(facility_tree, hf_x25_facility_min_acceptable_priority_keep_conn, tvb, *offset+7);
999                                         break;
1000                                 default:
1001                                         proto_tree_add_item(facility_tree, hf_x25_facility_classD_unknown, tvb, *offset+2, byte1, ENC_NA);
1002                                 }
1003                         }
1004                         byte1 = tvb_get_guint8(tvb, *offset+1);
1005                         (*offset) += byte1+2;
1006                         len -= byte1+2;
1007                         break;
1008                 }
1009         }
1010 }
1011
1012 static void
1013 x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1014          packet_info *pinfo, gboolean is_registration)
1015 {
1016     int len1, len2;
1017     int i;
1018     char *addr1, *addr2;
1019     char *first, *second;
1020     guint8 byte;
1021     int localoffset;
1022
1023     addr1=(char *)wmem_alloc(wmem_packet_scope(), 16);
1024     addr2=(char *)wmem_alloc(wmem_packet_scope(), 16);
1025
1026     byte = tvb_get_guint8(tvb, *offset);
1027     len1 = (byte >> 0) & 0x0F;
1028     len2 = (byte >> 4) & 0x0F;
1029
1030     if (tree) {
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);
1034         }
1035         else {
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);
1038         }
1039     }
1040     (*offset)++;
1041
1042     localoffset = *offset;
1043     byte = tvb_get_guint8(tvb, localoffset);
1044
1045     first=addr1;
1046     second=addr2;
1047     for (i = 0; i < (len1 + len2); i++) {
1048         if (i < len1) {
1049             if (i % 2 != 0) {
1050                 *first++ = ((byte >> 0) & 0x0F) + '0';
1051                 localoffset++;
1052                 byte = tvb_get_guint8(tvb, localoffset);
1053             } else {
1054                 *first++ = ((byte >> 4) & 0x0F) + '0';
1055             }
1056         } else {
1057             if (i % 2 != 0) {
1058                 *second++ = ((byte >> 0) & 0x0F) + '0';
1059                 localoffset++;
1060                 byte = tvb_get_guint8(tvb, localoffset);
1061             } else {
1062                 *second++ = ((byte >> 4) & 0x0F) + '0';
1063             }
1064         }
1065     }
1066
1067     *first  = '\0';
1068     *second = '\0';
1069
1070     if (len1) {
1071         col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1);
1072         if (tree)
1073             proto_tree_add_text(tree, tvb, *offset,
1074                                 (len1 + 1) / 2,
1075                                 is_registration ?
1076                                   "DCE address: %s" :
1077                                   "Called address: %s",
1078                                 addr1);
1079     }
1080     if (len2) {
1081         col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2);
1082         if (tree)
1083             proto_tree_add_text(tree, tvb, *offset + len1/2,
1084                                 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1085                                 is_registration ?
1086                                   "DTE address: %s" :
1087                                   "Calling address: %s",
1088                                 addr2);
1089     }
1090     (*offset) += ((len1 + len2 + 1) / 2);
1091 }
1092
1093 static void
1094 x25_toa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1095         packet_info *pinfo)
1096 {
1097     int len1, len2;
1098     int i;
1099     char *addr1, *addr2;
1100     char *first, *second;
1101     guint8 byte;
1102     int localoffset;
1103
1104     addr1=(char *)wmem_alloc(wmem_packet_scope(), 256);
1105     addr2=(char *)wmem_alloc(wmem_packet_scope(), 256);
1106
1107     len1 = tvb_get_guint8(tvb, *offset);
1108     if (tree) {
1109         proto_tree_add_text(tree, tvb, *offset, 1,
1110                     "Called address length: %u",
1111                     len1);
1112     }
1113     (*offset)++;
1114
1115     len2 = tvb_get_guint8(tvb, *offset);
1116     if (tree) {
1117         proto_tree_add_text(tree, tvb, *offset, 1,
1118                     "Calling address length: %u",
1119                     len2);
1120     }
1121     (*offset)++;
1122
1123     localoffset = *offset;
1124     byte = tvb_get_guint8(tvb, localoffset);
1125
1126     /*
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).
1131      */
1132     first=addr1;
1133     second=addr2;
1134     for (i = 0; i < (len1 + len2); i++) {
1135         if (i < len1) {
1136             if (i % 2 != 0) {
1137                 *first++ = ((byte >> 0) & 0x0F) + '0';
1138                 localoffset++;
1139                 byte = tvb_get_guint8(tvb, localoffset);
1140             } else {
1141                 *first++ = ((byte >> 4) & 0x0F) + '0';
1142             }
1143         } else {
1144             if (i % 2 != 0) {
1145                 *second++ = ((byte >> 0) & 0x0F) + '0';
1146                 localoffset++;
1147                 byte = tvb_get_guint8(tvb, localoffset);
1148             } else {
1149                 *second++ = ((byte >> 4) & 0x0F) + '0';
1150             }
1151         }
1152     }
1153
1154     *first  = '\0';
1155     *second = '\0';
1156
1157     if (len1) {
1158         col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1);
1159         if (tree)
1160             proto_tree_add_text(tree, tvb, *offset,
1161                                 (len1 + 1) / 2,
1162                                 "Called address: %s",
1163                                 addr1);
1164     }
1165     if (len2) {
1166         col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2);
1167         if (tree)
1168             proto_tree_add_text(tree, tvb, *offset + len1/2,
1169                                 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1170                                 "Calling address: %s",
1171                                 addr2);
1172     }
1173     (*offset) += ((len1 + len2 + 1) / 2);
1174 }
1175
1176 static int
1177 get_x25_pkt_len(tvbuff_t *tvb)
1178 {
1179     guint length, called_len, calling_len, dte_len, dce_len;
1180     guint8 byte2, bytex;
1181
1182     byte2 = tvb_get_guint8(tvb, 2);
1183     switch (byte2)
1184     {
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 */
1192
1193         return MIN(tvb_reported_length(tvb),length);
1194
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
1198          * to read it */
1199         if (tvb_reported_length(tvb) == 3)
1200             return(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 */
1207
1208         return MIN(tvb_reported_length(tvb),length);
1209
1210     case X25_CLEAR_REQUEST:
1211     case X25_RESET_REQUEST:
1212     case X25_RESTART_REQUEST:
1213         return MIN(tvb_reported_length(tvb),5);
1214
1215     case X25_DIAGNOSTIC:
1216         return MIN(tvb_reported_length(tvb),4);
1217
1218     case X25_CLEAR_CONFIRMATION:
1219     case X25_INTERRUPT:
1220     case X25_INTERRUPT_CONFIRMATION:
1221     case X25_RESET_CONFIRMATION:
1222     case X25_RESTART_CONFIRMATION:
1223         return MIN(tvb_reported_length(tvb),3);
1224
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 */
1232
1233         return MIN(tvb_reported_length(tvb),length);
1234
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 */
1242
1243         return MIN(tvb_reported_length(tvb),length);
1244     }
1245
1246     if (PACKET_IS_DATA(byte2))
1247         return MIN(tvb_reported_length(tvb),3);
1248
1249     switch (PACKET_TYPE_FC(byte2))
1250     {
1251     case X25_RR:
1252         return MIN(tvb_reported_length(tvb),3);
1253
1254     case X25_RNR:
1255         return MIN(tvb_reported_length(tvb),3);
1256
1257     case X25_REJ:
1258         return MIN(tvb_reported_length(tvb),3);
1259     }
1260
1261     return 0;
1262 }
1263
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"},
1269         {0x00,                      NULL}
1270 };
1271
1272 static const value_string sharing_strategy_vals[] = {
1273         {0x00,            "No sharing"},
1274         {0x00,            NULL}
1275 };
1276
1277 static void
1278 dissect_x25_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1279     x25_dir_t dir, gboolean side)
1280 {
1281     proto_tree *x25_tree=0, *gfi_tree=0, *userdata_tree=0;
1282     proto_item *ti;
1283     guint localoffset=0;
1284     guint x25_pkt_len;
1285     int modulo;
1286     guint16 vc;
1287     dissector_handle_t dissect = NULL;
1288     gboolean toa;         /* TOA/NPI address format */
1289     guint16 bytes0_1;
1290     guint8 pkt_type;
1291     const char *short_name = NULL, *long_name = NULL;
1292     tvbuff_t *next_tvb = NULL;
1293     gboolean q_bit_set = FALSE;
1294     gboolean m_bit_set;
1295     gint payload_len;
1296     guint32 frag_key;
1297     void *saved_private_data;
1298     fragment_head *fd_head;
1299
1300
1301     guint8 spi;
1302     int is_x_264;
1303     guint8 prt_id;
1304     col_set_str(pinfo->cinfo, COL_PROTOCOL, "X.25");
1305     col_clear(pinfo->cinfo, COL_INFO);
1306
1307     bytes0_1 = tvb_get_ntohs(tvb, 0);
1308
1309     modulo = ((bytes0_1 & 0x2000) ? 128 : 8);
1310     vc     = (int)(bytes0_1 & 0x0FFF);
1311
1312     pinfo->ctype = CT_X25;
1313     pinfo->circuit_id = vc;
1314
1315     if (bytes0_1 & X25_ABIT) toa = TRUE;
1316     else toa = FALSE;
1317
1318     x25_pkt_len = get_x25_pkt_len(tvb);
1319     if (x25_pkt_len < 3) /* packet too short */
1320     {
1321         col_set_str(pinfo->cinfo, COL_INFO, "Invalid/short X.25 packet");
1322         if (tree)
1323             proto_tree_add_protocol_format(tree, proto_x25, tvb, 0, -1,
1324                     "Invalid/short X.25 packet");
1325         return;
1326     }
1327
1328     pkt_type = tvb_get_guint8(tvb, 2);
1329     if (PACKET_IS_DATA(pkt_type)) {
1330         if (bytes0_1 & X25_QBIT)
1331             q_bit_set = TRUE;
1332     }
1333
1334     if (tree) {
1335         ti = proto_tree_add_item(tree, proto_x25, tvb, 0, x25_pkt_len, ENC_NA);
1336         x25_tree = proto_item_add_subtree(ti, ett_x25);
1337         ti = proto_tree_add_item(x25_tree, hf_x25_gfi, tvb, 0, 2, ENC_BIG_ENDIAN);
1338         gfi_tree = proto_item_add_subtree(ti, ett_x25_gfi);
1339
1340         if (PACKET_IS_DATA(pkt_type)) {
1341             proto_tree_add_boolean(gfi_tree, hf_x25_qbit, tvb, 0, 2,
1342                 bytes0_1);
1343         }
1344         else if (pkt_type == X25_CALL_REQUEST ||
1345             pkt_type == X25_CALL_ACCEPTED ||
1346             pkt_type == X25_CLEAR_REQUEST ||
1347             pkt_type == X25_CLEAR_CONFIRMATION) {
1348             proto_tree_add_boolean(gfi_tree, hf_x25_abit, tvb, 0, 2,
1349                 bytes0_1);
1350         }
1351
1352         if (pkt_type == X25_CALL_REQUEST || pkt_type == X25_CALL_ACCEPTED ||
1353             PACKET_IS_DATA(pkt_type)) {
1354             proto_tree_add_boolean(gfi_tree, hf_x25_dbit, tvb, 0, 2,
1355                 bytes0_1);
1356         }
1357         proto_tree_add_uint(gfi_tree, hf_x25_mod, tvb, 0, 2, bytes0_1);
1358     }
1359
1360     switch (pkt_type) {
1361     case X25_CALL_REQUEST:
1362         switch (dir) {
1363
1364         case X25_FROM_DCE:
1365             short_name = "Inc. call";
1366             long_name = "Incoming call";
1367             break;
1368
1369         case X25_FROM_DTE:
1370             short_name = "Call req.";
1371             long_name = "Call request";
1372             break;
1373
1374         case X25_UNKNOWN:
1375             short_name = "Inc. call/Call req.";
1376             long_name = "Incoming call/Call request";
1377             break;
1378         }
1379         col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
1380         if (x25_tree) {
1381             proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb,
1382                     0, 2, bytes0_1);
1383             proto_tree_add_uint_format_value(x25_tree, hf_x25_type, tvb, 2, 1,
1384                     X25_CALL_REQUEST, "%s", long_name);
1385         }
1386         localoffset = 3;
1387         if (localoffset < x25_pkt_len) { /* calling/called addresses */
1388             if (toa)
1389                 x25_toa(x25_tree, (gint*)&localoffset, tvb, pinfo);
1390             else
1391                 x25_ntoa(x25_tree, (gint*)&localoffset, tvb, pinfo, FALSE);
1392         }
1393
1394         if (localoffset < x25_pkt_len) /* facilities */
1395             dump_facilities(x25_tree, (gint*)&localoffset, tvb, pinfo);
1396
1397         if (localoffset < tvb_reported_length(tvb)) /* user data */
1398         {
1399
1400             if (x25_tree) {
1401                 ti = proto_tree_add_text(x25_tree, tvb, localoffset, -1,
1402                         "User data");
1403                 userdata_tree = proto_item_add_subtree(ti, ett_x25_user_data);
1404             }
1405
1406             /* X.263/ISO 9577 says that:
1407
1408                     When CLNP or ESIS are run over X.25, the SPI
1409                     is 0x81 or 0x82, respectively; those are the
1410                     NLPIDs for those protocol.
1411
1412                     When X.224/ISO 8073 COTP is run over X.25, and
1413                     when ISO 11570 explicit identification is being
1414                     used, the first octet of the user data field is
1415                     a TPDU length field, and the rest is "as defined
1416                     in ITU-T Rec. X.225 | ISO/IEC 8073, Annex B,
1417                     or ITU-T Rec. X.264 and ISO/IEC 11570".
1418
1419                     When X.264/ISO 11570 default identification is
1420                     being used, there is no user data field in the
1421                     CALL REQUEST packet.  This is for X.225/ISO 8073
1422                     COTP.
1423
1424                It also says that SPI values from 0x03 through 0x3f are
1425                reserved and are in use by X.224/ISO 8073 Annex B and
1426                X.264/ISO 11570.  The note says that those values are
1427                not NLPIDs, they're "used by the respective higher layer
1428                protocol" and "not used for higher layer protocol
1429                identification".  I infer from this and from what
1430                X.264/ISO 11570 says that this means that values in those
1431                range are valid values for the first octet of an
1432                X.224/ISO 8073 packet or for X.264/ISO 11570.
1433
1434                Annex B of X.225/ISO 8073 mentions some additional TPDU
1435                types that can be put in what I presume is the user
1436                data of connect requests.  It says that:
1437
1438                     The sending transport entity shall:
1439
1440                         a) either not transmit any TPDU in the NS-user data
1441                            parameter of the N-CONNECT request primitive; or
1442
1443                         b) transmit the UN-TPDU (see ITU-T Rec. X.264 and
1444                            ISO/IEC 11570) followed by the NCM-TPDU in the
1445                            NS-user data parameter of the N-CONNECT request
1446                            primitive.
1447
1448                I don't know if this means that the user data field
1449                will contain a UN TPDU followed by an NCM TPDU or not.
1450
1451                X.264/ISO 11570 says that:
1452
1453                     When default identification is being used,
1454                     X.225/ISO 8073 COTP is identified.  No user data
1455                     is sent in the network-layer connection request.
1456
1457                     When explicit identification is being used,
1458                     the user data is a UN TPDU ("Use of network
1459                     connection TPDU"), which specifies the transport
1460                     protocol to use over this network connection.
1461                     It also says that the length of a UN TPDU shall
1462                     not exceed 32 octets, i.e. shall not exceed 0x20;
1463                     it says this is "due to the desire not to conflict
1464                     with the protocol identifier field carried by X.25
1465                     CALL REQUEST/INCOMING CALL packets", and says that
1466                     field has values specified in X.244.  X.244 has been
1467                     superseded by X.263/ISO 9577, so that presumably
1468                     means the goal is to allow a UN TPDU's length
1469                     field to be distinguished from an NLPID, allowing
1470                     you to tell whether X.264/ISO 11570 explicit
1471                     identification is being used or an NLPID is
1472                     being used as the SPI.
1473
1474                I read this as meaning that, if the ISO mechanisms are
1475                used to identify the protocol being carried over X.25:
1476
1477                     if there's no user data in the CALL REQUEST/
1478                     INCOMING CALL packet, it's COTP;
1479
1480                     if there is user data, then:
1481
1482                         if the first octet is less than or equal to
1483                         32, it might be a UN TPDU, and that identifies
1484                         the transport protocol being used, and
1485                         it may be followed by more data, such
1486                         as a COTP NCM TPDU if it's COTP;
1487
1488                         if the first octet is greater than 32, it's
1489                         an NLPID, *not* a TPDU length, and the
1490                         stuff following it is *not* a TPDU.
1491
1492                Figure A.2 of X.263/ISO 9577 seems to say that the
1493                first octet of the user data is a TPDU length field,
1494                in the range 0x03 through 0x82, and says they are
1495                for X.225/ISO 8073 Annex B or X.264/ISO 11570.
1496
1497                However, X.264/ISO 11570 seems to imply that the length
1498                field would be that of a UN TPDU, which must be less
1499                than or equal to 0x20, and X.225/ISO 8073 Annex B seems
1500                to indicate that the user data must begin with
1501                an X.264/ISO 11570 UN TPDU, so I'd say that A.2 should
1502                have said "in the range 0x03 through 0x20", instead
1503                (the length value doesn't include the length field,
1504                and the minimum UN TPDU has length, type, PRT-ID,
1505                and SHARE, so that's 3 bytes without the length). */
1506             spi = tvb_get_guint8(tvb, localoffset);
1507             if (spi > 32 || spi < 3) {
1508                 /* First octet is > 32, or < 3, so the user data isn't an
1509                    X.264/ISO 11570 UN TPDU */
1510                 is_x_264 = FALSE;
1511             } else {
1512                 /* First octet is >= 3 and <= 32, so the user data *might*
1513                    be an X.264/ISO 11570 UN TPDU.  Check whether we have
1514                    enough data to see if it is. */
1515                 if (tvb_bytes_exist(tvb, localoffset+1, 1)) {
1516                     /* We do; check whether the second octet is 1. */
1517                     if (tvb_get_guint8(tvb, localoffset+1) == 0x01) {
1518                         /* Yes, the second byte is 1, so it looks like
1519                            a UN TPDU. */
1520                         is_x_264 = TRUE;
1521                     } else {
1522                         /* No, the second byte is not 1, so it's not a
1523                            UN TPDU. */
1524                         is_x_264 = FALSE;
1525                     }
1526                 } else {
1527                     /* We can't see the second byte of the putative UN
1528                        TPDU, so we don't know if that's what it is. */
1529                     is_x_264 = -1;
1530                 }
1531             }
1532             if (is_x_264 == -1) {
1533                 /*
1534                  * We don't know what it is; just skip it.
1535                  */
1536                 localoffset = tvb_length(tvb);
1537             } else if (is_x_264) {
1538                 /* It looks like an X.264 UN TPDU, so show it as such. */
1539                 if (userdata_tree) {
1540                         proto_tree_add_item( userdata_tree, hf_x264_length_indicator, tvb, localoffset, 1, ENC_NA);
1541                         proto_tree_add_item( userdata_tree, hf_x264_un_tpdu_id, tvb, localoffset+1, 1, ENC_NA);
1542                 }
1543                 prt_id = tvb_get_guint8(tvb, localoffset+2);
1544                 if (userdata_tree) {
1545                         proto_tree_add_item( userdata_tree, hf_x264_protocol_id, tvb, localoffset+2, 1, ENC_NA);
1546                         proto_tree_add_item( userdata_tree, hf_x264_sharing_strategy, tvb, localoffset+3, 1, ENC_NA);
1547                 }
1548
1549                 /* XXX - dissect the variable part? */
1550
1551                 /* The length doesn't include the length octet itself. */
1552                 localoffset += spi + 1;
1553
1554                 switch (prt_id) {
1555
1556                 case PRT_ID_ISO_8073:
1557                     /* ISO 8073 COTP */
1558                     if (!pinfo->fd->flags.visited)
1559                         x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
1560                     /* XXX - dissect the rest of the user data as COTP?
1561                        That needs support for NCM TPDUs, etc. */
1562                     break;
1563
1564                 case PRT_ID_ISO_8602:
1565                     /* ISO 8602 CLTP */
1566                     if (!pinfo->fd->flags.visited)
1567                         x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
1568                     break;
1569                 }
1570             } else if (is_x_264 == 0) {
1571                 /* It doesn't look like a UN TPDU, so compare the first
1572                    octet of the CALL REQUEST packet with various X.263/
1573                    ISO 9577 NLPIDs, as per Annex A of X.263/ISO 9577. */
1574
1575                 if (userdata_tree) {
1576                         proto_tree_add_item( userdata_tree, hf_x263_sec_protocol_id, tvb, localoffset, 1, ENC_NA);
1577                 }
1578
1579                 if (!pinfo->fd->flags.visited) {
1580                     /*
1581                      * Is there a dissector handle for this SPI?
1582                      * If so, assign it to this virtual circuit.
1583                      */
1584                     dissect = dissector_get_uint_handle(x25_subdissector_table, spi);
1585                     if (dissect != NULL)
1586                         x25_hash_add_proto_start(vc, pinfo->fd->num, dissect);
1587                 }
1588
1589                 /*
1590                  * If there's only one octet of user data, it's just
1591                  * an NLPID; don't try to dissect it.
1592                  */
1593                 if (localoffset + 1 == tvb_reported_length(tvb))
1594                     return;
1595
1596                 /*
1597                  * There's more than one octet of user data, so we'll
1598                  * dissect it; for some protocols, the NLPID is considered
1599                  * to be part of the PDU, so, for those cases, we don't
1600                  * skip past it.  For other protocols, we skip the NLPID.
1601                  */
1602                 switch (spi) {
1603
1604                 case NLPID_ISO8473_CLNP:
1605                 case NLPID_ISO9542_ESIS:
1606                 case NLPID_ISO10589_ISIS:
1607                 case NLPID_ISO10747_IDRP:
1608                 case NLPID_SNDCF:
1609                     /*
1610                      * The NLPID is part of the PDU.  Don't skip it.
1611                      * But if it's all there is to the PDU, don't
1612                      * bother dissecting it.
1613                      */
1614                     break;
1615
1616                 case NLPID_SPI_X_29:
1617                     /*
1618                      * The first 4 bytes of the call user data are
1619                      * the SPI plus 3 reserved bytes; they are not
1620                      * part of the data to be dissected as X.29 data.
1621                      */
1622                     localoffset += 4;
1623                     break;
1624
1625                 default:
1626                     /*
1627                      * The NLPID isn't part of the PDU - skip it.
1628                      * If that means there's nothing to dissect
1629                      */
1630                     localoffset++;
1631                 }
1632             }
1633         } else {
1634           /* if there's no user data in the CALL REQUEST/
1635              INCOMING CALL packet, it's COTP; */
1636
1637            if (call_request_nodata_is_cotp){
1638               x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
1639            }
1640         }
1641         break;
1642     case X25_CALL_ACCEPTED:
1643         switch (dir) {
1644
1645         case X25_FROM_DCE:
1646             short_name = "Call conn.";
1647             long_name = "Call connected";
1648             break;
1649
1650         case X25_FROM_DTE:
1651             short_name = "Call acc.";
1652             long_name = "Call accepted";
1653             break;
1654
1655         case X25_UNKNOWN:
1656             short_name = "Call conn./Call acc.";
1657             long_name = "Call connected/Call accepted";
1658             break;
1659         }
1660         col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
1661         if (x25_tree) {
1662             proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1663             proto_tree_add_uint_format_value(x25_tree, hf_x25_type, tvb, 2, 1,
1664                     X25_CALL_ACCEPTED, "%s", long_name);
1665         }
1666         localoffset = 3;
1667         if (localoffset < x25_pkt_len) { /* calling/called addresses */
1668             if (toa)
1669                 x25_toa(x25_tree, (gint*)&localoffset, tvb, pinfo);
1670             else
1671                 x25_ntoa(x25_tree, (gint*)&localoffset, tvb, pinfo, FALSE);
1672         }
1673
1674         if (localoffset < x25_pkt_len) /* facilities */
1675             dump_facilities(x25_tree, (gint*)&localoffset, tvb, pinfo);
1676         break;
1677     case X25_CLEAR_REQUEST:
1678         switch (dir) {
1679
1680         case X25_FROM_DCE:
1681             short_name = "Clear ind.";
1682             long_name = "Clear indication";
1683             break;
1684
1685         case X25_FROM_DTE:
1686             short_name = "Clear req.";
1687             long_name = "Clear request";
1688             break;
1689
1690         case X25_UNKNOWN:
1691             short_name = "Clear ind./Clear req.";
1692             long_name = "Clear indication/Clear request";
1693             break;
1694         }
1695         col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - %s", short_name,
1696                     vc, clear_code(tvb_get_guint8(tvb, 3)),
1697                     val_to_str_ext(tvb_get_guint8(tvb, 4), &x25_clear_diag_vals_ext, "Unknown (0x%02x)"));
1698         x25_hash_add_proto_end(vc, pinfo->fd->num);
1699         if (x25_tree) {
1700             proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1701             proto_tree_add_uint_format_value(x25_tree, hf_x25_type, tvb,
1702                     localoffset+2, 1, X25_CLEAR_REQUEST, "%s",
1703                     long_name);
1704             proto_tree_add_text(x25_tree, tvb, 3, 1,
1705                     "Cause: %s", clear_code(tvb_get_guint8(tvb, 3)));
1706             proto_tree_add_item(x25_tree, hf_x25_diagnostic, tvb, 4, 1, ENC_NA);
1707         }
1708         localoffset = x25_pkt_len;
1709         break;
1710     case X25_CLEAR_CONFIRMATION:
1711         col_add_fstr(pinfo->cinfo, COL_INFO, "Clear Conf. VC:%d", vc);
1712         if (x25_tree) {
1713             proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1714             proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1715                     X25_CLEAR_CONFIRMATION);
1716         }
1717         localoffset = x25_pkt_len;
1718
1719         if (localoffset < tvb_reported_length(tvb)) { /* extended clear conf format */
1720             if (toa)
1721                 x25_toa(x25_tree, (gint*)&localoffset, tvb, pinfo);
1722             else
1723                 x25_ntoa(x25_tree,(gint*)&localoffset, tvb, pinfo, FALSE);
1724         }
1725
1726         if (localoffset < tvb_reported_length(tvb)) /* facilities */
1727             dump_facilities(x25_tree, (gint*)&localoffset, tvb, pinfo);
1728         break;
1729     case X25_DIAGNOSTIC:
1730         col_add_fstr(pinfo->cinfo, COL_INFO, "Diag. %d",
1731                     (int)tvb_get_guint8(tvb, 3));
1732         if (x25_tree) {
1733             proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1734                     X25_DIAGNOSTIC);
1735             proto_tree_add_text(x25_tree, tvb, 3, 1,
1736                     "Diagnostic: %d", (int)tvb_get_guint8(tvb, 3));
1737         }
1738         localoffset = x25_pkt_len;
1739         break;
1740     case X25_INTERRUPT:
1741         col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt VC:%d", vc);
1742         if (x25_tree) {
1743             proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1744             proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1745                     X25_INTERRUPT);
1746         }
1747         localoffset = x25_pkt_len;
1748         break;
1749     case X25_INTERRUPT_CONFIRMATION:
1750         col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt Conf. VC:%d", vc);
1751         if (x25_tree) {
1752             proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1753             proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1754                     X25_INTERRUPT_CONFIRMATION);
1755         }
1756         localoffset = x25_pkt_len;
1757         break;
1758     case X25_RESET_REQUEST:
1759         switch (dir) {
1760
1761         case X25_FROM_DCE:
1762             short_name = "Reset ind.";
1763             long_name = "Reset indication";
1764             break;
1765
1766         case X25_FROM_DTE:
1767             short_name = "Reset req.";
1768             long_name = "Reset request";
1769             break;
1770
1771         case X25_UNKNOWN:
1772             short_name = "Reset ind./Reset req.";
1773             long_name = "Reset indication/Reset request";
1774             break;
1775         }
1776         col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - Diag.:%d",
1777                     short_name, vc, reset_code(tvb_get_guint8(tvb, 3)),
1778                     (int)tvb_get_guint8(tvb, 4));
1779         x25_hash_add_proto_end(vc, pinfo->fd->num);
1780         if (x25_tree) {
1781             proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1782             proto_tree_add_uint_format_value(x25_tree, hf_x25_type, tvb, 2, 1,
1783                     X25_RESET_REQUEST, "%s", long_name);
1784             proto_tree_add_text(x25_tree, tvb, 3, 1,
1785                     "Cause: %s", reset_code(tvb_get_guint8(tvb, 3)));
1786             proto_tree_add_text(x25_tree, tvb, 4, 1,
1787                     "Diagnostic: %d", (int)tvb_get_guint8(tvb, 4));
1788         }
1789         localoffset = x25_pkt_len;
1790         break;
1791     case X25_RESET_CONFIRMATION:
1792         col_add_fstr(pinfo->cinfo, COL_INFO, "Reset conf. VC:%d", vc);
1793         if (x25_tree) {
1794             proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1795             proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1796                     X25_RESET_CONFIRMATION);
1797         }
1798         localoffset = x25_pkt_len;
1799         break;
1800         case X25_RESTART_REQUEST:
1801         switch (dir) {
1802
1803         case X25_FROM_DCE:
1804             short_name = "Restart ind.";
1805             long_name = "Restart indication";
1806             break;
1807
1808         case X25_FROM_DTE:
1809             short_name = "Restart req.";
1810             long_name = "Restart request";
1811             break;
1812
1813         case X25_UNKNOWN:
1814             short_name = "Restart ind./Restart req.";
1815             long_name = "Restart indication/Restart request";
1816             break;
1817         }
1818         col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s - Diag.:%d",
1819                     short_name,
1820                     restart_code(tvb_get_guint8(tvb, 3)),
1821                     (int)tvb_get_guint8(tvb, 4));
1822         if (x25_tree) {
1823             proto_tree_add_uint_format_value(x25_tree, hf_x25_type, tvb, 2, 1,
1824                     X25_RESTART_REQUEST, "%s", long_name);
1825             proto_tree_add_text(x25_tree, tvb, 3, 1,
1826                     "Cause: %s", restart_code(tvb_get_guint8(tvb, 3)));
1827             proto_tree_add_text(x25_tree, tvb, 4, 1,
1828                     "Diagnostic: %d", (int)tvb_get_guint8(tvb, 4));
1829         }
1830         localoffset = x25_pkt_len;
1831         break;
1832     case X25_RESTART_CONFIRMATION:
1833         col_set_str(pinfo->cinfo, COL_INFO, "Restart conf.");
1834         if (x25_tree)
1835             proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1836                     X25_RESTART_CONFIRMATION);
1837         localoffset = x25_pkt_len;
1838         break;
1839     case X25_REGISTRATION_REQUEST:
1840         col_set_str(pinfo->cinfo, COL_INFO, "Registration req.");
1841         if (x25_tree)
1842             proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1843                     X25_REGISTRATION_REQUEST);
1844         localoffset = 3;
1845         if (localoffset < x25_pkt_len)
1846             x25_ntoa(x25_tree, (gint*)&localoffset, tvb, pinfo, TRUE);
1847
1848         if (x25_tree) {
1849                 if (localoffset < x25_pkt_len)
1850                         proto_tree_add_item( x25_tree, hf_x25_reg_request_length, tvb, localoffset, 1, ENC_NA);
1851                 if (localoffset+1 < x25_pkt_len)
1852                         proto_tree_add_text(x25_tree, tvb, localoffset+1,
1853                                 tvb_get_guint8(tvb, localoffset) & 0x7F,
1854                                 "Registration");
1855         }
1856         localoffset = tvb_reported_length(tvb);
1857         break;
1858     case X25_REGISTRATION_CONFIRMATION:
1859         col_set_str(pinfo->cinfo, COL_INFO, "Registration conf.");
1860         if (x25_tree) {
1861             proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1862                     X25_REGISTRATION_CONFIRMATION);
1863             proto_tree_add_item(x25_tree, hf_x25_reg_confirm_cause, tvb, 3, 1, ENC_NA);
1864             proto_tree_add_item(x25_tree, hf_x25_reg_confirm_diagnostic, tvb, 4, 1, ENC_NA);
1865         }
1866         localoffset = 5;
1867         if (localoffset < x25_pkt_len)
1868             x25_ntoa(x25_tree, (gint*)&localoffset, tvb, pinfo, TRUE);
1869
1870         if (x25_tree) {
1871                 if (localoffset < x25_pkt_len)
1872                         proto_tree_add_item( x25_tree, hf_x25_reg_confirm_length, tvb, localoffset, 1, ENC_NA);
1873                 if (localoffset+1 < x25_pkt_len)
1874                         proto_tree_add_text(x25_tree, tvb, localoffset+1,
1875                                 tvb_get_guint8(tvb, localoffset) & 0x7F,
1876                                 "Registration");
1877         }
1878         localoffset = tvb_reported_length(tvb);
1879         break;
1880     default:
1881         localoffset = 2;
1882         if (x25_tree) {
1883             proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
1884                                 2, bytes0_1);
1885         }
1886         if (PACKET_IS_DATA(pkt_type)) {
1887             if (modulo == 8)
1888                 col_add_fstr(pinfo->cinfo, COL_INFO,
1889                             "Data VC:%d P(S):%d P(R):%d %s", vc,
1890                             (pkt_type >> 1) & 0x07,
1891                             (pkt_type >> 5) & 0x07,
1892                             (pkt_type & X25_MBIT_MOD8) ? " M" : "");
1893             else
1894                 col_add_fstr(pinfo->cinfo, COL_INFO,
1895                             "Data VC:%d P(S):%d P(R):%d %s", vc,
1896                             tvb_get_guint8(tvb, localoffset+1) >> 1,
1897                             pkt_type >> 1,
1898                             (tvb_get_guint8(tvb, localoffset+1) & X25_MBIT_MOD128) ? " M" : "");
1899             if (x25_tree) {
1900                 if (modulo == 8) {
1901                     proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
1902                             localoffset, 1, pkt_type);
1903                     proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod8, tvb,
1904                             localoffset, 1, pkt_type);
1905                     proto_tree_add_uint(x25_tree, hf_x25_p_s_mod8, tvb,
1906                             localoffset, 1, pkt_type);
1907                     proto_tree_add_uint(x25_tree, hf_x25_type_data, tvb,
1908                             localoffset, 1, pkt_type);
1909                 }
1910                 else {
1911                     proto_tree_add_uint(x25_tree, hf_x25_p_r_mod128, tvb,
1912                             localoffset, 1, pkt_type);
1913                     proto_tree_add_uint(x25_tree, hf_x25_type_data, tvb,
1914                             localoffset, 1, pkt_type);
1915                     proto_tree_add_uint(x25_tree, hf_x25_p_s_mod128, tvb,
1916                             localoffset+1, 1,
1917                             tvb_get_guint8(tvb, localoffset+1));
1918                     proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod128, tvb,
1919                             localoffset+1, 1,
1920                             tvb_get_guint8(tvb, localoffset+1));
1921                 }
1922             }
1923             if (modulo == 8) {
1924                 m_bit_set = pkt_type & X25_MBIT_MOD8;
1925                 localoffset += 1;
1926             } else {
1927                 m_bit_set = tvb_get_guint8(tvb, localoffset+1) & X25_MBIT_MOD128;
1928                 localoffset += 2;
1929             }
1930             payload_len = tvb_reported_length_remaining(tvb, localoffset);
1931             if (reassemble_x25) {
1932                 /*
1933                  * Reassemble received and sent traffic separately.
1934                  * We don't reassemble traffic with an unknown direction
1935                  * at all.
1936                  */
1937                 frag_key = vc;
1938                 if (side) {
1939                     /*
1940                      * OR in an extra bit to distinguish from traffic
1941                      * in the other direction.
1942                      */
1943                     frag_key |= 0x10000;
1944                 }
1945                 fd_head = fragment_add_seq_next(&x25_reassembly_table,
1946                                                 tvb, localoffset,
1947                                                 pinfo, frag_key, NULL,
1948                                                 payload_len, m_bit_set);
1949                 pinfo->fragmented = m_bit_set;
1950
1951                 /* Fragment handling is not adapted to handle several x25
1952                  * packets in the same frame. This is common with XOT and
1953                  * shorter packet sizes.
1954                  * Therefore, fragment_add_seq_next seem to always return fd_head
1955                  * A fix to use m_bit_set to only show fragments for last pkt
1956                  */
1957                 if (!m_bit_set && fd_head) {
1958                     if (fd_head->next) {
1959                         proto_item *frag_tree_item;
1960
1961                         /* This is the last packet */
1962                         next_tvb = tvb_new_chain(tvb, fd_head->tvb_data);
1963                         add_new_data_source(pinfo, next_tvb, "Reassembled X.25");
1964                         if (x25_tree) {
1965                            show_fragment_seq_tree(fd_head,
1966                                                   &x25_frag_items,
1967                                                   x25_tree,
1968                                                   pinfo, next_tvb, &frag_tree_item);
1969                         }
1970                     }
1971                 }
1972
1973                 if (m_bit_set && next_tvb == NULL) {
1974                     /*
1975                      * This isn't the last packet, so just
1976                      * show it as X.25 user data.
1977                      */
1978                     proto_tree_add_text(x25_tree, tvb, localoffset, -1,
1979                         "User data (%u byte%s)", payload_len,
1980                         plurality(payload_len, "", "s"));
1981                     return;
1982                 }
1983             }
1984         } else {
1985             /*
1986              * Non-data packets (RR, RNR, REJ).
1987              */
1988             if (modulo == 8) {
1989                 if (x25_tree) {
1990                     proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
1991                             localoffset, 1, pkt_type);
1992                     proto_tree_add_item(x25_tree, hf_x25_type_fc_mod8, tvb,
1993                                         localoffset, 1, ENC_NA);
1994                 }
1995                 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d P(R):%d",
1996                              val_to_str(PACKET_TYPE_FC(pkt_type), vals_x25_type, "Unknown (0x%02X)"),
1997                              vc, (pkt_type >> 5) & 0x07);
1998                 localoffset += 1;
1999             } else {
2000                 if (x25_tree) {
2001                     proto_tree_add_item(x25_tree, hf_x25_type, tvb,
2002                                         localoffset, 1, ENC_NA);
2003                     proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2004                                         localoffset+1, 1, ENC_NA);
2005                 }
2006                 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d P(R):%d",
2007                              val_to_str(PACKET_TYPE_FC(pkt_type), vals_x25_type, "Unknown (0x%02X)"),
2008                              vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2009                 localoffset += 2;
2010             }
2011         }
2012         break;
2013     }
2014
2015     if (localoffset >= tvb_reported_length(tvb))
2016       return;
2017     if (pinfo->fragmented)
2018       return;
2019
2020     if (!next_tvb)
2021       next_tvb = tvb_new_subset_remaining(tvb, localoffset);
2022
2023     saved_private_data = pinfo->private_data;
2024     pinfo->private_data = &q_bit_set;
2025
2026     /* See if there's already a dissector for this circuit. */
2027     if (try_circuit_dissector(CT_X25, vc, pinfo->fd->num, next_tvb, pinfo,
2028                               tree, NULL)) {
2029         pinfo->private_data = saved_private_data;
2030         return; /* found it and dissected it */
2031     }
2032
2033     /* Did the user suggest QLLC/SNA? */
2034     if (payload_is_qllc_sna) {
2035         /* Yes - dissect it as QLLC/SNA. */
2036         if (!pinfo->fd->flags.visited)
2037             x25_hash_add_proto_start(vc, pinfo->fd->num, qllc_handle);
2038         call_dissector(qllc_handle, next_tvb, pinfo, tree);
2039         pinfo->private_data = saved_private_data;
2040         return;
2041     }
2042
2043     if (payload_check_data){
2044     /* If the Call Req. has not been captured, let's look at the first
2045        two bytes of the payload to see if this looks like COTP. */
2046     if (tvb_get_guint8(tvb, localoffset) == tvb_length(next_tvb)-1) {
2047       /* First byte contains the length of the remaining buffer */
2048       if ((tvb_get_guint8(tvb, localoffset+1) & 0x0F) == 0) {
2049         /* Second byte contains a valid COTP TPDU */
2050         if (!pinfo->fd->flags.visited)
2051             x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
2052         call_dissector(ositp_handle, next_tvb, pinfo, tree);
2053         pinfo->private_data = saved_private_data;
2054         return;
2055       }
2056     }
2057
2058     /* Then let's look at the first byte of the payload to see if this
2059        looks like IP or CLNP. */
2060     switch (tvb_get_guint8(tvb, localoffset)) {
2061
2062     case 0x45:
2063         /* Looks like an IP header */
2064         if (!pinfo->fd->flags.visited)
2065             x25_hash_add_proto_start(vc, pinfo->fd->num, ip_handle);
2066         call_dissector(ip_handle, next_tvb, pinfo, tree);
2067         pinfo->private_data = saved_private_data;
2068         return;
2069
2070     case NLPID_ISO8473_CLNP:
2071         if (!pinfo->fd->flags.visited)
2072             x25_hash_add_proto_start(vc, pinfo->fd->num, clnp_handle);
2073         call_dissector(clnp_handle, next_tvb, pinfo, tree);
2074         pinfo->private_data = saved_private_data;
2075         return;
2076     }
2077     }
2078
2079     /* Try the heuristic dissectors. */
2080     if (dissector_try_heuristic(x25_heur_subdissector_list, next_tvb, pinfo,
2081                                 tree, NULL)) {
2082         pinfo->private_data = saved_private_data;
2083         return;
2084     }
2085
2086     /* All else failed; dissect it as raw data */
2087     call_dissector(data_handle, next_tvb, pinfo, tree);
2088     pinfo->private_data = saved_private_data;
2089 }
2090
2091 /*
2092  * X.25 dissector for use when "pinfo->pseudo_header" points to a
2093  * "struct x25_phdr".
2094  */
2095 static void
2096 dissect_x25_dir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2097 {
2098     dissect_x25_common(tvb, pinfo, tree,
2099         (pinfo->pseudo_header->x25.flags & FROM_DCE) ? X25_FROM_DCE :
2100                                                        X25_FROM_DTE,
2101         pinfo->pseudo_header->x25.flags & FROM_DCE);
2102 }
2103
2104 /*
2105  * X.25 dissector for use when "pinfo->pseudo_header" doesn't point to a
2106  * "struct x25_phdr".
2107  */
2108 static void
2109 dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2110 {
2111     int direction;
2112
2113     /*
2114      * We don't know if this packet is DTE->DCE or DCE->DCE.
2115      * However, we can, at least, distinguish between the two
2116      * sides of the conversation, based on the addresses and
2117      * ports.
2118      */
2119     direction = CMP_ADDRESS(&pinfo->src, &pinfo->dst);
2120     if (direction == 0)
2121         direction = (pinfo->srcport > pinfo->destport)*2 - 1;
2122     dissect_x25_common(tvb, pinfo, tree, X25_UNKNOWN, direction > 0);
2123 }
2124
2125 static void
2126 x25_reassemble_init(void)
2127 {
2128   reassembly_table_init(&x25_reassembly_table,
2129                         &addresses_reassembly_table_functions);
2130 }
2131
2132 void
2133 proto_register_x25(void)
2134 {
2135     static hf_register_info hf[] = {
2136         { &hf_x25_facility,
2137           { "Facility", "x25.facility", FT_NONE, BASE_NONE, NULL, 0,
2138                 NULL, HFILL }},
2139         { &hf_x25_facilities_length,
2140           { "Facilities Length", "x25.facilities_length", FT_UINT8, BASE_DEC, NULL, 0,
2141                 NULL, HFILL }},
2142         { &hf_x25_facility_length,
2143           { "Length", "x25.facility_length", FT_UINT8, BASE_DEC, NULL, 0,
2144                 NULL, HFILL }},
2145         { &hf_x25_facility_class,
2146           { "Facility Class", "x25.facility.class", FT_UINT8, BASE_HEX, VALS(x25_facilities_class_vals), X25_FAC_CLASS_MASK,
2147                 NULL, HFILL }},
2148         { &hf_x25_facility_classA,
2149           { "Code", "x25.facility.classA", FT_UINT8, BASE_HEX, VALS(x25_facilities_classA_vals), 0,
2150                 "Facility ClassA Code", HFILL }},
2151         { &hf_x25_facility_classA_comp_mark,
2152           { "Parameter", "x25.facility.comp_mark", FT_UINT8, BASE_DEC, VALS(x25_facilities_classA_comp_mark_vals), 0,
2153                 "Facility Marker Parameter", HFILL }},
2154         { &hf_x25_facility_classA_reverse,
2155           { "Parameter", "x25.facility.reverse", FT_UINT8, BASE_HEX, NULL, 0,
2156                 "Facility Reverse Charging Parameter", HFILL }},
2157         { &hf_x25_facility_classA_charging_info,
2158           { "Parameter", "x25.facility.charging_info", FT_UINT8, BASE_HEX, NULL, 0,
2159                 "Facility Charging Information Parameter", HFILL }},
2160         { &hf_x25_facility_reverse_charging,
2161           { "Reverse charging", "x25.reverse_charging", FT_BOOLEAN, 8, TFS(&x25_reverse_charging_val), 0x01,
2162             NULL, HFILL }},
2163         { &hf_x25_facility_charging_info,
2164           { "Charging information", "x25.charging_info", FT_BOOLEAN, 8, TFS(&tfs_requested_not_requested), 0x01,
2165             NULL, HFILL }},
2166         { &hf_x25_facility_throughput_called_dte,
2167           { "From the called DTE", "x25.facility.throughput.called_dte", FT_UINT8, BASE_DEC, VALS(x25_facilities_classA_throughput_vals), 0xF0,
2168                 "Facility Throughput called DTE", HFILL }},
2169         { &hf_x25_throughput_called_dte,
2170           { "From the calling DTE", "x25.facility.throughput.called_dte", FT_UINT8, BASE_DEC, VALS(x25_facilities_classA_throughput_vals), 0x0F,
2171                 "Facility Throughput called DTE", HFILL }},
2172         { &hf_x25_facility_classA_cug,
2173           { "Closed user group", "x25.facility.cug", FT_UINT8, BASE_HEX, NULL, 0,
2174                 "Facility Closed user group", HFILL }},
2175         { &hf_x25_facility_classA_called_motif,
2176           { "Parameter", "x25.facility.called_motif", FT_UINT8, BASE_HEX, NULL, 0,
2177                 "Facility Called address modified parameter", HFILL }},
2178         { &hf_x25_facility_classA_cug_outgoing_acc,
2179           { "Closed user group", "x25.facility.cug_outgoing_acc", FT_UINT8, BASE_HEX, NULL, 0,
2180                 "Facility Closed user group with outgoing access selection", HFILL }},
2181         { &hf_x25_facility_classA_throughput_min,
2182           { "Parameter", "x25.facility.throughput_min", FT_UINT8, BASE_HEX, NULL, 0,
2183                 "Facility Minimum throughput class parameter", HFILL }},
2184         { &hf_x25_facility_classA_express_data,
2185           { "Parameter", "x25.facility.express_data", FT_UINT8, BASE_HEX, NULL, 0,
2186                 "Facility Negotiation of express data parameter", HFILL }},
2187         { &hf_x25_facility_classA_unknown,
2188           { "Parameter", "x25.facility.classA_unknown", FT_UINT8, BASE_HEX, NULL, 0,
2189                 "Facility Class A unknown parameter", HFILL }},
2190         { &hf_x25_facility_classB,
2191           { "Code", "x25.facility.classB", FT_UINT8, BASE_HEX, VALS(x25_facilities_classB_vals), 0,
2192                 "Facility ClassB Code", HFILL }},
2193         { &hf_x25_facility_classB_bilateral_cug,
2194           { "Bilateral CUG", "x25.facility.bilateral_cug", FT_UINT16, BASE_HEX, NULL, 0,
2195                 "Facility Bilateral CUG", HFILL }},
2196         { &hf_x25_facility_packet_size_called_dte,
2197           { "From the called DTE", "x25.facility.packet_size.called_dte", FT_UINT8, BASE_DEC, VALS(x25_facilities_classB_packet_size_vals), 0,
2198                 "Facility Packet size from the called DTE", HFILL }},
2199         { &hf_x25_facility_packet_size_calling_dte,
2200           { "From the calling DTE", "x25.facility.packet_size.calling_dte", FT_UINT8, BASE_DEC, VALS(x25_facilities_classB_packet_size_vals), 0,
2201                 "Facility Packet size from the calling DTE", HFILL }},
2202         { &hf_x25_facility_data_network_id_code,
2203           { "Data network identification code", "x25.facility.data_network_id_code", FT_UINT16, BASE_HEX, NULL, 0,
2204                 "Facility RPOA selection data network identification code", HFILL }},
2205         { &hf_x25_facility_cug_ext,
2206           { "Closed user group", "x25.facility.cug_ext", FT_UINT16, BASE_HEX, NULL, 0,
2207                 "Facility Extended closed user group selection", HFILL }},
2208         { &hf_x25_facility_cug_outgoing_acc_ext,
2209           { "Closed user group", "x25.facility.cug_outgoing_acc_ext", FT_UINT16, BASE_HEX, NULL, 0,
2210                 "Facility Extended closed user group with outgoing access selection", HFILL }},
2211         { &hf_x25_facility_transit_delay,
2212           { "Transit delay (ms)", "x25.facility.transit_delay", FT_UINT16, BASE_DEC, NULL, 0,
2213                 "Facility Transit delay selection and indication", HFILL }},
2214         { &hf_x25_facility_classB_unknown,
2215           { "Parameter", "x25.facility.classB_unknown", FT_UINT16, BASE_HEX, NULL, 0,
2216                 "Facility Class B unknown parameter", HFILL }},
2217         { &hf_x25_facility_classC_unknown,
2218           { "Parameter", "x25.facility.classC_unknown", FT_UINT24, BASE_HEX, NULL, 0,
2219                 "Facility Class C unknown parameter", HFILL }},
2220         { &hf_x25_facility_classC,
2221           { "Code", "x25.facility.classC", FT_UINT8, BASE_HEX, VALS(x25_facilities_classC_vals), 0,
2222                 "Facility ClassC Code", HFILL }},
2223         { &hf_x25_facility_classD,
2224           { "Code", "x25.facility.classD", FT_UINT8, BASE_HEX, VALS(x25_facilities_classD_vals), 0,
2225                 "Facility ClassD Code", HFILL }},
2226         { &hf_x25_gfi,
2227           { "GFI", "x25.gfi", FT_UINT16, BASE_DEC, NULL, 0xF000,
2228                 "General format identifier", HFILL }},
2229         { &hf_x25_abit,
2230           { "A Bit", "x25.a", FT_BOOLEAN, 16, NULL, X25_ABIT,
2231                 "Address Bit", HFILL }},
2232         { &hf_x25_qbit,
2233           { "Q Bit", "x25.q", FT_BOOLEAN, 16, NULL, X25_QBIT,
2234                 "Qualifier Bit", HFILL }},
2235         { &hf_x25_dbit,
2236           { "D Bit", "x25.d", FT_BOOLEAN, 16, NULL, X25_DBIT,
2237                 "Delivery Confirmation Bit", HFILL }},
2238         { &hf_x25_mod,
2239           { "Modulo", "x25.mod", FT_UINT16, BASE_DEC, VALS(vals_modulo), 0x3000,
2240                 "Specifies whether the frame is modulo 8 or 128", HFILL }},
2241         { &hf_x25_lcn,
2242           { "Logical Channel", "x25.lcn", FT_UINT16, BASE_DEC, NULL, 0x0FFF,
2243                 "Logical Channel Number", HFILL }},
2244         { &hf_x25_type,
2245           { "Packet Type", "x25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x0,
2246                 NULL, HFILL }},
2247         { &hf_x25_type_fc_mod8,
2248           { "Packet Type", "x25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x1F,
2249                 NULL, HFILL }},
2250         { &hf_x25_type_data,
2251           { "Packet Type", "x25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x01,
2252                 NULL, HFILL }},
2253         { &hf_x25_diagnostic,
2254           { "Diagnostic", "x25.diagnostic", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &x25_clear_diag_vals_ext, 0,
2255                 NULL, HFILL }},
2256         { &hf_x25_p_r_mod8,
2257           { "P(R)", "x25.p_r", FT_UINT8, BASE_DEC, NULL, 0xE0,
2258                 "Packet Receive Sequence Number", HFILL }},
2259         { &hf_x25_p_r_mod128,
2260           { "P(R)", "x25.p_r", FT_UINT8, BASE_DEC, NULL, 0xFE,
2261                 "Packet Receive Sequence Number", HFILL }},
2262         { &hf_x25_mbit_mod8,
2263           { "M Bit", "x25.m", FT_BOOLEAN, 8, TFS(&m_bit_tfs), X25_MBIT_MOD8,
2264                 "More Bit", HFILL }},
2265         { &hf_x25_mbit_mod128,
2266           { "M Bit", "x25.m", FT_BOOLEAN, 8, TFS(&m_bit_tfs), X25_MBIT_MOD128,
2267                 "More Bit", HFILL }},
2268         { &hf_x25_p_s_mod8,
2269           { "P(S)", "x25.p_s", FT_UINT8, BASE_DEC, NULL, 0x0E,
2270                 "Packet Send Sequence Number", HFILL }},
2271         { &hf_x25_p_s_mod128,
2272           { "P(S)", "x25.p_s", FT_UINT8, BASE_DEC, NULL, 0xFE,
2273                 "Packet Send Sequence Number", HFILL }},
2274         { &hf_x25_window_size_called_dte,
2275           { "From the called DTE", "x25.window_size.called_dte", FT_UINT8, BASE_DEC, NULL, 0x7F,
2276                 NULL, HFILL }},
2277         { &hf_x25_window_size_calling_dte,
2278           { "From the calling DTE", "x25.window_size.calling_dte", FT_UINT8, BASE_DEC, NULL, 0x7F,
2279                 NULL, HFILL }},
2280         { &hf_x25_dte_address_length,
2281           { "DTE address length", "x25.dte_address_length", FT_UINT8, BASE_DEC, NULL, 0xF0,
2282                 NULL, HFILL }},
2283         { &hf_x25_dce_address_length,
2284           { "DCE address length", "x25.dce_address_length", FT_UINT8, BASE_DEC, NULL, 0x0F,
2285                 NULL, HFILL }},
2286         { &hf_x25_calling_address_length,
2287           { "Calling address length", "x25.calling_address_length", FT_UINT8, BASE_DEC, NULL, 0xF0,
2288                 NULL, HFILL }},
2289         { &hf_x25_called_address_length,
2290           { "Called address length", "x25.called_address_length", FT_UINT8, BASE_DEC, NULL, 0x0F,
2291                 NULL, HFILL }},
2292         { &hf_x25_facility_call_transfer_reason,
2293           { "Reason", "x25.facility.call_transfer_reason", FT_UINT8, BASE_DEC, VALS(x25_facilities_call_transfer_reason_vals), 0,
2294                 NULL, HFILL }},
2295         { &hf_x25_facility_monetary_unit,
2296           { "Monetary unit", "x25.facility.monetary_unit", FT_BYTES, BASE_NONE, NULL, 0,
2297                 NULL, HFILL }},
2298         { &hf_x25_facility_nui,
2299           { "NUI", "x25.facility.nui", FT_BYTES, BASE_NONE, NULL, 0,
2300                 NULL, HFILL }},
2301         { &hf_x25_facility_cumulative_ete_transit_delay,
2302           { "Cumulative end-to-end transit delay (ms)", "x25.facility.cumulative_ete_transit_delay", FT_UINT16, BASE_DEC, NULL, 0,
2303                 NULL, HFILL }},
2304         { &hf_x25_facility_requested_ete_transit_delay,
2305           { "Requested end-to-end transit delay (ms)", "x25.facility.requested_ete_transit_delay", FT_UINT16, BASE_DEC, NULL, 0,
2306                 NULL, HFILL }},
2307         { &hf_x25_facility_max_acceptable_ete_transit_delay,
2308           { "Maximum acceptable end-to-end transit delay (ms)", "x25.facility.mac_acceptable_ete_transit_delay", FT_UINT16, BASE_DEC, NULL, 0,
2309                 NULL, HFILL }},
2310         { &hf_x25_facility_priority_data,
2311           { "Priority for data", "x25.facility.priority_data", FT_UINT8, BASE_DEC, NULL, 0,
2312                 NULL, HFILL }},
2313         { &hf_x25_facility_priority_estab_conn,
2314           { "Priority for establishing connection", "x25.facility.priority_estab_conn", FT_UINT8, BASE_DEC, NULL, 0,
2315                 NULL, HFILL }},
2316         { &hf_x25_facility_priority_keep_conn,
2317           { "Priority for keeping connection", "x25.facility.priority_keep_conn", FT_UINT8, BASE_DEC, NULL, 0,
2318                 NULL, HFILL }},
2319         { &hf_x25_facility_min_acceptable_priority_data,
2320           { "Minimum acceptable priority for data", "x25.facility.min_acceptable_priority_data", FT_UINT8, BASE_DEC, NULL, 0,
2321                 NULL, HFILL }},
2322         { &hf_x25_facility_min_acceptable_priority_estab_conn,
2323           { "Minimum acceptable priority for establishing connection", "x25.facility.min_acceptable_priority_estab_conn", FT_UINT8, BASE_DEC, NULL, 0,
2324                 NULL, HFILL }},
2325         { &hf_x25_facility_min_acceptable_priority_keep_conn,
2326           { "Minimum acceptable priority for keeping connection", "x25.facility.min_acceptable_priority_keep_conn", FT_UINT8, BASE_DEC, NULL, 0,
2327                 NULL, HFILL }},
2328         { &hf_x25_facility_classD_unknown,
2329           { "Parameter", "x25.facility.classD_unknown", FT_BYTES, BASE_NONE, NULL, 0,
2330                 "Facility Class D unknown parameter", HFILL }},
2331         { &hf_x25_facility_call_transfer_num_semi_octets,
2332           { "Number of semi-octets in DTE address", "x25.facility.call_transfer_num_semi_octets", FT_UINT8, BASE_DEC, NULL, 0,
2333                 NULL, HFILL }},
2334         { &hf_x25_facility_calling_addr_ext_num_semi_octets,
2335           { "Number of semi-octets in DTE address", "x25.facility.calling_addr_ext_num_semi_octets", FT_UINT8, BASE_DEC, NULL, 0,
2336                 NULL, HFILL }},
2337         { &hf_x25_facility_called_addr_ext_num_semi_octets,
2338           { "Number of semi-octets in DTE address", "x25.facility.called_addr_ext_num_semi_octets", FT_UINT8, BASE_DEC, NULL, 0,
2339                 NULL, HFILL }},
2340         { &hf_x25_facility_call_deflect_num_semi_octets,
2341           { "Number of semi-octets in the alternative DTE address", "x25.facility.call_deflect_num_semi_octets", FT_UINT8, BASE_DEC, NULL, 0,
2342                 NULL, HFILL }},
2343         { &hf_x264_length_indicator,
2344           { "X.264 length indicator", "x25.x264_length_indicator", FT_UINT8, BASE_DEC, NULL, 0,
2345                 NULL, HFILL }},
2346         { &hf_x264_un_tpdu_id,
2347           { "X.264 UN TPDU identifier", "x25.x264_un_tpdu_id", FT_UINT8, BASE_HEX, NULL, 0,
2348                 NULL, HFILL }},
2349         { &hf_x264_protocol_id,
2350           { "X.264 protocol identifier", "x25.x264_protocol_id", FT_UINT8, BASE_HEX, VALS(prt_id_vals), 0,
2351                 NULL, HFILL }},
2352         { &hf_x264_sharing_strategy,
2353           { "X.264 sharing strategy", "x25.x264_sharing_strategy", FT_UINT8, BASE_HEX, VALS(sharing_strategy_vals), 0,
2354                 NULL, HFILL }},
2355         { &hf_x263_sec_protocol_id,
2356           { "X.263 secondary protocol ID", "x25.x263_sec_protocol_id", FT_UINT8, BASE_HEX, VALS(nlpid_vals), 0,
2357                 NULL, HFILL }},
2358         { &hf_x25_reg_request_length,
2359           { "Registration length", "x25.reg_request_length", FT_UINT8, BASE_DEC, NULL, 0x7F,
2360                 NULL, HFILL }},
2361         { &hf_x25_reg_confirm_length,
2362           { "Registration length", "x25.reg_confirm_length", FT_UINT8, BASE_DEC, NULL, 0x7F,
2363                 NULL, HFILL }},
2364
2365         { &hf_x25_segment_overlap,
2366           { "Fragment overlap", "x25.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2367             "Fragment overlaps with other fragments", HFILL }},
2368
2369         { &hf_x25_segment_overlap_conflict,
2370           { "Conflicting data in fragment overlap",     "x25.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2371             "Overlapping fragments contained conflicting data", HFILL }},
2372
2373         { &hf_x25_segment_multiple_tails,
2374           { "Multiple tail fragments found",    "x25.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2375             "Several tails were found when defragmenting the packet", HFILL }},
2376
2377         { &hf_x25_segment_too_long_segment,
2378           { "Fragment too long",        "x25.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2379             "Fragment contained data past end of packet", HFILL }},
2380
2381         { &hf_x25_segment_error,
2382           { "Defragmentation error", "x25.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2383             "Defragmentation error due to illegal fragments", HFILL }},
2384
2385         { &hf_x25_segment_count,
2386           { "Fragment count", "x25.fragment.count", FT_UINT32, BASE_DEC, NULL, 0x0,
2387             NULL, HFILL }},
2388
2389         { &hf_x25_reassembled_length,
2390           { "Reassembled X.25 length", "x25.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x0,
2391             "The total length of the reassembled payload", HFILL }},
2392
2393         { &hf_x25_segment,
2394           { "X.25 Fragment", "x25.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2395             "X25 Fragment", HFILL }},
2396
2397         { &hf_x25_segments,
2398           { "X.25 Fragments", "x25.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
2399             NULL, HFILL }},
2400
2401         { &hf_x25_fast_select,
2402           { "Fast select", "x25.fast_select", FT_UINT8, BASE_DEC, VALS(x25_fast_select_vals), 0xC0,
2403             NULL, HFILL }},
2404
2405         { &hf_x25_icrd,
2406           { "ICRD", "x25.icrd", FT_UINT8, BASE_DEC, VALS(x25_icrd_vals), 0x30,
2407             NULL, HFILL }},
2408
2409         { &hf_x25_reg_confirm_cause,
2410           { "Cause", "x25.reg_confirm.cause", FT_UINT8, BASE_DEC, VALS(x25_registration_code_vals), 0,
2411             NULL, HFILL }},
2412
2413         { &hf_x25_reg_confirm_diagnostic,
2414           { "Diagnostic", "x25.reg_confirm.diagnostic", FT_UINT8, BASE_DEC, VALS(x25_registration_code_vals), 0,
2415             NULL, HFILL }},
2416     };
2417
2418     static gint *ett[] = {
2419         &ett_x25,
2420         &ett_x25_gfi,
2421         &ett_x25_facilities,
2422         &ett_x25_facility,
2423         &ett_x25_user_data,
2424         &ett_x25_segment,
2425         &ett_x25_segments
2426     };
2427
2428     static ei_register_info ei[] = {
2429         { &ei_x25_facility_length, { "x25.facility_length.bogus", PI_PROTOCOL, PI_WARN, "Bogus length", EXPFILL }},
2430     };
2431
2432     module_t *x25_module;
2433     expert_module_t* expert_x25;
2434
2435     proto_x25 = proto_register_protocol ("X.25", "X.25", "x25");
2436     proto_register_field_array (proto_x25, hf, array_length(hf));
2437     proto_register_subtree_array(ett, array_length(ett));
2438     expert_x25 = expert_register_protocol(proto_x25);
2439     expert_register_field_array(expert_x25, ei, array_length(ei));
2440
2441     x25_subdissector_table = register_dissector_table("x.25.spi",
2442         "X.25 secondary protocol identifier", FT_UINT8, BASE_HEX);
2443     register_heur_dissector_list("x.25", &x25_heur_subdissector_list);
2444
2445     register_dissector("x.25_dir", dissect_x25_dir, proto_x25);
2446     register_dissector("x.25", dissect_x25, proto_x25);
2447
2448     /* Preferences */
2449     x25_module = prefs_register_protocol(proto_x25, NULL);
2450     prefs_register_obsolete_preference(x25_module, "non_q_bit_is_sna");
2451     prefs_register_bool_preference(x25_module, "payload_is_qllc_sna",
2452             "Default to QLLC/SNA",
2453             "If CALL REQUEST not seen or didn't specify protocol, dissect as QLLC/SNA",
2454             &payload_is_qllc_sna);
2455     prefs_register_bool_preference(x25_module, "call_request_nodata_is_cotp",
2456             "Assume COTP for Call Request without data",
2457             "If CALL REQUEST has no data, assume the protocol handled is COTP",
2458             &call_request_nodata_is_cotp);
2459     prefs_register_bool_preference(x25_module, "payload_check_data",
2460             "Check data for COTP/IP/CLNP",
2461             "If CALL REQUEST not seen or didn't specify protocol, check user data before checking heuristic dissectors",
2462             &payload_check_data);
2463     prefs_register_bool_preference(x25_module, "reassemble",
2464                                    "Reassemble fragmented X.25 packets",
2465                                    "Reassemble fragmented X.25 packets",
2466                                    &reassemble_x25);
2467     register_init_routine(&x25_reassemble_init);
2468 }
2469
2470 void
2471 proto_reg_handoff_x25(void)
2472 {
2473     dissector_handle_t x25_handle;
2474
2475     /*
2476      * Get handles for various dissectors.
2477      */
2478     ip_handle = find_dissector("ip");
2479     clnp_handle = find_dissector("clnp");
2480     ositp_handle = find_dissector("ositp");
2481     qllc_handle = find_dissector("qllc");
2482     data_handle = find_dissector("data");
2483
2484     x25_handle = find_dissector("x.25");
2485     dissector_add_uint("llc.dsap", SAP_X25, x25_handle);
2486     dissector_add_uint("lapd.sapi", LAPD_SAPI_X25, x25_handle);
2487     dissector_add_uint("ax25.pid", AX25_P_ROSE, x25_handle);
2488 }