2 * Routines for X.25 packet disassembly
3 * Olivier Abad <oabad@noos.fr>
5 * $Id: packet-x25.c,v 1.76 2003/01/31 03:17:47 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.
35 #include <epan/packet.h>
36 #include <epan/circuit.h>
39 #include "x264_prt_id.h"
42 * Direction of packet.
45 X25_FROM_DCE, /* DCE->DTE */
46 X25_FROM_DTE, /* DTE->DCE */
47 X25_UNKNOWN /* direction unknown */
51 * 0 for data packets, 1 for non-data packets.
53 #define X25_NONDATA_BIT 0x01
55 #define X25_CALL_REQUEST 0x0B
56 #define X25_CALL_ACCEPTED 0x0F
57 #define X25_CLEAR_REQUEST 0x13
58 #define X25_CLEAR_CONFIRMATION 0x17
59 #define X25_INTERRUPT 0x23
60 #define X25_INTERRUPT_CONFIRMATION 0x27
61 #define X25_RESET_REQUEST 0x1B
62 #define X25_RESET_CONFIRMATION 0x1F
63 #define X25_RESTART_REQUEST 0xFB
64 #define X25_RESTART_CONFIRMATION 0xFF
65 #define X25_REGISTRATION_REQUEST 0xF3
66 #define X25_REGISTRATION_CONFIRMATION 0xF7
67 #define X25_DIAGNOSTIC 0xF1
73 #define PACKET_IS_DATA(type) (!(type & X25_NONDATA_BIT))
74 #define PACKET_TYPE_FC(type) (type & 0x1F)
76 #define X25_FAC_CLASS_MASK 0xC0
78 #define X25_FAC_CLASS_A 0x00
79 #define X25_FAC_CLASS_B 0x40
80 #define X25_FAC_CLASS_C 0x80
81 #define X25_FAC_CLASS_D 0xC0
83 #define X25_FAC_COMP_MARK 0x00
84 #define X25_FAC_REVERSE 0x01
85 #define X25_FAC_THROUGHPUT 0x02
86 #define X25_FAC_CUG 0x03
87 #define X25_FAC_CALLED_MODIF 0x08
88 #define X25_FAC_CUG_OUTGOING_ACC 0x09
89 #define X25_FAC_THROUGHPUT_MIN 0x0A
90 #define X25_FAC_EXPRESS_DATA 0x0B
91 #define X25_FAC_BILATERAL_CUG 0x41
92 #define X25_FAC_PACKET_SIZE 0x42
93 #define X25_FAC_WINDOW_SIZE 0x43
94 #define X25_FAC_RPOA_SELECTION 0x44
95 #define X25_FAC_TRANSIT_DELAY 0x49
96 #define X25_FAC_CALL_TRANSFER 0xC3
97 #define X25_FAC_CALLED_ADDR_EXT 0xC9
98 #define X25_FAC_ETE_TRANSIT_DELAY 0xCA
99 #define X25_FAC_CALLING_ADDR_EXT 0xCB
100 #define X25_FAC_CALL_DEFLECT 0xD1
101 #define X25_FAC_PRIORITY 0xD2
103 static int proto_x25 = -1;
104 static int hf_x25_gfi = -1;
105 static int hf_x25_abit = -1;
106 static int hf_x25_qbit = -1;
107 static int hf_x25_dbit = -1;
108 static int hf_x25_mod = -1;
109 static int hf_x25_lcn = -1;
110 static int hf_x25_type = -1;
111 static int hf_x25_type_fc_mod8 = -1;
112 static int hf_x25_type_data = -1;
113 static int hf_x25_p_r_mod8 = -1;
114 static int hf_x25_p_r_mod128 = -1;
115 static int hf_x25_mbit_mod8 = -1;
116 static int hf_x25_mbit_mod128 = -1;
117 static int hf_x25_p_s_mod8 = -1;
118 static int hf_x25_p_s_mod128 = -1;
120 static gint ett_x25 = -1;
121 static gint ett_x25_gfi = -1;
122 static gint ett_x25_fac = -1;
123 static gint ett_x25_fac_unknown = -1;
124 static gint ett_x25_fac_mark = -1;
125 static gint ett_x25_fac_reverse = -1;
126 static gint ett_x25_fac_throughput = -1;
127 static gint ett_x25_fac_cug = -1;
128 static gint ett_x25_fac_called_modif = -1;
129 static gint ett_x25_fac_cug_outgoing_acc = -1;
130 static gint ett_x25_fac_throughput_min = -1;
131 static gint ett_x25_fac_express_data = -1;
132 static gint ett_x25_fac_bilateral_cug = -1;
133 static gint ett_x25_fac_packet_size = -1;
134 static gint ett_x25_fac_window_size = -1;
135 static gint ett_x25_fac_rpoa_selection = -1;
136 static gint ett_x25_fac_transit_delay = -1;
137 static gint ett_x25_fac_call_transfer = -1;
138 static gint ett_x25_fac_called_addr_ext = -1;
139 static gint ett_x25_fac_ete_transit_delay = -1;
140 static gint ett_x25_fac_calling_addr_ext = -1;
141 static gint ett_x25_fac_call_deflect = -1;
142 static gint ett_x25_fac_priority = -1;
143 static gint ett_x25_user_data = -1;
145 static const value_string vals_modulo[] = {
151 static const value_string vals_x25_type[] = {
152 { X25_CALL_REQUEST, "Call" },
153 { X25_CALL_ACCEPTED, "Call Accepted" },
154 { X25_CLEAR_REQUEST, "Clear" },
155 { X25_CLEAR_CONFIRMATION, "Clear Confirmation" },
156 { X25_INTERRUPT, "Interrupt" },
157 { X25_INTERRUPT_CONFIRMATION, "Interrupt Confirmation" },
158 { X25_RESET_REQUEST, "Reset" },
159 { X25_RESET_CONFIRMATION, "Reset Confirmation" },
160 { X25_RESTART_REQUEST, "Restart" },
161 { X25_RESTART_CONFIRMATION, "Restart Confirmation" },
162 { X25_REGISTRATION_REQUEST, "Registration" },
163 { X25_REGISTRATION_CONFIRMATION, "Registration Confirmation" },
164 { X25_DIAGNOSTIC, "Diagnostic" },
168 { X25_DATA, "Data" },
172 static struct true_false_string m_bit_tfs = {
177 static dissector_handle_t ip_handle;
178 static dissector_handle_t clnp_handle;
179 static dissector_handle_t ositp_handle;
180 static dissector_handle_t qllc_handle;
181 static dissector_handle_t data_handle;
184 static gboolean payload_is_qllc_sna = FALSE;
186 static dissector_table_t x25_subdissector_table;
187 static heur_dissector_list_t x25_heur_subdissector_list;
190 x25_hash_add_proto_start(guint16 vc, guint32 frame, dissector_handle_t dissect)
195 * Is there already a circuit with this VC number?
197 circuit = find_circuit(CT_X25, vc, frame);
198 if (circuit != NULL) {
200 * Yes - close it, as we're creating a new one.
202 close_circuit(circuit, frame - 1);
206 * Set up a new circuit.
208 circuit = circuit_new(CT_X25, vc, frame);
213 circuit_set_dissector(circuit, dissect);
217 x25_hash_add_proto_end(guint16 vc, guint32 frame)
222 * Try to find the circuit.
224 circuit = find_circuit(CT_X25, vc, frame);
227 * If we succeeded, close it.
230 close_circuit(circuit, frame);
233 static char *clear_code(unsigned char code)
235 static char buffer[25];
237 if (code == 0x00 || (code & 0x80) == 0x80)
238 return "DTE Originated";
240 return "Number Busy";
242 return "Invalid Facility Requested";
244 return "Network Congestion";
246 return "Out Of Order";
248 return "Access Barred";
250 return "Not Obtainable";
252 return "Remote Procedure Error";
254 return "Local Procedure Error";
256 return "RPOA Out Of Order";
258 return "Reverse Charging Acceptance Not Subscribed";
260 return "Incompatible Destination";
262 return "Fast Select Acceptance Not Subscribed";
264 return "Destination Absent";
266 sprintf(buffer, "Unknown %02X", code);
271 static char *clear_diag(unsigned char code)
273 static char buffer[25];
276 return "No additional information";
278 return "Invalid P(S)";
280 return "Invalid P(R)";
282 return "Packet type invalid";
284 return "Packet type invalid for state r1";
286 return "Packet type invalid for state r2";
288 return "Packet type invalid for state r3";
290 return "Packet type invalid for state p1";
292 return "Packet type invalid for state p2";
294 return "Packet type invalid for state p3";
296 return "Packet type invalid for state p4";
298 return "Packet type invalid for state p5";
300 return "Packet type invalid for state p6";
302 return "Packet type invalid for state p7";
304 return "Packet type invalid for state d1";
306 return "Packet type invalid for state d2";
308 return "Packet type invalid for state d3";
310 return "Packet not allowed";
312 return "Unidentifiable packet";
314 return "Call on one-way logical channel";
316 return "Invalid packet type on a PVC";
318 return "Packet on unassigned LC";
320 return "Reject not subscribed to";
322 return "Packet too short";
324 return "Packet too long";
326 return "Invalid general format identifier";
328 return "Restart/registration packet with nonzero bits";
330 return "Packet type not compatible with facility";
332 return "Unauthorised interrupt confirmation";
334 return "Unauthorised interrupt";
336 return "Unauthorised reject";
338 return "Time expired";
340 return "Time expired for incoming call";
342 return "Time expired for clear indication";
344 return "Time expired for reset indication";
346 return "Time expired for restart indication";
348 return "Time expired for call deflection";
350 return "Call set-up/clearing or registration pb.";
352 return "Facility/registration code not allowed";
354 return "Facility parameter not allowed";
356 return "Invalid called DTE address";
358 return "Invalid calling DTE address";
360 return "Invalid facility/registration length";
362 return "Incoming call barred";
364 return "No logical channel available";
366 return "Call collision";
368 return "Duplicate facility requested";
370 return "Non zero address length";
372 return "Non zero facility length";
374 return "Facility not provided when expected";
376 return "Invalid CCITT-specified DTE facility";
378 return "Max. nb of call redir/defl. exceeded";
380 return "Miscellaneous";
382 return "Improper cause code from DTE";
384 return "Not aligned octet";
386 return "Inconsistent Q bit setting";
388 return "NUI problem";
390 return "International problem";
392 return "Remote network problem";
394 return "International protocol problem";
396 return "International link out of order";
398 return "International link busy";
400 return "Transit network facility problem";
402 return "Remote network facility problem";
404 return "International routing problem";
406 return "Temporary routing problem";
408 return "Unknown called DNIC";
410 return "Maintenance action";
412 return "Timer expired or retransmission count surpassed";
414 return "Timer expired or retransmission count surpassed for INTERRUPT";
416 return "Timer expired or retransmission count surpassed for DATA "
417 "packet transmission";
419 return "Timer expired or retransmission count surpassed for REJECT";
421 return "DTE-specific signals";
423 return "DTE operational";
425 return "DTE not operational";
427 return "DTE resource constraint";
429 return "Fast select not subscribed";
431 return "Invalid partially full DATA packet";
433 return "D-bit procedure not supported";
435 return "Registration/Cancellation confirmed";
437 return "OSI network service problem";
439 return "Disconnection (transient condition)";
441 return "Disconnection (permanent condition)";
443 return "Connection rejection - reason unspecified (transient "
446 return "Connection rejection - reason unspecified (permanent "
449 return "Connection rejection - quality of service not available "
450 "transient condition)";
452 return "Connection rejection - quality of service not available "
453 "permanent condition)";
455 return "Connection rejection - NSAP unreachable (transient condition)";
457 return "Connection rejection - NSAP unreachable (permanent condition)";
459 return "reset - reason unspecified";
461 return "reset - congestion";
463 return "Connection rejection - NSAP address unknown (permanent "
466 return "Higher layer initiated";
468 return "Disconnection - normal";
470 return "Disconnection - abnormal";
472 return "Disconnection - incompatible information in user data";
474 return "Connection rejection - reason unspecified (transient "
477 return "Connection rejection - reason unspecified (permanent "
480 return "Connection rejection - quality of service not available "
481 "(transient condition)";
483 return "Connection rejection - quality of service not available "
484 "(permanent condition)";
486 return "Connection rejection - incompatible information in user data";
488 return "Connection rejection - unrecognizable protocol indentifier "
491 return "Reset - user resynchronization";
493 sprintf(buffer, "Unknown %d", code);
498 static char *reset_code(unsigned char code)
500 static char buffer[25];
502 if (code == 0x00 || (code & 0x80) == 0x80)
503 return "DTE Originated";
505 return "Out of order";
507 return "Remote Procedure Error";
509 return "Local Procedure Error";
511 return "Network Congestion";
513 return "Remote DTE operational";
515 return "Network operational";
517 return "Incompatible Destination";
519 return "Network out of order";
521 sprintf(buffer, "Unknown %02X", code);
526 static char *restart_code(unsigned char code)
528 static char buffer[25];
530 if (code == 0x00 || (code & 0x80) == 0x80)
531 return "DTE Originated";
533 return "Local Procedure Error";
535 return "Network Congestion";
537 return "Network Operational";
539 return "Registration/cancellation confirmed";
541 sprintf(buffer, "Unknown %02X", code);
546 static char *registration_code(unsigned char code)
548 static char buffer[25];
551 return "Invalid facility request";
553 return "Network congestion";
555 return "Local procedure error";
557 return "Registration/cancellation confirmed";
559 sprintf(buffer, "Unknown %02X", code);
565 dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb)
567 guint8 fac, byte1, byte2, byte3;
568 guint32 len; /* facilities length */
570 proto_tree *fac_tree = 0;
571 proto_tree *fac_subtree;
573 len = tvb_get_guint8(tvb, *offset);
575 ti = proto_tree_add_text(tree, tvb, *offset, len + 1,
577 fac_tree = proto_item_add_subtree(ti, ett_x25_fac);
578 proto_tree_add_text(fac_tree, tvb, *offset, 1,
579 "Facilities length: %d", len);
584 fac = tvb_get_guint8(tvb, *offset);
585 switch(fac & X25_FAC_CLASS_MASK) {
586 case X25_FAC_CLASS_A:
588 case X25_FAC_COMP_MARK:
590 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
591 "Code : 00 (Marker)");
592 switch (tvb_get_guint8(tvb, *offset + 1)) {
595 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
596 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
597 "Parameter : 00 (Network complementary "
598 "services - calling DTE)");
603 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
604 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
605 "Parameter : FF (Network complementary "
606 "services - called DTE)");
611 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
612 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
613 "Parameter : 0F (DTE complementary "
619 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
620 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
621 "Parameter : %02X (Unknown marker)",
622 tvb_get_guint8(tvb, *offset+1));
627 case X25_FAC_REVERSE:
629 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
630 "(Reverse charging / Fast select)", fac);
631 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_reverse);
632 byte1 = tvb_get_guint8(tvb, *offset + 1);
633 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
634 "Parameter : %02X", byte1);
636 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
637 "11.. .... = Fast select with restriction");
638 else if (byte1 & 0x80)
639 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
640 "10.. .... = Fast select - no restriction");
642 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
643 "00.. .... = Fast select not requested");
644 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
645 decode_boolean_bitfield(byte1, 0x01, 1*8,
646 "Reverse charging requested",
647 "Reverse charging not requested"));
650 case X25_FAC_THROUGHPUT:
654 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
655 "(Throughput class negociation)", fac);
656 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_throughput);
657 byte1 = tvb_get_guint8(tvb, *offset + 1);
669 sprintf(tmpbuf, "From the called DTE : %%u (%d bps)",
670 75*(1<<((byte1 >> 4)-3)));
673 sprintf(tmpbuf, "From the called DTE : %%u (48000 bps)");
676 sprintf(tmpbuf, "From the called DTE : %%u (64000 bps)");
679 sprintf(tmpbuf, "From the called DTE : %%u (Reserved)");
681 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
682 decode_numeric_bitfield(byte1, 0xF0, 1*8, tmpbuf));
683 switch (byte1 & 0x0F)
694 sprintf(tmpbuf, "From the calling DTE : %%u (%d bps)",
695 75*(1<<((byte1 & 0x0F)-3)));
698 sprintf(tmpbuf, "From the calling DTE : %%u (48000 bps)");
701 sprintf(tmpbuf, "From the calling DTE : %%u (64000 bps)");
704 sprintf(tmpbuf, "From the calling DTE : %%u (Reserved)");
706 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
707 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
712 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
713 "(Closed user group selection)", fac);
714 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_cug);
715 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
716 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
719 case X25_FAC_CALLED_MODIF:
721 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
722 "(Called address modified)", fac);
723 fac_subtree = proto_item_add_subtree(ti,
724 ett_x25_fac_called_modif);
725 proto_tree_add_text(fac_tree, tvb, *offset+1, 1,
726 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
729 case X25_FAC_CUG_OUTGOING_ACC:
731 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
732 "(Closed user group with outgoing access selection)",
734 fac_subtree = proto_item_add_subtree(ti,
735 ett_x25_fac_cug_outgoing_acc);
736 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
737 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
740 case X25_FAC_THROUGHPUT_MIN:
742 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
743 "(Minimum throughput class)", fac);
744 fac_subtree = proto_item_add_subtree(ti,
745 ett_x25_fac_throughput_min);
746 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
747 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
750 case X25_FAC_EXPRESS_DATA:
752 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
753 "(Negociation of express data)", fac);
754 fac_subtree = proto_item_add_subtree(ti,
755 ett_x25_fac_express_data);
756 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
757 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
762 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
763 "Code : %02X (Unknown class A)", fac);
764 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
765 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
766 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
773 case X25_FAC_CLASS_B:
775 case X25_FAC_BILATERAL_CUG:
777 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
778 "(Bilateral closed user group selection)", fac);
779 fac_subtree = proto_item_add_subtree(ti,
780 ett_x25_fac_bilateral_cug);
781 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
782 "Bilateral CUG: %04X",
783 tvb_get_ntohs(tvb, *offset+1));
786 case X25_FAC_PACKET_SIZE:
791 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
792 "(Packet size)", fac);
793 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_packet_size);
794 byte1 = tvb_get_guint8(tvb, *offset + 1);
798 sprintf(tmpbuf, "From the called DTE : %%u (16)");
801 sprintf(tmpbuf, "From the called DTE : %%u (32)");
804 sprintf(tmpbuf, "From the called DTE : %%u (64)");
807 sprintf(tmpbuf, "From the called DTE : %%u (128)");
810 sprintf(tmpbuf, "From the called DTE : %%u (256)");
813 sprintf(tmpbuf, "From the called DTE : %%u (512)");
816 sprintf(tmpbuf, "From the called DTE : %%u (1024)");
819 sprintf(tmpbuf, "From the called DTE : %%u (2048)");
822 sprintf(tmpbuf, "From the called DTE : %%u (4096)");
825 sprintf(tmpbuf, "From the called DTE : %%u (Unknown)");
828 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
829 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
831 byte2 = tvb_get_guint8(tvb, *offset + 1);
835 sprintf(tmpbuf, "From the calling DTE : %%u (16)");
838 sprintf(tmpbuf, "From the calling DTE : %%u (32)");
841 sprintf(tmpbuf, "From the calling DTE : %%u (64)");
844 sprintf(tmpbuf, "From the calling DTE : %%u (128)");
847 sprintf(tmpbuf, "From the calling DTE : %%u (256)");
850 sprintf(tmpbuf, "From the calling DTE : %%u (512)");
853 sprintf(tmpbuf, "From the calling DTE : %%u (1024)");
856 sprintf(tmpbuf, "From the calling DTE : %%u (2048)");
859 sprintf(tmpbuf, "From the calling DTE : %%u (4096)");
862 sprintf(tmpbuf, "From the calling DTE : %%u (Unknown)");
865 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
866 decode_numeric_bitfield(byte2, 0x0F, 1*8, tmpbuf));
869 case X25_FAC_WINDOW_SIZE:
871 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
872 "(Window size)", fac);
873 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_window_size);
874 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
875 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+1),
876 0x7F, 1*8, "From the called DTE: %u"));
877 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
878 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+2),
879 0x7F, 1*8, "From the calling DTE: %u"));
882 case X25_FAC_RPOA_SELECTION:
884 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
885 "(RPOA selection)", fac);
886 fac_subtree = proto_item_add_subtree(ti,
887 ett_x25_fac_rpoa_selection);
888 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
889 "Data network identification code : %04X",
890 tvb_get_ntohs(tvb, *offset+1));
893 case X25_FAC_TRANSIT_DELAY:
895 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
896 "(Transit delay selection and indication)", fac);
897 fac_subtree = proto_item_add_subtree(ti,
898 ett_x25_fac_transit_delay);
899 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
900 "Transit delay: %d ms",
901 tvb_get_ntohs(tvb, *offset+1));
906 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
907 "Code : %02X (Unknown class B)", fac);
908 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
909 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
910 "Parameter %04X", tvb_get_ntohs(tvb, *offset+1));
917 case X25_FAC_CLASS_C:
919 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
920 "Code : %02X (Unknown class C)", fac);
921 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
922 proto_tree_add_text(fac_subtree, tvb, *offset+1, 3,
924 tvb_get_ntoh24(tvb, *offset+1));
929 case X25_FAC_CLASS_D:
931 case X25_FAC_CALL_TRANSFER:
936 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
937 "(Call redirection or deflection notification)", fac);
938 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_call_transfer);
939 byte1 = tvb_get_guint8(tvb, *offset+1);
940 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
941 "Length : %u", byte1);
942 byte2 = tvb_get_guint8(tvb, *offset+2);
943 if ((byte2 & 0xC0) == 0xC0) {
944 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
945 "Reason : call deflection by the originally "
946 "called DTE address");
951 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
952 "Reason : originally called DTE busy");
955 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
956 "Reason : call dist. within a hunt group");
959 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
960 "Reason : originally called DTE out of order");
963 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
964 "Reason : systematic call redirection");
967 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
972 byte3 = tvb_get_guint8(tvb, *offset+3);
973 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
974 "Number of semi-octets in DTE address : %u",
976 for (i = 0; i < byte3; i++) {
978 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
980 /* if > 9, convert to the right hexadecimal letter */
981 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
983 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
985 /* if > 9, convert to the right hexadecimal letter */
986 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
990 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
991 "DTE address : %s", tmpbuf);
994 case X25_FAC_CALLING_ADDR_EXT:
999 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1000 "(Calling address extension)", fac);
1001 fac_subtree = proto_item_add_subtree(ti,
1002 ett_x25_fac_calling_addr_ext);
1003 byte1 = tvb_get_guint8(tvb, *offset+1);
1004 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1005 "Length : %u", byte1);
1006 byte2 = tvb_get_guint8(tvb, *offset+2);
1007 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1008 "Number of semi-octets in DTE address : %u", byte2);
1009 for (i = 0; i < byte2; i++) {
1011 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1013 /* if > 9, convert to the right hexadecimal letter */
1014 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1016 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1018 /* if > 9, convert to the right hexadecimal letter */
1019 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1023 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1024 "DTE address : %s", tmpbuf);
1027 case X25_FAC_CALLED_ADDR_EXT:
1032 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1033 "(Called address extension)", fac);
1034 fac_subtree = proto_item_add_subtree(ti,
1035 ett_x25_fac_called_addr_ext);
1036 byte1 = tvb_get_guint8(tvb, *offset+1);
1037 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1038 "Length : %u", byte1);
1039 byte2 = tvb_get_guint8(tvb, *offset+2);
1040 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1041 "Number of semi-octets in DTE address : %u", byte2);
1042 for (i = 0; i < byte2; i++) {
1044 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1046 /* if > 9, convert to the right hexadecimal letter */
1047 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1049 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1051 /* if > 9, convert to the right hexadecimal letter */
1052 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1056 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1057 "DTE address : %s", tmpbuf);
1060 case X25_FAC_ETE_TRANSIT_DELAY:
1062 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1063 "(End to end transit delay)", fac);
1064 fac_subtree = proto_item_add_subtree(ti,
1065 ett_x25_fac_ete_transit_delay);
1066 byte1 = tvb_get_guint8(tvb, *offset+1);
1067 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1068 "Length : %u", byte1);
1069 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1072 case X25_FAC_CALL_DEFLECT:
1077 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1078 "(Call deflection selection)", fac);
1079 fac_subtree = proto_item_add_subtree(ti,
1080 ett_x25_fac_call_deflect);
1081 byte1 = tvb_get_guint8(tvb, *offset+1);
1082 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1083 "Length : %u", byte1);
1084 byte2 = tvb_get_guint8(tvb, *offset+2);
1085 if ((byte2 & 0xC0) == 0xC0)
1086 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1087 "Reason : call DTE originated");
1089 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1090 "Reason : unknown");
1091 byte3 = tvb_get_guint8(tvb, *offset+3);
1092 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1093 "Number of semi-octets in the alternative DTE address : %u",
1095 for (i = 0; i < byte3; i++) {
1097 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1099 /* if > 9, convert to the right hexadecimal letter */
1100 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1102 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1104 /* if > 9, convert to the right hexadecimal letter */
1105 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1109 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1110 "Alternative DTE address : %s", tmpbuf);
1113 case X25_FAC_PRIORITY:
1115 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1116 "Code : %02X (Priority)", fac);
1117 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_priority);
1118 byte1 = tvb_get_guint8(tvb, *offset+1);
1119 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1120 "Length : %u", byte1);
1121 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1126 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1127 "Code : %02X (Unknown class D)", fac);
1128 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1129 byte1 = tvb_get_guint8(tvb, *offset+1);
1130 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1131 "Length : %u", byte1);
1132 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1135 byte1 = tvb_get_guint8(tvb, *offset+1);
1136 (*offset) += byte1+2;
1144 x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1145 packet_info *pinfo, gboolean is_registration)
1149 char addr1[16], addr2[16];
1150 char *first, *second;
1154 byte = tvb_get_guint8(tvb, *offset);
1155 len1 = (byte >> 0) & 0x0F;
1156 len2 = (byte >> 4) & 0x0F;
1159 proto_tree_add_text(tree, tvb, *offset, 1,
1160 decode_numeric_bitfield(byte, 0xF0, 1*8,
1162 "DTE address length : %u" :
1163 "Calling address length : %u"));
1164 proto_tree_add_text(tree, tvb, *offset, 1,
1165 decode_numeric_bitfield(byte, 0x0F, 1*8,
1167 "DCE address length : %u" :
1168 "Called address length : %u"));
1172 localoffset = *offset;
1173 byte = tvb_get_guint8(tvb, localoffset);
1177 for (i = 0; i < (len1 + len2); i++) {
1180 *first++ = ((byte >> 0) & 0x0F) + '0';
1182 byte = tvb_get_guint8(tvb, localoffset);
1184 *first++ = ((byte >> 4) & 0x0F) + '0';
1188 *second++ = ((byte >> 0) & 0x0F) + '0';
1190 byte = tvb_get_guint8(tvb, localoffset);
1192 *second++ = ((byte >> 4) & 0x0F) + '0';
1201 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1202 col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1);
1204 proto_tree_add_text(tree, tvb, *offset,
1207 "DCE address : %s" :
1208 "Called address : %s",
1212 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1213 col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2);
1215 proto_tree_add_text(tree, tvb, *offset + len1/2,
1216 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1218 "DTE address : %s" :
1219 "Calling address : %s",
1222 (*offset) += ((len1 + len2 + 1) / 2);
1226 x25_toa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1231 char addr1[256], addr2[256];
1232 char *first, *second;
1236 len1 = tvb_get_guint8(tvb, *offset);
1238 proto_tree_add_text(tree, tvb, *offset, 1,
1239 "Called address length : %u",
1244 len2 = tvb_get_guint8(tvb, *offset);
1246 proto_tree_add_text(tree, tvb, *offset, 1,
1247 "Calling address length : %u",
1252 localoffset = *offset;
1253 byte = tvb_get_guint8(tvb, localoffset);
1256 * XXX - the first two half-octets of the address are the TOA and
1257 * NPI; process them as such and, if the TOA says an address is
1258 * an alternative address, process it correctly (i.e., not as a
1259 * sequence of half-octets containing digit values).
1263 for (i = 0; i < (len1 + len2); i++) {
1266 *first++ = ((byte >> 0) & 0x0F) + '0';
1268 byte = tvb_get_guint8(tvb, localoffset);
1270 *first++ = ((byte >> 4) & 0x0F) + '0';
1274 *second++ = ((byte >> 0) & 0x0F) + '0';
1276 byte = tvb_get_guint8(tvb, localoffset);
1278 *second++ = ((byte >> 4) & 0x0F) + '0';
1287 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1288 col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1);
1290 proto_tree_add_text(tree, tvb, *offset,
1292 "Called address : %s",
1296 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1297 col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2);
1299 proto_tree_add_text(tree, tvb, *offset + len1/2,
1300 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1301 "Calling address : %s",
1304 (*offset) += ((len1 + len2 + 1) / 2);
1308 get_x25_pkt_len(tvbuff_t *tvb)
1310 guint length, called_len, calling_len, dte_len, dce_len;
1311 guint8 byte2, bytex;
1313 byte2 = tvb_get_guint8(tvb, 2);
1316 case X25_CALL_REQUEST:
1317 bytex = tvb_get_guint8(tvb, 3);
1318 called_len = (bytex >> 0) & 0x0F;
1319 calling_len = (bytex >> 4) & 0x0F;
1320 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1321 if (length < tvb_reported_length(tvb))
1322 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1324 return MIN(tvb_reported_length(tvb),length);
1326 case X25_CALL_ACCEPTED:
1327 /* The calling/called address length byte (following the packet type)
1328 * is not mandatory, so we must check the packet length before trying
1330 if (tvb_reported_length(tvb) == 3)
1332 bytex = tvb_get_guint8(tvb, 3);
1333 called_len = (bytex >> 0) & 0x0F;
1334 calling_len = (bytex >> 4) & 0x0F;
1335 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1336 if (length < tvb_reported_length(tvb))
1337 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1339 return MIN(tvb_reported_length(tvb),length);
1341 case X25_CLEAR_REQUEST:
1342 case X25_RESET_REQUEST:
1343 case X25_RESTART_REQUEST:
1344 return MIN(tvb_reported_length(tvb),5);
1346 case X25_DIAGNOSTIC:
1347 return MIN(tvb_reported_length(tvb),4);
1349 case X25_CLEAR_CONFIRMATION:
1351 case X25_INTERRUPT_CONFIRMATION:
1352 case X25_RESET_CONFIRMATION:
1353 case X25_RESTART_CONFIRMATION:
1354 return MIN(tvb_reported_length(tvb),3);
1356 case X25_REGISTRATION_REQUEST:
1357 bytex = tvb_get_guint8(tvb, 3);
1358 dce_len = (bytex >> 0) & 0x0F;
1359 dte_len = (bytex >> 4) & 0x0F;
1360 length = 4 + (dte_len + dce_len + 1) / 2; /* addr */
1361 if (length < tvb_reported_length(tvb))
1362 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1364 return MIN(tvb_reported_length(tvb),length);
1366 case X25_REGISTRATION_CONFIRMATION:
1367 bytex = tvb_get_guint8(tvb, 5);
1368 dce_len = (bytex >> 0) & 0x0F;
1369 dte_len = (bytex >> 4) & 0x0F;
1370 length = 6 + (dte_len + dce_len + 1) / 2; /* addr */
1371 if (length < tvb_reported_length(tvb))
1372 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1374 return MIN(tvb_reported_length(tvb),length);
1377 if (PACKET_IS_DATA(byte2))
1378 return MIN(tvb_reported_length(tvb),3);
1380 switch (PACKET_TYPE_FC(byte2))
1383 return MIN(tvb_reported_length(tvb),3);
1386 return MIN(tvb_reported_length(tvb),3);
1389 return MIN(tvb_reported_length(tvb),3);
1395 static const value_string prt_id_vals[] = {
1396 {PRT_ID_ISO_8073, "ISO 8073 COTP"},
1397 {PRT_ID_ISO_8602, "ISO 8602 CLTP"},
1398 {PRT_ID_ISO_10736_ISO_8073, "ISO 10736 in conjunction with ISO 8073 COTP"},
1399 {PRT_ID_ISO_10736_ISO_8602, "ISO 10736 in conjunction with ISO 8602 CLTP"},
1403 static const value_string sharing_strategy_vals[] = {
1404 {0x00, "No sharing"},
1409 dissect_x25_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1412 proto_tree *x25_tree=0, *gfi_tree=0, *userdata_tree=0;
1414 guint localoffset=0;
1418 dissector_handle_t dissect;
1419 gboolean toa; /* TOA/NPI address format */
1422 char *short_name = NULL, *long_name = NULL;
1424 gboolean q_bit_set = FALSE;
1425 void *saved_private_data;
1427 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1428 col_set_str(pinfo->cinfo, COL_PROTOCOL, "X.25");
1430 bytes0_1 = tvb_get_ntohs(tvb, 0);
1432 modulo = ((bytes0_1 & 0x2000) ? 128 : 8);
1433 vc = (int)(bytes0_1 & 0x0FFF);
1435 pinfo->ctype = CT_X25;
1436 pinfo->circuit_id = vc;
1438 if (bytes0_1 & 0x8000) toa = TRUE;
1441 x25_pkt_len = get_x25_pkt_len(tvb);
1442 if (x25_pkt_len < 3) /* packet too short */
1444 if (check_col(pinfo->cinfo, COL_INFO))
1445 col_set_str(pinfo->cinfo, COL_INFO, "Invalid/short X.25 packet");
1447 proto_tree_add_protocol_format(tree, proto_x25, tvb, 0, -1,
1448 "Invalid/short X.25 packet");
1452 pkt_type = tvb_get_guint8(tvb, 2);
1453 if (PACKET_IS_DATA(pkt_type)) {
1454 if (bytes0_1 & 0x8000)
1459 ti = proto_tree_add_item(tree, proto_x25, tvb, 0, x25_pkt_len, FALSE);
1460 x25_tree = proto_item_add_subtree(ti, ett_x25);
1461 ti = proto_tree_add_item(x25_tree, hf_x25_gfi, tvb, 0, 2, FALSE);
1462 gfi_tree = proto_item_add_subtree(ti, ett_x25_gfi);
1464 if (PACKET_IS_DATA(pkt_type)) {
1465 proto_tree_add_boolean(gfi_tree, hf_x25_qbit, tvb, 0, 2,
1468 else if (pkt_type == X25_CALL_REQUEST ||
1469 pkt_type == X25_CALL_ACCEPTED ||
1470 pkt_type == X25_CLEAR_REQUEST ||
1471 pkt_type == X25_CLEAR_CONFIRMATION) {
1472 proto_tree_add_boolean(gfi_tree, hf_x25_abit, tvb, 0, 2,
1476 if (pkt_type == X25_CALL_REQUEST || pkt_type == X25_CALL_ACCEPTED ||
1477 PACKET_IS_DATA(pkt_type)) {
1478 proto_tree_add_boolean(gfi_tree, hf_x25_dbit, tvb, 0, 2,
1481 proto_tree_add_uint(gfi_tree, hf_x25_mod, tvb, 0, 2, bytes0_1);
1485 case X25_CALL_REQUEST:
1489 short_name = "Inc. call";
1490 long_name = "Incoming call";
1494 short_name = "Call req.";
1495 long_name = "Call request";
1499 short_name = "Inc. call/Call req.";
1500 long_name = "Incoming call/Call request";
1503 if (check_col(pinfo->cinfo, COL_INFO))
1504 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
1506 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb,
1508 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1509 X25_CALL_REQUEST, "Packet Type: %s", long_name);
1512 if (localoffset < x25_pkt_len) { /* calling/called addresses */
1514 x25_toa(x25_tree, &localoffset, tvb, pinfo);
1516 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
1519 if (localoffset < x25_pkt_len) /* facilities */
1520 dump_facilities(x25_tree, &localoffset, tvb);
1522 if (localoffset < tvb_reported_length(tvb)) /* user data */
1529 ti = proto_tree_add_text(x25_tree, tvb, localoffset, -1,
1531 userdata_tree = proto_item_add_subtree(ti, ett_x25_user_data);
1534 /* X.263/ISO 9577 says that:
1536 When CLNP or ESIS are run over X.25, the SPI
1537 is 0x81 or 0x82, respectively; those are the
1538 NLPIDs for those protocol.
1540 When X.224/ISO 8073 COTP is run over X.25, and
1541 when ISO 11570 explicit identification is being
1542 used, the first octet of the user data field is
1543 a TPDU length field, and the rest is "as defined
1544 in ITU-T Rec. X.225 | ISO/IEC 8073, Annex B,
1545 or ITU-T Rec. X.264 and ISO/IEC 11570".
1547 When X.264/ISO 11570 default identification is
1548 being used, there is no user data field in the
1549 CALL REQUEST packet. This is for X.225/ISO 8073
1552 It also says that SPI values from 0x03 through 0x3f are
1553 reserved and are in use by X.224/ISO 8073 Annex B and
1554 X.264/ISO 11570. The note says that those values are
1555 not NLPIDs, they're "used by the respective higher layer
1556 protocol" and "not used for higher layer protocol
1557 identification". I infer from this and from what
1558 X.264/ISO 11570 says that this means that values in those
1559 range are valid values for the first octet of an
1560 X.224/ISO 8073 packet or for X.264/ISO 11570.
1562 Annex B of X.225/ISO 8073 mentions some additional TPDU
1563 types that can be put in what I presume is the user
1564 data of connect requests. It says that:
1566 The sending transport entity shall:
1568 a) either not transmit any TPDU in the NS-user data
1569 parameter of the N-CONNECT request primitive; or
1571 b) transmit the UN-TPDU (see ITU-T Rec. X.264 and
1572 ISO/IEC 11570) followed by the NCM-TPDU in the
1573 NS-user data parameter of the N-CONNECT request
1576 I don't know if this means that the user data field
1577 will contain a UN TPDU followed by an NCM TPDU or not.
1579 X.264/ISO 11570 says that:
1581 When default identification is being used,
1582 X.225/ISO 8073 COTP is identified. No user data
1583 is sent in the network-layer connection request.
1585 When explicit identification is being used,
1586 the user data is a UN TPDU ("Use of network
1587 connection TPDU"), which specifies the transport
1588 protocol to use over this network connection.
1589 It also says that the length of a UN TPDU shall
1590 not exceed 32 octets, i.e. shall not exceed 0x20;
1591 it says this is "due to the desire not to conflict
1592 with the protocol identifier field carried by X.25
1593 CALL REQUEST/INCOMING CALL packets", and says that
1594 field has values specified in X.244. X.244 has been
1595 superseded by X.263/ISO 9577, so that presumably
1596 means the goal is to allow a UN TPDU's length
1597 field to be distinguished from an NLPID, allowing
1598 you to tell whether X.264/ISO 11570 explicit
1599 identification is being used or an NLPID is
1600 being used as the SPI.
1602 I read this as meaning that, if the ISO mechanisms are
1603 used to identify the protocol being carried over X.25:
1605 if there's no user data in the CALL REQUEST/
1606 INCOMING CALL packet, it's COTP;
1608 if there is user data, then:
1610 if the first octet is less than or equal to
1611 32, it might be a UN TPDU, and that identifies
1612 the transport protocol being used, and
1613 it may be followed by more data, such
1614 as a COTP NCM TPDU if it's COTP;
1616 if the first octet is greater than 32, it's
1617 an NLPID, *not* a TPDU length, and the
1618 stuff following it is *not* a TPDU.
1620 Figure A.2 of X.263/ISO 9577 seems to say that the
1621 first octet of the user data is a TPDU length field,
1622 in the range 0x03 through 0x82, and says they are
1623 for X.225/ISO 8073 Annex B or X.264/ISO 11570.
1625 However, X.264/ISO 11570 seems to imply that the length
1626 field would be that of a UN TPDU, which must be less
1627 than or equal to 0x20, and X.225/ISO 8073 Annex B seems
1628 to indicate that the user data must begin with
1629 an X.264/ISO 11570 UN TPDU, so I'd say that A.2 should
1630 have said "in the range 0x03 through 0x20", instead
1631 (the length value doesn't include the length field,
1632 and the minimum UN TPDU has length, type, PRT-ID,
1633 and SHARE, so that's 3 bytes without the length). */
1634 spi = tvb_get_guint8(tvb, localoffset);
1635 if (spi > 32 || spi < 3) {
1636 /* First octet is > 32, or < 3, so the user data isn't an
1637 X.264/ISO 11570 UN TPDU */
1640 /* First octet is >= 3 and <= 32, so the user data *might*
1641 be an X.264/ISO 11570 UN TPDU. Check whether we have
1642 enough data to see if it is. */
1643 if (tvb_bytes_exist(tvb, localoffset+1, 1)) {
1644 /* We do; check whether the second octet is 1. */
1645 if (tvb_get_guint8(tvb, localoffset+1) == 0x01) {
1646 /* Yes, the second byte is 1, so it looks like
1650 /* No, the second byte is not 1, so it's not a
1655 /* We can't see the second byte of the putative UN
1656 TPDU, so we don't know if that's what it is. */
1660 if (is_x_264 == -1) {
1662 * We don't know what it is; just skip it.
1664 localoffset = tvb_length(tvb);
1665 } else if (is_x_264) {
1666 /* It looks like an X.264 UN TPDU, so show it as such. */
1667 if (userdata_tree) {
1668 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1669 "X.264 length indicator: %u",
1671 proto_tree_add_text(userdata_tree, tvb, localoffset+1, 1,
1672 "X.264 UN TPDU identifier: 0x%02X",
1673 tvb_get_guint8(tvb, localoffset+1));
1675 prt_id = tvb_get_guint8(tvb, localoffset+2);
1676 if (userdata_tree) {
1677 proto_tree_add_text(x25_tree, tvb, localoffset+2, 1,
1678 "X.264 protocol identifier: %s",
1679 val_to_str(prt_id, prt_id_vals,
1680 "Unknown (0x%02X)"));
1681 proto_tree_add_text(x25_tree, tvb, localoffset+3, 1,
1682 "X.264 sharing strategy: %s",
1683 val_to_str(tvb_get_guint8(tvb, localoffset+3),
1684 sharing_strategy_vals, "Unknown (0x%02X)"));
1687 /* XXX - dissect the variable part? */
1689 /* The length doesn't include the length octet itself. */
1690 localoffset += spi + 1;
1694 case PRT_ID_ISO_8073:
1696 if (!pinfo->fd->flags.visited)
1697 x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
1698 /* XXX - dissect the rest of the user data as COTP?
1699 That needs support for NCM TPDUs, etc. */
1702 case PRT_ID_ISO_8602:
1704 if (!pinfo->fd->flags.visited)
1705 x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
1708 } else if (is_x_264 == 0) {
1709 /* It doesn't look like a UN TPDU, so compare the first
1710 octet of the CALL REQUEST packet with various X.263/
1711 ISO 9577 NLPIDs, as per Annex A of X.263/ISO 9577. */
1713 if (userdata_tree) {
1714 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1715 "X.263 secondary protocol ID: %s",
1716 val_to_str(spi, nlpid_vals, "Unknown (0x%02x)"));
1720 if (!pinfo->fd->flags.visited) {
1722 * Is there a dissector handle for this SPI?
1723 * If so, assign it to this virtual circuit.
1725 dissect = dissector_get_port_handle(x25_subdissector_table, spi);
1726 if (dissect != NULL)
1727 x25_hash_add_proto_start(vc, pinfo->fd->num, dissect);
1730 if (localoffset < tvb_length(tvb)) {
1731 if (userdata_tree) {
1732 proto_tree_add_text(userdata_tree, tvb, localoffset, -1,
1735 localoffset = tvb_length(tvb);
1739 case X25_CALL_ACCEPTED:
1743 short_name = "Call conn.";
1744 long_name = "Call connected";
1748 short_name = "Call acc.";
1749 long_name = "Call accepted";
1753 short_name = "Call conn./Call acc.";
1754 long_name = "Call connected/Call accepted";
1757 if(check_col(pinfo->cinfo, COL_INFO))
1758 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
1760 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1761 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1762 X25_CALL_ACCEPTED, "Packet Type: %s", long_name);
1765 if (localoffset < x25_pkt_len) { /* calling/called addresses */
1767 x25_toa(x25_tree, &localoffset, tvb, pinfo);
1769 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
1772 if (localoffset < x25_pkt_len) /* facilities */
1773 dump_facilities(x25_tree, &localoffset, tvb);
1775 if (localoffset < tvb_reported_length(tvb)) { /* user data */
1777 proto_tree_add_text(x25_tree, tvb, localoffset,
1778 tvb_reported_length(tvb)-localoffset, "Data");
1779 localoffset=tvb_reported_length(tvb);
1782 case X25_CLEAR_REQUEST:
1786 short_name = "Clear ind.";
1787 long_name = "Clear indication";
1791 short_name = "Clear req.";
1792 long_name = "Clear request";
1796 short_name = "Clear ind./Clear req.";
1797 long_name = "Clear indication/Clear request";
1800 if(check_col(pinfo->cinfo, COL_INFO)) {
1801 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - %s", short_name,
1802 vc, clear_code(tvb_get_guint8(tvb, 3)),
1803 clear_diag(tvb_get_guint8(tvb, 4)));
1805 x25_hash_add_proto_end(vc, pinfo->fd->num);
1807 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1808 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb,
1809 localoffset+2, 1, X25_CLEAR_REQUEST, "Packet Type: %s",
1811 proto_tree_add_text(x25_tree, tvb, 3, 1,
1812 "Cause : %s", clear_code(tvb_get_guint8(tvb, 3)));
1813 proto_tree_add_text(x25_tree, tvb, 4, 1,
1814 "Diagnostic : %s", clear_diag(tvb_get_guint8(tvb, 4)));
1816 localoffset = x25_pkt_len;
1818 case X25_CLEAR_CONFIRMATION:
1819 if(check_col(pinfo->cinfo, COL_INFO))
1820 col_add_fstr(pinfo->cinfo, COL_INFO, "Clear Conf. VC:%d", vc);
1822 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1823 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1824 X25_CLEAR_CONFIRMATION);
1826 localoffset = x25_pkt_len;
1828 if (localoffset < tvb_reported_length(tvb)) { /* extended clear conf format */
1830 x25_toa(x25_tree, &localoffset, tvb, pinfo);
1832 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
1835 if (localoffset < tvb_reported_length(tvb)) /* facilities */
1836 dump_facilities(x25_tree, &localoffset, tvb);
1838 case X25_DIAGNOSTIC:
1839 if(check_col(pinfo->cinfo, COL_INFO)) {
1840 col_add_fstr(pinfo->cinfo, COL_INFO, "Diag. %d",
1841 (int)tvb_get_guint8(tvb, 3));
1844 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1846 proto_tree_add_text(x25_tree, tvb, 3, 1,
1847 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 3));
1849 localoffset = x25_pkt_len;
1852 if(check_col(pinfo->cinfo, COL_INFO))
1853 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt VC:%d", vc);
1855 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1856 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1859 localoffset = x25_pkt_len;
1861 case X25_INTERRUPT_CONFIRMATION:
1862 if(check_col(pinfo->cinfo, COL_INFO))
1863 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt Conf. VC:%d", vc);
1865 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1866 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1867 X25_INTERRUPT_CONFIRMATION);
1869 localoffset = x25_pkt_len;
1871 case X25_RESET_REQUEST:
1875 short_name = "Reset ind.";
1876 long_name = "Reset indication";
1880 short_name = "Reset req.";
1881 long_name = "Reset request";
1885 short_name = "Reset ind./Reset req.";
1886 long_name = "Reset indication/Reset request";
1889 if(check_col(pinfo->cinfo, COL_INFO)) {
1890 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - Diag.:%d",
1891 short_name, vc, reset_code(tvb_get_guint8(tvb, 3)),
1892 (int)tvb_get_guint8(tvb, 4));
1894 x25_hash_add_proto_end(vc, pinfo->fd->num);
1896 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1897 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1898 X25_RESET_REQUEST, "Packet Type: %s", long_name);
1899 proto_tree_add_text(x25_tree, tvb, 3, 1,
1900 "Cause : %s", reset_code(tvb_get_guint8(tvb, 3)));
1901 proto_tree_add_text(x25_tree, tvb, 4, 1,
1902 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
1904 localoffset = x25_pkt_len;
1906 case X25_RESET_CONFIRMATION:
1907 if(check_col(pinfo->cinfo, COL_INFO))
1908 col_add_fstr(pinfo->cinfo, COL_INFO, "Reset conf. VC:%d", vc);
1910 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1911 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1912 X25_RESET_CONFIRMATION);
1914 localoffset = x25_pkt_len;
1916 case X25_RESTART_REQUEST:
1920 short_name = "Restart ind.";
1921 long_name = "Restart indication";
1925 short_name = "Restart req.";
1926 long_name = "Restart request";
1930 short_name = "Restart ind./Restart req.";
1931 long_name = "Restart indication/Restart request";
1934 if(check_col(pinfo->cinfo, COL_INFO)) {
1935 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s - Diag.:%d",
1937 restart_code(tvb_get_guint8(tvb, 3)),
1938 (int)tvb_get_guint8(tvb, 3));
1941 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1942 X25_RESTART_REQUEST, "Packet Type: %s", long_name);
1943 proto_tree_add_text(x25_tree, tvb, 3, 1,
1944 "Cause : %s", restart_code(tvb_get_guint8(tvb, 3)));
1945 proto_tree_add_text(x25_tree, tvb, 4, 1,
1946 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
1948 localoffset = x25_pkt_len;
1950 case X25_RESTART_CONFIRMATION:
1951 if(check_col(pinfo->cinfo, COL_INFO))
1952 col_set_str(pinfo->cinfo, COL_INFO, "Restart conf.");
1954 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1955 X25_RESTART_CONFIRMATION);
1956 localoffset = x25_pkt_len;
1958 case X25_REGISTRATION_REQUEST:
1959 if(check_col(pinfo->cinfo, COL_INFO))
1960 col_set_str(pinfo->cinfo, COL_INFO, "Registration req.");
1962 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1963 X25_REGISTRATION_REQUEST);
1965 if (localoffset < x25_pkt_len)
1966 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, TRUE);
1969 if (localoffset < x25_pkt_len)
1970 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
1971 "Registration length: %d",
1972 tvb_get_guint8(tvb, localoffset) & 0x7F);
1973 if (localoffset+1 < x25_pkt_len)
1974 proto_tree_add_text(x25_tree, tvb, localoffset+1,
1975 tvb_get_guint8(tvb, localoffset) & 0x7F,
1978 localoffset = tvb_reported_length(tvb);
1980 case X25_REGISTRATION_CONFIRMATION:
1981 if(check_col(pinfo->cinfo, COL_INFO))
1982 col_set_str(pinfo->cinfo, COL_INFO, "Registration conf.");
1984 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1985 X25_REGISTRATION_CONFIRMATION);
1986 proto_tree_add_text(x25_tree, tvb, 3, 1,
1987 "Cause: %s", registration_code(tvb_get_guint8(tvb, 3)));
1988 proto_tree_add_text(x25_tree, tvb, 4, 1,
1989 "Diagnostic: %s", registration_code(tvb_get_guint8(tvb, 4)));
1992 if (localoffset < x25_pkt_len)
1993 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, TRUE);
1996 if (localoffset < x25_pkt_len)
1997 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
1998 "Registration length: %d",
1999 tvb_get_guint8(tvb, localoffset) & 0x7F);
2000 if (localoffset+1 < x25_pkt_len)
2001 proto_tree_add_text(x25_tree, tvb, localoffset+1,
2002 tvb_get_guint8(tvb, localoffset) & 0x7F,
2005 localoffset = tvb_reported_length(tvb);
2009 if (PACKET_IS_DATA(pkt_type))
2011 if(check_col(pinfo->cinfo, COL_INFO)) {
2013 col_add_fstr(pinfo->cinfo, COL_INFO,
2014 "Data VC:%d P(S):%d P(R):%d %s", vc,
2015 (pkt_type >> 1) & 0x07,
2016 (pkt_type >> 5) & 0x07,
2017 ((pkt_type >> 4) & 0x01) ? " M" : "");
2019 col_add_fstr(pinfo->cinfo, COL_INFO,
2020 "Data VC:%d P(S):%d P(R):%d %s", vc,
2021 tvb_get_guint8(tvb, localoffset+1) >> 1,
2023 (tvb_get_guint8(tvb, localoffset+1) & 0x01) ? " M" : "");
2026 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2029 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2030 localoffset, 1, pkt_type);
2031 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod8, tvb,
2032 localoffset, 1, pkt_type);
2033 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod8, tvb,
2034 localoffset, 1, pkt_type);
2035 proto_tree_add_uint(x25_tree, hf_x25_type_data, tvb,
2036 localoffset, 1, pkt_type);
2039 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod128, tvb,
2040 localoffset, 1, pkt_type);
2041 proto_tree_add_uint(x25_tree, hf_x25_type_data, 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 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod128, tvb,
2048 tvb_get_guint8(tvb, localoffset+1));
2051 localoffset += (modulo == 8) ? 1 : 2;
2054 switch (PACKET_TYPE_FC(pkt_type))
2057 if(check_col(pinfo->cinfo, COL_INFO)) {
2059 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2060 vc, (pkt_type >> 5) & 0x07);
2062 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2063 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2066 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2069 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2070 localoffset, 1, pkt_type);
2071 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2072 localoffset, 1, X25_RR);
2075 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2076 localoffset, 1, X25_RR);
2077 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2078 localoffset+1, 1, FALSE);
2084 if(check_col(pinfo->cinfo, COL_INFO)) {
2086 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2087 vc, (pkt_type >> 5) & 0x07);
2089 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2090 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2093 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2096 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2097 localoffset, 1, pkt_type);
2098 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2099 localoffset, 1, X25_RNR);
2102 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2103 localoffset, 1, X25_RNR);
2104 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2105 localoffset+1, 1, FALSE);
2111 if(check_col(pinfo->cinfo, COL_INFO)) {
2113 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2114 vc, (pkt_type >> 5) & 0x07);
2116 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2117 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2120 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2123 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2124 localoffset, 1, pkt_type);
2125 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2126 localoffset, 1, X25_REJ);
2129 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2130 localoffset, 1, X25_REJ);
2131 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2132 localoffset+1, 1, FALSE);
2136 localoffset += (modulo == 8) ? 1 : 2;
2139 if (localoffset >= tvb_reported_length(tvb)) return;
2141 next_tvb = tvb_new_subset(tvb, localoffset, -1, -1);
2143 saved_private_data = pinfo->private_data;
2144 pinfo->private_data = &q_bit_set;
2146 /* See if there's already a dissector for this circuit. */
2147 if (try_circuit_dissector(CT_X25, vc, pinfo->fd->num, next_tvb, pinfo,
2149 pinfo->private_data = saved_private_data;
2150 return; /* found it and dissected it */
2153 /* Did the user suggest QLLC/SNA? */
2154 if (payload_is_qllc_sna) {
2155 /* Yes - dissect it as QLLC/SNA. */
2156 if (!pinfo->fd->flags.visited)
2157 x25_hash_add_proto_start(vc, pinfo->fd->num, qllc_handle);
2158 call_dissector(qllc_handle, next_tvb, pinfo, tree);
2159 pinfo->private_data = saved_private_data;
2163 /* If the Call Req. has not been captured, let's look at the first
2164 byte of the payload to see if this looks like IP or CLNP. */
2165 switch (tvb_get_guint8(tvb, localoffset)) {
2168 /* Looks like an IP header */
2169 if (!pinfo->fd->flags.visited)
2170 x25_hash_add_proto_start(vc, pinfo->fd->num, ip_handle);
2171 call_dissector(ip_handle, next_tvb, pinfo, tree);
2172 pinfo->private_data = saved_private_data;
2175 case NLPID_ISO8473_CLNP:
2176 if (!pinfo->fd->flags.visited)
2177 x25_hash_add_proto_start(vc, pinfo->fd->num, clnp_handle);
2178 call_dissector(clnp_handle, next_tvb, pinfo, tree);
2179 pinfo->private_data = saved_private_data;
2183 /* Try the heuristic dissectors. */
2184 if (dissector_try_heuristic(x25_heur_subdissector_list, next_tvb, pinfo,
2186 pinfo->private_data = saved_private_data;
2190 /* All else failed; dissect it as raw data */
2191 call_dissector(data_handle, next_tvb, pinfo, tree);
2192 pinfo->private_data = saved_private_data;
2196 * X.25 dissector for use when "pinfo->pseudo_header" points to a
2197 * "struct x25_phdr".
2200 dissect_x25_dir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2202 dissect_x25_common(tvb, pinfo, tree,
2203 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? X25_FROM_DCE :
2208 * X.25 dissector for use when "pinfo->pseudo_header" doesn't point to a
2209 * "struct x25_phdr".
2212 dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2215 * We don't know if this packet is DTE->DCE or DCE->DCE.
2217 dissect_x25_common(tvb, pinfo, tree, X25_UNKNOWN);
2221 proto_register_x25(void)
2223 static hf_register_info hf[] = {
2225 { "GFI", "x.25.gfi", FT_UINT16, BASE_DEC, NULL, 0xF000,
2226 "General format identifier", HFILL }},
2228 { "A Bit", "x.25.a", FT_BOOLEAN, 16, NULL, 0x8000,
2229 "Address Bit", HFILL }},
2231 { "Q Bit", "x.25.q", FT_BOOLEAN, 16, NULL, 0x8000,
2232 "Qualifier Bit", HFILL }},
2234 { "D Bit", "x.25.d", FT_BOOLEAN, 16, NULL, 0x4000,
2235 "Delivery Confirmation Bit", HFILL }},
2237 { "Modulo", "x.25.mod", FT_UINT16, BASE_DEC, VALS(vals_modulo), 0x3000,
2238 "Specifies whether the frame is modulo 8 or 128", HFILL }},
2240 { "Logical Channel", "x.25.lcn", FT_UINT16, BASE_DEC, NULL, 0x0FFF,
2241 "Logical Channel Number", HFILL }},
2243 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x0,
2244 "Packet Type", HFILL }},
2245 { &hf_x25_type_fc_mod8,
2246 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x1F,
2247 "Packet Type", HFILL }},
2248 { &hf_x25_type_data,
2249 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x01,
2250 "Packet Type", HFILL }},
2252 { "P(R)", "x.25.p_r", FT_UINT8, BASE_DEC, NULL, 0xE0,
2253 "Packet Receive Sequence Number", HFILL }},
2254 { &hf_x25_p_r_mod128,
2255 { "P(R)", "x.25.p_r", FT_UINT8, BASE_DEC, NULL, 0xFE,
2256 "Packet Receive Sequence Number", HFILL }},
2257 { &hf_x25_mbit_mod8,
2258 { "M Bit", "x.25.m", FT_BOOLEAN, 8, TFS(&m_bit_tfs), 0x10,
2259 "More Bit", HFILL }},
2260 { &hf_x25_mbit_mod128,
2261 { "M Bit", "x.25.m", FT_BOOLEAN, 8, TFS(&m_bit_tfs), 0x01,
2262 "More Bit", HFILL }},
2264 { "P(S)", "x.25.p_s", FT_UINT8, BASE_DEC, NULL, 0x0E,
2265 "Packet Send Sequence Number", HFILL }},
2266 { &hf_x25_p_s_mod128,
2267 { "P(S)", "x.25.p_s", FT_UINT8, BASE_DEC, NULL, 0xFE,
2268 "Packet Send Sequence Number", HFILL }},
2270 static gint *ett[] = {
2274 &ett_x25_fac_unknown,
2276 &ett_x25_fac_reverse,
2277 &ett_x25_fac_throughput,
2279 &ett_x25_fac_called_modif,
2280 &ett_x25_fac_cug_outgoing_acc,
2281 &ett_x25_fac_throughput_min,
2282 &ett_x25_fac_express_data,
2283 &ett_x25_fac_bilateral_cug,
2284 &ett_x25_fac_packet_size,
2285 &ett_x25_fac_window_size,
2286 &ett_x25_fac_rpoa_selection,
2287 &ett_x25_fac_transit_delay,
2288 &ett_x25_fac_call_transfer,
2289 &ett_x25_fac_called_addr_ext,
2290 &ett_x25_fac_ete_transit_delay,
2291 &ett_x25_fac_calling_addr_ext,
2292 &ett_x25_fac_call_deflect,
2293 &ett_x25_fac_priority,
2296 module_t *x25_module;
2298 proto_x25 = proto_register_protocol ("X.25", "X.25", "x.25");
2299 proto_register_field_array (proto_x25, hf, array_length(hf));
2300 proto_register_subtree_array(ett, array_length(ett));
2302 x25_subdissector_table = register_dissector_table("x.25.spi",
2303 "X.25 secondary protocol identifier", FT_UINT8, BASE_HEX);
2304 register_heur_dissector_list("x.25", &x25_heur_subdissector_list);
2306 register_dissector("x.25_dir", dissect_x25_dir, proto_x25);
2307 register_dissector("x.25", dissect_x25, proto_x25);
2310 x25_module = prefs_register_protocol(proto_x25, NULL);
2311 prefs_register_obsolete_preference(x25_module, "non_q_bit_is_sna");
2312 prefs_register_bool_preference(x25_module, "payload_is_qllc_sna",
2313 "Default to QLLC/SNA",
2314 "If CALL REQUEST not seen or didn't specify protocol, dissect as QLLC/SNA",
2315 &payload_is_qllc_sna);
2319 proto_reg_handoff_x25(void)
2321 dissector_handle_t x25_handle;
2324 * Get handles for various dissectors.
2326 ip_handle = find_dissector("ip");
2327 clnp_handle = find_dissector("clnp");
2328 ositp_handle = find_dissector("ositp");
2329 qllc_handle = find_dissector("qllc");
2330 data_handle = find_dissector("data");
2332 x25_handle = find_dissector("x.25");
2333 dissector_add("llc.dsap", SAP_X25, x25_handle);