2 * Routines for x25 packet disassembly
3 * Olivier Abad <oabad@cybercable.fr>
5 * $Id: packet-x25.c,v 1.63 2002/01/21 07:36:48 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"
46 #define X25_CALL_REQUEST 0x0B
47 #define X25_CALL_ACCEPTED 0x0F
48 #define X25_CLEAR_REQUEST 0x13
49 #define X25_CLEAR_CONFIRMATION 0x17
50 #define X25_INTERRUPT 0x23
51 #define X25_INTERRUPT_CONFIRMATION 0x27
52 #define X25_RESET_REQUEST 0x1B
53 #define X25_RESET_CONFIRMATION 0x1F
54 #define X25_RESTART_REQUEST 0xFB
55 #define X25_RESTART_CONFIRMATION 0xFF
56 #define X25_REGISTRATION_REQUEST 0xF3
57 #define X25_REGISTRATION_CONFIRMATION 0xF7
58 #define X25_DIAGNOSTIC 0xF1
64 #define X25_FAC_CLASS_MASK 0xC0
66 #define X25_FAC_CLASS_A 0x00
67 #define X25_FAC_CLASS_B 0x40
68 #define X25_FAC_CLASS_C 0x80
69 #define X25_FAC_CLASS_D 0xC0
71 #define X25_FAC_COMP_MARK 0x00
72 #define X25_FAC_REVERSE 0x01
73 #define X25_FAC_THROUGHPUT 0x02
74 #define X25_FAC_CUG 0x03
75 #define X25_FAC_CALLED_MODIF 0x08
76 #define X25_FAC_CUG_OUTGOING_ACC 0x09
77 #define X25_FAC_THROUGHPUT_MIN 0x0A
78 #define X25_FAC_EXPRESS_DATA 0x0B
79 #define X25_FAC_BILATERAL_CUG 0x41
80 #define X25_FAC_PACKET_SIZE 0x42
81 #define X25_FAC_WINDOW_SIZE 0x43
82 #define X25_FAC_RPOA_SELECTION 0x44
83 #define X25_FAC_TRANSIT_DELAY 0x49
84 #define X25_FAC_CALL_TRANSFER 0xC3
85 #define X25_FAC_CALLED_ADDR_EXT 0xC9
86 #define X25_FAC_ETE_TRANSIT_DELAY 0xCA
87 #define X25_FAC_CALLING_ADDR_EXT 0xCB
88 #define X25_FAC_CALL_DEFLECT 0xD1
89 #define X25_FAC_PRIORITY 0xD2
91 static int proto_x25 = -1;
92 static int hf_x25_gfi = -1;
93 static int hf_x25_abit = -1;
94 static int hf_x25_qbit = -1;
95 static int hf_x25_dbit = -1;
96 static int hf_x25_mod = -1;
97 static int hf_x25_lcn = -1;
98 static int hf_x25_type = -1;
99 static int hf_x25_p_r_mod8 = -1;
100 static int hf_x25_p_r_mod128 = -1;
101 static int hf_x25_mbit_mod8 = -1;
102 static int hf_x25_mbit_mod128 = -1;
103 static int hf_x25_p_s_mod8 = -1;
104 static int hf_x25_p_s_mod128 = -1;
106 static gint ett_x25 = -1;
107 static gint ett_x25_gfi = -1;
108 static gint ett_x25_fac = -1;
109 static gint ett_x25_fac_unknown = -1;
110 static gint ett_x25_fac_mark = -1;
111 static gint ett_x25_fac_reverse = -1;
112 static gint ett_x25_fac_throughput = -1;
113 static gint ett_x25_fac_cug = -1;
114 static gint ett_x25_fac_called_modif = -1;
115 static gint ett_x25_fac_cug_outgoing_acc = -1;
116 static gint ett_x25_fac_throughput_min = -1;
117 static gint ett_x25_fac_express_data = -1;
118 static gint ett_x25_fac_bilateral_cug = -1;
119 static gint ett_x25_fac_packet_size = -1;
120 static gint ett_x25_fac_window_size = -1;
121 static gint ett_x25_fac_rpoa_selection = -1;
122 static gint ett_x25_fac_transit_delay = -1;
123 static gint ett_x25_fac_call_transfer = -1;
124 static gint ett_x25_fac_called_addr_ext = -1;
125 static gint ett_x25_fac_ete_transit_delay = -1;
126 static gint ett_x25_fac_calling_addr_ext = -1;
127 static gint ett_x25_fac_call_deflect = -1;
128 static gint ett_x25_fac_priority = -1;
129 static gint ett_x25_user_data = -1;
131 static const value_string vals_modulo[] = {
137 static const value_string vals_x25_type[] = {
138 { X25_CALL_REQUEST, "Call" },
139 { X25_CALL_ACCEPTED, "Call Accepted" },
140 { X25_CLEAR_REQUEST, "Clear" },
141 { X25_CLEAR_CONFIRMATION, "Clear Confirmation" },
142 { X25_INTERRUPT, "Interrupt" },
143 { X25_INTERRUPT_CONFIRMATION, "Interrupt Confirmation" },
144 { X25_RESET_REQUEST, "Reset" },
145 { X25_RESET_CONFIRMATION, "Reset Confirmation" },
146 { X25_RESTART_REQUEST, "Restart" },
147 { X25_RESTART_CONFIRMATION, "Restart Confirmation" },
148 { X25_REGISTRATION_REQUEST, "Registration" },
149 { X25_REGISTRATION_CONFIRMATION, "Registration Confirmation" },
150 { X25_DIAGNOSTIC, "Diagnostic" },
154 { X25_DATA, "DATA" },
158 static dissector_handle_t ip_handle;
159 static dissector_handle_t ositp_handle;
160 static dissector_handle_t sna_handle;
161 static dissector_handle_t qllc_handle;
162 static dissector_handle_t data_handle;
165 static gboolean non_q_bit_is_sna = FALSE;
167 static dissector_table_t x25_subdissector_table;
168 static heur_dissector_list_t x25_heur_subdissector_list;
171 * each vc_info node contains :
172 * the time of the first frame using this dissector (secs and usecs)
173 * the time of the last frame using this dissector (0 if it is unknown)
174 * a handle for the dissector
176 * the "time of first frame" is initialized when a Call Req. is received
177 * the "time of last frame" is initialized when a Clear, Reset, or Restart
180 typedef struct _vc_info {
181 guint32 first_frame_secs, first_frame_usecs;
182 guint32 last_frame_secs, last_frame_usecs;
183 dissector_handle_t dissect;
184 struct _vc_info *next;
188 * the hash table will contain linked lists of global_vc_info
189 * each global_vc_info struct contains :
190 * the VC number (the hash table is indexed with VC % 64)
191 * a linked list of vc_info
193 typedef struct _global_vc_info {
196 struct _global_vc_info *next;
199 static global_vc_info *hash_table[64];
202 free_vc_info(vc_info *pt)
214 reinit_x25_hashtable(void)
218 for (i=0; i<64; i++) {
219 if (hash_table[i]) /* not NULL ==> free */
221 global_vc_info *hash_ent, *hash_ent2;
222 hash_ent2 = hash_ent = hash_table[i];
225 hash_ent2 = hash_ent;
226 hash_ent = hash_ent->next;
227 free_vc_info(hash_ent2->info);
236 x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs,
237 dissector_handle_t dissect)
240 global_vc_info *hash_ent;
241 global_vc_info *hash_ent2;
243 if (hash_table[idx] == 0)
245 hash_ent = (global_vc_info *)g_malloc(sizeof(global_vc_info));
247 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
250 hash_ent->vc_num = vc;
252 hash_ent->info = (vc_info *)g_malloc(sizeof(vc_info));
253 if (!hash_ent->info) {
254 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
257 hash_ent->info->first_frame_secs = frame_secs;
258 hash_ent->info->first_frame_usecs = frame_usecs;
259 hash_ent->info->last_frame_secs = 0;
260 hash_ent->info->last_frame_usecs = 0;
261 hash_ent->info->dissect = dissect;
262 hash_ent->info->next = 0;
263 hash_table[idx] = hash_ent;
267 hash_ent2 = hash_ent = hash_table[idx];
268 /* search an entry with the same VC number */
269 while (hash_ent != NULL && hash_ent->vc_num != vc) {
270 hash_ent2 = hash_ent;
271 hash_ent = hash_ent->next;
273 if (hash_ent != NULL) /* hash_ent->vc_num == vc */
275 vc_info *vci = hash_ent->info;
276 while (vci->next) vci = vci->next; /* last element */
277 if (vci->dissect == dissect) {
278 vci->last_frame_secs = 0;
279 vci->last_frame_usecs = 0;
282 vci->next = (vc_info *)g_malloc(sizeof(vc_info));
283 if (vci->next == 0) {
284 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
287 vci->next->first_frame_secs = frame_secs;
288 vci->next->first_frame_usecs = frame_usecs;
289 vci->next->last_frame_secs = 0;
290 vci->next->last_frame_usecs = 0;
291 vci->next->dissect = dissect;
295 else /* new vc number */
297 hash_ent2->next = (global_vc_info *)g_malloc(sizeof(global_vc_info));
298 if (!hash_ent2->next) {
299 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
302 hash_ent2->next->info = (vc_info *)g_malloc(sizeof(vc_info));
303 if (!hash_ent2->next->info) {
304 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
307 hash_ent2->next->info->first_frame_secs = frame_secs;
308 hash_ent2->next->info->first_frame_usecs = frame_usecs;
309 hash_ent2->next->info->last_frame_secs = 0;
310 hash_ent2->next->info->last_frame_usecs = 0;
311 hash_ent2->next->info->dissect = dissect;
312 hash_ent2->next->info->next = 0;
318 x25_hash_add_proto_end(guint16 vc, guint32 frame_secs, guint32 frame_usecs)
320 global_vc_info *hash_ent = hash_table[vc%64];
323 if (!hash_ent) return;
324 while(hash_ent->vc_num != vc) hash_ent = hash_ent->next;
325 if (!hash_ent) return;
327 vci = hash_ent->info;
328 while (vci->next) vci = vci->next;
329 vci->last_frame_secs = frame_secs;
330 vci->last_frame_usecs = frame_usecs;
333 static dissector_handle_t
334 x25_hash_get_dissect(guint32 frame_secs, guint32 frame_usecs, guint16 vc)
336 global_vc_info *hash_ent = hash_table[vc%64];
343 while (hash_ent && hash_ent->vc_num != vc)
344 hash_ent = hash_ent->next;
348 /* a hash_ent was found for this VC number */
349 vci2 = vci = hash_ent->info;
351 /* looking for an entry matching our frame time */
352 while (vci && (vci->last_frame_secs < frame_secs ||
353 (vci->last_frame_secs == frame_secs &&
354 vci->last_frame_usecs < frame_usecs))) {
358 /* we reached last record, and previous record has a non zero
359 * last frame time ==> no dissector */
360 if (!vci && (vci2->last_frame_secs || vci2->last_frame_usecs))
363 /* we reached last record, and previous record has a zero last frame time
364 * ==> dissector for previous frame has not been "stopped" by a Clear, etc */
366 /* if the start time for vci2 is greater than our frame time
367 * ==> no dissector */
368 if (frame_secs < vci2->first_frame_secs ||
369 (frame_secs == vci2->first_frame_secs &&
370 frame_usecs < vci2->first_frame_usecs))
373 return vci2->dissect;
376 /* our frame time is before vci's end. Check if it is after vci's start */
377 if (frame_secs < vci->first_frame_secs ||
378 (frame_secs == vci->first_frame_secs &&
379 frame_usecs < vci->first_frame_usecs))
385 static char *clear_code(unsigned char code)
387 static char buffer[25];
389 if (code == 0x00 || (code & 0x80) == 0x80)
390 return "DTE Originated";
392 return "Number Busy";
394 return "Invalid Facility Requested";
396 return "Network Congestion";
398 return "Out Of Order";
400 return "Access Barred";
402 return "Not Obtainable";
404 return "Remote Procedure Error";
406 return "Local Procedure Error";
408 return "RPOA Out Of Order";
410 return "Reverse Charging Acceptance Not Subscribed";
412 return "Incompatible Destination";
414 return "Fast Select Acceptance Not Subscribed";
416 return "Destination Absent";
418 sprintf(buffer, "Unknown %02X", code);
423 static char *clear_diag(unsigned char code)
425 static char buffer[25];
428 return "No additional information";
430 return "Invalid P(S)";
432 return "Invalid P(R)";
434 return "Packet type invalid";
436 return "Packet type invalid for state r1";
438 return "Packet type invalid for state r2";
440 return "Packet type invalid for state r3";
442 return "Packet type invalid for state p1";
444 return "Packet type invalid for state p2";
446 return "Packet type invalid for state p3";
448 return "Packet type invalid for state p4";
450 return "Packet type invalid for state p5";
452 return "Packet type invalid for state p6";
454 return "Packet type invalid for state p7";
456 return "Packet type invalid for state d1";
458 return "Packet type invalid for state d2";
460 return "Packet type invalid for state d3";
462 return "Packet not allowed";
464 return "Unidentifiable packet";
466 return "Call on one-way logical channel";
468 return "Invalid packet type on a PVC";
470 return "Packet on unassigned LC";
472 return "Reject not subscribed to";
474 return "Packet too short";
476 return "Packet too long";
478 return "Invalid general format identifier";
480 return "Restart/registration packet with nonzero bits";
482 return "Packet type not compatible with facility";
484 return "Unauthorised interrupt confirmation";
486 return "Unauthorised interrupt";
488 return "Unauthorised reject";
490 return "Time expired";
492 return "Time expired for incoming call";
494 return "Time expired for clear indication";
496 return "Time expired for reset indication";
498 return "Time expired for restart indication";
500 return "Time expired for call deflection";
502 return "Call set-up/clearing or registration pb.";
504 return "Facility/registration code not allowed";
506 return "Facility parameter not allowed";
508 return "Invalid called DTE address";
510 return "Invalid calling DTE address";
512 return "Invalid facility/registration length";
514 return "Incoming call barred";
516 return "No logical channel available";
518 return "Call collision";
520 return "Duplicate facility requested";
522 return "Non zero address length";
524 return "Non zero facility length";
526 return "Facility not provided when expected";
528 return "Invalid CCITT-specified DTE facility";
530 return "Max. nb of call redir/defl. exceeded";
532 return "Miscellaneous";
534 return "Improper cause code from DTE";
536 return "Not aligned octet";
538 return "Inconsistent Q bit setting";
540 return "NUI problem";
542 return "International problem";
544 return "Remote network problem";
546 return "International protocol problem";
548 return "International link out of order";
550 return "International link busy";
552 return "Transit network facility problem";
554 return "Remote network facility problem";
556 return "International routing problem";
558 return "Temporary routing problem";
560 return "Unknown called DNIC";
562 return "Maintenance action";
564 return "Timer expired or retransmission count surpassed";
566 return "Timer expired or retransmission count surpassed for INTERRUPT";
568 return "Timer expired or retransmission count surpassed for DATA "
569 "packet transmission";
571 return "Timer expired or retransmission count surpassed for REJECT";
573 return "DTE-specific signals";
575 return "DTE operational";
577 return "DTE not operational";
579 return "DTE resource constraint";
581 return "Fast select not subscribed";
583 return "Invalid partially full DATA packet";
585 return "D-bit procedure not supported";
587 return "Registration/Cancellation confirmed";
589 return "OSI network service problem";
591 return "Disconnection (transient condition)";
593 return "Disconnection (permanent condition)";
595 return "Connection rejection - reason unspecified (transient "
598 return "Connection rejection - reason unspecified (permanent "
601 return "Connection rejection - quality of service not available "
602 "transient condition)";
604 return "Connection rejection - quality of service not available "
605 "permanent condition)";
607 return "Connection rejection - NSAP unreachable (transient condition)";
609 return "Connection rejection - NSAP unreachable (permanent condition)";
611 return "reset - reason unspecified";
613 return "reset - congestion";
615 return "Connection rejection - NSAP address unknown (permanent "
618 return "Higher layer initiated";
620 return "Disconnection - normal";
622 return "Disconnection - abnormal";
624 return "Disconnection - incompatible information in user data";
626 return "Connection rejection - reason unspecified (transient "
629 return "Connection rejection - reason unspecified (permanent "
632 return "Connection rejection - quality of service not available "
633 "(transient condition)";
635 return "Connection rejection - quality of service not available "
636 "(permanent condition)";
638 return "Connection rejection - incompatible information in user data";
640 return "Connection rejection - unrecognizable protocol indentifier "
643 return "Reset - user resynchronization";
645 sprintf(buffer, "Unknown %d", code);
650 static char *reset_code(unsigned char code)
652 static char buffer[25];
654 if (code == 0x00 || (code & 0x80) == 0x80)
655 return "DTE Originated";
657 return "Out of order";
659 return "Remote Procedure Error";
661 return "Local Procedure Error";
663 return "Network Congestion";
665 return "Remote DTE operational";
667 return "Network operational";
669 return "Incompatible Destination";
671 return "Network out of order";
673 sprintf(buffer, "Unknown %02X", code);
678 static char *restart_code(unsigned char code)
680 static char buffer[25];
682 if (code == 0x00 || (code & 0x80) == 0x80)
683 return "DTE Originated";
685 return "Local Procedure Error";
687 return "Network Congestion";
689 return "Network Operational";
691 return "Registration/cancellation confirmed";
693 sprintf(buffer, "Unknown %02X", code);
698 static char *registration_code(unsigned char code)
700 static char buffer[25];
703 return "Invalid facility request";
705 return "Network congestion";
707 return "Local procedure error";
709 return "Registration/cancellation confirmed";
711 sprintf(buffer, "Unknown %02X", code);
717 dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb)
719 guint8 fac, byte1, byte2, byte3;
720 guint32 len; /* facilities length */
722 proto_tree *fac_tree = 0;
723 proto_tree *fac_subtree;
725 len = tvb_get_guint8(tvb, *offset);
727 ti = proto_tree_add_text(tree, tvb, *offset, len + 1,
729 fac_tree = proto_item_add_subtree(ti, ett_x25_fac);
730 proto_tree_add_text(fac_tree, tvb, *offset, 1,
731 "Facilities length: %d", len);
736 fac = tvb_get_guint8(tvb, *offset);
737 switch(fac & X25_FAC_CLASS_MASK) {
738 case X25_FAC_CLASS_A:
740 case X25_FAC_COMP_MARK:
742 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
743 "Code : 00 (Marker)");
744 switch (tvb_get_guint8(tvb, *offset + 1)) {
747 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
748 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
749 "Parameter : 00 (Network complementary "
750 "services - calling DTE)");
755 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
756 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
757 "Parameter : FF (Network complementary "
758 "services - called DTE)");
763 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
764 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
765 "Parameter : 0F (DTE complementary "
771 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
772 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
773 "Parameter : %02X (Unknown marker)",
774 tvb_get_guint8(tvb, *offset+1));
779 case X25_FAC_REVERSE:
781 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
782 "(Reverse charging / Fast select)", fac);
783 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_reverse);
784 byte1 = tvb_get_guint8(tvb, *offset + 1);
785 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
786 "Parameter : %02X", byte1);
788 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
789 "11.. .... = Fast select with restriction");
790 else if (byte1 & 0x80)
791 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
792 "10.. .... = Fast select - no restriction");
794 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
795 "00.. .... = Fast select not requested");
796 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
797 decode_boolean_bitfield(byte1, 0x01, 1*8,
798 "Reverse charging requested",
799 "Reverse charging not requested"));
802 case X25_FAC_THROUGHPUT:
806 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
807 "(Throughput class negociation)", fac);
808 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_throughput);
809 byte1 = tvb_get_guint8(tvb, *offset + 1);
821 sprintf(tmpbuf, "From the called DTE : %%u (%d bps)",
822 75*(1<<((byte1 >> 4)-3)));
825 sprintf(tmpbuf, "From the called DTE : %%u (48000 bps)");
828 sprintf(tmpbuf, "From the called DTE : %%u (64000 bps)");
831 sprintf(tmpbuf, "From the called DTE : %%u (Reserved)");
833 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
834 decode_numeric_bitfield(byte1, 0xF0, 1*8, tmpbuf));
835 switch (byte1 & 0x0F)
846 sprintf(tmpbuf, "From the calling DTE : %%u (%d bps)",
847 75*(1<<((byte1 & 0x0F)-3)));
850 sprintf(tmpbuf, "From the calling DTE : %%u (48000 bps)");
853 sprintf(tmpbuf, "From the calling DTE : %%u (64000 bps)");
856 sprintf(tmpbuf, "From the calling DTE : %%u (Reserved)");
858 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
859 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
864 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
865 "(Closed user group selection)", fac);
866 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_cug);
867 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
868 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
871 case X25_FAC_CALLED_MODIF:
873 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
874 "(Called address modified)", fac);
875 fac_subtree = proto_item_add_subtree(ti,
876 ett_x25_fac_called_modif);
877 proto_tree_add_text(fac_tree, tvb, *offset+1, 1,
878 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
881 case X25_FAC_CUG_OUTGOING_ACC:
883 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
884 "(Closed user group with outgoing access selection)",
886 fac_subtree = proto_item_add_subtree(ti,
887 ett_x25_fac_cug_outgoing_acc);
888 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
889 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
892 case X25_FAC_THROUGHPUT_MIN:
894 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
895 "(Minimum throughput class)", fac);
896 fac_subtree = proto_item_add_subtree(ti,
897 ett_x25_fac_throughput_min);
898 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
899 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
902 case X25_FAC_EXPRESS_DATA:
904 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
905 "(Negociation of express data)", fac);
906 fac_subtree = proto_item_add_subtree(ti,
907 ett_x25_fac_express_data);
908 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
909 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
914 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
915 "Code : %02X (Unknown class A)", fac);
916 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
917 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
918 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
925 case X25_FAC_CLASS_B:
927 case X25_FAC_BILATERAL_CUG:
929 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
930 "(Bilateral closed user group selection)", fac);
931 fac_subtree = proto_item_add_subtree(ti,
932 ett_x25_fac_bilateral_cug);
933 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
934 "Bilateral CUG: %04X",
935 tvb_get_ntohs(tvb, *offset+1));
938 case X25_FAC_PACKET_SIZE:
943 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
944 "(Packet size)", fac);
945 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_packet_size);
946 byte1 = tvb_get_guint8(tvb, *offset + 1);
950 sprintf(tmpbuf, "From the called DTE : %%u (16)");
953 sprintf(tmpbuf, "From the called DTE : %%u (32)");
956 sprintf(tmpbuf, "From the called DTE : %%u (64)");
959 sprintf(tmpbuf, "From the called DTE : %%u (128)");
962 sprintf(tmpbuf, "From the called DTE : %%u (256)");
965 sprintf(tmpbuf, "From the called DTE : %%u (512)");
968 sprintf(tmpbuf, "From the called DTE : %%u (1024)");
971 sprintf(tmpbuf, "From the called DTE : %%u (2048)");
974 sprintf(tmpbuf, "From the called DTE : %%u (4096)");
977 sprintf(tmpbuf, "From the called DTE : %%u (Unknown)");
980 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
981 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
983 byte2 = tvb_get_guint8(tvb, *offset + 1);
987 sprintf(tmpbuf, "From the calling DTE : %%u (16)");
990 sprintf(tmpbuf, "From the calling DTE : %%u (32)");
993 sprintf(tmpbuf, "From the calling DTE : %%u (64)");
996 sprintf(tmpbuf, "From the calling DTE : %%u (128)");
999 sprintf(tmpbuf, "From the calling DTE : %%u (256)");
1002 sprintf(tmpbuf, "From the calling DTE : %%u (512)");
1005 sprintf(tmpbuf, "From the calling DTE : %%u (1024)");
1008 sprintf(tmpbuf, "From the calling DTE : %%u (2048)");
1011 sprintf(tmpbuf, "From the calling DTE : %%u (4096)");
1014 sprintf(tmpbuf, "From the calling DTE : %%u (Unknown)");
1017 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1018 decode_numeric_bitfield(byte2, 0x0F, 1*8, tmpbuf));
1021 case X25_FAC_WINDOW_SIZE:
1023 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1024 "(Window size)", fac);
1025 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_window_size);
1026 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1027 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+1),
1028 0x7F, 1*8, "From the called DTE: %u"));
1029 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1030 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+2),
1031 0x7F, 1*8, "From the calling DTE: %u"));
1034 case X25_FAC_RPOA_SELECTION:
1036 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1037 "(RPOA selection)", fac);
1038 fac_subtree = proto_item_add_subtree(ti,
1039 ett_x25_fac_rpoa_selection);
1040 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
1041 "Data network identification code : %04X",
1042 tvb_get_ntohs(tvb, *offset+1));
1045 case X25_FAC_TRANSIT_DELAY:
1047 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1048 "(Transit delay selection and indication)", fac);
1049 fac_subtree = proto_item_add_subtree(ti,
1050 ett_x25_fac_transit_delay);
1051 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
1052 "Transit delay: %d ms",
1053 tvb_get_ntohs(tvb, *offset+1));
1058 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1059 "Code : %02X (Unknown class B)", fac);
1060 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1061 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
1062 "Parameter %04X", tvb_get_ntohs(tvb, *offset+1));
1069 case X25_FAC_CLASS_C:
1071 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1072 "Code : %02X (Unknown class C)", fac);
1073 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1074 proto_tree_add_text(fac_subtree, tvb, *offset+1, 3,
1076 tvb_get_ntoh24(tvb, *offset+1));
1081 case X25_FAC_CLASS_D:
1083 case X25_FAC_CALL_TRANSFER:
1088 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1089 "(Call redirection or deflection notification)", fac);
1090 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_call_transfer);
1091 byte1 = tvb_get_guint8(tvb, *offset+1);
1092 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1093 "Length : %u", byte1);
1094 byte2 = tvb_get_guint8(tvb, *offset+2);
1095 if ((byte2 & 0xC0) == 0xC0) {
1096 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1097 "Reason : call deflection by the originally "
1098 "called DTE address");
1103 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1104 "Reason : originally called DTE busy");
1107 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1108 "Reason : call dist. within a hunt group");
1111 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1112 "Reason : originally called DTE out of order");
1115 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1116 "Reason : systematic call redirection");
1119 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1120 "Reason : unknown");
1124 byte3 = tvb_get_guint8(tvb, *offset+3);
1125 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1126 "Number of semi-octets in DTE address : %u",
1128 for (i = 0; i < byte3; i++) {
1130 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1132 /* if > 9, convert to the right hexadecimal letter */
1133 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1135 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1137 /* if > 9, convert to the right hexadecimal letter */
1138 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1142 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1143 "DTE address : %s", tmpbuf);
1146 case X25_FAC_CALLING_ADDR_EXT:
1151 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1152 "(Calling address extension)", fac);
1153 fac_subtree = proto_item_add_subtree(ti,
1154 ett_x25_fac_calling_addr_ext);
1155 byte1 = tvb_get_guint8(tvb, *offset+1);
1156 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1157 "Length : %u", byte1);
1158 byte2 = tvb_get_guint8(tvb, *offset+2);
1159 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1160 "Number of semi-octets in DTE address : %u", byte2);
1161 for (i = 0; i < byte2; i++) {
1163 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1165 /* if > 9, convert to the right hexadecimal letter */
1166 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1168 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1170 /* if > 9, convert to the right hexadecimal letter */
1171 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1175 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1176 "DTE address : %s", tmpbuf);
1179 case X25_FAC_CALLED_ADDR_EXT:
1184 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1185 "(Called address extension)", fac);
1186 fac_subtree = proto_item_add_subtree(ti,
1187 ett_x25_fac_called_addr_ext);
1188 byte1 = tvb_get_guint8(tvb, *offset+1);
1189 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1190 "Length : %u", byte1);
1191 byte2 = tvb_get_guint8(tvb, *offset+2);
1192 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1193 "Number of semi-octets in DTE address : %u", byte2);
1194 for (i = 0; i < byte2; i++) {
1196 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1198 /* if > 9, convert to the right hexadecimal letter */
1199 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1201 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1203 /* if > 9, convert to the right hexadecimal letter */
1204 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1208 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1209 "DTE address : %s", tmpbuf);
1212 case X25_FAC_ETE_TRANSIT_DELAY:
1214 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1215 "(End to end transit delay)", fac);
1216 fac_subtree = proto_item_add_subtree(ti,
1217 ett_x25_fac_ete_transit_delay);
1218 byte1 = tvb_get_guint8(tvb, *offset+1);
1219 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1220 "Length : %u", byte1);
1221 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1224 case X25_FAC_CALL_DEFLECT:
1229 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1230 "(Call deflection selection)", fac);
1231 fac_subtree = proto_item_add_subtree(ti,
1232 ett_x25_fac_call_deflect);
1233 byte1 = tvb_get_guint8(tvb, *offset+1);
1234 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1235 "Length : %u", byte1);
1236 byte2 = tvb_get_guint8(tvb, *offset+2);
1237 if ((byte2 & 0xC0) == 0xC0)
1238 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1239 "Reason : call DTE originated");
1241 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1242 "Reason : unknown");
1243 byte3 = tvb_get_guint8(tvb, *offset+3);
1244 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1245 "Number of semi-octets in the alternative DTE address : %u",
1247 for (i = 0; i < byte3; i++) {
1249 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1251 /* if > 9, convert to the right hexadecimal letter */
1252 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1254 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1256 /* if > 9, convert to the right hexadecimal letter */
1257 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1261 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1262 "Alternative DTE address : %s", tmpbuf);
1265 case X25_FAC_PRIORITY:
1267 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1268 "Code : %02X (Priority)", fac);
1269 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_priority);
1270 byte1 = tvb_get_guint8(tvb, *offset+1);
1271 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1272 "Length : %u", byte1);
1273 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1278 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1279 "Code : %02X (Unknown class D)", fac);
1280 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1281 byte1 = tvb_get_guint8(tvb, *offset+1);
1282 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1283 "Length : %u", byte1);
1284 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1287 byte1 = tvb_get_guint8(tvb, *offset+1);
1288 (*offset) += byte1+2;
1296 x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1297 packet_info *pinfo, gboolean toa)
1301 char addr1[16], addr2[16];
1302 char *first, *second;
1306 byte = tvb_get_guint8(tvb, *offset);
1307 len1 = (byte >> 4) & 0x0F;
1308 len2 = (byte >> 0) & 0x0F;
1310 proto_tree_add_text(tree, tvb, *offset, 1,
1311 decode_numeric_bitfield(byte, 0xF0, 1*8,
1312 toa ? "Called address length : %u" :
1313 "Calling address length : %u"));
1314 proto_tree_add_text(tree, tvb, *offset, 1,
1315 decode_numeric_bitfield(byte, 0x0F, 1*8,
1316 toa ? "Calling address length : %u" :
1317 "Called address length : %u"));
1321 localoffset = *offset;
1322 byte = tvb_get_guint8(tvb, localoffset);
1326 for (i = 0; i < (len1 + len2); i++) {
1329 *first++ = ((byte >> 0) & 0x0F) + '0';
1331 byte = tvb_get_guint8(tvb, localoffset);
1333 *first++ = ((byte >> 4) & 0x0F) + '0';
1337 *second++ = ((byte >> 0) & 0x0F) + '0';
1339 byte = tvb_get_guint8(tvb, localoffset);
1341 *second++ = ((byte >> 4) & 0x0F) + '0';
1351 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1352 col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1);
1355 if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
1356 col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr1);
1359 proto_tree_add_text(tree, tvb, *offset,
1362 toa ? "Called" : "Calling",
1367 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1368 col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2);
1371 if(check_col(pinfo->cinfo, COL_RES_DL_DST))
1372 col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr2);
1375 proto_tree_add_text(tree, tvb, *offset + len1/2,
1376 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1378 toa ? "Calling" : "Called",
1381 (*offset) += ((len1 + len2 + 1) / 2);
1385 get_x25_pkt_len(tvbuff_t *tvb)
1387 guint length, called_len, calling_len, dte_len, dce_len;
1388 guint8 byte2, bytex;
1390 byte2 = tvb_get_guint8(tvb, 2);
1393 case X25_CALL_REQUEST:
1394 bytex = tvb_get_guint8(tvb, 3);
1395 called_len = (bytex >> 0) & 0x0F;
1396 calling_len = (bytex >> 4) & 0x0F;
1397 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1398 if (length < tvb_reported_length(tvb))
1399 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1401 return MIN(tvb_reported_length(tvb),length);
1403 case X25_CALL_ACCEPTED:
1404 /* The calling/called address length byte (following the packet type)
1405 * is not mandatory, so we must check the packet length before trying
1407 if (tvb_reported_length(tvb) == 3)
1409 bytex = tvb_get_guint8(tvb, 3);
1410 called_len = (bytex >> 0) & 0x0F;
1411 calling_len = (bytex >> 4) & 0x0F;
1412 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1413 if (length < tvb_reported_length(tvb))
1414 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1416 return MIN(tvb_reported_length(tvb),length);
1418 case X25_CLEAR_REQUEST:
1419 case X25_RESET_REQUEST:
1420 case X25_RESTART_REQUEST:
1421 return MIN(tvb_reported_length(tvb),5);
1423 case X25_DIAGNOSTIC:
1424 return MIN(tvb_reported_length(tvb),4);
1426 case X25_CLEAR_CONFIRMATION:
1428 case X25_INTERRUPT_CONFIRMATION:
1429 case X25_RESET_CONFIRMATION:
1430 case X25_RESTART_CONFIRMATION:
1431 return MIN(tvb_reported_length(tvb),3);
1433 case X25_REGISTRATION_REQUEST:
1434 bytex = tvb_get_guint8(tvb, 3);
1435 dce_len = (bytex >> 0) & 0x0F;
1436 dte_len = (bytex >> 4) & 0x0F;
1437 length = 4 + (dte_len + dce_len + 1) / 2; /* addr */
1438 if (length < tvb_reported_length(tvb))
1439 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1441 return MIN(tvb_reported_length(tvb),length);
1443 case X25_REGISTRATION_CONFIRMATION:
1444 bytex = tvb_get_guint8(tvb, 5);
1445 dce_len = (bytex >> 0) & 0x0F;
1446 dte_len = (bytex >> 4) & 0x0F;
1447 length = 6 + (dte_len + dce_len + 1) / 2; /* addr */
1448 if (length < tvb_reported_length(tvb))
1449 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1451 return MIN(tvb_reported_length(tvb),length);
1454 if ((byte2 & 0x01) == X25_DATA) return MIN(tvb_reported_length(tvb),3);
1456 switch (byte2 & 0x1F)
1459 return MIN(tvb_reported_length(tvb),3);
1462 return MIN(tvb_reported_length(tvb),3);
1465 return MIN(tvb_reported_length(tvb),3);
1471 static const value_string prt_id_vals[] = {
1472 {PRT_ID_ISO_8073, "ISO 8073 COTP"},
1473 {PRT_ID_ISO_8602, "ISO 8602 CLTP"},
1474 {PRT_ID_ISO_10736_ISO_8073, "ISO 10736 in conjunction with ISO 8073 COTP"},
1475 {PRT_ID_ISO_10736_ISO_8602, "ISO 10736 in conjunction with ISO 8602 CLTP"},
1479 static const value_string sharing_strategy_vals[] = {
1480 {0x00, "No sharing"},
1485 dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1487 proto_tree *x25_tree=0, *gfi_tree=0, *userdata_tree=0;
1489 guint localoffset=0;
1493 dissector_handle_t dissect;
1494 gboolean toa; /* TOA/NPI address format */
1498 gboolean q_bit_set = FALSE;
1500 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1501 col_set_str(pinfo->cinfo, COL_PROTOCOL, "X.25");
1503 bytes0_1 = tvb_get_ntohs(tvb, 0);
1505 modulo = ((bytes0_1 & 0x2000) ? 128 : 8);
1506 vc = (int)(bytes0_1 & 0x0FFF);
1508 if (bytes0_1 & 0x8000) toa = TRUE;
1511 x25_pkt_len = get_x25_pkt_len(tvb);
1512 if (x25_pkt_len < 3) /* packet too short */
1514 if (check_col(pinfo->cinfo, COL_INFO))
1515 col_set_str(pinfo->cinfo, COL_INFO, "Invalid/short X.25 packet");
1517 proto_tree_add_protocol_format(tree, proto_x25, tvb, 0,
1518 tvb_length(tvb), "Invalid/short X.25 packet");
1522 pkt_type = tvb_get_guint8(tvb, 2);
1525 ti = proto_tree_add_item(tree, proto_x25, tvb, 0, x25_pkt_len, FALSE);
1526 x25_tree = proto_item_add_subtree(ti, ett_x25);
1527 ti = proto_tree_add_item(x25_tree, hf_x25_gfi, tvb, 0, 2, FALSE);
1528 gfi_tree = proto_item_add_subtree(ti, ett_x25_gfi);
1530 if ((pkt_type & 0x01) == X25_DATA) {
1531 proto_tree_add_boolean(gfi_tree, hf_x25_qbit, tvb, 0, 2,
1533 if (bytes0_1 & 0x8000) {
1537 else if (pkt_type == X25_CALL_REQUEST ||
1538 pkt_type == X25_CALL_ACCEPTED ||
1539 pkt_type == X25_CLEAR_REQUEST ||
1540 pkt_type == X25_CLEAR_CONFIRMATION) {
1541 proto_tree_add_boolean(gfi_tree, hf_x25_abit, tvb, 0, 2,
1545 if (pkt_type == X25_CALL_REQUEST || pkt_type == X25_CALL_ACCEPTED ||
1546 (pkt_type & 0x01) == X25_DATA) {
1547 proto_tree_add_boolean(gfi_tree, hf_x25_dbit, tvb, 0, 2,
1550 proto_tree_add_uint(gfi_tree, hf_x25_mod, tvb, 0, 2, bytes0_1);
1554 case X25_CALL_REQUEST:
1555 if (check_col(pinfo->cinfo, COL_INFO))
1556 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d",
1557 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Inc. call"
1561 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb,
1563 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1565 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Incoming call"
1569 if (localoffset < x25_pkt_len) /* calling/called addresses */
1570 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, toa);
1572 if (localoffset < x25_pkt_len) /* facilities */
1573 dump_facilities(x25_tree, &localoffset, tvb);
1575 if (localoffset < tvb_reported_length(tvb)) /* user data */
1582 ti = proto_tree_add_text(x25_tree, tvb, localoffset,
1583 tvb_length_remaining(tvb, localoffset),
1585 userdata_tree = proto_item_add_subtree(ti, ett_x25_user_data);
1588 /* X.263/ISO 9577 says that:
1590 When CLNP or ESIS are run over X.25, the SPI
1591 is 0x81 or 0x82, respectively; those are the
1592 NLPIDs for those protocol.
1594 When X.224/ISO 8073 COTP is run over X.25, and
1595 when ISO 11570 explicit identification is being
1596 used, the first octet of the user data field is
1597 a TPDU length field, and the rest is "as defined
1598 in ITU-T Rec. X.225 | ISO/IEC 8073, Annex B,
1599 or ITU-T Rec. X.264 and ISO/IEC 11570".
1601 When X.264/ISO 11570 default identification is
1602 being used, there is no user data field in the
1603 CALL REQUEST packet. This is for X.225/ISO 8073
1606 It also says that SPI values from 0x03 through 0x3f are
1607 reserved and are in use by X.224/ISO 8073 Annex B and
1608 X.264/ISO 11570. The note says that those values are
1609 not NLPIDs, they're "used by the respective higher layer
1610 protocol" and "not used for higher layer protocol
1611 identification". I infer from this and from what
1612 X.264/ISO 11570 says that this means that values in those
1613 range are valid values for the first octet of an
1614 X.224/ISO 8073 packet or for X.264/ISO 11570.
1616 Annex B of X.225/ISO 8073 mentions some additional TPDU
1617 types that can be put in what I presume is the user
1618 data of connect requests. It says that:
1620 The sending transport entity shall:
1622 a) either not transmit any TPDU in the NS-user data
1623 parameter of the N-CONNECT request primitive; or
1625 b) transmit the UN-TPDU (see ITU-T Rec. X.264 and
1626 ISO/IEC 11570) followed by the NCM-TPDU in the
1627 NS-user data parameter of the N-CONNECT request
1630 I don't know if this means that the user data field
1631 will contain a UN TPDU followed by an NCM TPDU or not.
1633 X.264/ISO 11570 says that:
1635 When default identification is being used,
1636 X.225/ISO 8073 COTP is identified. No user data
1637 is sent in the network-layer connection request.
1639 When explicit identification is being used,
1640 the user data is a UN TPDU ("Use of network
1641 connection TPDU"), which specifies the transport
1642 protocol to use over this network connection.
1643 It also says that the length of a UN TPDU shall
1644 not exceed 32 octets, i.e. shall not exceed 0x20;
1645 it says this is "due to the desire not to conflict
1646 with the protocol identifier field carried by X.25
1647 CALL REQUEST/INCOMING CALL packets", and says that
1648 field has values specified in X.244. X.244 has been
1649 superseded by X.263/ISO 9577, so that presumably
1650 means the goal is to allow a UN TPDU's length
1651 field to be distinguished from an NLPID, allowing
1652 you to tell whether X.264/ISO 11570 explicit
1653 identification is being used or an NLPID is
1654 being used as the SPI.
1656 I read this as meaning that, if the ISO mechanisms are
1657 used to identify the protocol being carried over X.25:
1659 if there's no user data in the CALL REQUEST/
1660 INCOMING CALL packet, it's COTP;
1662 if there is user data, then:
1664 if the first octet is less than or equal to
1665 32, it might be a UN TPDU, and that identifies
1666 the transport protocol being used, and
1667 it may be followed by more data, such
1668 as a COTP NCM TPDU if it's COTP;
1670 if the first octet is greater than 32, it's
1671 an NLPID, *not* a TPDU length, and the
1672 stuff following it is *not* a TPDU.
1674 Figure A.2 of X.263/ISO 9577 seems to say that the
1675 first octet of the user data is a TPDU length field,
1676 in the range 0x03 through 0x82, and says they are
1677 for X.225/ISO 8073 Annex B or X.264/ISO 11570.
1679 However, X.264/ISO 11570 seems to imply that the length
1680 field would be that of a UN TPDU, which must be less
1681 than or equal to 0x20, and X.225/ISO 8073 Annex B seems
1682 to indicate that the user data must begin with
1683 an X.264/ISO 11570 UN TPDU, so I'd say that A.2 should
1684 have said "in the range 0x03 through 0x20", instead
1685 (the length value doesn't include the length field,
1686 and the minimum UN TPDU has length, type, PRT-ID,
1687 and SHARE, so that's 3 bytes without the length). */
1688 spi = tvb_get_guint8(tvb, localoffset);
1689 if (spi > 32 || spi < 3) {
1690 /* First octet is > 32, or < 3, so the user data isn't an
1691 X.264/ISO 11570 UN TPDU */
1694 /* First octet is >= 3 and <= 32, so the user data *might*
1695 be an X.264/ISO 11570 UN TPDU. Check whether we have
1696 enough data to see if it is. */
1697 if (tvb_bytes_exist(tvb, localoffset+1, 1)) {
1698 /* We do; check whether the second octet is 1. */
1699 if (tvb_get_guint8(tvb, localoffset+1) == 0x01) {
1700 /* Yes, the second byte is 1, so it looks like
1704 /* No, the second byte is not 1, so it's not a
1709 /* We can't see the second byte of the putative UN
1710 TPDU, so we don't know if that's what it is. */
1714 if (is_x_264 == -1) {
1716 * We don't know what it is; just skip it.
1718 localoffset = tvb_length(tvb);
1719 } else if (is_x_264) {
1720 /* It looks like an X.264 UN TPDU, so show it as such. */
1721 if (userdata_tree) {
1722 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1723 "X.264 length indicator: %u",
1725 proto_tree_add_text(userdata_tree, tvb, localoffset+1, 1,
1726 "X.264 UN TPDU identifier: 0x%02X",
1727 tvb_get_guint8(tvb, localoffset+1));
1729 prt_id = tvb_get_guint8(tvb, localoffset+2);
1730 if (userdata_tree) {
1731 proto_tree_add_text(x25_tree, tvb, localoffset+2, 1,
1732 "X.264 protocol identifier: %s",
1733 val_to_str(prt_id, prt_id_vals,
1734 "Unknown (0x%02X)"));
1735 proto_tree_add_text(x25_tree, tvb, localoffset+3, 1,
1736 "X.264 sharing strategy: %s",
1737 val_to_str(tvb_get_guint8(tvb, localoffset+3),
1738 sharing_strategy_vals, "Unknown (0x%02X)"));
1741 /* XXX - dissect the variable part? */
1743 /* The length doesn't include the length octet itself. */
1744 localoffset += spi + 1;
1748 case PRT_ID_ISO_8073:
1750 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
1751 pinfo->fd->abs_usecs,
1753 /* XXX - disssect the rest of the user data as COTP?
1754 That needs support for NCM TPDUs, etc. */
1757 case PRT_ID_ISO_8602:
1759 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
1760 pinfo->fd->abs_usecs,
1764 } else if (is_x_264 == 0) {
1765 /* It doesn't look like a UN TPDU, so compare the first
1766 octet of the CALL REQUEST packet with various X.263/
1767 ISO 9577 NLPIDs, as per Annex A of X.263/ISO 9577. */
1769 if (userdata_tree) {
1770 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1771 "X.263 secondary protocol ID: %s",
1772 val_to_str(spi, nlpid_vals, "Unknown (0x%02x)"));
1777 * What's the dissector handle for this SPI?
1779 dissect = dissector_get_port_handle(x25_subdissector_table, spi);
1780 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
1781 pinfo->fd->abs_usecs, dissect);
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->cinfo, COL_INFO))
1794 col_add_fstr(pinfo->cinfo, 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, 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->cinfo, COL_INFO)) {
1821 col_add_fstr(pinfo->cinfo, 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->cinfo, COL_INFO))
1843 col_add_fstr(pinfo->cinfo, 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, 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->cinfo, COL_INFO)) {
1859 col_add_fstr(pinfo->cinfo, 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->cinfo, COL_INFO))
1872 col_add_fstr(pinfo->cinfo, 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->cinfo, COL_INFO))
1882 col_add_fstr(pinfo->cinfo, 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->cinfo, COL_INFO)) {
1892 col_add_fstr(pinfo->cinfo, 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->cinfo, COL_INFO))
1914 col_add_fstr(pinfo->cinfo, 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->cinfo, COL_INFO)) {
1924 col_add_fstr(pinfo->cinfo, 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->cinfo, COL_INFO))
1944 col_set_str(pinfo->cinfo, 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->cinfo, COL_INFO))
1952 col_set_str(pinfo->cinfo, 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, 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->cinfo, COL_INFO))
1974 col_set_str(pinfo->cinfo, 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, 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->cinfo, COL_INFO)) {
2005 col_add_fstr(pinfo->cinfo, 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->cinfo, 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->cinfo, COL_INFO)) {
2054 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2055 vc, (pkt_type >> 5) & 0x07);
2057 col_add_fstr(pinfo->cinfo, 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->cinfo, COL_INFO)) {
2081 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2082 vc, (pkt_type >> 5) & 0x07);
2084 col_add_fstr(pinfo->cinfo, 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->cinfo, COL_INFO)) {
2108 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2109 vc, (pkt_type >> 5) & 0x07);
2111 col_add_fstr(pinfo->cinfo, 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 dissector in the hash table */
2145 if ((dissect = x25_hash_get_dissect(pinfo->fd->abs_secs, pinfo->fd->abs_usecs, vc))) {
2146 /* Found it in the hash table; use it. */
2147 call_dissector(dissect, next_tvb, pinfo, tree);
2151 /* Did the user suggest SNA-over-X.25? */
2152 if (non_q_bit_is_sna) {
2153 /* Yes - dissect it as SNA. */
2154 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
2155 pinfo->fd->abs_usecs, sna_handle);
2156 call_dissector(sna_handle, next_tvb, pinfo, tree);
2160 /* If the Call Req. has not been captured, and the payload begins
2161 with what appears to be an IP header, assume these packets carry
2163 if (tvb_get_guint8(tvb, localoffset) == 0x45) {
2164 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
2165 pinfo->fd->abs_usecs, ip_handle);
2166 call_dissector(ip_handle, next_tvb, pinfo, tree);
2170 /* Try the heuristic dissectors. */
2171 if (dissector_try_heuristic(x25_heur_subdissector_list, next_tvb, pinfo,
2175 /* All else failed; dissect it as raw data */
2176 call_dissector(data_handle, next_tvb, pinfo, tree);
2180 proto_register_x25(void)
2182 static hf_register_info hf[] = {
2184 { "GFI", "x.25.gfi", FT_UINT16, BASE_BIN, NULL, 0xF000,
2185 "General format identifier", HFILL }},
2187 { "A Bit", "x.25.a", FT_BOOLEAN, 16, NULL, 0x8000,
2188 "Address Bit", HFILL }},
2190 { "Q Bit", "x.25.q", FT_BOOLEAN, 16, NULL, 0x8000,
2191 "Qualifier Bit", HFILL }},
2193 { "D Bit", "x.25.d", FT_BOOLEAN, 16, NULL, 0x4000,
2194 "Delivery Confirmation Bit", HFILL }},
2196 { "Modulo", "x.25.mod", FT_UINT16, BASE_DEC, VALS(vals_modulo), 0x3000,
2197 "Specifies whether the frame is modulo 8 or 128", HFILL }},
2199 { "Logical Channel", "x.25.lcn", FT_UINT16, BASE_DEC, NULL, 0x0FFF,
2200 "Logical Channel Number", HFILL }},
2202 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x0,
2203 "Packet Type", HFILL }},
2205 { "P(R)", "x.25.p_r", FT_UINT8, BASE_HEX, NULL, 0xE0,
2206 "Packet Receive Sequence Number", HFILL }},
2207 { &hf_x25_p_r_mod128,
2208 { "P(R)", "x.25.p_r", FT_UINT8, BASE_HEX, NULL, 0xFE,
2209 "Packet Receive Sequence Number", HFILL }},
2210 { &hf_x25_mbit_mod8,
2211 { "M Bit", "x.25.m", FT_BOOLEAN, 8, NULL, 0x10,
2212 "More Bit", HFILL }},
2213 { &hf_x25_mbit_mod128,
2214 { "M Bit", "x.25.m", FT_BOOLEAN, 8, NULL, 0x01,
2215 "More Bit", HFILL }},
2217 { "P(S)", "x.25.p_s", FT_UINT8, BASE_HEX, NULL, 0x0E,
2218 "Packet Send Sequence Number", HFILL }},
2219 { &hf_x25_p_s_mod128,
2220 { "P(S)", "x.25.p_s", FT_UINT8, BASE_HEX, NULL, 0xFE,
2221 "Packet Send Sequence Number", HFILL }},
2223 static gint *ett[] = {
2227 &ett_x25_fac_unknown,
2229 &ett_x25_fac_reverse,
2230 &ett_x25_fac_throughput,
2232 &ett_x25_fac_called_modif,
2233 &ett_x25_fac_cug_outgoing_acc,
2234 &ett_x25_fac_throughput_min,
2235 &ett_x25_fac_express_data,
2236 &ett_x25_fac_bilateral_cug,
2237 &ett_x25_fac_packet_size,
2238 &ett_x25_fac_window_size,
2239 &ett_x25_fac_rpoa_selection,
2240 &ett_x25_fac_transit_delay,
2241 &ett_x25_fac_call_transfer,
2242 &ett_x25_fac_called_addr_ext,
2243 &ett_x25_fac_ete_transit_delay,
2244 &ett_x25_fac_calling_addr_ext,
2245 &ett_x25_fac_call_deflect,
2246 &ett_x25_fac_priority,
2249 module_t *x25_module;
2251 proto_x25 = proto_register_protocol ("X.25", "X.25", "x.25");
2252 proto_register_field_array (proto_x25, hf, array_length(hf));
2253 proto_register_subtree_array(ett, array_length(ett));
2254 register_init_routine(&reinit_x25_hashtable);
2256 x25_subdissector_table = register_dissector_table("x.25.spi",
2257 "X.25 secondary protocol identifier", FT_UINT8, BASE_HEX);
2258 register_heur_dissector_list("x.25", &x25_heur_subdissector_list);
2260 register_dissector("x.25", dissect_x25, proto_x25);
2263 x25_module = prefs_register_protocol(proto_x25, NULL);
2264 prefs_register_bool_preference(x25_module, "non_q_bit_is_sna",
2265 "When Q-bit is 0, payload is SNA", "When Q-bit is 0, payload is SNA",
2270 proto_reg_handoff_x25(void)
2272 dissector_handle_t x25_handle;
2275 * Get handles for various dissectors.
2277 ip_handle = find_dissector("ip");
2278 ositp_handle = find_dissector("ositp");
2279 sna_handle = find_dissector("sna");
2280 qllc_handle = find_dissector("qllc");
2281 data_handle = find_dissector("data");
2283 x25_handle = find_dissector("x.25");
2284 dissector_add("llc.dsap", SAP_X25, x25_handle);