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