2 * Routines for x25 packet disassembly
3 * Olivier Abad <oabad@cybercable.fr>
5 * $Id: packet-x25.c,v 1.67 2002/05/09 11:18:47 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
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.
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.
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.
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
39 #include <epan/packet.h>
42 #include "x264_prt_id.h"
45 * Direction of packet.
48 X25_FROM_DCE, /* DCE->DTE */
49 X25_FROM_DTE, /* DTE->DCE */
50 X25_UNKNOWN /* direction unknown */
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
71 #define X25_FAC_CLASS_MASK 0xC0
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
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
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;
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;
138 static const value_string vals_modulo[] = {
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" },
161 { X25_DATA, "DATA" },
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;
172 static gboolean non_q_bit_is_sna = FALSE;
174 static dissector_table_t x25_subdissector_table;
175 static heur_dissector_list_t x25_heur_subdissector_list;
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
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
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;
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
200 typedef struct _global_vc_info {
203 struct _global_vc_info *next;
206 static global_vc_info *hash_table[64];
209 free_vc_info(vc_info *pt)
221 reinit_x25_hashtable(void)
225 for (i=0; i<64; i++) {
226 if (hash_table[i]) /* not NULL ==> free */
228 global_vc_info *hash_ent, *hash_ent2;
229 hash_ent2 = hash_ent = hash_table[i];
232 hash_ent2 = hash_ent;
233 hash_ent = hash_ent->next;
234 free_vc_info(hash_ent2->info);
243 x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs,
244 dissector_handle_t dissect)
247 global_vc_info *hash_ent;
248 global_vc_info *hash_ent2;
250 if (hash_table[idx] == 0)
252 hash_ent = (global_vc_info *)g_malloc(sizeof(global_vc_info));
254 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
257 hash_ent->vc_num = vc;
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");
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;
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;
280 if (hash_ent != NULL) /* hash_ent->vc_num == vc */
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;
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");
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;
302 else /* new vc number */
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");
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");
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;
325 x25_hash_add_proto_end(guint16 vc, guint32 frame_secs, guint32 frame_usecs)
327 global_vc_info *hash_ent = hash_table[vc%64];
330 if (!hash_ent) return;
331 while(hash_ent->vc_num != vc) hash_ent = hash_ent->next;
332 if (!hash_ent) return;
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;
340 static dissector_handle_t
341 x25_hash_get_dissect(guint32 frame_secs, guint32 frame_usecs, guint16 vc)
343 global_vc_info *hash_ent = hash_table[vc%64];
350 while (hash_ent && hash_ent->vc_num != vc)
351 hash_ent = hash_ent->next;
355 /* a hash_ent was found for this VC number */
356 vci2 = vci = hash_ent->info;
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))) {
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))
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 */
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))
380 return vci2->dissect;
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))
392 static char *clear_code(unsigned char code)
394 static char buffer[25];
396 if (code == 0x00 || (code & 0x80) == 0x80)
397 return "DTE Originated";
399 return "Number Busy";
401 return "Invalid Facility Requested";
403 return "Network Congestion";
405 return "Out Of Order";
407 return "Access Barred";
409 return "Not Obtainable";
411 return "Remote Procedure Error";
413 return "Local Procedure Error";
415 return "RPOA Out Of Order";
417 return "Reverse Charging Acceptance Not Subscribed";
419 return "Incompatible Destination";
421 return "Fast Select Acceptance Not Subscribed";
423 return "Destination Absent";
425 sprintf(buffer, "Unknown %02X", code);
430 static char *clear_diag(unsigned char code)
432 static char buffer[25];
435 return "No additional information";
437 return "Invalid P(S)";
439 return "Invalid P(R)";
441 return "Packet type invalid";
443 return "Packet type invalid for state r1";
445 return "Packet type invalid for state r2";
447 return "Packet type invalid for state r3";
449 return "Packet type invalid for state p1";
451 return "Packet type invalid for state p2";
453 return "Packet type invalid for state p3";
455 return "Packet type invalid for state p4";
457 return "Packet type invalid for state p5";
459 return "Packet type invalid for state p6";
461 return "Packet type invalid for state p7";
463 return "Packet type invalid for state d1";
465 return "Packet type invalid for state d2";
467 return "Packet type invalid for state d3";
469 return "Packet not allowed";
471 return "Unidentifiable packet";
473 return "Call on one-way logical channel";
475 return "Invalid packet type on a PVC";
477 return "Packet on unassigned LC";
479 return "Reject not subscribed to";
481 return "Packet too short";
483 return "Packet too long";
485 return "Invalid general format identifier";
487 return "Restart/registration packet with nonzero bits";
489 return "Packet type not compatible with facility";
491 return "Unauthorised interrupt confirmation";
493 return "Unauthorised interrupt";
495 return "Unauthorised reject";
497 return "Time expired";
499 return "Time expired for incoming call";
501 return "Time expired for clear indication";
503 return "Time expired for reset indication";
505 return "Time expired for restart indication";
507 return "Time expired for call deflection";
509 return "Call set-up/clearing or registration pb.";
511 return "Facility/registration code not allowed";
513 return "Facility parameter not allowed";
515 return "Invalid called DTE address";
517 return "Invalid calling DTE address";
519 return "Invalid facility/registration length";
521 return "Incoming call barred";
523 return "No logical channel available";
525 return "Call collision";
527 return "Duplicate facility requested";
529 return "Non zero address length";
531 return "Non zero facility length";
533 return "Facility not provided when expected";
535 return "Invalid CCITT-specified DTE facility";
537 return "Max. nb of call redir/defl. exceeded";
539 return "Miscellaneous";
541 return "Improper cause code from DTE";
543 return "Not aligned octet";
545 return "Inconsistent Q bit setting";
547 return "NUI problem";
549 return "International problem";
551 return "Remote network problem";
553 return "International protocol problem";
555 return "International link out of order";
557 return "International link busy";
559 return "Transit network facility problem";
561 return "Remote network facility problem";
563 return "International routing problem";
565 return "Temporary routing problem";
567 return "Unknown called DNIC";
569 return "Maintenance action";
571 return "Timer expired or retransmission count surpassed";
573 return "Timer expired or retransmission count surpassed for INTERRUPT";
575 return "Timer expired or retransmission count surpassed for DATA "
576 "packet transmission";
578 return "Timer expired or retransmission count surpassed for REJECT";
580 return "DTE-specific signals";
582 return "DTE operational";
584 return "DTE not operational";
586 return "DTE resource constraint";
588 return "Fast select not subscribed";
590 return "Invalid partially full DATA packet";
592 return "D-bit procedure not supported";
594 return "Registration/Cancellation confirmed";
596 return "OSI network service problem";
598 return "Disconnection (transient condition)";
600 return "Disconnection (permanent condition)";
602 return "Connection rejection - reason unspecified (transient "
605 return "Connection rejection - reason unspecified (permanent "
608 return "Connection rejection - quality of service not available "
609 "transient condition)";
611 return "Connection rejection - quality of service not available "
612 "permanent condition)";
614 return "Connection rejection - NSAP unreachable (transient condition)";
616 return "Connection rejection - NSAP unreachable (permanent condition)";
618 return "reset - reason unspecified";
620 return "reset - congestion";
622 return "Connection rejection - NSAP address unknown (permanent "
625 return "Higher layer initiated";
627 return "Disconnection - normal";
629 return "Disconnection - abnormal";
631 return "Disconnection - incompatible information in user data";
633 return "Connection rejection - reason unspecified (transient "
636 return "Connection rejection - reason unspecified (permanent "
639 return "Connection rejection - quality of service not available "
640 "(transient condition)";
642 return "Connection rejection - quality of service not available "
643 "(permanent condition)";
645 return "Connection rejection - incompatible information in user data";
647 return "Connection rejection - unrecognizable protocol indentifier "
650 return "Reset - user resynchronization";
652 sprintf(buffer, "Unknown %d", code);
657 static char *reset_code(unsigned char code)
659 static char buffer[25];
661 if (code == 0x00 || (code & 0x80) == 0x80)
662 return "DTE Originated";
664 return "Out of order";
666 return "Remote Procedure Error";
668 return "Local Procedure Error";
670 return "Network Congestion";
672 return "Remote DTE operational";
674 return "Network operational";
676 return "Incompatible Destination";
678 return "Network out of order";
680 sprintf(buffer, "Unknown %02X", code);
685 static char *restart_code(unsigned char code)
687 static char buffer[25];
689 if (code == 0x00 || (code & 0x80) == 0x80)
690 return "DTE Originated";
692 return "Local Procedure Error";
694 return "Network Congestion";
696 return "Network Operational";
698 return "Registration/cancellation confirmed";
700 sprintf(buffer, "Unknown %02X", code);
705 static char *registration_code(unsigned char code)
707 static char buffer[25];
710 return "Invalid facility request";
712 return "Network congestion";
714 return "Local procedure error";
716 return "Registration/cancellation confirmed";
718 sprintf(buffer, "Unknown %02X", code);
724 dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb)
726 guint8 fac, byte1, byte2, byte3;
727 guint32 len; /* facilities length */
729 proto_tree *fac_tree = 0;
730 proto_tree *fac_subtree;
732 len = tvb_get_guint8(tvb, *offset);
734 ti = proto_tree_add_text(tree, tvb, *offset, len + 1,
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);
743 fac = tvb_get_guint8(tvb, *offset);
744 switch(fac & X25_FAC_CLASS_MASK) {
745 case X25_FAC_CLASS_A:
747 case X25_FAC_COMP_MARK:
749 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
750 "Code : 00 (Marker)");
751 switch (tvb_get_guint8(tvb, *offset + 1)) {
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)");
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)");
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 "
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));
786 case X25_FAC_REVERSE:
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);
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");
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"));
809 case X25_FAC_THROUGHPUT:
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);
828 sprintf(tmpbuf, "From the called DTE : %%u (%d bps)",
829 75*(1<<((byte1 >> 4)-3)));
832 sprintf(tmpbuf, "From the called DTE : %%u (48000 bps)");
835 sprintf(tmpbuf, "From the called DTE : %%u (64000 bps)");
838 sprintf(tmpbuf, "From the called DTE : %%u (Reserved)");
840 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
841 decode_numeric_bitfield(byte1, 0xF0, 1*8, tmpbuf));
842 switch (byte1 & 0x0F)
853 sprintf(tmpbuf, "From the calling DTE : %%u (%d bps)",
854 75*(1<<((byte1 & 0x0F)-3)));
857 sprintf(tmpbuf, "From the calling DTE : %%u (48000 bps)");
860 sprintf(tmpbuf, "From the calling DTE : %%u (64000 bps)");
863 sprintf(tmpbuf, "From the calling DTE : %%u (Reserved)");
865 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
866 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
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));
878 case X25_FAC_CALLED_MODIF:
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));
888 case X25_FAC_CUG_OUTGOING_ACC:
890 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
891 "(Closed user group with outgoing access selection)",
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));
899 case X25_FAC_THROUGHPUT_MIN:
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));
909 case X25_FAC_EXPRESS_DATA:
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));
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));
932 case X25_FAC_CLASS_B:
934 case X25_FAC_BILATERAL_CUG:
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));
945 case X25_FAC_PACKET_SIZE:
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);
957 sprintf(tmpbuf, "From the called DTE : %%u (16)");
960 sprintf(tmpbuf, "From the called DTE : %%u (32)");
963 sprintf(tmpbuf, "From the called DTE : %%u (64)");
966 sprintf(tmpbuf, "From the called DTE : %%u (128)");
969 sprintf(tmpbuf, "From the called DTE : %%u (256)");
972 sprintf(tmpbuf, "From the called DTE : %%u (512)");
975 sprintf(tmpbuf, "From the called DTE : %%u (1024)");
978 sprintf(tmpbuf, "From the called DTE : %%u (2048)");
981 sprintf(tmpbuf, "From the called DTE : %%u (4096)");
984 sprintf(tmpbuf, "From the called DTE : %%u (Unknown)");
987 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
988 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
990 byte2 = tvb_get_guint8(tvb, *offset + 1);
994 sprintf(tmpbuf, "From the calling DTE : %%u (16)");
997 sprintf(tmpbuf, "From the calling DTE : %%u (32)");
1000 sprintf(tmpbuf, "From the calling DTE : %%u (64)");
1003 sprintf(tmpbuf, "From the calling DTE : %%u (128)");
1006 sprintf(tmpbuf, "From the calling DTE : %%u (256)");
1009 sprintf(tmpbuf, "From the calling DTE : %%u (512)");
1012 sprintf(tmpbuf, "From the calling DTE : %%u (1024)");
1015 sprintf(tmpbuf, "From the calling DTE : %%u (2048)");
1018 sprintf(tmpbuf, "From the calling DTE : %%u (4096)");
1021 sprintf(tmpbuf, "From the calling DTE : %%u (Unknown)");
1024 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1025 decode_numeric_bitfield(byte2, 0x0F, 1*8, tmpbuf));
1028 case X25_FAC_WINDOW_SIZE:
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"));
1041 case X25_FAC_RPOA_SELECTION:
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));
1052 case X25_FAC_TRANSIT_DELAY:
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));
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));
1076 case X25_FAC_CLASS_C:
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,
1083 tvb_get_ntoh24(tvb, *offset+1));
1088 case X25_FAC_CLASS_D:
1090 case X25_FAC_CALL_TRANSFER:
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");
1110 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1111 "Reason : originally called DTE busy");
1114 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1115 "Reason : call dist. within a hunt group");
1118 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1119 "Reason : originally called DTE out of order");
1122 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1123 "Reason : systematic call redirection");
1126 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1127 "Reason : unknown");
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",
1135 for (i = 0; i < byte3; i++) {
1137 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1139 /* if > 9, convert to the right hexadecimal letter */
1140 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1142 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1144 /* if > 9, convert to the right hexadecimal letter */
1145 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1149 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1150 "DTE address : %s", tmpbuf);
1153 case X25_FAC_CALLING_ADDR_EXT:
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++) {
1170 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1172 /* if > 9, convert to the right hexadecimal letter */
1173 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1175 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1177 /* if > 9, convert to the right hexadecimal letter */
1178 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1182 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1183 "DTE address : %s", tmpbuf);
1186 case X25_FAC_CALLED_ADDR_EXT:
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++) {
1203 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1205 /* if > 9, convert to the right hexadecimal letter */
1206 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1208 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1210 /* if > 9, convert to the right hexadecimal letter */
1211 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1215 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1216 "DTE address : %s", tmpbuf);
1219 case X25_FAC_ETE_TRANSIT_DELAY:
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");
1231 case X25_FAC_CALL_DEFLECT:
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");
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",
1254 for (i = 0; i < byte3; i++) {
1256 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1258 /* if > 9, convert to the right hexadecimal letter */
1259 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1261 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1263 /* if > 9, convert to the right hexadecimal letter */
1264 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1268 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1269 "Alternative DTE address : %s", tmpbuf);
1272 case X25_FAC_PRIORITY:
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");
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");
1294 byte1 = tvb_get_guint8(tvb, *offset+1);
1295 (*offset) += byte1+2;
1303 x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1304 packet_info *pinfo, gboolean is_registration)
1308 char addr1[16], addr2[16];
1309 char *first, *second;
1313 byte = tvb_get_guint8(tvb, *offset);
1314 len1 = (byte >> 0) & 0x0F;
1315 len2 = (byte >> 4) & 0x0F;
1318 proto_tree_add_text(tree, tvb, *offset, 1,
1319 decode_numeric_bitfield(byte, 0xF0, 1*8,
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,
1326 "DCE address length : %u" :
1327 "Called address length : %u"));
1331 localoffset = *offset;
1332 byte = tvb_get_guint8(tvb, localoffset);
1336 for (i = 0; i < (len1 + len2); i++) {
1339 *first++ = ((byte >> 0) & 0x0F) + '0';
1341 byte = tvb_get_guint8(tvb, localoffset);
1343 *first++ = ((byte >> 4) & 0x0F) + '0';
1347 *second++ = ((byte >> 0) & 0x0F) + '0';
1349 byte = tvb_get_guint8(tvb, localoffset);
1351 *second++ = ((byte >> 4) & 0x0F) + '0';
1360 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1361 col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1);
1363 proto_tree_add_text(tree, tvb, *offset,
1366 "DCE address : %s" :
1367 "Called address : %s",
1371 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1372 col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2);
1374 proto_tree_add_text(tree, tvb, *offset + len1/2,
1375 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1377 "DTE address : %s" :
1378 "Calling address : %s",
1381 (*offset) += ((len1 + len2 + 1) / 2);
1385 x25_toa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1390 char addr1[256], addr2[256];
1391 char *first, *second;
1395 len1 = tvb_get_guint8(tvb, *offset);
1397 proto_tree_add_text(tree, tvb, *offset, 1,
1398 "Called address length : %u",
1403 len2 = tvb_get_guint8(tvb, *offset);
1405 proto_tree_add_text(tree, tvb, *offset, 1,
1406 "Calling address length : %u",
1411 localoffset = *offset;
1412 byte = tvb_get_guint8(tvb, localoffset);
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).
1422 for (i = 0; i < (len1 + len2); i++) {
1425 *first++ = ((byte >> 0) & 0x0F) + '0';
1427 byte = tvb_get_guint8(tvb, localoffset);
1429 *first++ = ((byte >> 4) & 0x0F) + '0';
1433 *second++ = ((byte >> 0) & 0x0F) + '0';
1435 byte = tvb_get_guint8(tvb, localoffset);
1437 *second++ = ((byte >> 4) & 0x0F) + '0';
1446 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1447 col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1);
1449 proto_tree_add_text(tree, tvb, *offset,
1451 "Called address : %s",
1455 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1456 col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2);
1458 proto_tree_add_text(tree, tvb, *offset + len1/2,
1459 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1460 "Calling address : %s",
1463 (*offset) += ((len1 + len2 + 1) / 2);
1467 get_x25_pkt_len(tvbuff_t *tvb)
1469 guint length, called_len, calling_len, dte_len, dce_len;
1470 guint8 byte2, bytex;
1472 byte2 = tvb_get_guint8(tvb, 2);
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 */
1483 return MIN(tvb_reported_length(tvb),length);
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
1489 if (tvb_reported_length(tvb) == 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 */
1498 return MIN(tvb_reported_length(tvb),length);
1500 case X25_CLEAR_REQUEST:
1501 case X25_RESET_REQUEST:
1502 case X25_RESTART_REQUEST:
1503 return MIN(tvb_reported_length(tvb),5);
1505 case X25_DIAGNOSTIC:
1506 return MIN(tvb_reported_length(tvb),4);
1508 case X25_CLEAR_CONFIRMATION:
1510 case X25_INTERRUPT_CONFIRMATION:
1511 case X25_RESET_CONFIRMATION:
1512 case X25_RESTART_CONFIRMATION:
1513 return MIN(tvb_reported_length(tvb),3);
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 */
1523 return MIN(tvb_reported_length(tvb),length);
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 */
1533 return MIN(tvb_reported_length(tvb),length);
1536 if ((byte2 & 0x01) == X25_DATA) return MIN(tvb_reported_length(tvb),3);
1538 switch (byte2 & 0x1F)
1541 return MIN(tvb_reported_length(tvb),3);
1544 return MIN(tvb_reported_length(tvb),3);
1547 return MIN(tvb_reported_length(tvb),3);
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"},
1561 static const value_string sharing_strategy_vals[] = {
1562 {0x00, "No sharing"},
1567 dissect_x25_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1570 proto_tree *x25_tree=0, *gfi_tree=0, *userdata_tree=0;
1572 guint localoffset=0;
1576 dissector_handle_t dissect;
1577 gboolean toa; /* TOA/NPI address format */
1580 char *short_name = NULL, *long_name = NULL;
1582 gboolean q_bit_set = FALSE;
1584 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1585 col_set_str(pinfo->cinfo, COL_PROTOCOL, "X.25");
1587 bytes0_1 = tvb_get_ntohs(tvb, 0);
1589 modulo = ((bytes0_1 & 0x2000) ? 128 : 8);
1590 vc = (int)(bytes0_1 & 0x0FFF);
1592 if (bytes0_1 & 0x8000) toa = TRUE;
1595 x25_pkt_len = get_x25_pkt_len(tvb);
1596 if (x25_pkt_len < 3) /* packet too short */
1598 if (check_col(pinfo->cinfo, COL_INFO))
1599 col_set_str(pinfo->cinfo, COL_INFO, "Invalid/short X.25 packet");
1601 proto_tree_add_protocol_format(tree, proto_x25, tvb, 0, -1,
1602 "Invalid/short X.25 packet");
1606 pkt_type = tvb_get_guint8(tvb, 2);
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);
1614 if ((pkt_type & 0x01) == X25_DATA) {
1615 proto_tree_add_boolean(gfi_tree, hf_x25_qbit, tvb, 0, 2,
1617 if (bytes0_1 & 0x8000) {
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,
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,
1634 proto_tree_add_uint(gfi_tree, hf_x25_mod, tvb, 0, 2, bytes0_1);
1638 case X25_CALL_REQUEST:
1642 short_name = "Inc. call";
1643 long_name = "Incoming call";
1647 short_name = "Call req.";
1648 long_name = "Call request";
1652 short_name = "Inc. call/Call req.";
1653 long_name = "Incoming call/Call request";
1656 if (check_col(pinfo->cinfo, COL_INFO))
1657 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
1659 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb,
1661 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1662 X25_CALL_REQUEST, "%s", long_name);
1665 if (localoffset < x25_pkt_len) { /* calling/called addresses */
1667 x25_toa(x25_tree, &localoffset, tvb, pinfo);
1669 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
1672 if (localoffset < x25_pkt_len) /* facilities */
1673 dump_facilities(x25_tree, &localoffset, tvb);
1675 if (localoffset < tvb_reported_length(tvb)) /* user data */
1682 ti = proto_tree_add_text(x25_tree, tvb, localoffset, -1,
1684 userdata_tree = proto_item_add_subtree(ti, ett_x25_user_data);
1687 /* X.263/ISO 9577 says that:
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.
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".
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
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.
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:
1719 The sending transport entity shall:
1721 a) either not transmit any TPDU in the NS-user data
1722 parameter of the N-CONNECT request primitive; or
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
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.
1732 X.264/ISO 11570 says that:
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.
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.
1755 I read this as meaning that, if the ISO mechanisms are
1756 used to identify the protocol being carried over X.25:
1758 if there's no user data in the CALL REQUEST/
1759 INCOMING CALL packet, it's COTP;
1761 if there is user data, then:
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;
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.
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.
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 */
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
1803 /* No, the second byte is not 1, so it's not a
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. */
1813 if (is_x_264 == -1) {
1815 * We don't know what it is; just skip it.
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",
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));
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)"));
1840 /* XXX - dissect the variable part? */
1842 /* The length doesn't include the length octet itself. */
1843 localoffset += spi + 1;
1847 case PRT_ID_ISO_8073:
1849 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
1850 pinfo->fd->abs_usecs,
1852 /* XXX - disssect the rest of the user data as COTP?
1853 That needs support for NCM TPDUs, etc. */
1856 case PRT_ID_ISO_8602:
1858 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
1859 pinfo->fd->abs_usecs,
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. */
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)"));
1876 * What's the dissector handle for this SPI?
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);
1882 if (localoffset < tvb_length(tvb)) {
1883 if (userdata_tree) {
1884 proto_tree_add_text(userdata_tree, tvb, localoffset, -1,
1887 localoffset = tvb_length(tvb);
1891 case X25_CALL_ACCEPTED:
1895 short_name = "Call conn.";
1896 long_name = "Call connected";
1900 short_name = "Call acc.";
1901 long_name = "Call accepted";
1905 short_name = "Call conn./Call acc.";
1906 long_name = "Call connected/Call accepted";
1909 if(check_col(pinfo->cinfo, COL_INFO))
1910 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
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);
1917 if (localoffset < x25_pkt_len) { /* calling/called addresses */
1919 x25_toa(x25_tree, &localoffset, tvb, pinfo);
1921 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
1924 if (localoffset < x25_pkt_len) /* facilities */
1925 dump_facilities(x25_tree, &localoffset, tvb);
1927 if (localoffset < tvb_reported_length(tvb)) { /* user data */
1929 proto_tree_add_text(x25_tree, tvb, localoffset,
1930 tvb_reported_length(tvb)-localoffset, "Data");
1931 localoffset=tvb_reported_length(tvb);
1934 case X25_CLEAR_REQUEST:
1938 short_name = "Clear ind.";
1939 long_name = "Clear indication";
1943 short_name = "Clear req.";
1944 long_name = "Clear request";
1948 short_name = "Clear ind./Clear req.";
1949 long_name = "Clear indication/Clear request";
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)));
1957 x25_hash_add_proto_end(vc, pinfo->fd->abs_secs, pinfo->fd->abs_usecs);
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)));
1967 localoffset = x25_pkt_len;
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);
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);
1977 localoffset = x25_pkt_len;
1979 if (localoffset < tvb_reported_length(tvb)) { /* extended clear conf format */
1981 x25_toa(x25_tree, &localoffset, tvb, pinfo);
1983 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
1986 if (localoffset < tvb_reported_length(tvb)) /* facilities */
1987 dump_facilities(x25_tree, &localoffset, tvb);
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));
1995 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1997 proto_tree_add_text(x25_tree, tvb, 3, 1,
1998 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 3));
2000 localoffset = x25_pkt_len;
2003 if(check_col(pinfo->cinfo, COL_INFO))
2004 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt VC:%d", vc);
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,
2010 localoffset = x25_pkt_len;
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);
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);
2020 localoffset = x25_pkt_len;
2022 case X25_RESET_REQUEST:
2026 short_name = "Reset ind.";
2027 long_name = "Reset indication";
2031 short_name = "Reset req.";
2032 long_name = "Reset request";
2036 short_name = "Reset ind./Reset req.";
2037 long_name = "Reset indication/Reset request";
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));
2045 x25_hash_add_proto_end(vc, pinfo->fd->abs_secs, pinfo->fd->abs_usecs);
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));
2055 localoffset = x25_pkt_len;
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);
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);
2065 localoffset = x25_pkt_len;
2067 case X25_RESTART_REQUEST:
2071 short_name = "Restart ind.";
2072 long_name = "Restart indication";
2076 short_name = "Restart req.";
2077 long_name = "Restart request";
2081 short_name = "Restart ind./Restart req.";
2082 long_name = "Restart indication/Restart request";
2085 if(check_col(pinfo->cinfo, COL_INFO)) {
2086 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s - Diag.:%d",
2088 restart_code(tvb_get_guint8(tvb, 3)),
2089 (int)tvb_get_guint8(tvb, 3));
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));
2099 localoffset = x25_pkt_len;
2101 case X25_RESTART_CONFIRMATION:
2102 if(check_col(pinfo->cinfo, COL_INFO))
2103 col_set_str(pinfo->cinfo, COL_INFO, "Restart conf.");
2105 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2106 X25_RESTART_CONFIRMATION);
2107 localoffset = x25_pkt_len;
2109 case X25_REGISTRATION_REQUEST:
2110 if(check_col(pinfo->cinfo, COL_INFO))
2111 col_set_str(pinfo->cinfo, COL_INFO, "Registration req.");
2113 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2114 X25_REGISTRATION_REQUEST);
2116 if (localoffset < x25_pkt_len)
2117 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, TRUE);
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,
2129 localoffset = tvb_reported_length(tvb);
2131 case X25_REGISTRATION_CONFIRMATION:
2132 if(check_col(pinfo->cinfo, COL_INFO))
2133 col_set_str(pinfo->cinfo, COL_INFO, "Registration conf.");
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)));
2143 if (localoffset < x25_pkt_len)
2144 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, TRUE);
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,
2156 localoffset = tvb_reported_length(tvb);
2160 if ((pkt_type & 0x01) == X25_DATA)
2162 if(check_col(pinfo->cinfo, COL_INFO)) {
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" : "");
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,
2174 (tvb_get_guint8(tvb, localoffset+1) & 0x01) ? " M" : "");
2177 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2179 proto_tree_add_uint_hidden(x25_tree, hf_x25_type, tvb,
2180 localoffset, 1, X25_DATA);
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,
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,
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,
2202 tvb_get_guint8(tvb, localoffset+1));
2205 localoffset += (modulo == 8) ? 1 : 2;
2208 switch (pkt_type & 0x1F)
2211 if(check_col(pinfo->cinfo, COL_INFO)) {
2213 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2214 vc, (pkt_type >> 5) & 0x07);
2216 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2217 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2220 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
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);
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);
2238 if(check_col(pinfo->cinfo, COL_INFO)) {
2240 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2241 vc, (pkt_type >> 5) & 0x07);
2243 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2244 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2247 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
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);
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);
2265 if(check_col(pinfo->cinfo, COL_INFO)) {
2267 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2268 vc, (pkt_type >> 5) & 0x07);
2270 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2271 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2274 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
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);
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);
2290 localoffset += (modulo == 8) ? 1 : 2;
2293 if (localoffset >= tvb_reported_length(tvb)) return;
2295 next_tvb = tvb_new_subset(tvb, localoffset, -1, -1);
2299 call_dissector(qllc_handle, next_tvb, pinfo, tree);
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);
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);
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
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);
2329 /* Try the heuristic dissectors. */
2330 if (dissector_try_heuristic(x25_heur_subdissector_list, next_tvb, pinfo,
2334 /* All else failed; dissect it as raw data */
2335 call_dissector(data_handle, next_tvb, pinfo, tree);
2339 * X.25 dissector for use when "pinfo->pseudo_header" points to a
2340 * "struct x25_phdr".
2343 dissect_x25_dir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2345 dissect_x25_common(tvb, pinfo, tree,
2346 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? X25_FROM_DCE :
2351 * X.25 dissector for use when "pinfo->pseudo_header" doesn't point to a
2352 * "struct x25_phdr".
2355 dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2358 * We don't know if this packet is DTE->DCE or DCE->DCE.
2360 dissect_x25_common(tvb, pinfo, tree, X25_UNKNOWN);
2364 proto_register_x25(void)
2366 static hf_register_info hf[] = {
2368 { "GFI", "x.25.gfi", FT_UINT16, BASE_BIN, NULL, 0xF000,
2369 "General format identifier", HFILL }},
2371 { "A Bit", "x.25.a", FT_BOOLEAN, 16, NULL, 0x8000,
2372 "Address Bit", HFILL }},
2374 { "Q Bit", "x.25.q", FT_BOOLEAN, 16, NULL, 0x8000,
2375 "Qualifier Bit", HFILL }},
2377 { "D Bit", "x.25.d", FT_BOOLEAN, 16, NULL, 0x4000,
2378 "Delivery Confirmation Bit", HFILL }},
2380 { "Modulo", "x.25.mod", FT_UINT16, BASE_DEC, VALS(vals_modulo), 0x3000,
2381 "Specifies whether the frame is modulo 8 or 128", HFILL }},
2383 { "Logical Channel", "x.25.lcn", FT_UINT16, BASE_DEC, NULL, 0x0FFF,
2384 "Logical Channel Number", HFILL }},
2386 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x0,
2387 "Packet Type", HFILL }},
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 }},
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 }},
2407 static gint *ett[] = {
2411 &ett_x25_fac_unknown,
2413 &ett_x25_fac_reverse,
2414 &ett_x25_fac_throughput,
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,
2433 module_t *x25_module;
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);
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);
2444 register_dissector("x.25_dir", dissect_x25_dir, proto_x25);
2445 register_dissector("x.25", dissect_x25, proto_x25);
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",
2455 proto_reg_handoff_x25(void)
2457 dissector_handle_t x25_handle;
2460 * Get handles for various dissectors.
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");
2468 x25_handle = find_dissector("x.25");
2469 dissector_add("llc.dsap", SAP_X25, x25_handle);