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