2 * Routines for x25 packet disassembly
3 * Olivier Abad <oabad@cybercable.fr>
5 * $Id: packet-x25.c,v 1.56 2001/12/02 00:07:46 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>
45 #define X25_CALL_REQUEST 0x0B
46 #define X25_CALL_ACCEPTED 0x0F
47 #define X25_CLEAR_REQUEST 0x13
48 #define X25_CLEAR_CONFIRMATION 0x17
49 #define X25_INTERRUPT 0x23
50 #define X25_INTERRUPT_CONFIRMATION 0x27
51 #define X25_RESET_REQUEST 0x1B
52 #define X25_RESET_CONFIRMATION 0x1F
53 #define X25_RESTART_REQUEST 0xFB
54 #define X25_RESTART_CONFIRMATION 0xFF
55 #define X25_REGISTRATION_REQUEST 0xF3
56 #define X25_REGISTRATION_CONFIRMATION 0xF7
57 #define X25_DIAGNOSTIC 0xF1
63 #define X25_FAC_CLASS_MASK 0xC0
65 #define X25_FAC_CLASS_A 0x00
66 #define X25_FAC_CLASS_B 0x40
67 #define X25_FAC_CLASS_C 0x80
68 #define X25_FAC_CLASS_D 0xC0
70 #define X25_FAC_COMP_MARK 0x00
71 #define X25_FAC_REVERSE 0x01
72 #define X25_FAC_THROUGHPUT 0x02
73 #define X25_FAC_CUG 0x03
74 #define X25_FAC_CALLED_MODIF 0x08
75 #define X25_FAC_CUG_OUTGOING_ACC 0x09
76 #define X25_FAC_THROUGHPUT_MIN 0x0A
77 #define X25_FAC_EXPRESS_DATA 0x0B
78 #define X25_FAC_BILATERAL_CUG 0x41
79 #define X25_FAC_PACKET_SIZE 0x42
80 #define X25_FAC_WINDOW_SIZE 0x43
81 #define X25_FAC_RPOA_SELECTION 0x44
82 #define X25_FAC_TRANSIT_DELAY 0x49
83 #define X25_FAC_CALL_TRANSFER 0xC3
84 #define X25_FAC_CALLED_ADDR_EXT 0xC9
85 #define X25_FAC_ETE_TRANSIT_DELAY 0xCA
86 #define X25_FAC_CALLING_ADDR_EXT 0xCB
87 #define X25_FAC_CALL_DEFLECT 0xD1
88 #define X25_FAC_PRIORITY 0xD2
90 static int proto_x25 = -1;
91 static int hf_x25_gfi = -1;
92 static int hf_x25_abit = -1;
93 static int hf_x25_qbit = -1;
94 static int hf_x25_dbit = -1;
95 static int hf_x25_mod = -1;
96 static int hf_x25_lcn = -1;
97 static int hf_x25_type = -1;
98 static int hf_x25_p_r_mod8 = -1;
99 static int hf_x25_p_r_mod128 = -1;
100 static int hf_x25_mbit_mod8 = -1;
101 static int hf_x25_mbit_mod128 = -1;
102 static int hf_x25_p_s_mod8 = -1;
103 static int hf_x25_p_s_mod128 = -1;
105 static gint ett_x25 = -1;
106 static gint ett_x25_gfi = -1;
107 static gint ett_x25_fac = -1;
108 static gint ett_x25_fac_unknown = -1;
109 static gint ett_x25_fac_mark = -1;
110 static gint ett_x25_fac_reverse = -1;
111 static gint ett_x25_fac_throughput = -1;
112 static gint ett_x25_fac_cug = -1;
113 static gint ett_x25_fac_called_modif = -1;
114 static gint ett_x25_fac_cug_outgoing_acc = -1;
115 static gint ett_x25_fac_throughput_min = -1;
116 static gint ett_x25_fac_express_data = -1;
117 static gint ett_x25_fac_bilateral_cug = -1;
118 static gint ett_x25_fac_packet_size = -1;
119 static gint ett_x25_fac_window_size = -1;
120 static gint ett_x25_fac_rpoa_selection = -1;
121 static gint ett_x25_fac_transit_delay = -1;
122 static gint ett_x25_fac_call_transfer = -1;
123 static gint ett_x25_fac_called_addr_ext = -1;
124 static gint ett_x25_fac_ete_transit_delay = -1;
125 static gint ett_x25_fac_calling_addr_ext = -1;
126 static gint ett_x25_fac_call_deflect = -1;
127 static gint ett_x25_fac_priority = -1;
128 static gint ett_x25_user_data = -1;
130 static const value_string vals_modulo[] = {
136 static const value_string vals_x25_type[] = {
137 { X25_CALL_REQUEST, "Call" },
138 { X25_CALL_ACCEPTED, "Call Accepted" },
139 { X25_CLEAR_REQUEST, "Clear" },
140 { X25_CLEAR_CONFIRMATION, "Clear Confirmation" },
141 { X25_INTERRUPT, "Interrupt" },
142 { X25_INTERRUPT_CONFIRMATION, "Interrupt Confirmation" },
143 { X25_RESET_REQUEST, "Reset" },
144 { X25_RESET_CONFIRMATION, "Reset Confirmation" },
145 { X25_RESTART_REQUEST, "Restart" },
146 { X25_RESTART_CONFIRMATION, "Restart Confirmation" },
147 { X25_REGISTRATION_REQUEST, "Registration" },
148 { X25_REGISTRATION_CONFIRMATION, "Registration Confirmation" },
149 { X25_DIAGNOSTIC, "Diagnostic" },
153 { X25_DATA, "DATA" },
157 static dissector_handle_t ositp_handle;
158 static dissector_handle_t sna_handle;
159 static dissector_handle_t qllc_handle;
160 static dissector_handle_t data_handle;
163 static gboolean non_q_bit_is_sna = FALSE;
165 static dissector_table_t x25_subdissector_table;
168 * each vc_info node contains :
169 * the time of the first frame using this dissector (secs and usecs)
170 * the time of the last frame using this dissector (0 if it is unknown)
171 * the protocol used over the VC
173 * the "time of first frame" is initialized when a Call Req. is received
174 * the "time of last frame" is initialized when a Clear, Reset, or Restart
177 typedef struct _vc_info {
178 guint32 first_frame_secs, first_frame_usecs;
179 guint32 last_frame_secs, last_frame_usecs;
181 struct _vc_info *next;
185 * Protocol unknown for connection.
187 #define PROTO_UNKNOWN -1
190 * Special protocol values, for protocols not indicated by an NLPID as a
191 * secondary protocol identifier.
194 #define PROTO_ISO_8073 -3
197 * the hash table will contain linked lists of global_vc_info
198 * each global_vc_info struct contains :
199 * the VC number (the hash table is indexed with VC % 64)
200 * a linked list of vc_info
202 typedef struct _global_vc_info {
205 struct _global_vc_info *next;
208 static global_vc_info *hash_table[64];
211 free_vc_info(vc_info *pt)
223 reinit_x25_hashtable(void)
227 for (i=0; i<64; i++) {
228 if (hash_table[i]) /* not NULL ==> free */
230 global_vc_info *hash_ent, *hash_ent2;
231 hash_ent2 = hash_ent = hash_table[i];
234 hash_ent2 = hash_ent;
235 hash_ent = hash_ent->next;
236 free_vc_info(hash_ent2->info);
245 x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs,
249 global_vc_info *hash_ent;
250 global_vc_info *hash_ent2;
252 if (hash_table[idx] == 0)
254 hash_ent = (global_vc_info *)g_malloc(sizeof(global_vc_info));
256 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
259 hash_ent->vc_num = vc;
261 hash_ent->info = (vc_info *)g_malloc(sizeof(vc_info));
262 if (!hash_ent->info) {
263 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
266 hash_ent->info->first_frame_secs = frame_secs;
267 hash_ent->info->first_frame_usecs = frame_usecs;
268 hash_ent->info->last_frame_secs = 0;
269 hash_ent->info->last_frame_usecs = 0;
270 hash_ent->info->proto = proto;
271 hash_ent->info->next = 0;
272 hash_table[idx] = hash_ent;
276 hash_ent2 = hash_ent = hash_table[idx];
277 /* search an entry with the same VC number */
278 while (hash_ent != NULL && hash_ent->vc_num != vc) {
279 hash_ent2 = hash_ent;
280 hash_ent = hash_ent->next;
282 if (hash_ent != NULL) /* hash_ent->vc_num == vc */
284 vc_info *vci = hash_ent->info;
285 while (vci->next) vci = vci->next; /* last element */
286 if (vci->proto == proto) {
287 vci->last_frame_secs = 0;
288 vci->last_frame_usecs = 0;
291 vci->next = (vc_info *)g_malloc(sizeof(vc_info));
292 if (vci->next == 0) {
293 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
296 vci->next->first_frame_secs = frame_secs;
297 vci->next->first_frame_usecs = frame_usecs;
298 vci->next->last_frame_secs = 0;
299 vci->next->last_frame_usecs = 0;
300 vci->next->proto = proto;
304 else /* new vc number */
306 hash_ent2->next = (global_vc_info *)g_malloc(sizeof(global_vc_info));
307 if (!hash_ent2->next) {
308 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
311 hash_ent2->next->info = (vc_info *)g_malloc(sizeof(vc_info));
312 if (!hash_ent2->next->info) {
313 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
316 hash_ent2->next->info->first_frame_secs = frame_secs;
317 hash_ent2->next->info->first_frame_usecs = frame_usecs;
318 hash_ent2->next->info->last_frame_secs = 0;
319 hash_ent2->next->info->last_frame_usecs = 0;
320 hash_ent2->next->info->proto = proto;
321 hash_ent2->next->info->next = 0;
327 x25_hash_add_proto_end(guint16 vc, guint32 frame_secs, guint32 frame_usecs)
329 global_vc_info *hash_ent = hash_table[vc%64];
332 if (!hash_ent) return;
333 while(hash_ent->vc_num != vc) hash_ent = hash_ent->next;
334 if (!hash_ent) return;
336 vci = hash_ent->info;
337 while (vci->next) vci = vci->next;
338 vci->last_frame_secs = frame_secs;
339 vci->last_frame_usecs = frame_usecs;
343 x25_hash_get_proto(guint32 frame_secs, guint32 frame_usecs, guint16 vc)
345 global_vc_info *hash_ent = hash_table[vc%64];
350 return PROTO_UNKNOWN;
352 while (hash_ent && hash_ent->vc_num != vc)
353 hash_ent = hash_ent->next;
355 return PROTO_UNKNOWN;
357 /* a hash_ent was found for this VC number */
358 vci2 = vci = hash_ent->info;
360 /* looking for an entry matching our frame time */
361 while (vci && (vci->last_frame_secs < frame_secs ||
362 (vci->last_frame_secs == frame_secs &&
363 vci->last_frame_usecs < frame_usecs))) {
367 /* we reached last record, and previous record has a non zero
368 * last frame time ==> no protocol known */
369 if (!vci && (vci2->last_frame_secs || vci2->last_frame_usecs))
370 return PROTO_UNKNOWN;
372 /* we reached last record, and previous record has a zero last frame time
373 * ==> dissector for previous frame has not been "stopped" by a Clear, etc */
375 /* if the start time for vci2 is greater than our frame time
376 * ==> no protocol known */
377 if (frame_secs < vci2->first_frame_secs ||
378 (frame_secs == vci2->first_frame_secs &&
379 frame_usecs < vci2->first_frame_usecs))
380 return PROTO_UNKNOWN;
385 /* our frame time is before vci's end. Check if it is after vci's start */
386 if (frame_secs < vci->first_frame_secs ||
387 (frame_secs == vci->first_frame_secs &&
388 frame_usecs < vci->first_frame_usecs))
394 static char *clear_code(unsigned char code)
396 static char buffer[25];
398 if (code == 0x00 || (code & 0x80) == 0x80)
399 return "DTE Originated";
401 return "Number Busy";
403 return "Invalid Facility Requested";
405 return "Network Congestion";
407 return "Out Of Order";
409 return "Access Barred";
411 return "Not Obtainable";
413 return "Remote Procedure Error";
415 return "Local Procedure Error";
417 return "RPOA Out Of Order";
419 return "Reverse Charging Acceptance Not Subscribed";
421 return "Incompatible Destination";
423 return "Fast Select Acceptance Not Subscribed";
425 return "Destination Absent";
427 sprintf(buffer, "Unknown %02X", code);
432 static char *clear_diag(unsigned char code)
434 static char buffer[25];
437 return "No additional information";
439 return "Invalid P(S)";
441 return "Invalid P(R)";
443 return "Packet type invalid";
445 return "Packet type invalid for state r1";
447 return "Packet type invalid for state r2";
449 return "Packet type invalid for state r3";
451 return "Packet type invalid for state p1";
453 return "Packet type invalid for state p2";
455 return "Packet type invalid for state p3";
457 return "Packet type invalid for state p4";
459 return "Packet type invalid for state p5";
461 return "Packet type invalid for state p6";
463 return "Packet type invalid for state p7";
465 return "Packet type invalid for state d1";
467 return "Packet type invalid for state d2";
469 return "Packet type invalid for state d3";
471 return "Packet not allowed";
473 return "Unidentifiable packet";
475 return "Call on one-way logical channel";
477 return "Invalid packet type on a PVC";
479 return "Packet on unassigned LC";
481 return "Reject not subscribed to";
483 return "Packet too short";
485 return "Packet too long";
487 return "Invalid general format identifier";
489 return "Restart/registration packet with nonzero bits";
491 return "Packet type not compatible with facility";
493 return "Unauthorised interrupt confirmation";
495 return "Unauthorised interrupt";
497 return "Unauthorised reject";
499 return "Time expired";
501 return "Time expired for incoming call";
503 return "Time expired for clear indication";
505 return "Time expired for reset indication";
507 return "Time expired for restart indication";
509 return "Time expired for call deflection";
511 return "Call set-up/clearing or registration pb.";
513 return "Facility/registration code not allowed";
515 return "Facility parameter not allowed";
517 return "Invalid called DTE address";
519 return "Invalid calling DTE address";
521 return "Invalid facility/registration length";
523 return "Incoming call barred";
525 return "No logical channel available";
527 return "Call collision";
529 return "Duplicate facility requested";
531 return "Non zero address length";
533 return "Non zero facility length";
535 return "Facility not provided when expected";
537 return "Invalid CCITT-specified DTE facility";
539 return "Max. nb of call redir/defl. exceeded";
541 return "Miscellaneous";
543 return "Improper cause code from DTE";
545 return "Not aligned octet";
547 return "Inconsistent Q bit setting";
549 return "NUI problem";
551 return "International problem";
553 return "Remote network problem";
555 return "International protocol problem";
557 return "International link out of order";
559 return "International link busy";
561 return "Transit network facility problem";
563 return "Remote network facility problem";
565 return "International routing problem";
567 return "Temporary routing problem";
569 return "Unknown called DNIC";
571 return "Maintenance action";
573 return "Timer expired or retransmission count surpassed";
575 return "Timer expired or retransmission count surpassed for INTERRUPT";
577 return "Timer expired or retransmission count surpassed for DATA "
578 "packet transmission";
580 return "Timer expired or retransmission count surpassed for REJECT";
582 return "DTE-specific signals";
584 return "DTE operational";
586 return "DTE not operational";
588 return "DTE resource constraint";
590 return "Fast select not subscribed";
592 return "Invalid partially full DATA packet";
594 return "D-bit procedure not supported";
596 return "Registration/Cancellation confirmed";
598 return "OSI network service problem";
600 return "Disconnection (transient condition)";
602 return "Disconnection (permanent condition)";
604 return "Connection rejection - reason unspecified (transient "
607 return "Connection rejection - reason unspecified (permanent "
610 return "Connection rejection - quality of service not available "
611 "transient condition)";
613 return "Connection rejection - quality of service not available "
614 "permanent condition)";
616 return "Connection rejection - NSAP unreachable (transient condition)";
618 return "Connection rejection - NSAP unreachable (permanent condition)";
620 return "reset - reason unspecified";
622 return "reset - congestion";
624 return "Connection rejection - NSAP address unknown (permanent "
627 return "Higher layer initiated";
629 return "Disconnection - normal";
631 return "Disconnection - abnormal";
633 return "Disconnection - incompatible information in user data";
635 return "Connection rejection - reason unspecified (transient "
638 return "Connection rejection - reason unspecified (permanent "
641 return "Connection rejection - quality of service not available "
642 "(transient condition)";
644 return "Connection rejection - quality of service not available "
645 "(permanent condition)";
647 return "Connection rejection - incompatible information in user data";
649 return "Connection rejection - unrecognizable protocol indentifier "
652 return "Reset - user resynchronization";
654 sprintf(buffer, "Unknown %d", code);
659 static char *reset_code(unsigned char code)
661 static char buffer[25];
663 if (code == 0x00 || (code & 0x80) == 0x80)
664 return "DTE Originated";
666 return "Out of order";
668 return "Remote Procedure Error";
670 return "Local Procedure Error";
672 return "Network Congestion";
674 return "Remote DTE operational";
676 return "Network operational";
678 return "Incompatible Destination";
680 return "Network out of order";
682 sprintf(buffer, "Unknown %02X", code);
687 static char *restart_code(unsigned char code)
689 static char buffer[25];
691 if (code == 0x00 || (code & 0x80) == 0x80)
692 return "DTE Originated";
694 return "Local Procedure Error";
696 return "Network Congestion";
698 return "Network Operational";
700 return "Registration/cancellation confirmed";
702 sprintf(buffer, "Unknown %02X", code);
707 static char *registration_code(unsigned char code)
709 static char buffer[25];
712 return "Invalid facility request";
714 return "Network congestion";
716 return "Local procedure error";
718 return "Registration/cancellation confirmed";
720 sprintf(buffer, "Unknown %02X", code);
726 dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb)
728 guint8 fac, byte1, byte2, byte3;
729 guint32 len; /* facilities length */
731 proto_tree *fac_tree = 0;
732 proto_tree *fac_subtree;
734 len = tvb_get_guint8(tvb, *offset);
736 ti = proto_tree_add_text(tree, tvb, *offset, len + 1,
738 fac_tree = proto_item_add_subtree(ti, ett_x25_fac);
739 proto_tree_add_text(fac_tree, tvb, *offset, 1,
740 "Facilities length: %d", len);
745 fac = tvb_get_guint8(tvb, *offset);
746 switch(fac & X25_FAC_CLASS_MASK) {
747 case X25_FAC_CLASS_A:
749 case X25_FAC_COMP_MARK:
751 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
752 "Code : 00 (Marker)");
753 switch (tvb_get_guint8(tvb, *offset + 1)) {
756 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
757 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
758 "Parameter : 00 (Network complementary "
759 "services - calling DTE)");
764 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
765 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
766 "Parameter : FF (Network complementary "
767 "services - called DTE)");
772 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
773 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
774 "Parameter : 0F (DTE complementary "
780 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
781 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
782 "Parameter : %02X (Unknown marker)",
783 tvb_get_guint8(tvb, *offset+1));
788 case X25_FAC_REVERSE:
790 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
791 "(Reverse charging / Fast select)", fac);
792 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_reverse);
793 byte1 = tvb_get_guint8(tvb, *offset + 1);
794 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
795 "Parameter : %02X", byte1);
797 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
798 "11.. .... = Fast select with restriction");
799 else if (byte1 & 0x80)
800 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
801 "10.. .... = Fast select - no restriction");
803 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
804 "00.. .... = Fast select not requested");
805 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
806 decode_boolean_bitfield(byte1, 0x01, 1*8,
807 "Reverse charging requested",
808 "Reverse charging not requested"));
811 case X25_FAC_THROUGHPUT:
815 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
816 "(Throughput class negociation)", fac);
817 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_throughput);
818 byte1 = tvb_get_guint8(tvb, *offset + 1);
830 sprintf(tmpbuf, "From the called DTE : %%u (%d bps)",
831 75*(1<<((byte1 >> 4)-3)));
834 sprintf(tmpbuf, "From the called DTE : %%u (48000 bps)");
837 sprintf(tmpbuf, "From the called DTE : %%u (64000 bps)");
840 sprintf(tmpbuf, "From the called DTE : %%u (Reserved)");
842 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
843 decode_numeric_bitfield(byte1, 0xF0, 1*8, tmpbuf));
844 switch (byte1 & 0x0F)
855 sprintf(tmpbuf, "From the calling DTE : %%u (%d bps)",
856 75*(1<<((byte1 & 0x0F)-3)));
859 sprintf(tmpbuf, "From the calling DTE : %%u (48000 bps)");
862 sprintf(tmpbuf, "From the calling DTE : %%u (64000 bps)");
865 sprintf(tmpbuf, "From the calling DTE : %%u (Reserved)");
867 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
868 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
873 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
874 "(Closed user group selection)", fac);
875 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_cug);
876 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
877 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
880 case X25_FAC_CALLED_MODIF:
882 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
883 "(Called address modified)", fac);
884 fac_subtree = proto_item_add_subtree(ti,
885 ett_x25_fac_called_modif);
886 proto_tree_add_text(fac_tree, tvb, *offset+1, 1,
887 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
890 case X25_FAC_CUG_OUTGOING_ACC:
892 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
893 "(Closed user group with outgoing access selection)",
895 fac_subtree = proto_item_add_subtree(ti,
896 ett_x25_fac_cug_outgoing_acc);
897 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
898 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
901 case X25_FAC_THROUGHPUT_MIN:
903 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
904 "(Minimum throughput class)", fac);
905 fac_subtree = proto_item_add_subtree(ti,
906 ett_x25_fac_throughput_min);
907 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
908 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
911 case X25_FAC_EXPRESS_DATA:
913 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
914 "(Negociation of express data)", fac);
915 fac_subtree = proto_item_add_subtree(ti,
916 ett_x25_fac_express_data);
917 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
918 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
923 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
924 "Code : %02X (Unknown class A)", fac);
925 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
926 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
927 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
934 case X25_FAC_CLASS_B:
936 case X25_FAC_BILATERAL_CUG:
938 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
939 "(Bilateral closed user group selection)", fac);
940 fac_subtree = proto_item_add_subtree(ti,
941 ett_x25_fac_bilateral_cug);
942 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
943 "Bilateral CUG: %04X",
944 tvb_get_ntohs(tvb, *offset+1));
947 case X25_FAC_PACKET_SIZE:
952 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
953 "(Packet size)", fac);
954 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_packet_size);
955 byte1 = tvb_get_guint8(tvb, *offset + 1);
959 sprintf(tmpbuf, "From the called DTE : %%u (16)");
962 sprintf(tmpbuf, "From the called DTE : %%u (32)");
965 sprintf(tmpbuf, "From the called DTE : %%u (64)");
968 sprintf(tmpbuf, "From the called DTE : %%u (128)");
971 sprintf(tmpbuf, "From the called DTE : %%u (256)");
974 sprintf(tmpbuf, "From the called DTE : %%u (512)");
977 sprintf(tmpbuf, "From the called DTE : %%u (1024)");
980 sprintf(tmpbuf, "From the called DTE : %%u (2048)");
983 sprintf(tmpbuf, "From the called DTE : %%u (4096)");
986 sprintf(tmpbuf, "From the called DTE : %%u (Unknown)");
989 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
990 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
992 byte2 = tvb_get_guint8(tvb, *offset + 1);
996 sprintf(tmpbuf, "From the calling DTE : %%u (16)");
999 sprintf(tmpbuf, "From the calling DTE : %%u (32)");
1002 sprintf(tmpbuf, "From the calling DTE : %%u (64)");
1005 sprintf(tmpbuf, "From the calling DTE : %%u (128)");
1008 sprintf(tmpbuf, "From the calling DTE : %%u (256)");
1011 sprintf(tmpbuf, "From the calling DTE : %%u (512)");
1014 sprintf(tmpbuf, "From the calling DTE : %%u (1024)");
1017 sprintf(tmpbuf, "From the calling DTE : %%u (2048)");
1020 sprintf(tmpbuf, "From the calling DTE : %%u (4096)");
1023 sprintf(tmpbuf, "From the calling DTE : %%u (Unknown)");
1026 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1027 decode_numeric_bitfield(byte2, 0x0F, 1*8, tmpbuf));
1030 case X25_FAC_WINDOW_SIZE:
1032 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1033 "(Window size)", fac);
1034 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_window_size);
1035 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1036 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+1),
1037 0x7F, 1*8, "From the called DTE: %u"));
1038 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1039 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+2),
1040 0x7F, 1*8, "From the calling DTE: %u"));
1043 case X25_FAC_RPOA_SELECTION:
1045 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1046 "(RPOA selection)", fac);
1047 fac_subtree = proto_item_add_subtree(ti,
1048 ett_x25_fac_rpoa_selection);
1049 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
1050 "Data network identification code : %04X",
1051 tvb_get_ntohs(tvb, *offset+1));
1054 case X25_FAC_TRANSIT_DELAY:
1056 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1057 "(Transit delay selection and indication)", fac);
1058 fac_subtree = proto_item_add_subtree(ti,
1059 ett_x25_fac_transit_delay);
1060 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
1061 "Transit delay: %d ms",
1062 tvb_get_ntohs(tvb, *offset+1));
1067 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1068 "Code : %02X (Unknown class B)", fac);
1069 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1070 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
1071 "Parameter %04X", tvb_get_ntohs(tvb, *offset+1));
1078 case X25_FAC_CLASS_C:
1080 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1081 "Code : %02X (Unknown class C)", fac);
1082 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1083 proto_tree_add_text(fac_subtree, tvb, *offset+1, 3,
1085 tvb_get_ntoh24(tvb, *offset+1));
1090 case X25_FAC_CLASS_D:
1092 case X25_FAC_CALL_TRANSFER:
1097 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1098 "(Call redirection or deflection notification)", fac);
1099 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_call_transfer);
1100 byte1 = tvb_get_guint8(tvb, *offset+1);
1101 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1102 "Length : %u", byte1);
1103 byte2 = tvb_get_guint8(tvb, *offset+2);
1104 if ((byte2 & 0xC0) == 0xC0) {
1105 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1106 "Reason : call deflection by the originally "
1107 "called DTE address");
1112 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1113 "Reason : originally called DTE busy");
1116 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1117 "Reason : call dist. within a hunt group");
1120 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1121 "Reason : originally called DTE out of order");
1124 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1125 "Reason : systematic call redirection");
1128 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1129 "Reason : unknown");
1133 byte3 = tvb_get_guint8(tvb, *offset+3);
1134 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1135 "Number of semi-octets in DTE address : %u",
1137 for (i = 0; i < byte3; i++) {
1139 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1141 /* if > 9, convert to the right hexadecimal letter */
1142 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1144 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1146 /* if > 9, convert to the right hexadecimal letter */
1147 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1151 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1152 "DTE address : %s", tmpbuf);
1155 case X25_FAC_CALLING_ADDR_EXT:
1160 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1161 "(Calling address extension)", fac);
1162 fac_subtree = proto_item_add_subtree(ti,
1163 ett_x25_fac_calling_addr_ext);
1164 byte1 = tvb_get_guint8(tvb, *offset+1);
1165 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1166 "Length : %u", byte1);
1167 byte2 = tvb_get_guint8(tvb, *offset+2);
1168 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1169 "Number of semi-octets in DTE address : %u", byte2);
1170 for (i = 0; i < byte2; i++) {
1172 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1174 /* if > 9, convert to the right hexadecimal letter */
1175 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1177 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1179 /* if > 9, convert to the right hexadecimal letter */
1180 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1184 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1185 "DTE address : %s", tmpbuf);
1188 case X25_FAC_CALLED_ADDR_EXT:
1193 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1194 "(Called address extension)", fac);
1195 fac_subtree = proto_item_add_subtree(ti,
1196 ett_x25_fac_called_addr_ext);
1197 byte1 = tvb_get_guint8(tvb, *offset+1);
1198 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1199 "Length : %u", byte1);
1200 byte2 = tvb_get_guint8(tvb, *offset+2);
1201 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1202 "Number of semi-octets in DTE address : %u", byte2);
1203 for (i = 0; i < byte2; i++) {
1205 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1207 /* if > 9, convert to the right hexadecimal letter */
1208 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1210 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1212 /* if > 9, convert to the right hexadecimal letter */
1213 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1217 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1218 "DTE address : %s", tmpbuf);
1221 case X25_FAC_ETE_TRANSIT_DELAY:
1223 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1224 "(End to end transit delay)", fac);
1225 fac_subtree = proto_item_add_subtree(ti,
1226 ett_x25_fac_ete_transit_delay);
1227 byte1 = tvb_get_guint8(tvb, *offset+1);
1228 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1229 "Length : %u", byte1);
1230 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1233 case X25_FAC_CALL_DEFLECT:
1238 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1239 "(Call deflection selection)", fac);
1240 fac_subtree = proto_item_add_subtree(ti,
1241 ett_x25_fac_call_deflect);
1242 byte1 = tvb_get_guint8(tvb, *offset+1);
1243 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1244 "Length : %u", byte1);
1245 byte2 = tvb_get_guint8(tvb, *offset+2);
1246 if ((byte2 & 0xC0) == 0xC0)
1247 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1248 "Reason : call DTE originated");
1250 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1251 "Reason : unknown");
1252 byte3 = tvb_get_guint8(tvb, *offset+3);
1253 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1254 "Number of semi-octets in the alternative DTE address : %u",
1256 for (i = 0; i < byte3; i++) {
1258 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1260 /* if > 9, convert to the right hexadecimal letter */
1261 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1263 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1265 /* if > 9, convert to the right hexadecimal letter */
1266 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1270 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1271 "Alternative DTE address : %s", tmpbuf);
1274 case X25_FAC_PRIORITY:
1276 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1277 "Code : %02X (Priority)", fac);
1278 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_priority);
1279 byte1 = tvb_get_guint8(tvb, *offset+1);
1280 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1281 "Length : %u", byte1);
1282 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1287 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1288 "Code : %02X (Unknown class D)", fac);
1289 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1290 byte1 = tvb_get_guint8(tvb, *offset+1);
1291 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1292 "Length : %u", byte1);
1293 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1296 byte1 = tvb_get_guint8(tvb, *offset+1);
1297 (*offset) += byte1+2;
1305 x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1306 frame_data *fd, gboolean toa)
1310 char addr1[16], addr2[16];
1311 char *first, *second;
1315 byte = tvb_get_guint8(tvb, *offset);
1316 len1 = (byte >> 4) & 0x0F;
1317 len2 = (byte >> 0) & 0x0F;
1319 proto_tree_add_text(tree, tvb, *offset, 1,
1320 decode_numeric_bitfield(byte, 0xF0, 1*8,
1321 toa ? "Called 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 toa ? "Calling address length : %u" :
1326 "Called address length : %u"));
1330 localoffset = *offset;
1331 byte = tvb_get_guint8(tvb, localoffset);
1335 for (i = 0; i < (len1 + len2); i++) {
1338 *first++ = ((byte >> 0) & 0x0F) + '0';
1340 byte = tvb_get_guint8(tvb, localoffset);
1342 *first++ = ((byte >> 4) & 0x0F) + '0';
1346 *second++ = ((byte >> 0) & 0x0F) + '0';
1348 byte = tvb_get_guint8(tvb, localoffset);
1350 *second++ = ((byte >> 4) & 0x0F) + '0';
1360 if (check_col(fd, COL_RES_DL_DST))
1361 col_add_str(fd, COL_RES_DL_DST, addr1);
1364 if(check_col(fd, COL_RES_DL_SRC))
1365 col_add_str(fd, COL_RES_DL_SRC, addr1);
1368 proto_tree_add_text(tree, tvb, *offset,
1371 toa ? "Called" : "Calling",
1376 if (check_col(fd, COL_RES_DL_SRC))
1377 col_add_str(fd, COL_RES_DL_SRC, addr2);
1380 if(check_col(fd, COL_RES_DL_DST))
1381 col_add_str(fd, COL_RES_DL_DST, addr2);
1384 proto_tree_add_text(tree, tvb, *offset + len1/2,
1385 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1387 toa ? "Calling" : "Called",
1390 (*offset) += ((len1 + len2 + 1) / 2);
1394 get_x25_pkt_len(tvbuff_t *tvb)
1396 guint length, called_len, calling_len, dte_len, dce_len;
1397 guint8 byte2, bytex;
1399 byte2 = tvb_get_guint8(tvb, 2);
1402 case X25_CALL_REQUEST:
1403 bytex = tvb_get_guint8(tvb, 3);
1404 called_len = (bytex >> 0) & 0x0F;
1405 calling_len = (bytex >> 4) & 0x0F;
1406 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1407 if (length < tvb_reported_length(tvb))
1408 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1410 return MIN(tvb_reported_length(tvb),length);
1412 case X25_CALL_ACCEPTED:
1413 /* The calling/called address length byte (following the packet type)
1414 * is not mandatory, so we must check the packet length before trying
1416 if (tvb_reported_length(tvb) == 3)
1418 bytex = tvb_get_guint8(tvb, 3);
1419 called_len = (bytex >> 0) & 0x0F;
1420 calling_len = (bytex >> 4) & 0x0F;
1421 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1422 if (length < tvb_reported_length(tvb))
1423 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1425 return MIN(tvb_reported_length(tvb),length);
1427 case X25_CLEAR_REQUEST:
1428 case X25_RESET_REQUEST:
1429 case X25_RESTART_REQUEST:
1430 return MIN(tvb_reported_length(tvb),5);
1432 case X25_DIAGNOSTIC:
1433 return MIN(tvb_reported_length(tvb),4);
1435 case X25_CLEAR_CONFIRMATION:
1437 case X25_INTERRUPT_CONFIRMATION:
1438 case X25_RESET_CONFIRMATION:
1439 case X25_RESTART_CONFIRMATION:
1440 return MIN(tvb_reported_length(tvb),3);
1442 case X25_REGISTRATION_REQUEST:
1443 bytex = tvb_get_guint8(tvb, 3);
1444 dce_len = (bytex >> 0) & 0x0F;
1445 dte_len = (bytex >> 4) & 0x0F;
1446 length = 4 + (dte_len + dce_len + 1) / 2; /* addr */
1447 if (length < tvb_reported_length(tvb))
1448 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1450 return MIN(tvb_reported_length(tvb),length);
1452 case X25_REGISTRATION_CONFIRMATION:
1453 bytex = tvb_get_guint8(tvb, 5);
1454 dce_len = (bytex >> 0) & 0x0F;
1455 dte_len = (bytex >> 4) & 0x0F;
1456 length = 6 + (dte_len + dce_len + 1) / 2; /* addr */
1457 if (length < tvb_reported_length(tvb))
1458 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1460 return MIN(tvb_reported_length(tvb),length);
1463 if ((byte2 & 0x01) == X25_DATA) return MIN(tvb_reported_length(tvb),3);
1465 switch (byte2 & 0x1F)
1468 return MIN(tvb_reported_length(tvb),3);
1471 return MIN(tvb_reported_length(tvb),3);
1474 return MIN(tvb_reported_length(tvb),3);
1480 #define PRT_ID_ISO_8073 0x01
1482 static const value_string prt_id_vals[] = {
1483 {PRT_ID_ISO_8073, "ISO 8073 COTP"},
1485 {0x03, "ISO 10732 in conjunction with ISO 8073"},
1486 {0x04, "ISO 10736 in conjunction with ISO 8602"},
1490 static const value_string sharing_strategy_vals[] = {
1491 {0x00, "No sharing"},
1496 dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1498 proto_tree *x25_tree=0, *gfi_tree=0, *userdata_tree=0;
1500 guint localoffset=0;
1505 gboolean toa; /* TOA/NPI address format */
1509 gboolean q_bit_set = FALSE;
1511 if (check_col(pinfo->fd, COL_PROTOCOL))
1512 col_set_str(pinfo->fd, COL_PROTOCOL, "X.25");
1514 bytes0_1 = tvb_get_ntohs(tvb, 0);
1516 modulo = ((bytes0_1 & 0x2000) ? 128 : 8);
1517 vc = (int)(bytes0_1 & 0x0FFF);
1519 if (bytes0_1 & 0x8000) toa = TRUE;
1522 x25_pkt_len = get_x25_pkt_len(tvb);
1523 if (x25_pkt_len < 3) /* packet too short */
1525 if (check_col(pinfo->fd, COL_INFO))
1526 col_set_str(pinfo->fd, COL_INFO, "Invalid/short X.25 packet");
1528 proto_tree_add_protocol_format(tree, proto_x25, tvb, 0,
1529 tvb_length(tvb), "Invalid/short X.25 packet");
1533 pkt_type = tvb_get_guint8(tvb, 2);
1536 ti = proto_tree_add_item(tree, proto_x25, tvb, 0, x25_pkt_len, FALSE);
1537 x25_tree = proto_item_add_subtree(ti, ett_x25);
1538 ti = proto_tree_add_item(x25_tree, hf_x25_gfi, tvb, 0, 2, FALSE);
1539 gfi_tree = proto_item_add_subtree(ti, ett_x25_gfi);
1541 if ((pkt_type & 0x01) == X25_DATA) {
1542 proto_tree_add_boolean(gfi_tree, hf_x25_qbit, tvb, 0, 2,
1544 if (bytes0_1 & 0x8000) {
1548 else if (pkt_type == X25_CALL_REQUEST ||
1549 pkt_type == X25_CALL_ACCEPTED ||
1550 pkt_type == X25_CLEAR_REQUEST ||
1551 pkt_type == X25_CLEAR_CONFIRMATION) {
1552 proto_tree_add_boolean(gfi_tree, hf_x25_abit, tvb, 0, 2,
1556 if (pkt_type == X25_CALL_REQUEST || pkt_type == X25_CALL_ACCEPTED ||
1557 (pkt_type & 0x01) == X25_DATA) {
1558 proto_tree_add_boolean(gfi_tree, hf_x25_dbit, tvb, 0, 2,
1561 proto_tree_add_uint(gfi_tree, hf_x25_mod, tvb, 0, 2, bytes0_1);
1565 case X25_CALL_REQUEST:
1566 if (check_col(pinfo->fd, COL_INFO))
1567 col_add_fstr(pinfo->fd, COL_INFO, "%s VC:%d",
1568 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Inc. call"
1572 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb,
1574 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1576 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Incoming call"
1580 if (localoffset < x25_pkt_len) /* calling/called addresses */
1581 x25_ntoa(x25_tree, &localoffset, tvb, pinfo->fd, toa);
1583 if (localoffset < x25_pkt_len) /* facilities */
1584 dump_facilities(x25_tree, &localoffset, tvb);
1586 if (localoffset < tvb_reported_length(tvb)) /* user data */
1593 ti = proto_tree_add_text(x25_tree, tvb, localoffset,
1594 tvb_length_remaining(tvb, localoffset),
1596 userdata_tree = proto_item_add_subtree(ti, ett_x25_user_data);
1599 /* X.263/ISO 9577 says that:
1601 When CLNP or ESIS are run over X.25, the SPI
1602 is 0x81 or 0x82, respectively; those are the
1603 NLPIDs for those protocol.
1605 When X.224/ISO 8073 COTP is run over X.25, and
1606 when ISO 11570 explicit identification is being
1607 used, the first octet of the user data field is
1608 a TPDU length field, and the rest is "as defined
1609 in ITU-T Rec. X.225 | ISO/IEC 8073, Annex B,
1610 or ITU-T Rec. X.264 and ISO/IEC 11570".
1612 When X.264/ISO 11570 default identification is
1613 being used, there is no user data field in the
1614 CALL REQUEST packet. This is for X.225/ISO 8073
1617 It also says that SPI values from 0x03 through 0x3f are
1618 reserved and are in use by X.224/ISO 8073 Annex B and
1619 X.264/ISO 11570. The note says that those values are
1620 not NLPIDs, they're "used by the respective higher layer
1621 protocol" and "not used for higher layer protocol
1622 identification". I infer from this and from what
1623 X.264/ISO 11570 says that this means that values in those
1624 range are valid values for the first octet of an
1625 X.224/ISO 8073 packet or for X.264/ISO 11570.
1627 Annex B of X.225/ISO 8073 mentions some additional TPDU
1628 types that can be put in what I presume is the user
1629 data of connect requests. It says that:
1631 The sending transport entity shall:
1633 a) either not transmit any TPDU in the NS-user data
1634 parameter of the N-CONNECT request primitive; or
1636 b) transmit the UN-TPDU (see ITU-T Rec. X.264 and
1637 ISO/IEC 11570) followed by the NCM-TPDU in the
1638 NS-user data parameter of the N-CONNECT request
1641 I don't know if this means that the user data field
1642 will contain a UN TPDU followed by an NCM TPDU or not.
1644 X.264/ISO 11570 says that:
1646 When default identification is being used,
1647 X.225/ISO 8073 COTP is identified. No user data
1648 is sent in the network-layer connection request.
1650 When explicit identification is being used,
1651 the user data is a UN TPDU ("Use of network
1652 connection TPDU"), which specifies the transport
1653 protocol to use over this network connection.
1654 It also says that the length of a UN TPDU shall
1655 not exceed 32 octets, i.e. shall not exceed 0x20;
1656 it says this is "due to the desire not to conflict
1657 with the protocol identifier field carried by X.25
1658 CALL REQUEST/INCOMING CALL packets", and says that
1659 field has values specified in X.244. X.244 has been
1660 superseded by X.263/ISO 9577, so that presumably
1661 means the goal is to allow a UN TPDU's length
1662 field to be distinguished from an NLPID, allowing
1663 you to tell whether X.264/ISO 11570 explicit
1664 identification is being used or an NLPID is
1665 being used as the SPI.
1667 I read this as meaning that, if the ISO mechanisms are
1668 used to identify the protocol being carried over X.25:
1670 if there's no user data in the CALL REQUEST/
1671 INCOMING CALL packet, it's COTP;
1673 if there is user data, then:
1675 if the first octet is less than or equal to
1676 32, it might be a UN TPDU, and that identifies
1677 the transport protocol being used, and
1678 it may be followed by more data, such
1679 as a COTP NCM TPDU if it's COTP;
1681 if the first octet is greater than 32, it's
1682 an NLPID, *not* a TPDU length, and the
1683 stuff following it is *not* a TPDU.
1685 Figure A.2 of X.263/ISO 9577 seems to say that the
1686 first octet of the user data is a TPDU length field,
1687 in the range 0x03 through 0x82, and says they are
1688 for X.225/ISO 8073 Annex B or X.264/ISO 11570.
1690 However, X.264/ISO 11570 seems to imply that the length
1691 field would be that of a UN TPDU, which must be less
1692 than or equal to 0x20, and X.225/ISO 8073 Annex B seems
1693 to indicate that the user data must begin with
1694 an X.264/ISO 11570 UN TPDU, so I'd say that A.2 should
1695 have said "in the range 0x03 through 0x20", instead
1696 (the length value doesn't include the length field,
1697 and the minimum UN TPDU has length, type, PRT-ID,
1698 and SHARE, so that's 3 bytes without the length). */
1699 spi = tvb_get_guint8(tvb, localoffset);
1700 if (spi > 32 || spi < 3) {
1701 /* First octet is > 32, or < 3, so the user data isn't an
1702 X.264/ISO 11570 UN TPDU */
1705 /* First octet is >= 3 and <= 32, so the user data *might*
1706 be an X.264/ISO 11570 UN TPDU. Check whether we have
1707 enough data to see if it is. */
1708 if (tvb_bytes_exist(tvb, localoffset+1, 1)) {
1709 /* We do; check whether the second octet is 1. */
1710 if (tvb_get_guint8(tvb, localoffset+1) == 0x01) {
1711 /* Yes, the second byte is 1, so it looks like
1715 /* No, the second byte is not 1, so it's not a
1720 /* We can't see the second byte of the putative UN
1721 TPDU, so we don't know if that's what it is. */
1725 if (is_x_264 == -1) {
1727 * We don't know what it is; just skip it.
1729 localoffset = tvb_length(tvb);
1730 } else if (is_x_264) {
1731 /* It looks like an X.264 UN TPDU, so show it as such. */
1732 if (userdata_tree) {
1733 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1734 "X.264 length indicator: %u",
1736 proto_tree_add_text(userdata_tree, tvb, localoffset+1, 1,
1737 "X.264 UN TPDU identifier: 0x%02X",
1738 tvb_get_guint8(tvb, localoffset+1));
1740 prt_id = tvb_get_guint8(tvb, localoffset+2);
1741 if (userdata_tree) {
1742 proto_tree_add_text(x25_tree, tvb, localoffset+2, 1,
1743 "X.264 protocol identifier: %s",
1744 val_to_str(prt_id, prt_id_vals,
1745 "Unknown (0x%02X)"));
1746 proto_tree_add_text(x25_tree, tvb, localoffset+3, 1,
1747 "X.264 sharing strategy: %s",
1748 val_to_str(tvb_get_guint8(tvb, localoffset+3),
1749 sharing_strategy_vals, "Unknown (0x%02X)"));
1752 /* XXX - dissect the variable part? */
1754 /* The length doesn't include the length octet itself. */
1755 localoffset += spi + 1;
1759 case PRT_ID_ISO_8073:
1761 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
1762 pinfo->fd->abs_usecs,
1764 /* XXX - disssect the rest of the user data as COTP?
1765 That needs support for NCM TPDUs, etc. */
1768 } else if (is_x_264 == 0) {
1769 /* It doesn't look like a UN TPDU, so compare the first
1770 octet of the CALL REQUEST packet with various X.263/
1771 ISO 9577 NLPIDs, as per Annex A of X.263/ISO 9577. */
1773 if (userdata_tree) {
1774 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1775 "X.263 secondary protocol ID: %s",
1776 val_to_str(spi, nlpid_vals, "Unknown (0x%02x)"));
1780 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
1781 pinfo->fd->abs_usecs, spi);
1783 if (localoffset < tvb_length(tvb)) {
1784 if (userdata_tree) {
1785 proto_tree_add_text(userdata_tree, tvb, localoffset,
1786 tvb_length(tvb)-localoffset, "Data");
1788 localoffset = tvb_length(tvb);
1792 case X25_CALL_ACCEPTED:
1793 if(check_col(pinfo->fd, COL_INFO))
1794 col_add_fstr(pinfo->fd, COL_INFO, "%s VC:%d",
1795 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Call conn."
1799 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1800 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1802 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Call connected"
1806 if (localoffset < x25_pkt_len) /* calling/called addresses */
1807 x25_ntoa(x25_tree, &localoffset, tvb, pinfo->fd, toa);
1809 if (localoffset < x25_pkt_len) /* facilities */
1810 dump_facilities(x25_tree, &localoffset, tvb);
1812 if (localoffset < tvb_reported_length(tvb)) { /* user data */
1814 proto_tree_add_text(x25_tree, tvb, localoffset,
1815 tvb_reported_length(tvb)-localoffset, "Data");
1816 localoffset=tvb_reported_length(tvb);
1819 case X25_CLEAR_REQUEST:
1820 if(check_col(pinfo->fd, COL_INFO)) {
1821 col_add_fstr(pinfo->fd, COL_INFO, "%s VC:%d %s - %s",
1822 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Clear ind."
1824 vc, clear_code(tvb_get_guint8(tvb, 3)),
1825 clear_diag(tvb_get_guint8(tvb, 4)));
1827 x25_hash_add_proto_end(vc, pinfo->fd->abs_secs, pinfo->fd->abs_usecs);
1829 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1830 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb,
1831 localoffset+2, 1, X25_CLEAR_REQUEST,
1832 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Clear indication"
1834 proto_tree_add_text(x25_tree, tvb, 3, 1,
1835 "Cause : %s", clear_code(tvb_get_guint8(tvb, 3)));
1836 proto_tree_add_text(x25_tree, tvb, 4, 1,
1837 "Diagnostic : %s", clear_diag(tvb_get_guint8(tvb, 4)));
1839 localoffset = x25_pkt_len;
1841 case X25_CLEAR_CONFIRMATION:
1842 if(check_col(pinfo->fd, COL_INFO))
1843 col_add_fstr(pinfo->fd, COL_INFO, "Clear Conf. VC:%d", vc);
1845 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1846 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1847 X25_CLEAR_CONFIRMATION);
1849 localoffset = x25_pkt_len;
1851 if (localoffset < tvb_reported_length(tvb)) /* extended clear conf format */
1852 x25_ntoa(x25_tree, &localoffset, tvb, pinfo->fd, toa);
1854 if (localoffset < tvb_reported_length(tvb)) /* facilities */
1855 dump_facilities(x25_tree, &localoffset, tvb);
1857 case X25_DIAGNOSTIC:
1858 if(check_col(pinfo->fd, COL_INFO)) {
1859 col_add_fstr(pinfo->fd, COL_INFO, "Diag. %d",
1860 (int)tvb_get_guint8(tvb, 3));
1863 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1865 proto_tree_add_text(x25_tree, tvb, 3, 1,
1866 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 3));
1868 localoffset = x25_pkt_len;
1871 if(check_col(pinfo->fd, COL_INFO))
1872 col_add_fstr(pinfo->fd, COL_INFO, "Interrupt VC:%d", vc);
1874 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1875 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1878 localoffset = x25_pkt_len;
1880 case X25_INTERRUPT_CONFIRMATION:
1881 if(check_col(pinfo->fd, COL_INFO))
1882 col_add_fstr(pinfo->fd, COL_INFO, "Interrupt Conf. VC:%d", vc);
1884 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1885 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1886 X25_INTERRUPT_CONFIRMATION);
1888 localoffset = x25_pkt_len;
1890 case X25_RESET_REQUEST:
1891 if(check_col(pinfo->fd, COL_INFO)) {
1892 col_add_fstr(pinfo->fd, COL_INFO, "%s VC:%d %s - Diag.:%d",
1893 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Reset ind."
1895 vc, reset_code(tvb_get_guint8(tvb, 3)),
1896 (int)tvb_get_guint8(tvb, 4));
1898 x25_hash_add_proto_end(vc, pinfo->fd->abs_secs, pinfo->fd->abs_usecs);
1900 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1901 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1903 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Reset indication"
1905 proto_tree_add_text(x25_tree, tvb, 3, 1,
1906 "Cause : %s", reset_code(tvb_get_guint8(tvb, 3)));
1907 proto_tree_add_text(x25_tree, tvb, 4, 1,
1908 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
1910 localoffset = x25_pkt_len;
1912 case X25_RESET_CONFIRMATION:
1913 if(check_col(pinfo->fd, COL_INFO))
1914 col_add_fstr(pinfo->fd, COL_INFO, "Reset conf. VC:%d", vc);
1916 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1917 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1918 X25_RESET_CONFIRMATION);
1920 localoffset = x25_pkt_len;
1922 case X25_RESTART_REQUEST:
1923 if(check_col(pinfo->fd, COL_INFO)) {
1924 col_add_fstr(pinfo->fd, COL_INFO, "%s %s - Diag.:%d",
1925 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Restart ind."
1927 restart_code(tvb_get_guint8(tvb, 3)),
1928 (int)tvb_get_guint8(tvb, 3));
1931 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1932 X25_RESTART_REQUEST,
1933 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Restart indication"
1934 : "Restart request");
1935 proto_tree_add_text(x25_tree, tvb, 3, 1,
1936 "Cause : %s", restart_code(tvb_get_guint8(tvb, 3)));
1937 proto_tree_add_text(x25_tree, tvb, 4, 1,
1938 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
1940 localoffset = x25_pkt_len;
1942 case X25_RESTART_CONFIRMATION:
1943 if(check_col(pinfo->fd, COL_INFO))
1944 col_set_str(pinfo->fd, COL_INFO, "Restart conf.");
1946 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1947 X25_RESTART_CONFIRMATION);
1948 localoffset = x25_pkt_len;
1950 case X25_REGISTRATION_REQUEST:
1951 if(check_col(pinfo->fd, COL_INFO))
1952 col_set_str(pinfo->fd, COL_INFO, "Registration req.");
1954 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1955 X25_REGISTRATION_REQUEST);
1957 if (localoffset < x25_pkt_len)
1958 x25_ntoa(x25_tree, &localoffset, tvb, pinfo->fd, FALSE);
1961 if (localoffset < x25_pkt_len)
1962 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
1963 "Registration length: %d",
1964 tvb_get_guint8(tvb, localoffset) & 0x7F);
1965 if (localoffset+1 < x25_pkt_len)
1966 proto_tree_add_text(x25_tree, tvb, localoffset+1,
1967 tvb_get_guint8(tvb, localoffset) & 0x7F,
1970 localoffset = tvb_reported_length(tvb);
1972 case X25_REGISTRATION_CONFIRMATION:
1973 if(check_col(pinfo->fd, COL_INFO))
1974 col_set_str(pinfo->fd, COL_INFO, "Registration conf.");
1976 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1977 X25_REGISTRATION_CONFIRMATION);
1978 proto_tree_add_text(x25_tree, tvb, 3, 1,
1979 "Cause: %s", registration_code(tvb_get_guint8(tvb, 3)));
1980 proto_tree_add_text(x25_tree, tvb, 4, 1,
1981 "Diagnostic: %s", registration_code(tvb_get_guint8(tvb, 4)));
1984 if (localoffset < x25_pkt_len)
1985 x25_ntoa(x25_tree, &localoffset, tvb, pinfo->fd, TRUE);
1988 if (localoffset < x25_pkt_len)
1989 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
1990 "Registration length: %d",
1991 tvb_get_guint8(tvb, localoffset) & 0x7F);
1992 if (localoffset+1 < x25_pkt_len)
1993 proto_tree_add_text(x25_tree, tvb, localoffset+1,
1994 tvb_get_guint8(tvb, localoffset) & 0x7F,
1997 localoffset = tvb_reported_length(tvb);
2001 if ((pkt_type & 0x01) == X25_DATA)
2003 if(check_col(pinfo->fd, COL_INFO)) {
2005 col_add_fstr(pinfo->fd, COL_INFO,
2006 "Data VC:%d P(S):%d P(R):%d %s", vc,
2007 (pkt_type >> 1) & 0x07,
2008 (pkt_type >> 5) & 0x07,
2009 ((pkt_type >> 4) & 0x01) ? " M" : "");
2011 col_add_fstr(pinfo->fd, COL_INFO,
2012 "Data VC:%d P(S):%d P(R):%d %s", vc,
2013 tvb_get_guint8(tvb, localoffset+1) >> 1,
2015 (tvb_get_guint8(tvb, localoffset+1) & 0x01) ? " M" : "");
2018 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2020 proto_tree_add_uint_hidden(x25_tree, hf_x25_type, tvb,
2021 localoffset, 1, X25_DATA);
2023 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2024 localoffset, 1, pkt_type);
2025 if (pkt_type & 0x10)
2026 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod8, tvb,
2027 localoffset, 1, pkt_type);
2028 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod8, tvb,
2029 localoffset, 1, pkt_type);
2030 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
2031 decode_boolean_bitfield(pkt_type, 0x01, 1*8,
2035 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod128, tvb,
2036 localoffset, 1, pkt_type);
2037 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod128, tvb,
2039 tvb_get_guint8(tvb, localoffset+1));
2040 if (tvb_get_guint8(tvb, localoffset+1) & 0x01)
2041 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod128, tvb,
2043 tvb_get_guint8(tvb, localoffset+1));
2046 localoffset += (modulo == 8) ? 1 : 2;
2049 switch (pkt_type & 0x1F)
2052 if(check_col(pinfo->fd, COL_INFO)) {
2054 col_add_fstr(pinfo->fd, COL_INFO, "RR VC:%d P(R):%d",
2055 vc, (pkt_type >> 5) & 0x07);
2057 col_add_fstr(pinfo->fd, COL_INFO, "RR VC:%d P(R):%d",
2058 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2061 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2064 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2065 localoffset, 1, pkt_type);
2066 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2067 localoffset, 1, X25_RR);
2070 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2071 localoffset, 1, X25_RR);
2072 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2073 localoffset+1, 1, FALSE);
2079 if(check_col(pinfo->fd, COL_INFO)) {
2081 col_add_fstr(pinfo->fd, COL_INFO, "RNR VC:%d P(R):%d",
2082 vc, (pkt_type >> 5) & 0x07);
2084 col_add_fstr(pinfo->fd, COL_INFO, "RNR VC:%d P(R):%d",
2085 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2088 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2091 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2092 localoffset, 1, pkt_type);
2093 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2094 localoffset, 1, X25_RNR);
2097 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2098 localoffset, 1, X25_RNR);
2099 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2100 localoffset+1, 1, FALSE);
2106 if(check_col(pinfo->fd, COL_INFO)) {
2108 col_add_fstr(pinfo->fd, COL_INFO, "REJ VC:%d P(R):%d",
2109 vc, (pkt_type >> 5) & 0x07);
2111 col_add_fstr(pinfo->fd, COL_INFO, "REJ VC:%d P(R):%d",
2112 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2115 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2118 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2119 localoffset, 1, pkt_type);
2120 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2121 localoffset, 1, X25_REJ);
2124 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2125 localoffset, 1, X25_REJ);
2126 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2127 localoffset+1, 1, FALSE);
2131 localoffset += (modulo == 8) ? 1 : 2;
2134 if (localoffset >= tvb_reported_length(tvb)) return;
2136 next_tvb = tvb_new_subset(tvb, localoffset, -1, -1);
2140 call_dissector(qllc_handle, next_tvb, pinfo, tree);
2144 /* search the protocol in the hash table */
2145 proto = x25_hash_get_proto(pinfo->fd->abs_secs, pinfo->fd->abs_usecs, vc);
2149 /* Did the user suggest SNA-over-X.25? */
2150 if (non_q_bit_is_sna) {
2151 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
2152 pinfo->fd->abs_usecs, PROTO_SNA);
2153 call_dissector(sna_handle, next_tvb, pinfo, tree);
2156 /* If the Call Req. has not been captured, and the payload begins
2157 with what appears to be an IP header, assume these packets carry
2159 if (tvb_get_guint8(tvb, localoffset) == 0x45) {
2160 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
2161 pinfo->fd->abs_usecs, NLPID_IP);
2162 if (dissector_try_port(x25_subdissector_table, NLPID_IP,
2163 next_tvb, pinfo, tree))
2169 call_dissector(sna_handle, next_tvb, pinfo, tree);
2172 case PROTO_ISO_8073:
2173 call_dissector(ositp_handle, next_tvb, pinfo, tree);
2177 if (dissector_try_port(x25_subdissector_table, proto,
2178 next_tvb, pinfo, tree))
2182 call_dissector(data_handle, next_tvb, pinfo, tree);
2186 proto_register_x25(void)
2188 static hf_register_info hf[] = {
2190 { "GFI", "x.25.gfi", FT_UINT16, BASE_BIN, NULL, 0xF000,
2191 "General format identifier", HFILL }},
2193 { "A Bit", "x.25.a", FT_BOOLEAN, 16, NULL, 0x8000,
2194 "Address Bit", HFILL }},
2196 { "Q Bit", "x.25.q", FT_BOOLEAN, 16, NULL, 0x8000,
2197 "Qualifier Bit", HFILL }},
2199 { "D Bit", "x.25.d", FT_BOOLEAN, 16, NULL, 0x4000,
2200 "Delivery Confirmation Bit", HFILL }},
2202 { "Modulo", "x.25.mod", FT_UINT16, BASE_DEC, VALS(vals_modulo), 0x3000,
2203 "Specifies whether the frame is modulo 8 or 128", HFILL }},
2205 { "Logical Channel", "x.25.lcn", FT_UINT16, BASE_DEC, NULL, 0x0FFF,
2206 "Logical Channel Number", HFILL }},
2208 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x0,
2209 "Packet Type", HFILL }},
2211 { "P(R)", "x.25.p_r", FT_UINT8, BASE_HEX, NULL, 0xE0,
2212 "Packet Receive Sequence Number", HFILL }},
2213 { &hf_x25_p_r_mod128,
2214 { "P(R)", "x.25.p_r", FT_UINT8, BASE_HEX, NULL, 0xFE,
2215 "Packet Receive Sequence Number", HFILL }},
2216 { &hf_x25_mbit_mod8,
2217 { "M Bit", "x.25.m", FT_BOOLEAN, 8, NULL, 0x10,
2218 "More Bit", HFILL }},
2219 { &hf_x25_mbit_mod128,
2220 { "M Bit", "x.25.m", FT_BOOLEAN, 8, NULL, 0x01,
2221 "More Bit", HFILL }},
2223 { "P(S)", "x.25.p_s", FT_UINT8, BASE_HEX, NULL, 0x0E,
2224 "Packet Send Sequence Number", HFILL }},
2225 { &hf_x25_p_s_mod128,
2226 { "P(S)", "x.25.p_s", FT_UINT8, BASE_HEX, NULL, 0xFE,
2227 "Packet Send Sequence Number", HFILL }},
2229 static gint *ett[] = {
2233 &ett_x25_fac_unknown,
2235 &ett_x25_fac_reverse,
2236 &ett_x25_fac_throughput,
2238 &ett_x25_fac_called_modif,
2239 &ett_x25_fac_cug_outgoing_acc,
2240 &ett_x25_fac_throughput_min,
2241 &ett_x25_fac_express_data,
2242 &ett_x25_fac_bilateral_cug,
2243 &ett_x25_fac_packet_size,
2244 &ett_x25_fac_window_size,
2245 &ett_x25_fac_rpoa_selection,
2246 &ett_x25_fac_transit_delay,
2247 &ett_x25_fac_call_transfer,
2248 &ett_x25_fac_called_addr_ext,
2249 &ett_x25_fac_ete_transit_delay,
2250 &ett_x25_fac_calling_addr_ext,
2251 &ett_x25_fac_call_deflect,
2252 &ett_x25_fac_priority,
2255 module_t *x25_module;
2257 proto_x25 = proto_register_protocol ("X.25", "X.25", "x.25");
2258 proto_register_field_array (proto_x25, hf, array_length(hf));
2259 proto_register_subtree_array(ett, array_length(ett));
2260 register_init_routine(&reinit_x25_hashtable);
2262 x25_subdissector_table = register_dissector_table("x.25.spi");
2264 register_dissector("x.25", dissect_x25, proto_x25);
2267 x25_module = prefs_register_protocol(proto_x25, NULL);
2268 prefs_register_bool_preference(x25_module, "non_q_bit_is_sna",
2269 "When Q-bit is 0, payload is SNA", "When Q-bit is 0, payload is SNA",
2274 proto_reg_handoff_x25(void)
2277 * Get handles for various dissectors.
2279 ositp_handle = find_dissector("ositp");
2280 sna_handle = find_dissector("sna");
2281 qllc_handle = find_dissector("qllc");
2282 data_handle = find_dissector("data");
2284 dissector_add("llc.dsap", SAP_X25, dissect_x25, proto_x25);