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