2 * Routines for x25 packet disassembly
3 * Olivier Abad <oabad@cybercable.fr>
5 * $Id: packet-x25.c,v 1.64 2002/01/24 09:20:53 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, -1,
1518 "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, -1,
1584 userdata_tree = proto_item_add_subtree(ti, ett_x25_user_data);
1587 /* X.263/ISO 9577 says that:
1589 When CLNP or ESIS are run over X.25, the SPI
1590 is 0x81 or 0x82, respectively; those are the
1591 NLPIDs for those protocol.
1593 When X.224/ISO 8073 COTP is run over X.25, and
1594 when ISO 11570 explicit identification is being
1595 used, the first octet of the user data field is
1596 a TPDU length field, and the rest is "as defined
1597 in ITU-T Rec. X.225 | ISO/IEC 8073, Annex B,
1598 or ITU-T Rec. X.264 and ISO/IEC 11570".
1600 When X.264/ISO 11570 default identification is
1601 being used, there is no user data field in the
1602 CALL REQUEST packet. This is for X.225/ISO 8073
1605 It also says that SPI values from 0x03 through 0x3f are
1606 reserved and are in use by X.224/ISO 8073 Annex B and
1607 X.264/ISO 11570. The note says that those values are
1608 not NLPIDs, they're "used by the respective higher layer
1609 protocol" and "not used for higher layer protocol
1610 identification". I infer from this and from what
1611 X.264/ISO 11570 says that this means that values in those
1612 range are valid values for the first octet of an
1613 X.224/ISO 8073 packet or for X.264/ISO 11570.
1615 Annex B of X.225/ISO 8073 mentions some additional TPDU
1616 types that can be put in what I presume is the user
1617 data of connect requests. It says that:
1619 The sending transport entity shall:
1621 a) either not transmit any TPDU in the NS-user data
1622 parameter of the N-CONNECT request primitive; or
1624 b) transmit the UN-TPDU (see ITU-T Rec. X.264 and
1625 ISO/IEC 11570) followed by the NCM-TPDU in the
1626 NS-user data parameter of the N-CONNECT request
1629 I don't know if this means that the user data field
1630 will contain a UN TPDU followed by an NCM TPDU or not.
1632 X.264/ISO 11570 says that:
1634 When default identification is being used,
1635 X.225/ISO 8073 COTP is identified. No user data
1636 is sent in the network-layer connection request.
1638 When explicit identification is being used,
1639 the user data is a UN TPDU ("Use of network
1640 connection TPDU"), which specifies the transport
1641 protocol to use over this network connection.
1642 It also says that the length of a UN TPDU shall
1643 not exceed 32 octets, i.e. shall not exceed 0x20;
1644 it says this is "due to the desire not to conflict
1645 with the protocol identifier field carried by X.25
1646 CALL REQUEST/INCOMING CALL packets", and says that
1647 field has values specified in X.244. X.244 has been
1648 superseded by X.263/ISO 9577, so that presumably
1649 means the goal is to allow a UN TPDU's length
1650 field to be distinguished from an NLPID, allowing
1651 you to tell whether X.264/ISO 11570 explicit
1652 identification is being used or an NLPID is
1653 being used as the SPI.
1655 I read this as meaning that, if the ISO mechanisms are
1656 used to identify the protocol being carried over X.25:
1658 if there's no user data in the CALL REQUEST/
1659 INCOMING CALL packet, it's COTP;
1661 if there is user data, then:
1663 if the first octet is less than or equal to
1664 32, it might be a UN TPDU, and that identifies
1665 the transport protocol being used, and
1666 it may be followed by more data, such
1667 as a COTP NCM TPDU if it's COTP;
1669 if the first octet is greater than 32, it's
1670 an NLPID, *not* a TPDU length, and the
1671 stuff following it is *not* a TPDU.
1673 Figure A.2 of X.263/ISO 9577 seems to say that the
1674 first octet of the user data is a TPDU length field,
1675 in the range 0x03 through 0x82, and says they are
1676 for X.225/ISO 8073 Annex B or X.264/ISO 11570.
1678 However, X.264/ISO 11570 seems to imply that the length
1679 field would be that of a UN TPDU, which must be less
1680 than or equal to 0x20, and X.225/ISO 8073 Annex B seems
1681 to indicate that the user data must begin with
1682 an X.264/ISO 11570 UN TPDU, so I'd say that A.2 should
1683 have said "in the range 0x03 through 0x20", instead
1684 (the length value doesn't include the length field,
1685 and the minimum UN TPDU has length, type, PRT-ID,
1686 and SHARE, so that's 3 bytes without the length). */
1687 spi = tvb_get_guint8(tvb, localoffset);
1688 if (spi > 32 || spi < 3) {
1689 /* First octet is > 32, or < 3, so the user data isn't an
1690 X.264/ISO 11570 UN TPDU */
1693 /* First octet is >= 3 and <= 32, so the user data *might*
1694 be an X.264/ISO 11570 UN TPDU. Check whether we have
1695 enough data to see if it is. */
1696 if (tvb_bytes_exist(tvb, localoffset+1, 1)) {
1697 /* We do; check whether the second octet is 1. */
1698 if (tvb_get_guint8(tvb, localoffset+1) == 0x01) {
1699 /* Yes, the second byte is 1, so it looks like
1703 /* No, the second byte is not 1, so it's not a
1708 /* We can't see the second byte of the putative UN
1709 TPDU, so we don't know if that's what it is. */
1713 if (is_x_264 == -1) {
1715 * We don't know what it is; just skip it.
1717 localoffset = tvb_length(tvb);
1718 } else if (is_x_264) {
1719 /* It looks like an X.264 UN TPDU, so show it as such. */
1720 if (userdata_tree) {
1721 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1722 "X.264 length indicator: %u",
1724 proto_tree_add_text(userdata_tree, tvb, localoffset+1, 1,
1725 "X.264 UN TPDU identifier: 0x%02X",
1726 tvb_get_guint8(tvb, localoffset+1));
1728 prt_id = tvb_get_guint8(tvb, localoffset+2);
1729 if (userdata_tree) {
1730 proto_tree_add_text(x25_tree, tvb, localoffset+2, 1,
1731 "X.264 protocol identifier: %s",
1732 val_to_str(prt_id, prt_id_vals,
1733 "Unknown (0x%02X)"));
1734 proto_tree_add_text(x25_tree, tvb, localoffset+3, 1,
1735 "X.264 sharing strategy: %s",
1736 val_to_str(tvb_get_guint8(tvb, localoffset+3),
1737 sharing_strategy_vals, "Unknown (0x%02X)"));
1740 /* XXX - dissect the variable part? */
1742 /* The length doesn't include the length octet itself. */
1743 localoffset += spi + 1;
1747 case PRT_ID_ISO_8073:
1749 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
1750 pinfo->fd->abs_usecs,
1752 /* XXX - disssect the rest of the user data as COTP?
1753 That needs support for NCM TPDUs, etc. */
1756 case PRT_ID_ISO_8602:
1758 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
1759 pinfo->fd->abs_usecs,
1763 } else if (is_x_264 == 0) {
1764 /* It doesn't look like a UN TPDU, so compare the first
1765 octet of the CALL REQUEST packet with various X.263/
1766 ISO 9577 NLPIDs, as per Annex A of X.263/ISO 9577. */
1768 if (userdata_tree) {
1769 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1770 "X.263 secondary protocol ID: %s",
1771 val_to_str(spi, nlpid_vals, "Unknown (0x%02x)"));
1776 * What's the dissector handle for this SPI?
1778 dissect = dissector_get_port_handle(x25_subdissector_table, spi);
1779 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
1780 pinfo->fd->abs_usecs, dissect);
1782 if (localoffset < tvb_length(tvb)) {
1783 if (userdata_tree) {
1784 proto_tree_add_text(userdata_tree, tvb, localoffset, -1,
1787 localoffset = tvb_length(tvb);
1791 case X25_CALL_ACCEPTED:
1792 if(check_col(pinfo->cinfo, COL_INFO))
1793 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d",
1794 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Call conn."
1798 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1799 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1801 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Call connected"
1805 if (localoffset < x25_pkt_len) /* calling/called addresses */
1806 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, toa);
1808 if (localoffset < x25_pkt_len) /* facilities */
1809 dump_facilities(x25_tree, &localoffset, tvb);
1811 if (localoffset < tvb_reported_length(tvb)) { /* user data */
1813 proto_tree_add_text(x25_tree, tvb, localoffset,
1814 tvb_reported_length(tvb)-localoffset, "Data");
1815 localoffset=tvb_reported_length(tvb);
1818 case X25_CLEAR_REQUEST:
1819 if(check_col(pinfo->cinfo, COL_INFO)) {
1820 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - %s",
1821 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Clear ind."
1823 vc, clear_code(tvb_get_guint8(tvb, 3)),
1824 clear_diag(tvb_get_guint8(tvb, 4)));
1826 x25_hash_add_proto_end(vc, pinfo->fd->abs_secs, pinfo->fd->abs_usecs);
1828 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1829 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb,
1830 localoffset+2, 1, X25_CLEAR_REQUEST,
1831 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Clear indication"
1833 proto_tree_add_text(x25_tree, tvb, 3, 1,
1834 "Cause : %s", clear_code(tvb_get_guint8(tvb, 3)));
1835 proto_tree_add_text(x25_tree, tvb, 4, 1,
1836 "Diagnostic : %s", clear_diag(tvb_get_guint8(tvb, 4)));
1838 localoffset = x25_pkt_len;
1840 case X25_CLEAR_CONFIRMATION:
1841 if(check_col(pinfo->cinfo, COL_INFO))
1842 col_add_fstr(pinfo->cinfo, COL_INFO, "Clear Conf. VC:%d", vc);
1844 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1845 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1846 X25_CLEAR_CONFIRMATION);
1848 localoffset = x25_pkt_len;
1850 if (localoffset < tvb_reported_length(tvb)) /* extended clear conf format */
1851 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, toa);
1853 if (localoffset < tvb_reported_length(tvb)) /* facilities */
1854 dump_facilities(x25_tree, &localoffset, tvb);
1856 case X25_DIAGNOSTIC:
1857 if(check_col(pinfo->cinfo, COL_INFO)) {
1858 col_add_fstr(pinfo->cinfo, COL_INFO, "Diag. %d",
1859 (int)tvb_get_guint8(tvb, 3));
1862 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1864 proto_tree_add_text(x25_tree, tvb, 3, 1,
1865 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 3));
1867 localoffset = x25_pkt_len;
1870 if(check_col(pinfo->cinfo, COL_INFO))
1871 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt VC:%d", vc);
1873 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1874 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1877 localoffset = x25_pkt_len;
1879 case X25_INTERRUPT_CONFIRMATION:
1880 if(check_col(pinfo->cinfo, COL_INFO))
1881 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt Conf. VC:%d", vc);
1883 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1884 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1885 X25_INTERRUPT_CONFIRMATION);
1887 localoffset = x25_pkt_len;
1889 case X25_RESET_REQUEST:
1890 if(check_col(pinfo->cinfo, COL_INFO)) {
1891 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - Diag.:%d",
1892 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Reset ind."
1894 vc, reset_code(tvb_get_guint8(tvb, 3)),
1895 (int)tvb_get_guint8(tvb, 4));
1897 x25_hash_add_proto_end(vc, pinfo->fd->abs_secs, pinfo->fd->abs_usecs);
1899 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1900 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1902 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Reset indication"
1904 proto_tree_add_text(x25_tree, tvb, 3, 1,
1905 "Cause : %s", reset_code(tvb_get_guint8(tvb, 3)));
1906 proto_tree_add_text(x25_tree, tvb, 4, 1,
1907 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
1909 localoffset = x25_pkt_len;
1911 case X25_RESET_CONFIRMATION:
1912 if(check_col(pinfo->cinfo, COL_INFO))
1913 col_add_fstr(pinfo->cinfo, COL_INFO, "Reset conf. VC:%d", vc);
1915 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1916 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1917 X25_RESET_CONFIRMATION);
1919 localoffset = x25_pkt_len;
1921 case X25_RESTART_REQUEST:
1922 if(check_col(pinfo->cinfo, COL_INFO)) {
1923 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s - Diag.:%d",
1924 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Restart ind."
1926 restart_code(tvb_get_guint8(tvb, 3)),
1927 (int)tvb_get_guint8(tvb, 3));
1930 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1931 X25_RESTART_REQUEST,
1932 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Restart indication"
1933 : "Restart request");
1934 proto_tree_add_text(x25_tree, tvb, 3, 1,
1935 "Cause : %s", restart_code(tvb_get_guint8(tvb, 3)));
1936 proto_tree_add_text(x25_tree, tvb, 4, 1,
1937 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
1939 localoffset = x25_pkt_len;
1941 case X25_RESTART_CONFIRMATION:
1942 if(check_col(pinfo->cinfo, COL_INFO))
1943 col_set_str(pinfo->cinfo, COL_INFO, "Restart conf.");
1945 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1946 X25_RESTART_CONFIRMATION);
1947 localoffset = x25_pkt_len;
1949 case X25_REGISTRATION_REQUEST:
1950 if(check_col(pinfo->cinfo, COL_INFO))
1951 col_set_str(pinfo->cinfo, COL_INFO, "Registration req.");
1953 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1954 X25_REGISTRATION_REQUEST);
1956 if (localoffset < x25_pkt_len)
1957 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
1960 if (localoffset < x25_pkt_len)
1961 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
1962 "Registration length: %d",
1963 tvb_get_guint8(tvb, localoffset) & 0x7F);
1964 if (localoffset+1 < x25_pkt_len)
1965 proto_tree_add_text(x25_tree, tvb, localoffset+1,
1966 tvb_get_guint8(tvb, localoffset) & 0x7F,
1969 localoffset = tvb_reported_length(tvb);
1971 case X25_REGISTRATION_CONFIRMATION:
1972 if(check_col(pinfo->cinfo, COL_INFO))
1973 col_set_str(pinfo->cinfo, COL_INFO, "Registration conf.");
1975 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1976 X25_REGISTRATION_CONFIRMATION);
1977 proto_tree_add_text(x25_tree, tvb, 3, 1,
1978 "Cause: %s", registration_code(tvb_get_guint8(tvb, 3)));
1979 proto_tree_add_text(x25_tree, tvb, 4, 1,
1980 "Diagnostic: %s", registration_code(tvb_get_guint8(tvb, 4)));
1983 if (localoffset < x25_pkt_len)
1984 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, TRUE);
1987 if (localoffset < x25_pkt_len)
1988 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
1989 "Registration length: %d",
1990 tvb_get_guint8(tvb, localoffset) & 0x7F);
1991 if (localoffset+1 < x25_pkt_len)
1992 proto_tree_add_text(x25_tree, tvb, localoffset+1,
1993 tvb_get_guint8(tvb, localoffset) & 0x7F,
1996 localoffset = tvb_reported_length(tvb);
2000 if ((pkt_type & 0x01) == X25_DATA)
2002 if(check_col(pinfo->cinfo, COL_INFO)) {
2004 col_add_fstr(pinfo->cinfo, COL_INFO,
2005 "Data VC:%d P(S):%d P(R):%d %s", vc,
2006 (pkt_type >> 1) & 0x07,
2007 (pkt_type >> 5) & 0x07,
2008 ((pkt_type >> 4) & 0x01) ? " M" : "");
2010 col_add_fstr(pinfo->cinfo, COL_INFO,
2011 "Data VC:%d P(S):%d P(R):%d %s", vc,
2012 tvb_get_guint8(tvb, localoffset+1) >> 1,
2014 (tvb_get_guint8(tvb, localoffset+1) & 0x01) ? " M" : "");
2017 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2019 proto_tree_add_uint_hidden(x25_tree, hf_x25_type, tvb,
2020 localoffset, 1, X25_DATA);
2022 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2023 localoffset, 1, pkt_type);
2024 if (pkt_type & 0x10)
2025 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod8, tvb,
2026 localoffset, 1, pkt_type);
2027 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod8, tvb,
2028 localoffset, 1, pkt_type);
2029 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
2030 decode_boolean_bitfield(pkt_type, 0x01, 1*8,
2034 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod128, tvb,
2035 localoffset, 1, pkt_type);
2036 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod128, tvb,
2038 tvb_get_guint8(tvb, localoffset+1));
2039 if (tvb_get_guint8(tvb, localoffset+1) & 0x01)
2040 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod128, tvb,
2042 tvb_get_guint8(tvb, localoffset+1));
2045 localoffset += (modulo == 8) ? 1 : 2;
2048 switch (pkt_type & 0x1F)
2051 if(check_col(pinfo->cinfo, COL_INFO)) {
2053 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2054 vc, (pkt_type >> 5) & 0x07);
2056 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2057 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2060 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2063 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2064 localoffset, 1, pkt_type);
2065 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2066 localoffset, 1, X25_RR);
2069 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2070 localoffset, 1, X25_RR);
2071 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2072 localoffset+1, 1, FALSE);
2078 if(check_col(pinfo->cinfo, COL_INFO)) {
2080 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2081 vc, (pkt_type >> 5) & 0x07);
2083 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2084 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2087 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2090 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2091 localoffset, 1, pkt_type);
2092 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2093 localoffset, 1, X25_RNR);
2096 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2097 localoffset, 1, X25_RNR);
2098 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2099 localoffset+1, 1, FALSE);
2105 if(check_col(pinfo->cinfo, COL_INFO)) {
2107 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2108 vc, (pkt_type >> 5) & 0x07);
2110 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2111 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2114 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2117 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2118 localoffset, 1, pkt_type);
2119 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2120 localoffset, 1, X25_REJ);
2123 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2124 localoffset, 1, X25_REJ);
2125 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2126 localoffset+1, 1, FALSE);
2130 localoffset += (modulo == 8) ? 1 : 2;
2133 if (localoffset >= tvb_reported_length(tvb)) return;
2135 next_tvb = tvb_new_subset(tvb, localoffset, -1, -1);
2139 call_dissector(qllc_handle, next_tvb, pinfo, tree);
2143 /* search the dissector in the hash table */
2144 if ((dissect = x25_hash_get_dissect(pinfo->fd->abs_secs, pinfo->fd->abs_usecs, vc))) {
2145 /* Found it in the hash table; use it. */
2146 call_dissector(dissect, next_tvb, pinfo, tree);
2150 /* Did the user suggest SNA-over-X.25? */
2151 if (non_q_bit_is_sna) {
2152 /* Yes - dissect it as SNA. */
2153 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
2154 pinfo->fd->abs_usecs, sna_handle);
2155 call_dissector(sna_handle, next_tvb, pinfo, tree);
2159 /* If the Call Req. has not been captured, and the payload begins
2160 with what appears to be an IP header, assume these packets carry
2162 if (tvb_get_guint8(tvb, localoffset) == 0x45) {
2163 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
2164 pinfo->fd->abs_usecs, ip_handle);
2165 call_dissector(ip_handle, next_tvb, pinfo, tree);
2169 /* Try the heuristic dissectors. */
2170 if (dissector_try_heuristic(x25_heur_subdissector_list, next_tvb, pinfo,
2174 /* All else failed; dissect it as raw data */
2175 call_dissector(data_handle, next_tvb, pinfo, tree);
2179 proto_register_x25(void)
2181 static hf_register_info hf[] = {
2183 { "GFI", "x.25.gfi", FT_UINT16, BASE_BIN, NULL, 0xF000,
2184 "General format identifier", HFILL }},
2186 { "A Bit", "x.25.a", FT_BOOLEAN, 16, NULL, 0x8000,
2187 "Address Bit", HFILL }},
2189 { "Q Bit", "x.25.q", FT_BOOLEAN, 16, NULL, 0x8000,
2190 "Qualifier Bit", HFILL }},
2192 { "D Bit", "x.25.d", FT_BOOLEAN, 16, NULL, 0x4000,
2193 "Delivery Confirmation Bit", HFILL }},
2195 { "Modulo", "x.25.mod", FT_UINT16, BASE_DEC, VALS(vals_modulo), 0x3000,
2196 "Specifies whether the frame is modulo 8 or 128", HFILL }},
2198 { "Logical Channel", "x.25.lcn", FT_UINT16, BASE_DEC, NULL, 0x0FFF,
2199 "Logical Channel Number", HFILL }},
2201 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x0,
2202 "Packet Type", HFILL }},
2204 { "P(R)", "x.25.p_r", FT_UINT8, BASE_HEX, NULL, 0xE0,
2205 "Packet Receive Sequence Number", HFILL }},
2206 { &hf_x25_p_r_mod128,
2207 { "P(R)", "x.25.p_r", FT_UINT8, BASE_HEX, NULL, 0xFE,
2208 "Packet Receive Sequence Number", HFILL }},
2209 { &hf_x25_mbit_mod8,
2210 { "M Bit", "x.25.m", FT_BOOLEAN, 8, NULL, 0x10,
2211 "More Bit", HFILL }},
2212 { &hf_x25_mbit_mod128,
2213 { "M Bit", "x.25.m", FT_BOOLEAN, 8, NULL, 0x01,
2214 "More Bit", HFILL }},
2216 { "P(S)", "x.25.p_s", FT_UINT8, BASE_HEX, NULL, 0x0E,
2217 "Packet Send Sequence Number", HFILL }},
2218 { &hf_x25_p_s_mod128,
2219 { "P(S)", "x.25.p_s", FT_UINT8, BASE_HEX, NULL, 0xFE,
2220 "Packet Send Sequence Number", HFILL }},
2222 static gint *ett[] = {
2226 &ett_x25_fac_unknown,
2228 &ett_x25_fac_reverse,
2229 &ett_x25_fac_throughput,
2231 &ett_x25_fac_called_modif,
2232 &ett_x25_fac_cug_outgoing_acc,
2233 &ett_x25_fac_throughput_min,
2234 &ett_x25_fac_express_data,
2235 &ett_x25_fac_bilateral_cug,
2236 &ett_x25_fac_packet_size,
2237 &ett_x25_fac_window_size,
2238 &ett_x25_fac_rpoa_selection,
2239 &ett_x25_fac_transit_delay,
2240 &ett_x25_fac_call_transfer,
2241 &ett_x25_fac_called_addr_ext,
2242 &ett_x25_fac_ete_transit_delay,
2243 &ett_x25_fac_calling_addr_ext,
2244 &ett_x25_fac_call_deflect,
2245 &ett_x25_fac_priority,
2248 module_t *x25_module;
2250 proto_x25 = proto_register_protocol ("X.25", "X.25", "x.25");
2251 proto_register_field_array (proto_x25, hf, array_length(hf));
2252 proto_register_subtree_array(ett, array_length(ett));
2253 register_init_routine(&reinit_x25_hashtable);
2255 x25_subdissector_table = register_dissector_table("x.25.spi",
2256 "X.25 secondary protocol identifier", FT_UINT8, BASE_HEX);
2257 register_heur_dissector_list("x.25", &x25_heur_subdissector_list);
2259 register_dissector("x.25", dissect_x25, proto_x25);
2262 x25_module = prefs_register_protocol(proto_x25, NULL);
2263 prefs_register_bool_preference(x25_module, "non_q_bit_is_sna",
2264 "When Q-bit is 0, payload is SNA", "When Q-bit is 0, payload is SNA",
2269 proto_reg_handoff_x25(void)
2271 dissector_handle_t x25_handle;
2274 * Get handles for various dissectors.
2276 ip_handle = find_dissector("ip");
2277 ositp_handle = find_dissector("ositp");
2278 sna_handle = find_dissector("sna");
2279 qllc_handle = find_dissector("qllc");
2280 data_handle = find_dissector("data");
2282 x25_handle = find_dissector("x.25");
2283 dissector_add("llc.dsap", SAP_X25, x25_handle);