Coverage Report

Created: 2026-05-14 06:28

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