2 * Routines for x25 packet disassembly
3 * Olivier Abad <oabad@cybercable.fr>
5 * $Id: packet-x25.c,v 1.65 2002/04/09 08:15:02 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
39 #include <epan/packet.h>
42 #include "x264_prt_id.h"
45 * Direction of packet.
48 X25_FROM_DCE, /* DCE->DTE */
49 X25_FROM_DTE, /* DTE->DCE */
50 X25_UNKNOWN /* direction unknown */
53 #define X25_CALL_REQUEST 0x0B
54 #define X25_CALL_ACCEPTED 0x0F
55 #define X25_CLEAR_REQUEST 0x13
56 #define X25_CLEAR_CONFIRMATION 0x17
57 #define X25_INTERRUPT 0x23
58 #define X25_INTERRUPT_CONFIRMATION 0x27
59 #define X25_RESET_REQUEST 0x1B
60 #define X25_RESET_CONFIRMATION 0x1F
61 #define X25_RESTART_REQUEST 0xFB
62 #define X25_RESTART_CONFIRMATION 0xFF
63 #define X25_REGISTRATION_REQUEST 0xF3
64 #define X25_REGISTRATION_CONFIRMATION 0xF7
65 #define X25_DIAGNOSTIC 0xF1
71 #define X25_FAC_CLASS_MASK 0xC0
73 #define X25_FAC_CLASS_A 0x00
74 #define X25_FAC_CLASS_B 0x40
75 #define X25_FAC_CLASS_C 0x80
76 #define X25_FAC_CLASS_D 0xC0
78 #define X25_FAC_COMP_MARK 0x00
79 #define X25_FAC_REVERSE 0x01
80 #define X25_FAC_THROUGHPUT 0x02
81 #define X25_FAC_CUG 0x03
82 #define X25_FAC_CALLED_MODIF 0x08
83 #define X25_FAC_CUG_OUTGOING_ACC 0x09
84 #define X25_FAC_THROUGHPUT_MIN 0x0A
85 #define X25_FAC_EXPRESS_DATA 0x0B
86 #define X25_FAC_BILATERAL_CUG 0x41
87 #define X25_FAC_PACKET_SIZE 0x42
88 #define X25_FAC_WINDOW_SIZE 0x43
89 #define X25_FAC_RPOA_SELECTION 0x44
90 #define X25_FAC_TRANSIT_DELAY 0x49
91 #define X25_FAC_CALL_TRANSFER 0xC3
92 #define X25_FAC_CALLED_ADDR_EXT 0xC9
93 #define X25_FAC_ETE_TRANSIT_DELAY 0xCA
94 #define X25_FAC_CALLING_ADDR_EXT 0xCB
95 #define X25_FAC_CALL_DEFLECT 0xD1
96 #define X25_FAC_PRIORITY 0xD2
98 static int proto_x25 = -1;
99 static int hf_x25_gfi = -1;
100 static int hf_x25_abit = -1;
101 static int hf_x25_qbit = -1;
102 static int hf_x25_dbit = -1;
103 static int hf_x25_mod = -1;
104 static int hf_x25_lcn = -1;
105 static int hf_x25_type = -1;
106 static int hf_x25_p_r_mod8 = -1;
107 static int hf_x25_p_r_mod128 = -1;
108 static int hf_x25_mbit_mod8 = -1;
109 static int hf_x25_mbit_mod128 = -1;
110 static int hf_x25_p_s_mod8 = -1;
111 static int hf_x25_p_s_mod128 = -1;
113 static gint ett_x25 = -1;
114 static gint ett_x25_gfi = -1;
115 static gint ett_x25_fac = -1;
116 static gint ett_x25_fac_unknown = -1;
117 static gint ett_x25_fac_mark = -1;
118 static gint ett_x25_fac_reverse = -1;
119 static gint ett_x25_fac_throughput = -1;
120 static gint ett_x25_fac_cug = -1;
121 static gint ett_x25_fac_called_modif = -1;
122 static gint ett_x25_fac_cug_outgoing_acc = -1;
123 static gint ett_x25_fac_throughput_min = -1;
124 static gint ett_x25_fac_express_data = -1;
125 static gint ett_x25_fac_bilateral_cug = -1;
126 static gint ett_x25_fac_packet_size = -1;
127 static gint ett_x25_fac_window_size = -1;
128 static gint ett_x25_fac_rpoa_selection = -1;
129 static gint ett_x25_fac_transit_delay = -1;
130 static gint ett_x25_fac_call_transfer = -1;
131 static gint ett_x25_fac_called_addr_ext = -1;
132 static gint ett_x25_fac_ete_transit_delay = -1;
133 static gint ett_x25_fac_calling_addr_ext = -1;
134 static gint ett_x25_fac_call_deflect = -1;
135 static gint ett_x25_fac_priority = -1;
136 static gint ett_x25_user_data = -1;
138 static const value_string vals_modulo[] = {
144 static const value_string vals_x25_type[] = {
145 { X25_CALL_REQUEST, "Call" },
146 { X25_CALL_ACCEPTED, "Call Accepted" },
147 { X25_CLEAR_REQUEST, "Clear" },
148 { X25_CLEAR_CONFIRMATION, "Clear Confirmation" },
149 { X25_INTERRUPT, "Interrupt" },
150 { X25_INTERRUPT_CONFIRMATION, "Interrupt Confirmation" },
151 { X25_RESET_REQUEST, "Reset" },
152 { X25_RESET_CONFIRMATION, "Reset Confirmation" },
153 { X25_RESTART_REQUEST, "Restart" },
154 { X25_RESTART_CONFIRMATION, "Restart Confirmation" },
155 { X25_REGISTRATION_REQUEST, "Registration" },
156 { X25_REGISTRATION_CONFIRMATION, "Registration Confirmation" },
157 { X25_DIAGNOSTIC, "Diagnostic" },
161 { X25_DATA, "DATA" },
165 static dissector_handle_t ip_handle;
166 static dissector_handle_t ositp_handle;
167 static dissector_handle_t sna_handle;
168 static dissector_handle_t qllc_handle;
169 static dissector_handle_t data_handle;
172 static gboolean non_q_bit_is_sna = FALSE;
174 static dissector_table_t x25_subdissector_table;
175 static heur_dissector_list_t x25_heur_subdissector_list;
178 * each vc_info node contains :
179 * the time of the first frame using this dissector (secs and usecs)
180 * the time of the last frame using this dissector (0 if it is unknown)
181 * a handle for the dissector
183 * the "time of first frame" is initialized when a Call Req. is received
184 * the "time of last frame" is initialized when a Clear, Reset, or Restart
187 typedef struct _vc_info {
188 guint32 first_frame_secs, first_frame_usecs;
189 guint32 last_frame_secs, last_frame_usecs;
190 dissector_handle_t dissect;
191 struct _vc_info *next;
195 * the hash table will contain linked lists of global_vc_info
196 * each global_vc_info struct contains :
197 * the VC number (the hash table is indexed with VC % 64)
198 * a linked list of vc_info
200 typedef struct _global_vc_info {
203 struct _global_vc_info *next;
206 static global_vc_info *hash_table[64];
209 free_vc_info(vc_info *pt)
221 reinit_x25_hashtable(void)
225 for (i=0; i<64; i++) {
226 if (hash_table[i]) /* not NULL ==> free */
228 global_vc_info *hash_ent, *hash_ent2;
229 hash_ent2 = hash_ent = hash_table[i];
232 hash_ent2 = hash_ent;
233 hash_ent = hash_ent->next;
234 free_vc_info(hash_ent2->info);
243 x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs,
244 dissector_handle_t dissect)
247 global_vc_info *hash_ent;
248 global_vc_info *hash_ent2;
250 if (hash_table[idx] == 0)
252 hash_ent = (global_vc_info *)g_malloc(sizeof(global_vc_info));
254 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
257 hash_ent->vc_num = vc;
259 hash_ent->info = (vc_info *)g_malloc(sizeof(vc_info));
260 if (!hash_ent->info) {
261 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
264 hash_ent->info->first_frame_secs = frame_secs;
265 hash_ent->info->first_frame_usecs = frame_usecs;
266 hash_ent->info->last_frame_secs = 0;
267 hash_ent->info->last_frame_usecs = 0;
268 hash_ent->info->dissect = dissect;
269 hash_ent->info->next = 0;
270 hash_table[idx] = hash_ent;
274 hash_ent2 = hash_ent = hash_table[idx];
275 /* search an entry with the same VC number */
276 while (hash_ent != NULL && hash_ent->vc_num != vc) {
277 hash_ent2 = hash_ent;
278 hash_ent = hash_ent->next;
280 if (hash_ent != NULL) /* hash_ent->vc_num == vc */
282 vc_info *vci = hash_ent->info;
283 while (vci->next) vci = vci->next; /* last element */
284 if (vci->dissect == dissect) {
285 vci->last_frame_secs = 0;
286 vci->last_frame_usecs = 0;
289 vci->next = (vc_info *)g_malloc(sizeof(vc_info));
290 if (vci->next == 0) {
291 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
294 vci->next->first_frame_secs = frame_secs;
295 vci->next->first_frame_usecs = frame_usecs;
296 vci->next->last_frame_secs = 0;
297 vci->next->last_frame_usecs = 0;
298 vci->next->dissect = dissect;
302 else /* new vc number */
304 hash_ent2->next = (global_vc_info *)g_malloc(sizeof(global_vc_info));
305 if (!hash_ent2->next) {
306 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
309 hash_ent2->next->info = (vc_info *)g_malloc(sizeof(vc_info));
310 if (!hash_ent2->next->info) {
311 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
314 hash_ent2->next->info->first_frame_secs = frame_secs;
315 hash_ent2->next->info->first_frame_usecs = frame_usecs;
316 hash_ent2->next->info->last_frame_secs = 0;
317 hash_ent2->next->info->last_frame_usecs = 0;
318 hash_ent2->next->info->dissect = dissect;
319 hash_ent2->next->info->next = 0;
325 x25_hash_add_proto_end(guint16 vc, guint32 frame_secs, guint32 frame_usecs)
327 global_vc_info *hash_ent = hash_table[vc%64];
330 if (!hash_ent) return;
331 while(hash_ent->vc_num != vc) hash_ent = hash_ent->next;
332 if (!hash_ent) return;
334 vci = hash_ent->info;
335 while (vci->next) vci = vci->next;
336 vci->last_frame_secs = frame_secs;
337 vci->last_frame_usecs = frame_usecs;
340 static dissector_handle_t
341 x25_hash_get_dissect(guint32 frame_secs, guint32 frame_usecs, guint16 vc)
343 global_vc_info *hash_ent = hash_table[vc%64];
350 while (hash_ent && hash_ent->vc_num != vc)
351 hash_ent = hash_ent->next;
355 /* a hash_ent was found for this VC number */
356 vci2 = vci = hash_ent->info;
358 /* looking for an entry matching our frame time */
359 while (vci && (vci->last_frame_secs < frame_secs ||
360 (vci->last_frame_secs == frame_secs &&
361 vci->last_frame_usecs < frame_usecs))) {
365 /* we reached last record, and previous record has a non zero
366 * last frame time ==> no dissector */
367 if (!vci && (vci2->last_frame_secs || vci2->last_frame_usecs))
370 /* we reached last record, and previous record has a zero last frame time
371 * ==> dissector for previous frame has not been "stopped" by a Clear, etc */
373 /* if the start time for vci2 is greater than our frame time
374 * ==> no dissector */
375 if (frame_secs < vci2->first_frame_secs ||
376 (frame_secs == vci2->first_frame_secs &&
377 frame_usecs < vci2->first_frame_usecs))
380 return vci2->dissect;
383 /* our frame time is before vci's end. Check if it is after vci's start */
384 if (frame_secs < vci->first_frame_secs ||
385 (frame_secs == vci->first_frame_secs &&
386 frame_usecs < vci->first_frame_usecs))
392 static char *clear_code(unsigned char code)
394 static char buffer[25];
396 if (code == 0x00 || (code & 0x80) == 0x80)
397 return "DTE Originated";
399 return "Number Busy";
401 return "Invalid Facility Requested";
403 return "Network Congestion";
405 return "Out Of Order";
407 return "Access Barred";
409 return "Not Obtainable";
411 return "Remote Procedure Error";
413 return "Local Procedure Error";
415 return "RPOA Out Of Order";
417 return "Reverse Charging Acceptance Not Subscribed";
419 return "Incompatible Destination";
421 return "Fast Select Acceptance Not Subscribed";
423 return "Destination Absent";
425 sprintf(buffer, "Unknown %02X", code);
430 static char *clear_diag(unsigned char code)
432 static char buffer[25];
435 return "No additional information";
437 return "Invalid P(S)";
439 return "Invalid P(R)";
441 return "Packet type invalid";
443 return "Packet type invalid for state r1";
445 return "Packet type invalid for state r2";
447 return "Packet type invalid for state r3";
449 return "Packet type invalid for state p1";
451 return "Packet type invalid for state p2";
453 return "Packet type invalid for state p3";
455 return "Packet type invalid for state p4";
457 return "Packet type invalid for state p5";
459 return "Packet type invalid for state p6";
461 return "Packet type invalid for state p7";
463 return "Packet type invalid for state d1";
465 return "Packet type invalid for state d2";
467 return "Packet type invalid for state d3";
469 return "Packet not allowed";
471 return "Unidentifiable packet";
473 return "Call on one-way logical channel";
475 return "Invalid packet type on a PVC";
477 return "Packet on unassigned LC";
479 return "Reject not subscribed to";
481 return "Packet too short";
483 return "Packet too long";
485 return "Invalid general format identifier";
487 return "Restart/registration packet with nonzero bits";
489 return "Packet type not compatible with facility";
491 return "Unauthorised interrupt confirmation";
493 return "Unauthorised interrupt";
495 return "Unauthorised reject";
497 return "Time expired";
499 return "Time expired for incoming call";
501 return "Time expired for clear indication";
503 return "Time expired for reset indication";
505 return "Time expired for restart indication";
507 return "Time expired for call deflection";
509 return "Call set-up/clearing or registration pb.";
511 return "Facility/registration code not allowed";
513 return "Facility parameter not allowed";
515 return "Invalid called DTE address";
517 return "Invalid calling DTE address";
519 return "Invalid facility/registration length";
521 return "Incoming call barred";
523 return "No logical channel available";
525 return "Call collision";
527 return "Duplicate facility requested";
529 return "Non zero address length";
531 return "Non zero facility length";
533 return "Facility not provided when expected";
535 return "Invalid CCITT-specified DTE facility";
537 return "Max. nb of call redir/defl. exceeded";
539 return "Miscellaneous";
541 return "Improper cause code from DTE";
543 return "Not aligned octet";
545 return "Inconsistent Q bit setting";
547 return "NUI problem";
549 return "International problem";
551 return "Remote network problem";
553 return "International protocol problem";
555 return "International link out of order";
557 return "International link busy";
559 return "Transit network facility problem";
561 return "Remote network facility problem";
563 return "International routing problem";
565 return "Temporary routing problem";
567 return "Unknown called DNIC";
569 return "Maintenance action";
571 return "Timer expired or retransmission count surpassed";
573 return "Timer expired or retransmission count surpassed for INTERRUPT";
575 return "Timer expired or retransmission count surpassed for DATA "
576 "packet transmission";
578 return "Timer expired or retransmission count surpassed for REJECT";
580 return "DTE-specific signals";
582 return "DTE operational";
584 return "DTE not operational";
586 return "DTE resource constraint";
588 return "Fast select not subscribed";
590 return "Invalid partially full DATA packet";
592 return "D-bit procedure not supported";
594 return "Registration/Cancellation confirmed";
596 return "OSI network service problem";
598 return "Disconnection (transient condition)";
600 return "Disconnection (permanent condition)";
602 return "Connection rejection - reason unspecified (transient "
605 return "Connection rejection - reason unspecified (permanent "
608 return "Connection rejection - quality of service not available "
609 "transient condition)";
611 return "Connection rejection - quality of service not available "
612 "permanent condition)";
614 return "Connection rejection - NSAP unreachable (transient condition)";
616 return "Connection rejection - NSAP unreachable (permanent condition)";
618 return "reset - reason unspecified";
620 return "reset - congestion";
622 return "Connection rejection - NSAP address unknown (permanent "
625 return "Higher layer initiated";
627 return "Disconnection - normal";
629 return "Disconnection - abnormal";
631 return "Disconnection - incompatible information in user data";
633 return "Connection rejection - reason unspecified (transient "
636 return "Connection rejection - reason unspecified (permanent "
639 return "Connection rejection - quality of service not available "
640 "(transient condition)";
642 return "Connection rejection - quality of service not available "
643 "(permanent condition)";
645 return "Connection rejection - incompatible information in user data";
647 return "Connection rejection - unrecognizable protocol indentifier "
650 return "Reset - user resynchronization";
652 sprintf(buffer, "Unknown %d", code);
657 static char *reset_code(unsigned char code)
659 static char buffer[25];
661 if (code == 0x00 || (code & 0x80) == 0x80)
662 return "DTE Originated";
664 return "Out of order";
666 return "Remote Procedure Error";
668 return "Local Procedure Error";
670 return "Network Congestion";
672 return "Remote DTE operational";
674 return "Network operational";
676 return "Incompatible Destination";
678 return "Network out of order";
680 sprintf(buffer, "Unknown %02X", code);
685 static char *restart_code(unsigned char code)
687 static char buffer[25];
689 if (code == 0x00 || (code & 0x80) == 0x80)
690 return "DTE Originated";
692 return "Local Procedure Error";
694 return "Network Congestion";
696 return "Network Operational";
698 return "Registration/cancellation confirmed";
700 sprintf(buffer, "Unknown %02X", code);
705 static char *registration_code(unsigned char code)
707 static char buffer[25];
710 return "Invalid facility request";
712 return "Network congestion";
714 return "Local procedure error";
716 return "Registration/cancellation confirmed";
718 sprintf(buffer, "Unknown %02X", code);
724 dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb)
726 guint8 fac, byte1, byte2, byte3;
727 guint32 len; /* facilities length */
729 proto_tree *fac_tree = 0;
730 proto_tree *fac_subtree;
732 len = tvb_get_guint8(tvb, *offset);
734 ti = proto_tree_add_text(tree, tvb, *offset, len + 1,
736 fac_tree = proto_item_add_subtree(ti, ett_x25_fac);
737 proto_tree_add_text(fac_tree, tvb, *offset, 1,
738 "Facilities length: %d", len);
743 fac = tvb_get_guint8(tvb, *offset);
744 switch(fac & X25_FAC_CLASS_MASK) {
745 case X25_FAC_CLASS_A:
747 case X25_FAC_COMP_MARK:
749 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
750 "Code : 00 (Marker)");
751 switch (tvb_get_guint8(tvb, *offset + 1)) {
754 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
755 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
756 "Parameter : 00 (Network complementary "
757 "services - calling DTE)");
762 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
763 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
764 "Parameter : FF (Network complementary "
765 "services - called DTE)");
770 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
771 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
772 "Parameter : 0F (DTE complementary "
778 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
779 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
780 "Parameter : %02X (Unknown marker)",
781 tvb_get_guint8(tvb, *offset+1));
786 case X25_FAC_REVERSE:
788 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
789 "(Reverse charging / Fast select)", fac);
790 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_reverse);
791 byte1 = tvb_get_guint8(tvb, *offset + 1);
792 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
793 "Parameter : %02X", byte1);
795 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
796 "11.. .... = Fast select with restriction");
797 else if (byte1 & 0x80)
798 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
799 "10.. .... = Fast select - no restriction");
801 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
802 "00.. .... = Fast select not requested");
803 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
804 decode_boolean_bitfield(byte1, 0x01, 1*8,
805 "Reverse charging requested",
806 "Reverse charging not requested"));
809 case X25_FAC_THROUGHPUT:
813 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
814 "(Throughput class negociation)", fac);
815 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_throughput);
816 byte1 = tvb_get_guint8(tvb, *offset + 1);
828 sprintf(tmpbuf, "From the called DTE : %%u (%d bps)",
829 75*(1<<((byte1 >> 4)-3)));
832 sprintf(tmpbuf, "From the called DTE : %%u (48000 bps)");
835 sprintf(tmpbuf, "From the called DTE : %%u (64000 bps)");
838 sprintf(tmpbuf, "From the called DTE : %%u (Reserved)");
840 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
841 decode_numeric_bitfield(byte1, 0xF0, 1*8, tmpbuf));
842 switch (byte1 & 0x0F)
853 sprintf(tmpbuf, "From the calling DTE : %%u (%d bps)",
854 75*(1<<((byte1 & 0x0F)-3)));
857 sprintf(tmpbuf, "From the calling DTE : %%u (48000 bps)");
860 sprintf(tmpbuf, "From the calling DTE : %%u (64000 bps)");
863 sprintf(tmpbuf, "From the calling DTE : %%u (Reserved)");
865 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
866 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
871 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
872 "(Closed user group selection)", fac);
873 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_cug);
874 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
875 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
878 case X25_FAC_CALLED_MODIF:
880 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
881 "(Called address modified)", fac);
882 fac_subtree = proto_item_add_subtree(ti,
883 ett_x25_fac_called_modif);
884 proto_tree_add_text(fac_tree, tvb, *offset+1, 1,
885 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
888 case X25_FAC_CUG_OUTGOING_ACC:
890 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
891 "(Closed user group with outgoing access selection)",
893 fac_subtree = proto_item_add_subtree(ti,
894 ett_x25_fac_cug_outgoing_acc);
895 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
896 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
899 case X25_FAC_THROUGHPUT_MIN:
901 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
902 "(Minimum throughput class)", fac);
903 fac_subtree = proto_item_add_subtree(ti,
904 ett_x25_fac_throughput_min);
905 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
906 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
909 case X25_FAC_EXPRESS_DATA:
911 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
912 "(Negociation of express data)", fac);
913 fac_subtree = proto_item_add_subtree(ti,
914 ett_x25_fac_express_data);
915 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
916 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
921 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
922 "Code : %02X (Unknown class A)", fac);
923 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
924 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
925 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
932 case X25_FAC_CLASS_B:
934 case X25_FAC_BILATERAL_CUG:
936 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
937 "(Bilateral closed user group selection)", fac);
938 fac_subtree = proto_item_add_subtree(ti,
939 ett_x25_fac_bilateral_cug);
940 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
941 "Bilateral CUG: %04X",
942 tvb_get_ntohs(tvb, *offset+1));
945 case X25_FAC_PACKET_SIZE:
950 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
951 "(Packet size)", fac);
952 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_packet_size);
953 byte1 = tvb_get_guint8(tvb, *offset + 1);
957 sprintf(tmpbuf, "From the called DTE : %%u (16)");
960 sprintf(tmpbuf, "From the called DTE : %%u (32)");
963 sprintf(tmpbuf, "From the called DTE : %%u (64)");
966 sprintf(tmpbuf, "From the called DTE : %%u (128)");
969 sprintf(tmpbuf, "From the called DTE : %%u (256)");
972 sprintf(tmpbuf, "From the called DTE : %%u (512)");
975 sprintf(tmpbuf, "From the called DTE : %%u (1024)");
978 sprintf(tmpbuf, "From the called DTE : %%u (2048)");
981 sprintf(tmpbuf, "From the called DTE : %%u (4096)");
984 sprintf(tmpbuf, "From the called DTE : %%u (Unknown)");
987 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
988 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
990 byte2 = tvb_get_guint8(tvb, *offset + 1);
994 sprintf(tmpbuf, "From the calling DTE : %%u (16)");
997 sprintf(tmpbuf, "From the calling DTE : %%u (32)");
1000 sprintf(tmpbuf, "From the calling DTE : %%u (64)");
1003 sprintf(tmpbuf, "From the calling DTE : %%u (128)");
1006 sprintf(tmpbuf, "From the calling DTE : %%u (256)");
1009 sprintf(tmpbuf, "From the calling DTE : %%u (512)");
1012 sprintf(tmpbuf, "From the calling DTE : %%u (1024)");
1015 sprintf(tmpbuf, "From the calling DTE : %%u (2048)");
1018 sprintf(tmpbuf, "From the calling DTE : %%u (4096)");
1021 sprintf(tmpbuf, "From the calling DTE : %%u (Unknown)");
1024 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1025 decode_numeric_bitfield(byte2, 0x0F, 1*8, tmpbuf));
1028 case X25_FAC_WINDOW_SIZE:
1030 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1031 "(Window size)", fac);
1032 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_window_size);
1033 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1034 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+1),
1035 0x7F, 1*8, "From the called DTE: %u"));
1036 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1037 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+2),
1038 0x7F, 1*8, "From the calling DTE: %u"));
1041 case X25_FAC_RPOA_SELECTION:
1043 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1044 "(RPOA selection)", fac);
1045 fac_subtree = proto_item_add_subtree(ti,
1046 ett_x25_fac_rpoa_selection);
1047 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
1048 "Data network identification code : %04X",
1049 tvb_get_ntohs(tvb, *offset+1));
1052 case X25_FAC_TRANSIT_DELAY:
1054 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1055 "(Transit delay selection and indication)", fac);
1056 fac_subtree = proto_item_add_subtree(ti,
1057 ett_x25_fac_transit_delay);
1058 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
1059 "Transit delay: %d ms",
1060 tvb_get_ntohs(tvb, *offset+1));
1065 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1066 "Code : %02X (Unknown class B)", fac);
1067 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1068 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
1069 "Parameter %04X", tvb_get_ntohs(tvb, *offset+1));
1076 case X25_FAC_CLASS_C:
1078 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1079 "Code : %02X (Unknown class C)", fac);
1080 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1081 proto_tree_add_text(fac_subtree, tvb, *offset+1, 3,
1083 tvb_get_ntoh24(tvb, *offset+1));
1088 case X25_FAC_CLASS_D:
1090 case X25_FAC_CALL_TRANSFER:
1095 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1096 "(Call redirection or deflection notification)", fac);
1097 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_call_transfer);
1098 byte1 = tvb_get_guint8(tvb, *offset+1);
1099 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1100 "Length : %u", byte1);
1101 byte2 = tvb_get_guint8(tvb, *offset+2);
1102 if ((byte2 & 0xC0) == 0xC0) {
1103 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1104 "Reason : call deflection by the originally "
1105 "called DTE address");
1110 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1111 "Reason : originally called DTE busy");
1114 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1115 "Reason : call dist. within a hunt group");
1118 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1119 "Reason : originally called DTE out of order");
1122 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1123 "Reason : systematic call redirection");
1126 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1127 "Reason : unknown");
1131 byte3 = tvb_get_guint8(tvb, *offset+3);
1132 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1133 "Number of semi-octets in DTE address : %u",
1135 for (i = 0; i < byte3; i++) {
1137 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1139 /* if > 9, convert to the right hexadecimal letter */
1140 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1142 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1144 /* if > 9, convert to the right hexadecimal letter */
1145 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1149 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1150 "DTE address : %s", tmpbuf);
1153 case X25_FAC_CALLING_ADDR_EXT:
1158 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1159 "(Calling address extension)", fac);
1160 fac_subtree = proto_item_add_subtree(ti,
1161 ett_x25_fac_calling_addr_ext);
1162 byte1 = tvb_get_guint8(tvb, *offset+1);
1163 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1164 "Length : %u", byte1);
1165 byte2 = tvb_get_guint8(tvb, *offset+2);
1166 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1167 "Number of semi-octets in DTE address : %u", byte2);
1168 for (i = 0; i < byte2; i++) {
1170 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1172 /* if > 9, convert to the right hexadecimal letter */
1173 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1175 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1177 /* if > 9, convert to the right hexadecimal letter */
1178 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1182 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1183 "DTE address : %s", tmpbuf);
1186 case X25_FAC_CALLED_ADDR_EXT:
1191 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1192 "(Called address extension)", fac);
1193 fac_subtree = proto_item_add_subtree(ti,
1194 ett_x25_fac_called_addr_ext);
1195 byte1 = tvb_get_guint8(tvb, *offset+1);
1196 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1197 "Length : %u", byte1);
1198 byte2 = tvb_get_guint8(tvb, *offset+2);
1199 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1200 "Number of semi-octets in DTE address : %u", byte2);
1201 for (i = 0; i < byte2; i++) {
1203 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1205 /* if > 9, convert to the right hexadecimal letter */
1206 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1208 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1210 /* if > 9, convert to the right hexadecimal letter */
1211 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1215 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1216 "DTE address : %s", tmpbuf);
1219 case X25_FAC_ETE_TRANSIT_DELAY:
1221 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1222 "(End to end transit delay)", fac);
1223 fac_subtree = proto_item_add_subtree(ti,
1224 ett_x25_fac_ete_transit_delay);
1225 byte1 = tvb_get_guint8(tvb, *offset+1);
1226 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1227 "Length : %u", byte1);
1228 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1231 case X25_FAC_CALL_DEFLECT:
1236 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1237 "(Call deflection selection)", fac);
1238 fac_subtree = proto_item_add_subtree(ti,
1239 ett_x25_fac_call_deflect);
1240 byte1 = tvb_get_guint8(tvb, *offset+1);
1241 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1242 "Length : %u", byte1);
1243 byte2 = tvb_get_guint8(tvb, *offset+2);
1244 if ((byte2 & 0xC0) == 0xC0)
1245 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1246 "Reason : call DTE originated");
1248 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1249 "Reason : unknown");
1250 byte3 = tvb_get_guint8(tvb, *offset+3);
1251 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1252 "Number of semi-octets in the alternative DTE address : %u",
1254 for (i = 0; i < byte3; i++) {
1256 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1258 /* if > 9, convert to the right hexadecimal letter */
1259 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1261 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1263 /* if > 9, convert to the right hexadecimal letter */
1264 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1268 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1269 "Alternative DTE address : %s", tmpbuf);
1272 case X25_FAC_PRIORITY:
1274 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1275 "Code : %02X (Priority)", fac);
1276 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_priority);
1277 byte1 = tvb_get_guint8(tvb, *offset+1);
1278 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1279 "Length : %u", byte1);
1280 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1285 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1286 "Code : %02X (Unknown class D)", fac);
1287 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1288 byte1 = tvb_get_guint8(tvb, *offset+1);
1289 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1290 "Length : %u", byte1);
1291 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1294 byte1 = tvb_get_guint8(tvb, *offset+1);
1295 (*offset) += byte1+2;
1303 x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1304 packet_info *pinfo, gboolean toa)
1308 char addr1[16], addr2[16];
1309 char *first, *second;
1313 byte = tvb_get_guint8(tvb, *offset);
1314 len1 = (byte >> 4) & 0x0F;
1315 len2 = (byte >> 0) & 0x0F;
1317 proto_tree_add_text(tree, tvb, *offset, 1,
1318 decode_numeric_bitfield(byte, 0xF0, 1*8,
1319 toa ? "Called address length : %u" :
1320 "Calling address length : %u"));
1321 proto_tree_add_text(tree, tvb, *offset, 1,
1322 decode_numeric_bitfield(byte, 0x0F, 1*8,
1323 toa ? "Calling address length : %u" :
1324 "Called address length : %u"));
1328 localoffset = *offset;
1329 byte = tvb_get_guint8(tvb, localoffset);
1333 for (i = 0; i < (len1 + len2); i++) {
1336 *first++ = ((byte >> 0) & 0x0F) + '0';
1338 byte = tvb_get_guint8(tvb, localoffset);
1340 *first++ = ((byte >> 4) & 0x0F) + '0';
1344 *second++ = ((byte >> 0) & 0x0F) + '0';
1346 byte = tvb_get_guint8(tvb, localoffset);
1348 *second++ = ((byte >> 4) & 0x0F) + '0';
1358 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1359 col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1);
1362 if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
1363 col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr1);
1366 proto_tree_add_text(tree, tvb, *offset,
1369 toa ? "Called" : "Calling",
1374 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1375 col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2);
1378 if(check_col(pinfo->cinfo, COL_RES_DL_DST))
1379 col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr2);
1382 proto_tree_add_text(tree, tvb, *offset + len1/2,
1383 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1385 toa ? "Calling" : "Called",
1388 (*offset) += ((len1 + len2 + 1) / 2);
1392 get_x25_pkt_len(tvbuff_t *tvb)
1394 guint length, called_len, calling_len, dte_len, dce_len;
1395 guint8 byte2, bytex;
1397 byte2 = tvb_get_guint8(tvb, 2);
1400 case X25_CALL_REQUEST:
1401 bytex = tvb_get_guint8(tvb, 3);
1402 called_len = (bytex >> 0) & 0x0F;
1403 calling_len = (bytex >> 4) & 0x0F;
1404 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1405 if (length < tvb_reported_length(tvb))
1406 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1408 return MIN(tvb_reported_length(tvb),length);
1410 case X25_CALL_ACCEPTED:
1411 /* The calling/called address length byte (following the packet type)
1412 * is not mandatory, so we must check the packet length before trying
1414 if (tvb_reported_length(tvb) == 3)
1416 bytex = tvb_get_guint8(tvb, 3);
1417 called_len = (bytex >> 0) & 0x0F;
1418 calling_len = (bytex >> 4) & 0x0F;
1419 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1420 if (length < tvb_reported_length(tvb))
1421 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1423 return MIN(tvb_reported_length(tvb),length);
1425 case X25_CLEAR_REQUEST:
1426 case X25_RESET_REQUEST:
1427 case X25_RESTART_REQUEST:
1428 return MIN(tvb_reported_length(tvb),5);
1430 case X25_DIAGNOSTIC:
1431 return MIN(tvb_reported_length(tvb),4);
1433 case X25_CLEAR_CONFIRMATION:
1435 case X25_INTERRUPT_CONFIRMATION:
1436 case X25_RESET_CONFIRMATION:
1437 case X25_RESTART_CONFIRMATION:
1438 return MIN(tvb_reported_length(tvb),3);
1440 case X25_REGISTRATION_REQUEST:
1441 bytex = tvb_get_guint8(tvb, 3);
1442 dce_len = (bytex >> 0) & 0x0F;
1443 dte_len = (bytex >> 4) & 0x0F;
1444 length = 4 + (dte_len + dce_len + 1) / 2; /* addr */
1445 if (length < tvb_reported_length(tvb))
1446 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1448 return MIN(tvb_reported_length(tvb),length);
1450 case X25_REGISTRATION_CONFIRMATION:
1451 bytex = tvb_get_guint8(tvb, 5);
1452 dce_len = (bytex >> 0) & 0x0F;
1453 dte_len = (bytex >> 4) & 0x0F;
1454 length = 6 + (dte_len + dce_len + 1) / 2; /* addr */
1455 if (length < tvb_reported_length(tvb))
1456 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1458 return MIN(tvb_reported_length(tvb),length);
1461 if ((byte2 & 0x01) == X25_DATA) return MIN(tvb_reported_length(tvb),3);
1463 switch (byte2 & 0x1F)
1466 return MIN(tvb_reported_length(tvb),3);
1469 return MIN(tvb_reported_length(tvb),3);
1472 return MIN(tvb_reported_length(tvb),3);
1478 static const value_string prt_id_vals[] = {
1479 {PRT_ID_ISO_8073, "ISO 8073 COTP"},
1480 {PRT_ID_ISO_8602, "ISO 8602 CLTP"},
1481 {PRT_ID_ISO_10736_ISO_8073, "ISO 10736 in conjunction with ISO 8073 COTP"},
1482 {PRT_ID_ISO_10736_ISO_8602, "ISO 10736 in conjunction with ISO 8602 CLTP"},
1486 static const value_string sharing_strategy_vals[] = {
1487 {0x00, "No sharing"},
1492 dissect_x25_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1495 proto_tree *x25_tree=0, *gfi_tree=0, *userdata_tree=0;
1497 guint localoffset=0;
1501 dissector_handle_t dissect;
1502 gboolean toa; /* TOA/NPI address format */
1505 char *short_name = NULL, *long_name = NULL;
1507 gboolean q_bit_set = FALSE;
1509 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1510 col_set_str(pinfo->cinfo, COL_PROTOCOL, "X.25");
1512 bytes0_1 = tvb_get_ntohs(tvb, 0);
1514 modulo = ((bytes0_1 & 0x2000) ? 128 : 8);
1515 vc = (int)(bytes0_1 & 0x0FFF);
1517 if (bytes0_1 & 0x8000) toa = TRUE;
1520 x25_pkt_len = get_x25_pkt_len(tvb);
1521 if (x25_pkt_len < 3) /* packet too short */
1523 if (check_col(pinfo->cinfo, COL_INFO))
1524 col_set_str(pinfo->cinfo, COL_INFO, "Invalid/short X.25 packet");
1526 proto_tree_add_protocol_format(tree, proto_x25, tvb, 0, -1,
1527 "Invalid/short X.25 packet");
1531 pkt_type = tvb_get_guint8(tvb, 2);
1534 ti = proto_tree_add_item(tree, proto_x25, tvb, 0, x25_pkt_len, FALSE);
1535 x25_tree = proto_item_add_subtree(ti, ett_x25);
1536 ti = proto_tree_add_item(x25_tree, hf_x25_gfi, tvb, 0, 2, FALSE);
1537 gfi_tree = proto_item_add_subtree(ti, ett_x25_gfi);
1539 if ((pkt_type & 0x01) == X25_DATA) {
1540 proto_tree_add_boolean(gfi_tree, hf_x25_qbit, tvb, 0, 2,
1542 if (bytes0_1 & 0x8000) {
1546 else if (pkt_type == X25_CALL_REQUEST ||
1547 pkt_type == X25_CALL_ACCEPTED ||
1548 pkt_type == X25_CLEAR_REQUEST ||
1549 pkt_type == X25_CLEAR_CONFIRMATION) {
1550 proto_tree_add_boolean(gfi_tree, hf_x25_abit, tvb, 0, 2,
1554 if (pkt_type == X25_CALL_REQUEST || pkt_type == X25_CALL_ACCEPTED ||
1555 (pkt_type & 0x01) == X25_DATA) {
1556 proto_tree_add_boolean(gfi_tree, hf_x25_dbit, tvb, 0, 2,
1559 proto_tree_add_uint(gfi_tree, hf_x25_mod, tvb, 0, 2, bytes0_1);
1563 case X25_CALL_REQUEST:
1567 short_name = "Inc. call";
1568 long_name = "Incoming call";
1572 short_name = "Call req.";
1573 long_name = "Call request";
1577 short_name = "Inc. call/Call req.";
1578 long_name = "Incoming call/Call request";
1581 if (check_col(pinfo->cinfo, COL_INFO))
1582 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
1584 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb,
1586 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1587 X25_CALL_REQUEST, "%s", long_name);
1590 if (localoffset < x25_pkt_len) /* calling/called addresses */
1591 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, toa);
1593 if (localoffset < x25_pkt_len) /* facilities */
1594 dump_facilities(x25_tree, &localoffset, tvb);
1596 if (localoffset < tvb_reported_length(tvb)) /* user data */
1603 ti = proto_tree_add_text(x25_tree, tvb, localoffset, -1,
1605 userdata_tree = proto_item_add_subtree(ti, ett_x25_user_data);
1608 /* X.263/ISO 9577 says that:
1610 When CLNP or ESIS are run over X.25, the SPI
1611 is 0x81 or 0x82, respectively; those are the
1612 NLPIDs for those protocol.
1614 When X.224/ISO 8073 COTP is run over X.25, and
1615 when ISO 11570 explicit identification is being
1616 used, the first octet of the user data field is
1617 a TPDU length field, and the rest is "as defined
1618 in ITU-T Rec. X.225 | ISO/IEC 8073, Annex B,
1619 or ITU-T Rec. X.264 and ISO/IEC 11570".
1621 When X.264/ISO 11570 default identification is
1622 being used, there is no user data field in the
1623 CALL REQUEST packet. This is for X.225/ISO 8073
1626 It also says that SPI values from 0x03 through 0x3f are
1627 reserved and are in use by X.224/ISO 8073 Annex B and
1628 X.264/ISO 11570. The note says that those values are
1629 not NLPIDs, they're "used by the respective higher layer
1630 protocol" and "not used for higher layer protocol
1631 identification". I infer from this and from what
1632 X.264/ISO 11570 says that this means that values in those
1633 range are valid values for the first octet of an
1634 X.224/ISO 8073 packet or for X.264/ISO 11570.
1636 Annex B of X.225/ISO 8073 mentions some additional TPDU
1637 types that can be put in what I presume is the user
1638 data of connect requests. It says that:
1640 The sending transport entity shall:
1642 a) either not transmit any TPDU in the NS-user data
1643 parameter of the N-CONNECT request primitive; or
1645 b) transmit the UN-TPDU (see ITU-T Rec. X.264 and
1646 ISO/IEC 11570) followed by the NCM-TPDU in the
1647 NS-user data parameter of the N-CONNECT request
1650 I don't know if this means that the user data field
1651 will contain a UN TPDU followed by an NCM TPDU or not.
1653 X.264/ISO 11570 says that:
1655 When default identification is being used,
1656 X.225/ISO 8073 COTP is identified. No user data
1657 is sent in the network-layer connection request.
1659 When explicit identification is being used,
1660 the user data is a UN TPDU ("Use of network
1661 connection TPDU"), which specifies the transport
1662 protocol to use over this network connection.
1663 It also says that the length of a UN TPDU shall
1664 not exceed 32 octets, i.e. shall not exceed 0x20;
1665 it says this is "due to the desire not to conflict
1666 with the protocol identifier field carried by X.25
1667 CALL REQUEST/INCOMING CALL packets", and says that
1668 field has values specified in X.244. X.244 has been
1669 superseded by X.263/ISO 9577, so that presumably
1670 means the goal is to allow a UN TPDU's length
1671 field to be distinguished from an NLPID, allowing
1672 you to tell whether X.264/ISO 11570 explicit
1673 identification is being used or an NLPID is
1674 being used as the SPI.
1676 I read this as meaning that, if the ISO mechanisms are
1677 used to identify the protocol being carried over X.25:
1679 if there's no user data in the CALL REQUEST/
1680 INCOMING CALL packet, it's COTP;
1682 if there is user data, then:
1684 if the first octet is less than or equal to
1685 32, it might be a UN TPDU, and that identifies
1686 the transport protocol being used, and
1687 it may be followed by more data, such
1688 as a COTP NCM TPDU if it's COTP;
1690 if the first octet is greater than 32, it's
1691 an NLPID, *not* a TPDU length, and the
1692 stuff following it is *not* a TPDU.
1694 Figure A.2 of X.263/ISO 9577 seems to say that the
1695 first octet of the user data is a TPDU length field,
1696 in the range 0x03 through 0x82, and says they are
1697 for X.225/ISO 8073 Annex B or X.264/ISO 11570.
1699 However, X.264/ISO 11570 seems to imply that the length
1700 field would be that of a UN TPDU, which must be less
1701 than or equal to 0x20, and X.225/ISO 8073 Annex B seems
1702 to indicate that the user data must begin with
1703 an X.264/ISO 11570 UN TPDU, so I'd say that A.2 should
1704 have said "in the range 0x03 through 0x20", instead
1705 (the length value doesn't include the length field,
1706 and the minimum UN TPDU has length, type, PRT-ID,
1707 and SHARE, so that's 3 bytes without the length). */
1708 spi = tvb_get_guint8(tvb, localoffset);
1709 if (spi > 32 || spi < 3) {
1710 /* First octet is > 32, or < 3, so the user data isn't an
1711 X.264/ISO 11570 UN TPDU */
1714 /* First octet is >= 3 and <= 32, so the user data *might*
1715 be an X.264/ISO 11570 UN TPDU. Check whether we have
1716 enough data to see if it is. */
1717 if (tvb_bytes_exist(tvb, localoffset+1, 1)) {
1718 /* We do; check whether the second octet is 1. */
1719 if (tvb_get_guint8(tvb, localoffset+1) == 0x01) {
1720 /* Yes, the second byte is 1, so it looks like
1724 /* No, the second byte is not 1, so it's not a
1729 /* We can't see the second byte of the putative UN
1730 TPDU, so we don't know if that's what it is. */
1734 if (is_x_264 == -1) {
1736 * We don't know what it is; just skip it.
1738 localoffset = tvb_length(tvb);
1739 } else if (is_x_264) {
1740 /* It looks like an X.264 UN TPDU, so show it as such. */
1741 if (userdata_tree) {
1742 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1743 "X.264 length indicator: %u",
1745 proto_tree_add_text(userdata_tree, tvb, localoffset+1, 1,
1746 "X.264 UN TPDU identifier: 0x%02X",
1747 tvb_get_guint8(tvb, localoffset+1));
1749 prt_id = tvb_get_guint8(tvb, localoffset+2);
1750 if (userdata_tree) {
1751 proto_tree_add_text(x25_tree, tvb, localoffset+2, 1,
1752 "X.264 protocol identifier: %s",
1753 val_to_str(prt_id, prt_id_vals,
1754 "Unknown (0x%02X)"));
1755 proto_tree_add_text(x25_tree, tvb, localoffset+3, 1,
1756 "X.264 sharing strategy: %s",
1757 val_to_str(tvb_get_guint8(tvb, localoffset+3),
1758 sharing_strategy_vals, "Unknown (0x%02X)"));
1761 /* XXX - dissect the variable part? */
1763 /* The length doesn't include the length octet itself. */
1764 localoffset += spi + 1;
1768 case PRT_ID_ISO_8073:
1770 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
1771 pinfo->fd->abs_usecs,
1773 /* XXX - disssect the rest of the user data as COTP?
1774 That needs support for NCM TPDUs, etc. */
1777 case PRT_ID_ISO_8602:
1779 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
1780 pinfo->fd->abs_usecs,
1784 } else if (is_x_264 == 0) {
1785 /* It doesn't look like a UN TPDU, so compare the first
1786 octet of the CALL REQUEST packet with various X.263/
1787 ISO 9577 NLPIDs, as per Annex A of X.263/ISO 9577. */
1789 if (userdata_tree) {
1790 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1791 "X.263 secondary protocol ID: %s",
1792 val_to_str(spi, nlpid_vals, "Unknown (0x%02x)"));
1797 * What's the dissector handle for this SPI?
1799 dissect = dissector_get_port_handle(x25_subdissector_table, spi);
1800 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
1801 pinfo->fd->abs_usecs, dissect);
1803 if (localoffset < tvb_length(tvb)) {
1804 if (userdata_tree) {
1805 proto_tree_add_text(userdata_tree, tvb, localoffset, -1,
1808 localoffset = tvb_length(tvb);
1812 case X25_CALL_ACCEPTED:
1816 short_name = "Call conn.";
1817 long_name = "Call connected";
1821 short_name = "Call acc.";
1822 long_name = "Call accepted";
1826 short_name = "Call conn./Call acc.";
1827 long_name = "Call connected/Call accepted";
1830 if(check_col(pinfo->cinfo, COL_INFO))
1831 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
1833 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1834 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1835 X25_CALL_ACCEPTED, "%s", long_name);
1838 if (localoffset < x25_pkt_len) /* calling/called addresses */
1839 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, toa);
1841 if (localoffset < x25_pkt_len) /* facilities */
1842 dump_facilities(x25_tree, &localoffset, tvb);
1844 if (localoffset < tvb_reported_length(tvb)) { /* user data */
1846 proto_tree_add_text(x25_tree, tvb, localoffset,
1847 tvb_reported_length(tvb)-localoffset, "Data");
1848 localoffset=tvb_reported_length(tvb);
1851 case X25_CLEAR_REQUEST:
1855 short_name = "Clear ind.";
1856 long_name = "Clear indication";
1860 short_name = "Clear req.";
1861 long_name = "Clear request";
1865 short_name = "Clear ind./Clear req.";
1866 long_name = "Clear indication/Clear request";
1869 if(check_col(pinfo->cinfo, COL_INFO)) {
1870 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - %s", short_name,
1871 vc, clear_code(tvb_get_guint8(tvb, 3)),
1872 clear_diag(tvb_get_guint8(tvb, 4)));
1874 x25_hash_add_proto_end(vc, pinfo->fd->abs_secs, pinfo->fd->abs_usecs);
1876 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1877 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb,
1878 localoffset+2, 1, X25_CLEAR_REQUEST, "%s", long_name);
1879 proto_tree_add_text(x25_tree, tvb, 3, 1,
1880 "Cause : %s", clear_code(tvb_get_guint8(tvb, 3)));
1881 proto_tree_add_text(x25_tree, tvb, 4, 1,
1882 "Diagnostic : %s", clear_diag(tvb_get_guint8(tvb, 4)));
1884 localoffset = x25_pkt_len;
1886 case X25_CLEAR_CONFIRMATION:
1887 if(check_col(pinfo->cinfo, COL_INFO))
1888 col_add_fstr(pinfo->cinfo, COL_INFO, "Clear Conf. VC:%d", vc);
1890 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1891 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1892 X25_CLEAR_CONFIRMATION);
1894 localoffset = x25_pkt_len;
1896 if (localoffset < tvb_reported_length(tvb)) /* extended clear conf format */
1897 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, toa);
1899 if (localoffset < tvb_reported_length(tvb)) /* facilities */
1900 dump_facilities(x25_tree, &localoffset, tvb);
1902 case X25_DIAGNOSTIC:
1903 if(check_col(pinfo->cinfo, COL_INFO)) {
1904 col_add_fstr(pinfo->cinfo, COL_INFO, "Diag. %d",
1905 (int)tvb_get_guint8(tvb, 3));
1908 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1910 proto_tree_add_text(x25_tree, tvb, 3, 1,
1911 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 3));
1913 localoffset = x25_pkt_len;
1916 if(check_col(pinfo->cinfo, COL_INFO))
1917 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt VC:%d", vc);
1919 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1920 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1923 localoffset = x25_pkt_len;
1925 case X25_INTERRUPT_CONFIRMATION:
1926 if(check_col(pinfo->cinfo, COL_INFO))
1927 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt Conf. VC:%d", vc);
1929 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1930 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1931 X25_INTERRUPT_CONFIRMATION);
1933 localoffset = x25_pkt_len;
1935 case X25_RESET_REQUEST:
1939 short_name = "Reset ind.";
1940 long_name = "Reset indication";
1944 short_name = "Reset req.";
1945 long_name = "Reset request";
1949 short_name = "Reset ind./Reset req.";
1950 long_name = "Reset indication/Reset request";
1953 if(check_col(pinfo->cinfo, COL_INFO)) {
1954 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - Diag.:%d",
1955 short_name, vc, reset_code(tvb_get_guint8(tvb, 3)),
1956 (int)tvb_get_guint8(tvb, 4));
1958 x25_hash_add_proto_end(vc, pinfo->fd->abs_secs, pinfo->fd->abs_usecs);
1960 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1961 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1962 X25_RESET_REQUEST, "%s", long_name);
1963 proto_tree_add_text(x25_tree, tvb, 3, 1,
1964 "Cause : %s", reset_code(tvb_get_guint8(tvb, 3)));
1965 proto_tree_add_text(x25_tree, tvb, 4, 1,
1966 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
1968 localoffset = x25_pkt_len;
1970 case X25_RESET_CONFIRMATION:
1971 if(check_col(pinfo->cinfo, COL_INFO))
1972 col_add_fstr(pinfo->cinfo, COL_INFO, "Reset conf. VC:%d", vc);
1974 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1975 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1976 X25_RESET_CONFIRMATION);
1978 localoffset = x25_pkt_len;
1980 case X25_RESTART_REQUEST:
1984 short_name = "Restart ind.";
1985 long_name = "Restart indication";
1989 short_name = "Restart req.";
1990 long_name = "Restart request";
1994 short_name = "Restart ind./Restart req.";
1995 long_name = "Restart indication/Restart request";
1998 if(check_col(pinfo->cinfo, COL_INFO)) {
1999 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s - Diag.:%d",
2001 restart_code(tvb_get_guint8(tvb, 3)),
2002 (int)tvb_get_guint8(tvb, 3));
2005 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
2006 X25_RESTART_REQUEST, "%s", long_name);
2007 proto_tree_add_text(x25_tree, tvb, 3, 1,
2008 "Cause : %s", restart_code(tvb_get_guint8(tvb, 3)));
2009 proto_tree_add_text(x25_tree, tvb, 4, 1,
2010 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
2012 localoffset = x25_pkt_len;
2014 case X25_RESTART_CONFIRMATION:
2015 if(check_col(pinfo->cinfo, COL_INFO))
2016 col_set_str(pinfo->cinfo, COL_INFO, "Restart conf.");
2018 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2019 X25_RESTART_CONFIRMATION);
2020 localoffset = x25_pkt_len;
2022 case X25_REGISTRATION_REQUEST:
2023 if(check_col(pinfo->cinfo, COL_INFO))
2024 col_set_str(pinfo->cinfo, COL_INFO, "Registration req.");
2026 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2027 X25_REGISTRATION_REQUEST);
2029 if (localoffset < x25_pkt_len)
2030 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
2033 if (localoffset < x25_pkt_len)
2034 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
2035 "Registration length: %d",
2036 tvb_get_guint8(tvb, localoffset) & 0x7F);
2037 if (localoffset+1 < x25_pkt_len)
2038 proto_tree_add_text(x25_tree, tvb, localoffset+1,
2039 tvb_get_guint8(tvb, localoffset) & 0x7F,
2042 localoffset = tvb_reported_length(tvb);
2044 case X25_REGISTRATION_CONFIRMATION:
2045 if(check_col(pinfo->cinfo, COL_INFO))
2046 col_set_str(pinfo->cinfo, COL_INFO, "Registration conf.");
2048 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2049 X25_REGISTRATION_CONFIRMATION);
2050 proto_tree_add_text(x25_tree, tvb, 3, 1,
2051 "Cause: %s", registration_code(tvb_get_guint8(tvb, 3)));
2052 proto_tree_add_text(x25_tree, tvb, 4, 1,
2053 "Diagnostic: %s", registration_code(tvb_get_guint8(tvb, 4)));
2056 if (localoffset < x25_pkt_len)
2057 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, TRUE);
2060 if (localoffset < x25_pkt_len)
2061 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
2062 "Registration length: %d",
2063 tvb_get_guint8(tvb, localoffset) & 0x7F);
2064 if (localoffset+1 < x25_pkt_len)
2065 proto_tree_add_text(x25_tree, tvb, localoffset+1,
2066 tvb_get_guint8(tvb, localoffset) & 0x7F,
2069 localoffset = tvb_reported_length(tvb);
2073 if ((pkt_type & 0x01) == X25_DATA)
2075 if(check_col(pinfo->cinfo, COL_INFO)) {
2077 col_add_fstr(pinfo->cinfo, COL_INFO,
2078 "Data VC:%d P(S):%d P(R):%d %s", vc,
2079 (pkt_type >> 1) & 0x07,
2080 (pkt_type >> 5) & 0x07,
2081 ((pkt_type >> 4) & 0x01) ? " M" : "");
2083 col_add_fstr(pinfo->cinfo, COL_INFO,
2084 "Data VC:%d P(S):%d P(R):%d %s", vc,
2085 tvb_get_guint8(tvb, localoffset+1) >> 1,
2087 (tvb_get_guint8(tvb, localoffset+1) & 0x01) ? " M" : "");
2090 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2092 proto_tree_add_uint_hidden(x25_tree, hf_x25_type, tvb,
2093 localoffset, 1, X25_DATA);
2095 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2096 localoffset, 1, pkt_type);
2097 if (pkt_type & 0x10)
2098 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod8, tvb,
2099 localoffset, 1, pkt_type);
2100 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod8, tvb,
2101 localoffset, 1, pkt_type);
2102 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
2103 decode_boolean_bitfield(pkt_type, 0x01, 1*8,
2107 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod128, tvb,
2108 localoffset, 1, pkt_type);
2109 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod128, tvb,
2111 tvb_get_guint8(tvb, localoffset+1));
2112 if (tvb_get_guint8(tvb, localoffset+1) & 0x01)
2113 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod128, tvb,
2115 tvb_get_guint8(tvb, localoffset+1));
2118 localoffset += (modulo == 8) ? 1 : 2;
2121 switch (pkt_type & 0x1F)
2124 if(check_col(pinfo->cinfo, COL_INFO)) {
2126 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2127 vc, (pkt_type >> 5) & 0x07);
2129 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2130 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2133 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2136 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2137 localoffset, 1, pkt_type);
2138 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2139 localoffset, 1, X25_RR);
2142 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2143 localoffset, 1, X25_RR);
2144 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2145 localoffset+1, 1, FALSE);
2151 if(check_col(pinfo->cinfo, COL_INFO)) {
2153 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2154 vc, (pkt_type >> 5) & 0x07);
2156 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2157 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2160 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2163 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2164 localoffset, 1, pkt_type);
2165 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2166 localoffset, 1, X25_RNR);
2169 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2170 localoffset, 1, X25_RNR);
2171 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2172 localoffset+1, 1, FALSE);
2178 if(check_col(pinfo->cinfo, COL_INFO)) {
2180 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2181 vc, (pkt_type >> 5) & 0x07);
2183 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2184 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2187 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2190 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2191 localoffset, 1, pkt_type);
2192 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2193 localoffset, 1, X25_REJ);
2196 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2197 localoffset, 1, X25_REJ);
2198 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2199 localoffset+1, 1, FALSE);
2203 localoffset += (modulo == 8) ? 1 : 2;
2206 if (localoffset >= tvb_reported_length(tvb)) return;
2208 next_tvb = tvb_new_subset(tvb, localoffset, -1, -1);
2212 call_dissector(qllc_handle, next_tvb, pinfo, tree);
2216 /* search the dissector in the hash table */
2217 if ((dissect = x25_hash_get_dissect(pinfo->fd->abs_secs, pinfo->fd->abs_usecs, vc))) {
2218 /* Found it in the hash table; use it. */
2219 call_dissector(dissect, next_tvb, pinfo, tree);
2223 /* Did the user suggest SNA-over-X.25? */
2224 if (non_q_bit_is_sna) {
2225 /* Yes - dissect it as SNA. */
2226 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
2227 pinfo->fd->abs_usecs, sna_handle);
2228 call_dissector(sna_handle, next_tvb, pinfo, tree);
2232 /* If the Call Req. has not been captured, and the payload begins
2233 with what appears to be an IP header, assume these packets carry
2235 if (tvb_get_guint8(tvb, localoffset) == 0x45) {
2236 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
2237 pinfo->fd->abs_usecs, ip_handle);
2238 call_dissector(ip_handle, next_tvb, pinfo, tree);
2242 /* Try the heuristic dissectors. */
2243 if (dissector_try_heuristic(x25_heur_subdissector_list, next_tvb, pinfo,
2247 /* All else failed; dissect it as raw data */
2248 call_dissector(data_handle, next_tvb, pinfo, tree);
2252 * X.25 dissector for use when "pinfo->pseudo_header" points to a
2253 * "struct x25_phdr".
2256 dissect_x25_dir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2258 dissect_x25_common(tvb, pinfo, tree,
2259 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? X25_FROM_DCE :
2264 * X.25 dissector for use when "pinfo->pseudo_header" doesn't point to a
2265 * "struct x25_phdr".
2268 dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2271 * We don't know if this packet is DTE->DCE or DCE->DCE.
2273 dissect_x25_common(tvb, pinfo, tree, X25_UNKNOWN);
2277 proto_register_x25(void)
2279 static hf_register_info hf[] = {
2281 { "GFI", "x.25.gfi", FT_UINT16, BASE_BIN, NULL, 0xF000,
2282 "General format identifier", HFILL }},
2284 { "A Bit", "x.25.a", FT_BOOLEAN, 16, NULL, 0x8000,
2285 "Address Bit", HFILL }},
2287 { "Q Bit", "x.25.q", FT_BOOLEAN, 16, NULL, 0x8000,
2288 "Qualifier Bit", HFILL }},
2290 { "D Bit", "x.25.d", FT_BOOLEAN, 16, NULL, 0x4000,
2291 "Delivery Confirmation Bit", HFILL }},
2293 { "Modulo", "x.25.mod", FT_UINT16, BASE_DEC, VALS(vals_modulo), 0x3000,
2294 "Specifies whether the frame is modulo 8 or 128", HFILL }},
2296 { "Logical Channel", "x.25.lcn", FT_UINT16, BASE_DEC, NULL, 0x0FFF,
2297 "Logical Channel Number", HFILL }},
2299 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x0,
2300 "Packet Type", HFILL }},
2302 { "P(R)", "x.25.p_r", FT_UINT8, BASE_HEX, NULL, 0xE0,
2303 "Packet Receive Sequence Number", HFILL }},
2304 { &hf_x25_p_r_mod128,
2305 { "P(R)", "x.25.p_r", FT_UINT8, BASE_HEX, NULL, 0xFE,
2306 "Packet Receive Sequence Number", HFILL }},
2307 { &hf_x25_mbit_mod8,
2308 { "M Bit", "x.25.m", FT_BOOLEAN, 8, NULL, 0x10,
2309 "More Bit", HFILL }},
2310 { &hf_x25_mbit_mod128,
2311 { "M Bit", "x.25.m", FT_BOOLEAN, 8, NULL, 0x01,
2312 "More Bit", HFILL }},
2314 { "P(S)", "x.25.p_s", FT_UINT8, BASE_HEX, NULL, 0x0E,
2315 "Packet Send Sequence Number", HFILL }},
2316 { &hf_x25_p_s_mod128,
2317 { "P(S)", "x.25.p_s", FT_UINT8, BASE_HEX, NULL, 0xFE,
2318 "Packet Send Sequence Number", HFILL }},
2320 static gint *ett[] = {
2324 &ett_x25_fac_unknown,
2326 &ett_x25_fac_reverse,
2327 &ett_x25_fac_throughput,
2329 &ett_x25_fac_called_modif,
2330 &ett_x25_fac_cug_outgoing_acc,
2331 &ett_x25_fac_throughput_min,
2332 &ett_x25_fac_express_data,
2333 &ett_x25_fac_bilateral_cug,
2334 &ett_x25_fac_packet_size,
2335 &ett_x25_fac_window_size,
2336 &ett_x25_fac_rpoa_selection,
2337 &ett_x25_fac_transit_delay,
2338 &ett_x25_fac_call_transfer,
2339 &ett_x25_fac_called_addr_ext,
2340 &ett_x25_fac_ete_transit_delay,
2341 &ett_x25_fac_calling_addr_ext,
2342 &ett_x25_fac_call_deflect,
2343 &ett_x25_fac_priority,
2346 module_t *x25_module;
2348 proto_x25 = proto_register_protocol ("X.25", "X.25", "x.25");
2349 proto_register_field_array (proto_x25, hf, array_length(hf));
2350 proto_register_subtree_array(ett, array_length(ett));
2351 register_init_routine(&reinit_x25_hashtable);
2353 x25_subdissector_table = register_dissector_table("x.25.spi",
2354 "X.25 secondary protocol identifier", FT_UINT8, BASE_HEX);
2355 register_heur_dissector_list("x.25", &x25_heur_subdissector_list);
2357 register_dissector("x.25_dir", dissect_x25_dir, proto_x25);
2358 register_dissector("x.25", dissect_x25, proto_x25);
2361 x25_module = prefs_register_protocol(proto_x25, NULL);
2362 prefs_register_bool_preference(x25_module, "non_q_bit_is_sna",
2363 "When Q-bit is 0, payload is SNA", "When Q-bit is 0, payload is SNA",
2368 proto_reg_handoff_x25(void)
2370 dissector_handle_t x25_handle;
2373 * Get handles for various dissectors.
2375 ip_handle = find_dissector("ip");
2376 ositp_handle = find_dissector("ositp");
2377 sna_handle = find_dissector("sna");
2378 qllc_handle = find_dissector("qllc");
2379 data_handle = find_dissector("data");
2381 x25_handle = find_dissector("x.25");
2382 dissector_add("llc.dsap", SAP_X25, x25_handle);