2 * Routines for x25 packet disassembly
3 * Olivier Abad <oabad@cybercable.fr>
5 * $Id: packet-x25.c,v 1.58 2001/12/03 03:59:43 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>
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 ositp_handle;
159 static dissector_handle_t sna_handle;
160 static dissector_handle_t qllc_handle;
161 static dissector_handle_t data_handle;
164 static gboolean non_q_bit_is_sna = FALSE;
166 static dissector_table_t x25_subdissector_table;
169 * each vc_info node contains :
170 * the time of the first frame using this dissector (secs and usecs)
171 * the time of the last frame using this dissector (0 if it is unknown)
172 * the protocol used over the VC
174 * the "time of first frame" is initialized when a Call Req. is received
175 * the "time of last frame" is initialized when a Clear, Reset, or Restart
178 typedef struct _vc_info {
179 guint32 first_frame_secs, first_frame_usecs;
180 guint32 last_frame_secs, last_frame_usecs;
182 struct _vc_info *next;
186 * Protocol unknown for connection.
188 #define PROTO_UNKNOWN -1
191 * Special protocol values, for protocols not indicated by an NLPID as a
192 * secondary protocol identifier.
195 #define PROTO_OSITP -3
198 * the hash table will contain linked lists of global_vc_info
199 * each global_vc_info struct contains :
200 * the VC number (the hash table is indexed with VC % 64)
201 * a linked list of vc_info
203 typedef struct _global_vc_info {
206 struct _global_vc_info *next;
209 static global_vc_info *hash_table[64];
212 free_vc_info(vc_info *pt)
224 reinit_x25_hashtable(void)
228 for (i=0; i<64; i++) {
229 if (hash_table[i]) /* not NULL ==> free */
231 global_vc_info *hash_ent, *hash_ent2;
232 hash_ent2 = hash_ent = hash_table[i];
235 hash_ent2 = hash_ent;
236 hash_ent = hash_ent->next;
237 free_vc_info(hash_ent2->info);
246 x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs,
250 global_vc_info *hash_ent;
251 global_vc_info *hash_ent2;
253 if (hash_table[idx] == 0)
255 hash_ent = (global_vc_info *)g_malloc(sizeof(global_vc_info));
257 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
260 hash_ent->vc_num = vc;
262 hash_ent->info = (vc_info *)g_malloc(sizeof(vc_info));
263 if (!hash_ent->info) {
264 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
267 hash_ent->info->first_frame_secs = frame_secs;
268 hash_ent->info->first_frame_usecs = frame_usecs;
269 hash_ent->info->last_frame_secs = 0;
270 hash_ent->info->last_frame_usecs = 0;
271 hash_ent->info->proto = proto;
272 hash_ent->info->next = 0;
273 hash_table[idx] = hash_ent;
277 hash_ent2 = hash_ent = hash_table[idx];
278 /* search an entry with the same VC number */
279 while (hash_ent != NULL && hash_ent->vc_num != vc) {
280 hash_ent2 = hash_ent;
281 hash_ent = hash_ent->next;
283 if (hash_ent != NULL) /* hash_ent->vc_num == vc */
285 vc_info *vci = hash_ent->info;
286 while (vci->next) vci = vci->next; /* last element */
287 if (vci->proto == proto) {
288 vci->last_frame_secs = 0;
289 vci->last_frame_usecs = 0;
292 vci->next = (vc_info *)g_malloc(sizeof(vc_info));
293 if (vci->next == 0) {
294 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
297 vci->next->first_frame_secs = frame_secs;
298 vci->next->first_frame_usecs = frame_usecs;
299 vci->next->last_frame_secs = 0;
300 vci->next->last_frame_usecs = 0;
301 vci->next->proto = proto;
305 else /* new vc number */
307 hash_ent2->next = (global_vc_info *)g_malloc(sizeof(global_vc_info));
308 if (!hash_ent2->next) {
309 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
312 hash_ent2->next->info = (vc_info *)g_malloc(sizeof(vc_info));
313 if (!hash_ent2->next->info) {
314 fprintf(stderr, "Could not allocate space for hash structure in dissect_x25\n");
317 hash_ent2->next->info->first_frame_secs = frame_secs;
318 hash_ent2->next->info->first_frame_usecs = frame_usecs;
319 hash_ent2->next->info->last_frame_secs = 0;
320 hash_ent2->next->info->last_frame_usecs = 0;
321 hash_ent2->next->info->proto = proto;
322 hash_ent2->next->info->next = 0;
328 x25_hash_add_proto_end(guint16 vc, guint32 frame_secs, guint32 frame_usecs)
330 global_vc_info *hash_ent = hash_table[vc%64];
333 if (!hash_ent) return;
334 while(hash_ent->vc_num != vc) hash_ent = hash_ent->next;
335 if (!hash_ent) return;
337 vci = hash_ent->info;
338 while (vci->next) vci = vci->next;
339 vci->last_frame_secs = frame_secs;
340 vci->last_frame_usecs = frame_usecs;
344 x25_hash_get_proto(guint32 frame_secs, guint32 frame_usecs, guint16 vc)
346 global_vc_info *hash_ent = hash_table[vc%64];
351 return PROTO_UNKNOWN;
353 while (hash_ent && hash_ent->vc_num != vc)
354 hash_ent = hash_ent->next;
356 return PROTO_UNKNOWN;
358 /* a hash_ent was found for this VC number */
359 vci2 = vci = hash_ent->info;
361 /* looking for an entry matching our frame time */
362 while (vci && (vci->last_frame_secs < frame_secs ||
363 (vci->last_frame_secs == frame_secs &&
364 vci->last_frame_usecs < frame_usecs))) {
368 /* we reached last record, and previous record has a non zero
369 * last frame time ==> no protocol known */
370 if (!vci && (vci2->last_frame_secs || vci2->last_frame_usecs))
371 return PROTO_UNKNOWN;
373 /* we reached last record, and previous record has a zero last frame time
374 * ==> dissector for previous frame has not been "stopped" by a Clear, etc */
376 /* if the start time for vci2 is greater than our frame time
377 * ==> no protocol known */
378 if (frame_secs < vci2->first_frame_secs ||
379 (frame_secs == vci2->first_frame_secs &&
380 frame_usecs < vci2->first_frame_usecs))
381 return PROTO_UNKNOWN;
386 /* our frame time is before vci's end. Check if it is after vci's start */
387 if (frame_secs < vci->first_frame_secs ||
388 (frame_secs == vci->first_frame_secs &&
389 frame_usecs < vci->first_frame_usecs))
395 static char *clear_code(unsigned char code)
397 static char buffer[25];
399 if (code == 0x00 || (code & 0x80) == 0x80)
400 return "DTE Originated";
402 return "Number Busy";
404 return "Invalid Facility Requested";
406 return "Network Congestion";
408 return "Out Of Order";
410 return "Access Barred";
412 return "Not Obtainable";
414 return "Remote Procedure Error";
416 return "Local Procedure Error";
418 return "RPOA Out Of Order";
420 return "Reverse Charging Acceptance Not Subscribed";
422 return "Incompatible Destination";
424 return "Fast Select Acceptance Not Subscribed";
426 return "Destination Absent";
428 sprintf(buffer, "Unknown %02X", code);
433 static char *clear_diag(unsigned char code)
435 static char buffer[25];
438 return "No additional information";
440 return "Invalid P(S)";
442 return "Invalid P(R)";
444 return "Packet type invalid";
446 return "Packet type invalid for state r1";
448 return "Packet type invalid for state r2";
450 return "Packet type invalid for state r3";
452 return "Packet type invalid for state p1";
454 return "Packet type invalid for state p2";
456 return "Packet type invalid for state p3";
458 return "Packet type invalid for state p4";
460 return "Packet type invalid for state p5";
462 return "Packet type invalid for state p6";
464 return "Packet type invalid for state p7";
466 return "Packet type invalid for state d1";
468 return "Packet type invalid for state d2";
470 return "Packet type invalid for state d3";
472 return "Packet not allowed";
474 return "Unidentifiable packet";
476 return "Call on one-way logical channel";
478 return "Invalid packet type on a PVC";
480 return "Packet on unassigned LC";
482 return "Reject not subscribed to";
484 return "Packet too short";
486 return "Packet too long";
488 return "Invalid general format identifier";
490 return "Restart/registration packet with nonzero bits";
492 return "Packet type not compatible with facility";
494 return "Unauthorised interrupt confirmation";
496 return "Unauthorised interrupt";
498 return "Unauthorised reject";
500 return "Time expired";
502 return "Time expired for incoming call";
504 return "Time expired for clear indication";
506 return "Time expired for reset indication";
508 return "Time expired for restart indication";
510 return "Time expired for call deflection";
512 return "Call set-up/clearing or registration pb.";
514 return "Facility/registration code not allowed";
516 return "Facility parameter not allowed";
518 return "Invalid called DTE address";
520 return "Invalid calling DTE address";
522 return "Invalid facility/registration length";
524 return "Incoming call barred";
526 return "No logical channel available";
528 return "Call collision";
530 return "Duplicate facility requested";
532 return "Non zero address length";
534 return "Non zero facility length";
536 return "Facility not provided when expected";
538 return "Invalid CCITT-specified DTE facility";
540 return "Max. nb of call redir/defl. exceeded";
542 return "Miscellaneous";
544 return "Improper cause code from DTE";
546 return "Not aligned octet";
548 return "Inconsistent Q bit setting";
550 return "NUI problem";
552 return "International problem";
554 return "Remote network problem";
556 return "International protocol problem";
558 return "International link out of order";
560 return "International link busy";
562 return "Transit network facility problem";
564 return "Remote network facility problem";
566 return "International routing problem";
568 return "Temporary routing problem";
570 return "Unknown called DNIC";
572 return "Maintenance action";
574 return "Timer expired or retransmission count surpassed";
576 return "Timer expired or retransmission count surpassed for INTERRUPT";
578 return "Timer expired or retransmission count surpassed for DATA "
579 "packet transmission";
581 return "Timer expired or retransmission count surpassed for REJECT";
583 return "DTE-specific signals";
585 return "DTE operational";
587 return "DTE not operational";
589 return "DTE resource constraint";
591 return "Fast select not subscribed";
593 return "Invalid partially full DATA packet";
595 return "D-bit procedure not supported";
597 return "Registration/Cancellation confirmed";
599 return "OSI network service problem";
601 return "Disconnection (transient condition)";
603 return "Disconnection (permanent condition)";
605 return "Connection rejection - reason unspecified (transient "
608 return "Connection rejection - reason unspecified (permanent "
611 return "Connection rejection - quality of service not available "
612 "transient condition)";
614 return "Connection rejection - quality of service not available "
615 "permanent condition)";
617 return "Connection rejection - NSAP unreachable (transient condition)";
619 return "Connection rejection - NSAP unreachable (permanent condition)";
621 return "reset - reason unspecified";
623 return "reset - congestion";
625 return "Connection rejection - NSAP address unknown (permanent "
628 return "Higher layer initiated";
630 return "Disconnection - normal";
632 return "Disconnection - abnormal";
634 return "Disconnection - incompatible information in user data";
636 return "Connection rejection - reason unspecified (transient "
639 return "Connection rejection - reason unspecified (permanent "
642 return "Connection rejection - quality of service not available "
643 "(transient condition)";
645 return "Connection rejection - quality of service not available "
646 "(permanent condition)";
648 return "Connection rejection - incompatible information in user data";
650 return "Connection rejection - unrecognizable protocol indentifier "
653 return "Reset - user resynchronization";
655 sprintf(buffer, "Unknown %d", code);
660 static char *reset_code(unsigned char code)
662 static char buffer[25];
664 if (code == 0x00 || (code & 0x80) == 0x80)
665 return "DTE Originated";
667 return "Out of order";
669 return "Remote Procedure Error";
671 return "Local Procedure Error";
673 return "Network Congestion";
675 return "Remote DTE operational";
677 return "Network operational";
679 return "Incompatible Destination";
681 return "Network out of order";
683 sprintf(buffer, "Unknown %02X", code);
688 static char *restart_code(unsigned char code)
690 static char buffer[25];
692 if (code == 0x00 || (code & 0x80) == 0x80)
693 return "DTE Originated";
695 return "Local Procedure Error";
697 return "Network Congestion";
699 return "Network Operational";
701 return "Registration/cancellation confirmed";
703 sprintf(buffer, "Unknown %02X", code);
708 static char *registration_code(unsigned char code)
710 static char buffer[25];
713 return "Invalid facility request";
715 return "Network congestion";
717 return "Local procedure error";
719 return "Registration/cancellation confirmed";
721 sprintf(buffer, "Unknown %02X", code);
727 dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb)
729 guint8 fac, byte1, byte2, byte3;
730 guint32 len; /* facilities length */
732 proto_tree *fac_tree = 0;
733 proto_tree *fac_subtree;
735 len = tvb_get_guint8(tvb, *offset);
737 ti = proto_tree_add_text(tree, tvb, *offset, len + 1,
739 fac_tree = proto_item_add_subtree(ti, ett_x25_fac);
740 proto_tree_add_text(fac_tree, tvb, *offset, 1,
741 "Facilities length: %d", len);
746 fac = tvb_get_guint8(tvb, *offset);
747 switch(fac & X25_FAC_CLASS_MASK) {
748 case X25_FAC_CLASS_A:
750 case X25_FAC_COMP_MARK:
752 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
753 "Code : 00 (Marker)");
754 switch (tvb_get_guint8(tvb, *offset + 1)) {
757 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
758 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
759 "Parameter : 00 (Network complementary "
760 "services - calling DTE)");
765 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
766 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
767 "Parameter : FF (Network complementary "
768 "services - called DTE)");
773 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
774 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
775 "Parameter : 0F (DTE complementary "
781 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
782 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
783 "Parameter : %02X (Unknown marker)",
784 tvb_get_guint8(tvb, *offset+1));
789 case X25_FAC_REVERSE:
791 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
792 "(Reverse charging / Fast select)", fac);
793 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_reverse);
794 byte1 = tvb_get_guint8(tvb, *offset + 1);
795 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
796 "Parameter : %02X", byte1);
798 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
799 "11.. .... = Fast select with restriction");
800 else if (byte1 & 0x80)
801 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
802 "10.. .... = Fast select - no restriction");
804 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
805 "00.. .... = Fast select not requested");
806 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
807 decode_boolean_bitfield(byte1, 0x01, 1*8,
808 "Reverse charging requested",
809 "Reverse charging not requested"));
812 case X25_FAC_THROUGHPUT:
816 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
817 "(Throughput class negociation)", fac);
818 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_throughput);
819 byte1 = tvb_get_guint8(tvb, *offset + 1);
831 sprintf(tmpbuf, "From the called DTE : %%u (%d bps)",
832 75*(1<<((byte1 >> 4)-3)));
835 sprintf(tmpbuf, "From the called DTE : %%u (48000 bps)");
838 sprintf(tmpbuf, "From the called DTE : %%u (64000 bps)");
841 sprintf(tmpbuf, "From the called DTE : %%u (Reserved)");
843 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
844 decode_numeric_bitfield(byte1, 0xF0, 1*8, tmpbuf));
845 switch (byte1 & 0x0F)
856 sprintf(tmpbuf, "From the calling DTE : %%u (%d bps)",
857 75*(1<<((byte1 & 0x0F)-3)));
860 sprintf(tmpbuf, "From the calling DTE : %%u (48000 bps)");
863 sprintf(tmpbuf, "From the calling DTE : %%u (64000 bps)");
866 sprintf(tmpbuf, "From the calling DTE : %%u (Reserved)");
868 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
869 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
874 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
875 "(Closed user group selection)", fac);
876 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_cug);
877 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
878 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
881 case X25_FAC_CALLED_MODIF:
883 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
884 "(Called address modified)", fac);
885 fac_subtree = proto_item_add_subtree(ti,
886 ett_x25_fac_called_modif);
887 proto_tree_add_text(fac_tree, tvb, *offset+1, 1,
888 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
891 case X25_FAC_CUG_OUTGOING_ACC:
893 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
894 "(Closed user group with outgoing access selection)",
896 fac_subtree = proto_item_add_subtree(ti,
897 ett_x25_fac_cug_outgoing_acc);
898 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
899 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
902 case X25_FAC_THROUGHPUT_MIN:
904 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
905 "(Minimum throughput class)", fac);
906 fac_subtree = proto_item_add_subtree(ti,
907 ett_x25_fac_throughput_min);
908 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
909 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
912 case X25_FAC_EXPRESS_DATA:
914 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
915 "(Negociation of express data)", fac);
916 fac_subtree = proto_item_add_subtree(ti,
917 ett_x25_fac_express_data);
918 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
919 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
924 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
925 "Code : %02X (Unknown class A)", fac);
926 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
927 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
928 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
935 case X25_FAC_CLASS_B:
937 case X25_FAC_BILATERAL_CUG:
939 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
940 "(Bilateral closed user group selection)", fac);
941 fac_subtree = proto_item_add_subtree(ti,
942 ett_x25_fac_bilateral_cug);
943 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
944 "Bilateral CUG: %04X",
945 tvb_get_ntohs(tvb, *offset+1));
948 case X25_FAC_PACKET_SIZE:
953 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
954 "(Packet size)", fac);
955 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_packet_size);
956 byte1 = tvb_get_guint8(tvb, *offset + 1);
960 sprintf(tmpbuf, "From the called DTE : %%u (16)");
963 sprintf(tmpbuf, "From the called DTE : %%u (32)");
966 sprintf(tmpbuf, "From the called DTE : %%u (64)");
969 sprintf(tmpbuf, "From the called DTE : %%u (128)");
972 sprintf(tmpbuf, "From the called DTE : %%u (256)");
975 sprintf(tmpbuf, "From the called DTE : %%u (512)");
978 sprintf(tmpbuf, "From the called DTE : %%u (1024)");
981 sprintf(tmpbuf, "From the called DTE : %%u (2048)");
984 sprintf(tmpbuf, "From the called DTE : %%u (4096)");
987 sprintf(tmpbuf, "From the called DTE : %%u (Unknown)");
990 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
991 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
993 byte2 = tvb_get_guint8(tvb, *offset + 1);
997 sprintf(tmpbuf, "From the calling DTE : %%u (16)");
1000 sprintf(tmpbuf, "From the calling DTE : %%u (32)");
1003 sprintf(tmpbuf, "From the calling DTE : %%u (64)");
1006 sprintf(tmpbuf, "From the calling DTE : %%u (128)");
1009 sprintf(tmpbuf, "From the calling DTE : %%u (256)");
1012 sprintf(tmpbuf, "From the calling DTE : %%u (512)");
1015 sprintf(tmpbuf, "From the calling DTE : %%u (1024)");
1018 sprintf(tmpbuf, "From the calling DTE : %%u (2048)");
1021 sprintf(tmpbuf, "From the calling DTE : %%u (4096)");
1024 sprintf(tmpbuf, "From the calling DTE : %%u (Unknown)");
1027 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1028 decode_numeric_bitfield(byte2, 0x0F, 1*8, tmpbuf));
1031 case X25_FAC_WINDOW_SIZE:
1033 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1034 "(Window size)", fac);
1035 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_window_size);
1036 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1037 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+1),
1038 0x7F, 1*8, "From the called DTE: %u"));
1039 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1040 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+2),
1041 0x7F, 1*8, "From the calling DTE: %u"));
1044 case X25_FAC_RPOA_SELECTION:
1046 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1047 "(RPOA selection)", fac);
1048 fac_subtree = proto_item_add_subtree(ti,
1049 ett_x25_fac_rpoa_selection);
1050 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
1051 "Data network identification code : %04X",
1052 tvb_get_ntohs(tvb, *offset+1));
1055 case X25_FAC_TRANSIT_DELAY:
1057 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1058 "(Transit delay selection and indication)", fac);
1059 fac_subtree = proto_item_add_subtree(ti,
1060 ett_x25_fac_transit_delay);
1061 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
1062 "Transit delay: %d ms",
1063 tvb_get_ntohs(tvb, *offset+1));
1068 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1069 "Code : %02X (Unknown class B)", fac);
1070 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1071 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
1072 "Parameter %04X", tvb_get_ntohs(tvb, *offset+1));
1079 case X25_FAC_CLASS_C:
1081 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1082 "Code : %02X (Unknown class C)", fac);
1083 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1084 proto_tree_add_text(fac_subtree, tvb, *offset+1, 3,
1086 tvb_get_ntoh24(tvb, *offset+1));
1091 case X25_FAC_CLASS_D:
1093 case X25_FAC_CALL_TRANSFER:
1098 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1099 "(Call redirection or deflection notification)", fac);
1100 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_call_transfer);
1101 byte1 = tvb_get_guint8(tvb, *offset+1);
1102 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1103 "Length : %u", byte1);
1104 byte2 = tvb_get_guint8(tvb, *offset+2);
1105 if ((byte2 & 0xC0) == 0xC0) {
1106 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1107 "Reason : call deflection by the originally "
1108 "called DTE address");
1113 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1114 "Reason : originally called DTE busy");
1117 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1118 "Reason : call dist. within a hunt group");
1121 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1122 "Reason : originally called DTE out of order");
1125 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1126 "Reason : systematic call redirection");
1129 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1130 "Reason : unknown");
1134 byte3 = tvb_get_guint8(tvb, *offset+3);
1135 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1136 "Number of semi-octets in DTE address : %u",
1138 for (i = 0; i < byte3; i++) {
1140 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1142 /* if > 9, convert to the right hexadecimal letter */
1143 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1145 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1147 /* if > 9, convert to the right hexadecimal letter */
1148 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1152 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1153 "DTE address : %s", tmpbuf);
1156 case X25_FAC_CALLING_ADDR_EXT:
1161 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1162 "(Calling address extension)", fac);
1163 fac_subtree = proto_item_add_subtree(ti,
1164 ett_x25_fac_calling_addr_ext);
1165 byte1 = tvb_get_guint8(tvb, *offset+1);
1166 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1167 "Length : %u", byte1);
1168 byte2 = tvb_get_guint8(tvb, *offset+2);
1169 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1170 "Number of semi-octets in DTE address : %u", byte2);
1171 for (i = 0; i < byte2; i++) {
1173 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1175 /* if > 9, convert to the right hexadecimal letter */
1176 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1178 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1180 /* if > 9, convert to the right hexadecimal letter */
1181 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1185 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1186 "DTE address : %s", tmpbuf);
1189 case X25_FAC_CALLED_ADDR_EXT:
1194 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1195 "(Called address extension)", fac);
1196 fac_subtree = proto_item_add_subtree(ti,
1197 ett_x25_fac_called_addr_ext);
1198 byte1 = tvb_get_guint8(tvb, *offset+1);
1199 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1200 "Length : %u", byte1);
1201 byte2 = tvb_get_guint8(tvb, *offset+2);
1202 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1203 "Number of semi-octets in DTE address : %u", byte2);
1204 for (i = 0; i < byte2; i++) {
1206 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1208 /* if > 9, convert to the right hexadecimal letter */
1209 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1211 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1213 /* if > 9, convert to the right hexadecimal letter */
1214 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1218 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1219 "DTE address : %s", tmpbuf);
1222 case X25_FAC_ETE_TRANSIT_DELAY:
1224 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1225 "(End to end transit delay)", fac);
1226 fac_subtree = proto_item_add_subtree(ti,
1227 ett_x25_fac_ete_transit_delay);
1228 byte1 = tvb_get_guint8(tvb, *offset+1);
1229 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1230 "Length : %u", byte1);
1231 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1234 case X25_FAC_CALL_DEFLECT:
1239 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1240 "(Call deflection selection)", fac);
1241 fac_subtree = proto_item_add_subtree(ti,
1242 ett_x25_fac_call_deflect);
1243 byte1 = tvb_get_guint8(tvb, *offset+1);
1244 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1245 "Length : %u", byte1);
1246 byte2 = tvb_get_guint8(tvb, *offset+2);
1247 if ((byte2 & 0xC0) == 0xC0)
1248 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1249 "Reason : call DTE originated");
1251 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1252 "Reason : unknown");
1253 byte3 = tvb_get_guint8(tvb, *offset+3);
1254 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1255 "Number of semi-octets in the alternative DTE address : %u",
1257 for (i = 0; i < byte3; i++) {
1259 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1261 /* if > 9, convert to the right hexadecimal letter */
1262 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1264 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1266 /* if > 9, convert to the right hexadecimal letter */
1267 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1271 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1272 "Alternative DTE address : %s", tmpbuf);
1275 case X25_FAC_PRIORITY:
1277 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1278 "Code : %02X (Priority)", fac);
1279 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_priority);
1280 byte1 = tvb_get_guint8(tvb, *offset+1);
1281 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1282 "Length : %u", byte1);
1283 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1288 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1289 "Code : %02X (Unknown class D)", fac);
1290 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1291 byte1 = tvb_get_guint8(tvb, *offset+1);
1292 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1293 "Length : %u", byte1);
1294 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1297 byte1 = tvb_get_guint8(tvb, *offset+1);
1298 (*offset) += byte1+2;
1306 x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1307 frame_data *fd, gboolean toa)
1311 char addr1[16], addr2[16];
1312 char *first, *second;
1316 byte = tvb_get_guint8(tvb, *offset);
1317 len1 = (byte >> 4) & 0x0F;
1318 len2 = (byte >> 0) & 0x0F;
1320 proto_tree_add_text(tree, tvb, *offset, 1,
1321 decode_numeric_bitfield(byte, 0xF0, 1*8,
1322 toa ? "Called address length : %u" :
1323 "Calling address length : %u"));
1324 proto_tree_add_text(tree, tvb, *offset, 1,
1325 decode_numeric_bitfield(byte, 0x0F, 1*8,
1326 toa ? "Calling address length : %u" :
1327 "Called address length : %u"));
1331 localoffset = *offset;
1332 byte = tvb_get_guint8(tvb, localoffset);
1336 for (i = 0; i < (len1 + len2); i++) {
1339 *first++ = ((byte >> 0) & 0x0F) + '0';
1341 byte = tvb_get_guint8(tvb, localoffset);
1343 *first++ = ((byte >> 4) & 0x0F) + '0';
1347 *second++ = ((byte >> 0) & 0x0F) + '0';
1349 byte = tvb_get_guint8(tvb, localoffset);
1351 *second++ = ((byte >> 4) & 0x0F) + '0';
1361 if (check_col(fd, COL_RES_DL_DST))
1362 col_add_str(fd, COL_RES_DL_DST, addr1);
1365 if(check_col(fd, COL_RES_DL_SRC))
1366 col_add_str(fd, COL_RES_DL_SRC, addr1);
1369 proto_tree_add_text(tree, tvb, *offset,
1372 toa ? "Called" : "Calling",
1377 if (check_col(fd, COL_RES_DL_SRC))
1378 col_add_str(fd, COL_RES_DL_SRC, addr2);
1381 if(check_col(fd, COL_RES_DL_DST))
1382 col_add_str(fd, COL_RES_DL_DST, addr2);
1385 proto_tree_add_text(tree, tvb, *offset + len1/2,
1386 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1388 toa ? "Calling" : "Called",
1391 (*offset) += ((len1 + len2 + 1) / 2);
1395 get_x25_pkt_len(tvbuff_t *tvb)
1397 guint length, called_len, calling_len, dte_len, dce_len;
1398 guint8 byte2, bytex;
1400 byte2 = tvb_get_guint8(tvb, 2);
1403 case X25_CALL_REQUEST:
1404 bytex = tvb_get_guint8(tvb, 3);
1405 called_len = (bytex >> 0) & 0x0F;
1406 calling_len = (bytex >> 4) & 0x0F;
1407 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1408 if (length < tvb_reported_length(tvb))
1409 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1411 return MIN(tvb_reported_length(tvb),length);
1413 case X25_CALL_ACCEPTED:
1414 /* The calling/called address length byte (following the packet type)
1415 * is not mandatory, so we must check the packet length before trying
1417 if (tvb_reported_length(tvb) == 3)
1419 bytex = tvb_get_guint8(tvb, 3);
1420 called_len = (bytex >> 0) & 0x0F;
1421 calling_len = (bytex >> 4) & 0x0F;
1422 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1423 if (length < tvb_reported_length(tvb))
1424 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1426 return MIN(tvb_reported_length(tvb),length);
1428 case X25_CLEAR_REQUEST:
1429 case X25_RESET_REQUEST:
1430 case X25_RESTART_REQUEST:
1431 return MIN(tvb_reported_length(tvb),5);
1433 case X25_DIAGNOSTIC:
1434 return MIN(tvb_reported_length(tvb),4);
1436 case X25_CLEAR_CONFIRMATION:
1438 case X25_INTERRUPT_CONFIRMATION:
1439 case X25_RESET_CONFIRMATION:
1440 case X25_RESTART_CONFIRMATION:
1441 return MIN(tvb_reported_length(tvb),3);
1443 case X25_REGISTRATION_REQUEST:
1444 bytex = tvb_get_guint8(tvb, 3);
1445 dce_len = (bytex >> 0) & 0x0F;
1446 dte_len = (bytex >> 4) & 0x0F;
1447 length = 4 + (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);
1453 case X25_REGISTRATION_CONFIRMATION:
1454 bytex = tvb_get_guint8(tvb, 5);
1455 dce_len = (bytex >> 0) & 0x0F;
1456 dte_len = (bytex >> 4) & 0x0F;
1457 length = 6 + (dte_len + dce_len + 1) / 2; /* addr */
1458 if (length < tvb_reported_length(tvb))
1459 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1461 return MIN(tvb_reported_length(tvb),length);
1464 if ((byte2 & 0x01) == X25_DATA) return MIN(tvb_reported_length(tvb),3);
1466 switch (byte2 & 0x1F)
1469 return MIN(tvb_reported_length(tvb),3);
1472 return MIN(tvb_reported_length(tvb),3);
1475 return MIN(tvb_reported_length(tvb),3);
1481 static const value_string prt_id_vals[] = {
1482 {PRT_ID_ISO_8073, "ISO 8073 COTP"},
1483 {PRT_ID_ISO_8602, "ISO 8602 CLTP"},
1484 {PRT_ID_ISO_10736_ISO_8073, "ISO 10736 in conjunction with ISO 8073 COTP"},
1485 {PRT_ID_ISO_10736_ISO_8602, "ISO 10736 in conjunction with ISO 8602 CLTP"},
1489 static const value_string sharing_strategy_vals[] = {
1490 {0x00, "No sharing"},
1495 dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1497 proto_tree *x25_tree=0, *gfi_tree=0, *userdata_tree=0;
1499 guint localoffset=0;
1504 gboolean toa; /* TOA/NPI address format */
1508 gboolean q_bit_set = FALSE;
1510 if (check_col(pinfo->fd, COL_PROTOCOL))
1511 col_set_str(pinfo->fd, COL_PROTOCOL, "X.25");
1513 bytes0_1 = tvb_get_ntohs(tvb, 0);
1515 modulo = ((bytes0_1 & 0x2000) ? 128 : 8);
1516 vc = (int)(bytes0_1 & 0x0FFF);
1518 if (bytes0_1 & 0x8000) toa = TRUE;
1521 x25_pkt_len = get_x25_pkt_len(tvb);
1522 if (x25_pkt_len < 3) /* packet too short */
1524 if (check_col(pinfo->fd, COL_INFO))
1525 col_set_str(pinfo->fd, COL_INFO, "Invalid/short X.25 packet");
1527 proto_tree_add_protocol_format(tree, proto_x25, tvb, 0,
1528 tvb_length(tvb), "Invalid/short X.25 packet");
1532 pkt_type = tvb_get_guint8(tvb, 2);
1535 ti = proto_tree_add_item(tree, proto_x25, tvb, 0, x25_pkt_len, FALSE);
1536 x25_tree = proto_item_add_subtree(ti, ett_x25);
1537 ti = proto_tree_add_item(x25_tree, hf_x25_gfi, tvb, 0, 2, FALSE);
1538 gfi_tree = proto_item_add_subtree(ti, ett_x25_gfi);
1540 if ((pkt_type & 0x01) == X25_DATA) {
1541 proto_tree_add_boolean(gfi_tree, hf_x25_qbit, tvb, 0, 2,
1543 if (bytes0_1 & 0x8000) {
1547 else if (pkt_type == X25_CALL_REQUEST ||
1548 pkt_type == X25_CALL_ACCEPTED ||
1549 pkt_type == X25_CLEAR_REQUEST ||
1550 pkt_type == X25_CLEAR_CONFIRMATION) {
1551 proto_tree_add_boolean(gfi_tree, hf_x25_abit, tvb, 0, 2,
1555 if (pkt_type == X25_CALL_REQUEST || pkt_type == X25_CALL_ACCEPTED ||
1556 (pkt_type & 0x01) == X25_DATA) {
1557 proto_tree_add_boolean(gfi_tree, hf_x25_dbit, tvb, 0, 2,
1560 proto_tree_add_uint(gfi_tree, hf_x25_mod, tvb, 0, 2, bytes0_1);
1564 case X25_CALL_REQUEST:
1565 if (check_col(pinfo->fd, COL_INFO))
1566 col_add_fstr(pinfo->fd, COL_INFO, "%s VC:%d",
1567 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Inc. call"
1571 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb,
1573 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1575 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Incoming call"
1579 if (localoffset < x25_pkt_len) /* calling/called addresses */
1580 x25_ntoa(x25_tree, &localoffset, tvb, pinfo->fd, toa);
1582 if (localoffset < x25_pkt_len) /* facilities */
1583 dump_facilities(x25_tree, &localoffset, tvb);
1585 if (localoffset < tvb_reported_length(tvb)) /* user data */
1592 ti = proto_tree_add_text(x25_tree, tvb, localoffset,
1593 tvb_length_remaining(tvb, localoffset),
1595 userdata_tree = proto_item_add_subtree(ti, ett_x25_user_data);
1598 /* X.263/ISO 9577 says that:
1600 When CLNP or ESIS are run over X.25, the SPI
1601 is 0x81 or 0x82, respectively; those are the
1602 NLPIDs for those protocol.
1604 When X.224/ISO 8073 COTP is run over X.25, and
1605 when ISO 11570 explicit identification is being
1606 used, the first octet of the user data field is
1607 a TPDU length field, and the rest is "as defined
1608 in ITU-T Rec. X.225 | ISO/IEC 8073, Annex B,
1609 or ITU-T Rec. X.264 and ISO/IEC 11570".
1611 When X.264/ISO 11570 default identification is
1612 being used, there is no user data field in the
1613 CALL REQUEST packet. This is for X.225/ISO 8073
1616 It also says that SPI values from 0x03 through 0x3f are
1617 reserved and are in use by X.224/ISO 8073 Annex B and
1618 X.264/ISO 11570. The note says that those values are
1619 not NLPIDs, they're "used by the respective higher layer
1620 protocol" and "not used for higher layer protocol
1621 identification". I infer from this and from what
1622 X.264/ISO 11570 says that this means that values in those
1623 range are valid values for the first octet of an
1624 X.224/ISO 8073 packet or for X.264/ISO 11570.
1626 Annex B of X.225/ISO 8073 mentions some additional TPDU
1627 types that can be put in what I presume is the user
1628 data of connect requests. It says that:
1630 The sending transport entity shall:
1632 a) either not transmit any TPDU in the NS-user data
1633 parameter of the N-CONNECT request primitive; or
1635 b) transmit the UN-TPDU (see ITU-T Rec. X.264 and
1636 ISO/IEC 11570) followed by the NCM-TPDU in the
1637 NS-user data parameter of the N-CONNECT request
1640 I don't know if this means that the user data field
1641 will contain a UN TPDU followed by an NCM TPDU or not.
1643 X.264/ISO 11570 says that:
1645 When default identification is being used,
1646 X.225/ISO 8073 COTP is identified. No user data
1647 is sent in the network-layer connection request.
1649 When explicit identification is being used,
1650 the user data is a UN TPDU ("Use of network
1651 connection TPDU"), which specifies the transport
1652 protocol to use over this network connection.
1653 It also says that the length of a UN TPDU shall
1654 not exceed 32 octets, i.e. shall not exceed 0x20;
1655 it says this is "due to the desire not to conflict
1656 with the protocol identifier field carried by X.25
1657 CALL REQUEST/INCOMING CALL packets", and says that
1658 field has values specified in X.244. X.244 has been
1659 superseded by X.263/ISO 9577, so that presumably
1660 means the goal is to allow a UN TPDU's length
1661 field to be distinguished from an NLPID, allowing
1662 you to tell whether X.264/ISO 11570 explicit
1663 identification is being used or an NLPID is
1664 being used as the SPI.
1666 I read this as meaning that, if the ISO mechanisms are
1667 used to identify the protocol being carried over X.25:
1669 if there's no user data in the CALL REQUEST/
1670 INCOMING CALL packet, it's COTP;
1672 if there is user data, then:
1674 if the first octet is less than or equal to
1675 32, it might be a UN TPDU, and that identifies
1676 the transport protocol being used, and
1677 it may be followed by more data, such
1678 as a COTP NCM TPDU if it's COTP;
1680 if the first octet is greater than 32, it's
1681 an NLPID, *not* a TPDU length, and the
1682 stuff following it is *not* a TPDU.
1684 Figure A.2 of X.263/ISO 9577 seems to say that the
1685 first octet of the user data is a TPDU length field,
1686 in the range 0x03 through 0x82, and says they are
1687 for X.225/ISO 8073 Annex B or X.264/ISO 11570.
1689 However, X.264/ISO 11570 seems to imply that the length
1690 field would be that of a UN TPDU, which must be less
1691 than or equal to 0x20, and X.225/ISO 8073 Annex B seems
1692 to indicate that the user data must begin with
1693 an X.264/ISO 11570 UN TPDU, so I'd say that A.2 should
1694 have said "in the range 0x03 through 0x20", instead
1695 (the length value doesn't include the length field,
1696 and the minimum UN TPDU has length, type, PRT-ID,
1697 and SHARE, so that's 3 bytes without the length). */
1698 spi = tvb_get_guint8(tvb, localoffset);
1699 if (spi > 32 || spi < 3) {
1700 /* First octet is > 32, or < 3, so the user data isn't an
1701 X.264/ISO 11570 UN TPDU */
1704 /* First octet is >= 3 and <= 32, so the user data *might*
1705 be an X.264/ISO 11570 UN TPDU. Check whether we have
1706 enough data to see if it is. */
1707 if (tvb_bytes_exist(tvb, localoffset+1, 1)) {
1708 /* We do; check whether the second octet is 1. */
1709 if (tvb_get_guint8(tvb, localoffset+1) == 0x01) {
1710 /* Yes, the second byte is 1, so it looks like
1714 /* No, the second byte is not 1, so it's not a
1719 /* We can't see the second byte of the putative UN
1720 TPDU, so we don't know if that's what it is. */
1724 if (is_x_264 == -1) {
1726 * We don't know what it is; just skip it.
1728 localoffset = tvb_length(tvb);
1729 } else if (is_x_264) {
1730 /* It looks like an X.264 UN TPDU, so show it as such. */
1731 if (userdata_tree) {
1732 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1733 "X.264 length indicator: %u",
1735 proto_tree_add_text(userdata_tree, tvb, localoffset+1, 1,
1736 "X.264 UN TPDU identifier: 0x%02X",
1737 tvb_get_guint8(tvb, localoffset+1));
1739 prt_id = tvb_get_guint8(tvb, localoffset+2);
1740 if (userdata_tree) {
1741 proto_tree_add_text(x25_tree, tvb, localoffset+2, 1,
1742 "X.264 protocol identifier: %s",
1743 val_to_str(prt_id, prt_id_vals,
1744 "Unknown (0x%02X)"));
1745 proto_tree_add_text(x25_tree, tvb, localoffset+3, 1,
1746 "X.264 sharing strategy: %s",
1747 val_to_str(tvb_get_guint8(tvb, localoffset+3),
1748 sharing_strategy_vals, "Unknown (0x%02X)"));
1751 /* XXX - dissect the variable part? */
1753 /* The length doesn't include the length octet itself. */
1754 localoffset += spi + 1;
1758 case PRT_ID_ISO_8073:
1760 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
1761 pinfo->fd->abs_usecs,
1763 /* XXX - disssect the rest of the user data as COTP?
1764 That needs support for NCM TPDUs, etc. */
1767 case PRT_ID_ISO_8602:
1769 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
1770 pinfo->fd->abs_usecs,
1774 } else if (is_x_264 == 0) {
1775 /* It doesn't look like a UN TPDU, so compare the first
1776 octet of the CALL REQUEST packet with various X.263/
1777 ISO 9577 NLPIDs, as per Annex A of X.263/ISO 9577. */
1779 if (userdata_tree) {
1780 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1781 "X.263 secondary protocol ID: %s",
1782 val_to_str(spi, nlpid_vals, "Unknown (0x%02x)"));
1786 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
1787 pinfo->fd->abs_usecs, spi);
1789 if (localoffset < tvb_length(tvb)) {
1790 if (userdata_tree) {
1791 proto_tree_add_text(userdata_tree, tvb, localoffset,
1792 tvb_length(tvb)-localoffset, "Data");
1794 localoffset = tvb_length(tvb);
1798 case X25_CALL_ACCEPTED:
1799 if(check_col(pinfo->fd, COL_INFO))
1800 col_add_fstr(pinfo->fd, COL_INFO, "%s VC:%d",
1801 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Call conn."
1805 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1806 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1808 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Call connected"
1812 if (localoffset < x25_pkt_len) /* calling/called addresses */
1813 x25_ntoa(x25_tree, &localoffset, tvb, pinfo->fd, toa);
1815 if (localoffset < x25_pkt_len) /* facilities */
1816 dump_facilities(x25_tree, &localoffset, tvb);
1818 if (localoffset < tvb_reported_length(tvb)) { /* user data */
1820 proto_tree_add_text(x25_tree, tvb, localoffset,
1821 tvb_reported_length(tvb)-localoffset, "Data");
1822 localoffset=tvb_reported_length(tvb);
1825 case X25_CLEAR_REQUEST:
1826 if(check_col(pinfo->fd, COL_INFO)) {
1827 col_add_fstr(pinfo->fd, COL_INFO, "%s VC:%d %s - %s",
1828 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Clear ind."
1830 vc, clear_code(tvb_get_guint8(tvb, 3)),
1831 clear_diag(tvb_get_guint8(tvb, 4)));
1833 x25_hash_add_proto_end(vc, pinfo->fd->abs_secs, pinfo->fd->abs_usecs);
1835 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1836 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb,
1837 localoffset+2, 1, X25_CLEAR_REQUEST,
1838 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Clear indication"
1840 proto_tree_add_text(x25_tree, tvb, 3, 1,
1841 "Cause : %s", clear_code(tvb_get_guint8(tvb, 3)));
1842 proto_tree_add_text(x25_tree, tvb, 4, 1,
1843 "Diagnostic : %s", clear_diag(tvb_get_guint8(tvb, 4)));
1845 localoffset = x25_pkt_len;
1847 case X25_CLEAR_CONFIRMATION:
1848 if(check_col(pinfo->fd, COL_INFO))
1849 col_add_fstr(pinfo->fd, COL_INFO, "Clear Conf. VC:%d", vc);
1851 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1852 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1853 X25_CLEAR_CONFIRMATION);
1855 localoffset = x25_pkt_len;
1857 if (localoffset < tvb_reported_length(tvb)) /* extended clear conf format */
1858 x25_ntoa(x25_tree, &localoffset, tvb, pinfo->fd, toa);
1860 if (localoffset < tvb_reported_length(tvb)) /* facilities */
1861 dump_facilities(x25_tree, &localoffset, tvb);
1863 case X25_DIAGNOSTIC:
1864 if(check_col(pinfo->fd, COL_INFO)) {
1865 col_add_fstr(pinfo->fd, COL_INFO, "Diag. %d",
1866 (int)tvb_get_guint8(tvb, 3));
1869 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1871 proto_tree_add_text(x25_tree, tvb, 3, 1,
1872 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 3));
1874 localoffset = x25_pkt_len;
1877 if(check_col(pinfo->fd, COL_INFO))
1878 col_add_fstr(pinfo->fd, COL_INFO, "Interrupt VC:%d", vc);
1880 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1881 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1884 localoffset = x25_pkt_len;
1886 case X25_INTERRUPT_CONFIRMATION:
1887 if(check_col(pinfo->fd, COL_INFO))
1888 col_add_fstr(pinfo->fd, COL_INFO, "Interrupt 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_INTERRUPT_CONFIRMATION);
1894 localoffset = x25_pkt_len;
1896 case X25_RESET_REQUEST:
1897 if(check_col(pinfo->fd, COL_INFO)) {
1898 col_add_fstr(pinfo->fd, COL_INFO, "%s VC:%d %s - Diag.:%d",
1899 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Reset ind."
1901 vc, reset_code(tvb_get_guint8(tvb, 3)),
1902 (int)tvb_get_guint8(tvb, 4));
1904 x25_hash_add_proto_end(vc, pinfo->fd->abs_secs, pinfo->fd->abs_usecs);
1906 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1907 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1909 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Reset indication"
1911 proto_tree_add_text(x25_tree, tvb, 3, 1,
1912 "Cause : %s", reset_code(tvb_get_guint8(tvb, 3)));
1913 proto_tree_add_text(x25_tree, tvb, 4, 1,
1914 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
1916 localoffset = x25_pkt_len;
1918 case X25_RESET_CONFIRMATION:
1919 if(check_col(pinfo->fd, COL_INFO))
1920 col_add_fstr(pinfo->fd, COL_INFO, "Reset conf. VC:%d", vc);
1922 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1923 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1924 X25_RESET_CONFIRMATION);
1926 localoffset = x25_pkt_len;
1928 case X25_RESTART_REQUEST:
1929 if(check_col(pinfo->fd, COL_INFO)) {
1930 col_add_fstr(pinfo->fd, COL_INFO, "%s %s - Diag.:%d",
1931 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Restart ind."
1933 restart_code(tvb_get_guint8(tvb, 3)),
1934 (int)tvb_get_guint8(tvb, 3));
1937 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1938 X25_RESTART_REQUEST,
1939 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Restart indication"
1940 : "Restart request");
1941 proto_tree_add_text(x25_tree, tvb, 3, 1,
1942 "Cause : %s", restart_code(tvb_get_guint8(tvb, 3)));
1943 proto_tree_add_text(x25_tree, tvb, 4, 1,
1944 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
1946 localoffset = x25_pkt_len;
1948 case X25_RESTART_CONFIRMATION:
1949 if(check_col(pinfo->fd, COL_INFO))
1950 col_set_str(pinfo->fd, COL_INFO, "Restart conf.");
1952 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1953 X25_RESTART_CONFIRMATION);
1954 localoffset = x25_pkt_len;
1956 case X25_REGISTRATION_REQUEST:
1957 if(check_col(pinfo->fd, COL_INFO))
1958 col_set_str(pinfo->fd, COL_INFO, "Registration req.");
1960 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1961 X25_REGISTRATION_REQUEST);
1963 if (localoffset < x25_pkt_len)
1964 x25_ntoa(x25_tree, &localoffset, tvb, pinfo->fd, FALSE);
1967 if (localoffset < x25_pkt_len)
1968 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
1969 "Registration length: %d",
1970 tvb_get_guint8(tvb, localoffset) & 0x7F);
1971 if (localoffset+1 < x25_pkt_len)
1972 proto_tree_add_text(x25_tree, tvb, localoffset+1,
1973 tvb_get_guint8(tvb, localoffset) & 0x7F,
1976 localoffset = tvb_reported_length(tvb);
1978 case X25_REGISTRATION_CONFIRMATION:
1979 if(check_col(pinfo->fd, COL_INFO))
1980 col_set_str(pinfo->fd, COL_INFO, "Registration conf.");
1982 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1983 X25_REGISTRATION_CONFIRMATION);
1984 proto_tree_add_text(x25_tree, tvb, 3, 1,
1985 "Cause: %s", registration_code(tvb_get_guint8(tvb, 3)));
1986 proto_tree_add_text(x25_tree, tvb, 4, 1,
1987 "Diagnostic: %s", registration_code(tvb_get_guint8(tvb, 4)));
1990 if (localoffset < x25_pkt_len)
1991 x25_ntoa(x25_tree, &localoffset, tvb, pinfo->fd, TRUE);
1994 if (localoffset < x25_pkt_len)
1995 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
1996 "Registration length: %d",
1997 tvb_get_guint8(tvb, localoffset) & 0x7F);
1998 if (localoffset+1 < x25_pkt_len)
1999 proto_tree_add_text(x25_tree, tvb, localoffset+1,
2000 tvb_get_guint8(tvb, localoffset) & 0x7F,
2003 localoffset = tvb_reported_length(tvb);
2007 if ((pkt_type & 0x01) == X25_DATA)
2009 if(check_col(pinfo->fd, COL_INFO)) {
2011 col_add_fstr(pinfo->fd, COL_INFO,
2012 "Data VC:%d P(S):%d P(R):%d %s", vc,
2013 (pkt_type >> 1) & 0x07,
2014 (pkt_type >> 5) & 0x07,
2015 ((pkt_type >> 4) & 0x01) ? " M" : "");
2017 col_add_fstr(pinfo->fd, COL_INFO,
2018 "Data VC:%d P(S):%d P(R):%d %s", vc,
2019 tvb_get_guint8(tvb, localoffset+1) >> 1,
2021 (tvb_get_guint8(tvb, localoffset+1) & 0x01) ? " M" : "");
2024 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2026 proto_tree_add_uint_hidden(x25_tree, hf_x25_type, tvb,
2027 localoffset, 1, X25_DATA);
2029 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2030 localoffset, 1, pkt_type);
2031 if (pkt_type & 0x10)
2032 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod8, tvb,
2033 localoffset, 1, pkt_type);
2034 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod8, tvb,
2035 localoffset, 1, pkt_type);
2036 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
2037 decode_boolean_bitfield(pkt_type, 0x01, 1*8,
2041 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod128, tvb,
2042 localoffset, 1, pkt_type);
2043 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod128, tvb,
2045 tvb_get_guint8(tvb, localoffset+1));
2046 if (tvb_get_guint8(tvb, localoffset+1) & 0x01)
2047 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod128, tvb,
2049 tvb_get_guint8(tvb, localoffset+1));
2052 localoffset += (modulo == 8) ? 1 : 2;
2055 switch (pkt_type & 0x1F)
2058 if(check_col(pinfo->fd, COL_INFO)) {
2060 col_add_fstr(pinfo->fd, COL_INFO, "RR VC:%d P(R):%d",
2061 vc, (pkt_type >> 5) & 0x07);
2063 col_add_fstr(pinfo->fd, COL_INFO, "RR VC:%d P(R):%d",
2064 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2067 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2070 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2071 localoffset, 1, pkt_type);
2072 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2073 localoffset, 1, X25_RR);
2076 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2077 localoffset, 1, X25_RR);
2078 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2079 localoffset+1, 1, FALSE);
2085 if(check_col(pinfo->fd, COL_INFO)) {
2087 col_add_fstr(pinfo->fd, COL_INFO, "RNR VC:%d P(R):%d",
2088 vc, (pkt_type >> 5) & 0x07);
2090 col_add_fstr(pinfo->fd, COL_INFO, "RNR VC:%d P(R):%d",
2091 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2094 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2097 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2098 localoffset, 1, pkt_type);
2099 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2100 localoffset, 1, X25_RNR);
2103 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2104 localoffset, 1, X25_RNR);
2105 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2106 localoffset+1, 1, FALSE);
2112 if(check_col(pinfo->fd, COL_INFO)) {
2114 col_add_fstr(pinfo->fd, COL_INFO, "REJ VC:%d P(R):%d",
2115 vc, (pkt_type >> 5) & 0x07);
2117 col_add_fstr(pinfo->fd, COL_INFO, "REJ VC:%d P(R):%d",
2118 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2121 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2124 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2125 localoffset, 1, pkt_type);
2126 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2127 localoffset, 1, X25_REJ);
2130 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2131 localoffset, 1, X25_REJ);
2132 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2133 localoffset+1, 1, FALSE);
2137 localoffset += (modulo == 8) ? 1 : 2;
2140 if (localoffset >= tvb_reported_length(tvb)) return;
2142 next_tvb = tvb_new_subset(tvb, localoffset, -1, -1);
2146 call_dissector(qllc_handle, next_tvb, pinfo, tree);
2150 /* search the protocol in the hash table */
2151 proto = x25_hash_get_proto(pinfo->fd->abs_secs, pinfo->fd->abs_usecs, vc);
2155 /* Did the user suggest SNA-over-X.25? */
2156 if (non_q_bit_is_sna) {
2157 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
2158 pinfo->fd->abs_usecs, PROTO_SNA);
2159 call_dissector(sna_handle, next_tvb, pinfo, tree);
2162 /* If the Call Req. has not been captured, and the payload begins
2163 with what appears to be an IP header, assume these packets carry
2165 if (tvb_get_guint8(tvb, localoffset) == 0x45) {
2166 x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
2167 pinfo->fd->abs_usecs, NLPID_IP);
2168 if (dissector_try_port(x25_subdissector_table, NLPID_IP,
2169 next_tvb, pinfo, tree))
2175 call_dissector(sna_handle, next_tvb, pinfo, tree);
2179 call_dissector(ositp_handle, next_tvb, pinfo, tree);
2183 if (dissector_try_port(x25_subdissector_table, proto,
2184 next_tvb, pinfo, tree))
2188 call_dissector(data_handle, next_tvb, pinfo, tree);
2192 proto_register_x25(void)
2194 static hf_register_info hf[] = {
2196 { "GFI", "x.25.gfi", FT_UINT16, BASE_BIN, NULL, 0xF000,
2197 "General format identifier", HFILL }},
2199 { "A Bit", "x.25.a", FT_BOOLEAN, 16, NULL, 0x8000,
2200 "Address Bit", HFILL }},
2202 { "Q Bit", "x.25.q", FT_BOOLEAN, 16, NULL, 0x8000,
2203 "Qualifier Bit", HFILL }},
2205 { "D Bit", "x.25.d", FT_BOOLEAN, 16, NULL, 0x4000,
2206 "Delivery Confirmation Bit", HFILL }},
2208 { "Modulo", "x.25.mod", FT_UINT16, BASE_DEC, VALS(vals_modulo), 0x3000,
2209 "Specifies whether the frame is modulo 8 or 128", HFILL }},
2211 { "Logical Channel", "x.25.lcn", FT_UINT16, BASE_DEC, NULL, 0x0FFF,
2212 "Logical Channel Number", HFILL }},
2214 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x0,
2215 "Packet Type", HFILL }},
2217 { "P(R)", "x.25.p_r", FT_UINT8, BASE_HEX, NULL, 0xE0,
2218 "Packet Receive Sequence Number", HFILL }},
2219 { &hf_x25_p_r_mod128,
2220 { "P(R)", "x.25.p_r", FT_UINT8, BASE_HEX, NULL, 0xFE,
2221 "Packet Receive Sequence Number", HFILL }},
2222 { &hf_x25_mbit_mod8,
2223 { "M Bit", "x.25.m", FT_BOOLEAN, 8, NULL, 0x10,
2224 "More Bit", HFILL }},
2225 { &hf_x25_mbit_mod128,
2226 { "M Bit", "x.25.m", FT_BOOLEAN, 8, NULL, 0x01,
2227 "More Bit", HFILL }},
2229 { "P(S)", "x.25.p_s", FT_UINT8, BASE_HEX, NULL, 0x0E,
2230 "Packet Send Sequence Number", HFILL }},
2231 { &hf_x25_p_s_mod128,
2232 { "P(S)", "x.25.p_s", FT_UINT8, BASE_HEX, NULL, 0xFE,
2233 "Packet Send Sequence Number", HFILL }},
2235 static gint *ett[] = {
2239 &ett_x25_fac_unknown,
2241 &ett_x25_fac_reverse,
2242 &ett_x25_fac_throughput,
2244 &ett_x25_fac_called_modif,
2245 &ett_x25_fac_cug_outgoing_acc,
2246 &ett_x25_fac_throughput_min,
2247 &ett_x25_fac_express_data,
2248 &ett_x25_fac_bilateral_cug,
2249 &ett_x25_fac_packet_size,
2250 &ett_x25_fac_window_size,
2251 &ett_x25_fac_rpoa_selection,
2252 &ett_x25_fac_transit_delay,
2253 &ett_x25_fac_call_transfer,
2254 &ett_x25_fac_called_addr_ext,
2255 &ett_x25_fac_ete_transit_delay,
2256 &ett_x25_fac_calling_addr_ext,
2257 &ett_x25_fac_call_deflect,
2258 &ett_x25_fac_priority,
2261 module_t *x25_module;
2263 proto_x25 = proto_register_protocol ("X.25", "X.25", "x.25");
2264 proto_register_field_array (proto_x25, hf, array_length(hf));
2265 proto_register_subtree_array(ett, array_length(ett));
2266 register_init_routine(&reinit_x25_hashtable);
2268 x25_subdissector_table = register_dissector_table("x.25.spi");
2270 register_dissector("x.25", dissect_x25, proto_x25);
2273 x25_module = prefs_register_protocol(proto_x25, NULL);
2274 prefs_register_bool_preference(x25_module, "non_q_bit_is_sna",
2275 "When Q-bit is 0, payload is SNA", "When Q-bit is 0, payload is SNA",
2280 proto_reg_handoff_x25(void)
2282 dissector_handle_t x25_handle;
2285 * Get handles for various dissectors.
2287 ositp_handle = find_dissector("ositp");
2288 sna_handle = find_dissector("sna");
2289 qllc_handle = find_dissector("qllc");
2290 data_handle = find_dissector("data");
2292 x25_handle = find_dissector("x.25");
2293 dissector_add("llc.dsap", SAP_X25, x25_handle);