2 * Routines for X.25 packet disassembly
3 * Olivier Abad <oabad@noos.fr>
5 * $Id: packet-x25.c,v 1.80 2003/03/01 10:02:35 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) & 0x3F;
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) & 0x3F;
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 = NULL;
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)"));
1719 if (!pinfo->fd->flags.visited) {
1721 * Is there a dissector handle for this SPI?
1722 * If so, assign it to this virtual circuit.
1724 dissect = dissector_get_port_handle(x25_subdissector_table, spi);
1725 if (dissect != NULL)
1726 x25_hash_add_proto_start(vc, pinfo->fd->num, dissect);
1730 * If there's only one octet of user data, it's just
1731 * an NLPID; don't try to dissect it.
1733 if (localoffset + 1 <= tvb_reported_length(tvb))
1737 * There's more than one octet of user data, so we'll
1738 * dissect it; for some protocols, the NLPID is considered
1739 * to be part of the PDU, so, for those cases, we don't
1740 * skip past it. For other protocols, we skip the NLPID.
1744 case NLPID_ISO8473_CLNP:
1745 case NLPID_ISO9542_ESIS:
1746 case NLPID_ISO10589_ISIS:
1747 case NLPID_ISO10747_IDRP:
1750 * The NLPID is part of the PDU. Don't skip it.
1751 * But if it's all there is to the PDU, don't
1752 * bother dissecting it.
1756 case NLPID_SPI_X_29:
1758 * The first 4 bytes of the call user data are
1759 * the SPI plus 3 reserved bytes; they are not
1760 * part of the data to be dissected as X.29 data.
1767 * The NLPID isn't part of the PDU - skip it.
1768 * If that means there's nothing to dissect
1775 case X25_CALL_ACCEPTED:
1779 short_name = "Call conn.";
1780 long_name = "Call connected";
1784 short_name = "Call acc.";
1785 long_name = "Call accepted";
1789 short_name = "Call conn./Call acc.";
1790 long_name = "Call connected/Call accepted";
1793 if(check_col(pinfo->cinfo, COL_INFO))
1794 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
1796 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1797 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1798 X25_CALL_ACCEPTED, "Packet Type: %s", long_name);
1801 if (localoffset < x25_pkt_len) { /* calling/called addresses */
1803 x25_toa(x25_tree, &localoffset, tvb, pinfo);
1805 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
1808 if (localoffset < x25_pkt_len) /* facilities */
1809 dump_facilities(x25_tree, &localoffset, tvb);
1811 case X25_CLEAR_REQUEST:
1815 short_name = "Clear ind.";
1816 long_name = "Clear indication";
1820 short_name = "Clear req.";
1821 long_name = "Clear request";
1825 short_name = "Clear ind./Clear req.";
1826 long_name = "Clear indication/Clear request";
1829 if(check_col(pinfo->cinfo, COL_INFO)) {
1830 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - %s", short_name,
1831 vc, clear_code(tvb_get_guint8(tvb, 3)),
1832 clear_diag(tvb_get_guint8(tvb, 4)));
1834 x25_hash_add_proto_end(vc, pinfo->fd->num);
1836 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1837 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb,
1838 localoffset+2, 1, X25_CLEAR_REQUEST, "Packet Type: %s",
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->cinfo, COL_INFO))
1849 col_add_fstr(pinfo->cinfo, 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 */
1859 x25_toa(x25_tree, &localoffset, tvb, pinfo);
1861 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
1864 if (localoffset < tvb_reported_length(tvb)) /* facilities */
1865 dump_facilities(x25_tree, &localoffset, tvb);
1867 case X25_DIAGNOSTIC:
1868 if(check_col(pinfo->cinfo, COL_INFO)) {
1869 col_add_fstr(pinfo->cinfo, COL_INFO, "Diag. %d",
1870 (int)tvb_get_guint8(tvb, 3));
1873 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1875 proto_tree_add_text(x25_tree, tvb, 3, 1,
1876 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 3));
1878 localoffset = x25_pkt_len;
1881 if(check_col(pinfo->cinfo, COL_INFO))
1882 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt VC:%d", vc);
1884 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1885 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1888 localoffset = x25_pkt_len;
1890 case X25_INTERRUPT_CONFIRMATION:
1891 if(check_col(pinfo->cinfo, COL_INFO))
1892 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt Conf. VC:%d", vc);
1894 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1895 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1896 X25_INTERRUPT_CONFIRMATION);
1898 localoffset = x25_pkt_len;
1900 case X25_RESET_REQUEST:
1904 short_name = "Reset ind.";
1905 long_name = "Reset indication";
1909 short_name = "Reset req.";
1910 long_name = "Reset request";
1914 short_name = "Reset ind./Reset req.";
1915 long_name = "Reset indication/Reset request";
1918 if(check_col(pinfo->cinfo, COL_INFO)) {
1919 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - Diag.:%d",
1920 short_name, vc, reset_code(tvb_get_guint8(tvb, 3)),
1921 (int)tvb_get_guint8(tvb, 4));
1923 x25_hash_add_proto_end(vc, pinfo->fd->num);
1925 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1926 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1927 X25_RESET_REQUEST, "Packet Type: %s", long_name);
1928 proto_tree_add_text(x25_tree, tvb, 3, 1,
1929 "Cause : %s", reset_code(tvb_get_guint8(tvb, 3)));
1930 proto_tree_add_text(x25_tree, tvb, 4, 1,
1931 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
1933 localoffset = x25_pkt_len;
1935 case X25_RESET_CONFIRMATION:
1936 if(check_col(pinfo->cinfo, COL_INFO))
1937 col_add_fstr(pinfo->cinfo, COL_INFO, "Reset conf. VC:%d", vc);
1939 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1940 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1941 X25_RESET_CONFIRMATION);
1943 localoffset = x25_pkt_len;
1945 case X25_RESTART_REQUEST:
1949 short_name = "Restart ind.";
1950 long_name = "Restart indication";
1954 short_name = "Restart req.";
1955 long_name = "Restart request";
1959 short_name = "Restart ind./Restart req.";
1960 long_name = "Restart indication/Restart request";
1963 if(check_col(pinfo->cinfo, COL_INFO)) {
1964 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s - Diag.:%d",
1966 restart_code(tvb_get_guint8(tvb, 3)),
1967 (int)tvb_get_guint8(tvb, 3));
1970 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1971 X25_RESTART_REQUEST, "Packet Type: %s", long_name);
1972 proto_tree_add_text(x25_tree, tvb, 3, 1,
1973 "Cause : %s", restart_code(tvb_get_guint8(tvb, 3)));
1974 proto_tree_add_text(x25_tree, tvb, 4, 1,
1975 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
1977 localoffset = x25_pkt_len;
1979 case X25_RESTART_CONFIRMATION:
1980 if(check_col(pinfo->cinfo, COL_INFO))
1981 col_set_str(pinfo->cinfo, COL_INFO, "Restart conf.");
1983 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1984 X25_RESTART_CONFIRMATION);
1985 localoffset = x25_pkt_len;
1987 case X25_REGISTRATION_REQUEST:
1988 if(check_col(pinfo->cinfo, COL_INFO))
1989 col_set_str(pinfo->cinfo, COL_INFO, "Registration req.");
1991 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1992 X25_REGISTRATION_REQUEST);
1994 if (localoffset < x25_pkt_len)
1995 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, TRUE);
1998 if (localoffset < x25_pkt_len)
1999 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
2000 "Registration length: %d",
2001 tvb_get_guint8(tvb, localoffset) & 0x7F);
2002 if (localoffset+1 < x25_pkt_len)
2003 proto_tree_add_text(x25_tree, tvb, localoffset+1,
2004 tvb_get_guint8(tvb, localoffset) & 0x7F,
2007 localoffset = tvb_reported_length(tvb);
2009 case X25_REGISTRATION_CONFIRMATION:
2010 if(check_col(pinfo->cinfo, COL_INFO))
2011 col_set_str(pinfo->cinfo, COL_INFO, "Registration conf.");
2013 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2014 X25_REGISTRATION_CONFIRMATION);
2015 proto_tree_add_text(x25_tree, tvb, 3, 1,
2016 "Cause: %s", registration_code(tvb_get_guint8(tvb, 3)));
2017 proto_tree_add_text(x25_tree, tvb, 4, 1,
2018 "Diagnostic: %s", registration_code(tvb_get_guint8(tvb, 4)));
2021 if (localoffset < x25_pkt_len)
2022 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, TRUE);
2025 if (localoffset < x25_pkt_len)
2026 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
2027 "Registration length: %d",
2028 tvb_get_guint8(tvb, localoffset) & 0x7F);
2029 if (localoffset+1 < x25_pkt_len)
2030 proto_tree_add_text(x25_tree, tvb, localoffset+1,
2031 tvb_get_guint8(tvb, localoffset) & 0x7F,
2034 localoffset = tvb_reported_length(tvb);
2038 if (PACKET_IS_DATA(pkt_type))
2040 if(check_col(pinfo->cinfo, COL_INFO)) {
2042 col_add_fstr(pinfo->cinfo, COL_INFO,
2043 "Data VC:%d P(S):%d P(R):%d %s", vc,
2044 (pkt_type >> 1) & 0x07,
2045 (pkt_type >> 5) & 0x07,
2046 ((pkt_type >> 4) & 0x01) ? " M" : "");
2048 col_add_fstr(pinfo->cinfo, COL_INFO,
2049 "Data VC:%d P(S):%d P(R):%d %s", vc,
2050 tvb_get_guint8(tvb, localoffset+1) >> 1,
2052 (tvb_get_guint8(tvb, localoffset+1) & 0x01) ? " M" : "");
2055 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2058 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2059 localoffset, 1, pkt_type);
2060 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod8, tvb,
2061 localoffset, 1, pkt_type);
2062 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod8, tvb,
2063 localoffset, 1, pkt_type);
2064 proto_tree_add_uint(x25_tree, hf_x25_type_data, tvb,
2065 localoffset, 1, pkt_type);
2068 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod128, tvb,
2069 localoffset, 1, pkt_type);
2070 proto_tree_add_uint(x25_tree, hf_x25_type_data, tvb,
2071 localoffset, 1, pkt_type);
2072 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod128, tvb,
2074 tvb_get_guint8(tvb, localoffset+1));
2075 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod128, tvb,
2077 tvb_get_guint8(tvb, localoffset+1));
2080 localoffset += (modulo == 8) ? 1 : 2;
2083 switch (PACKET_TYPE_FC(pkt_type))
2086 if(check_col(pinfo->cinfo, COL_INFO)) {
2088 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2089 vc, (pkt_type >> 5) & 0x07);
2091 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2092 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2095 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2098 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2099 localoffset, 1, pkt_type);
2100 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2101 localoffset, 1, X25_RR);
2104 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2105 localoffset, 1, X25_RR);
2106 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2107 localoffset+1, 1, FALSE);
2113 if(check_col(pinfo->cinfo, COL_INFO)) {
2115 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2116 vc, (pkt_type >> 5) & 0x07);
2118 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2119 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2122 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2125 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2126 localoffset, 1, pkt_type);
2127 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2128 localoffset, 1, X25_RNR);
2131 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2132 localoffset, 1, X25_RNR);
2133 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2134 localoffset+1, 1, FALSE);
2140 if(check_col(pinfo->cinfo, COL_INFO)) {
2142 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2143 vc, (pkt_type >> 5) & 0x07);
2145 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2146 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2149 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2152 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2153 localoffset, 1, pkt_type);
2154 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2155 localoffset, 1, X25_REJ);
2158 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2159 localoffset, 1, X25_REJ);
2160 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2161 localoffset+1, 1, FALSE);
2165 localoffset += (modulo == 8) ? 1 : 2;
2168 if (localoffset >= tvb_reported_length(tvb)) return;
2170 next_tvb = tvb_new_subset(tvb, localoffset, -1, -1);
2172 saved_private_data = pinfo->private_data;
2173 pinfo->private_data = &q_bit_set;
2175 /* See if there's already a dissector for this circuit. */
2176 if (try_circuit_dissector(CT_X25, vc, pinfo->fd->num, next_tvb, pinfo,
2178 pinfo->private_data = saved_private_data;
2179 return; /* found it and dissected it */
2182 /* Did the user suggest QLLC/SNA? */
2183 if (payload_is_qllc_sna) {
2184 /* Yes - dissect it as QLLC/SNA. */
2185 if (!pinfo->fd->flags.visited)
2186 x25_hash_add_proto_start(vc, pinfo->fd->num, qllc_handle);
2187 call_dissector(qllc_handle, next_tvb, pinfo, tree);
2188 pinfo->private_data = saved_private_data;
2192 /* If the Call Req. has not been captured, let's look at the first
2193 byte of the payload to see if this looks like IP or CLNP. */
2194 switch (tvb_get_guint8(tvb, localoffset)) {
2197 /* Looks like an IP header */
2198 if (!pinfo->fd->flags.visited)
2199 x25_hash_add_proto_start(vc, pinfo->fd->num, ip_handle);
2200 call_dissector(ip_handle, next_tvb, pinfo, tree);
2201 pinfo->private_data = saved_private_data;
2204 case NLPID_ISO8473_CLNP:
2205 if (!pinfo->fd->flags.visited)
2206 x25_hash_add_proto_start(vc, pinfo->fd->num, clnp_handle);
2207 call_dissector(clnp_handle, next_tvb, pinfo, tree);
2208 pinfo->private_data = saved_private_data;
2212 /* Try the heuristic dissectors. */
2213 if (dissector_try_heuristic(x25_heur_subdissector_list, next_tvb, pinfo,
2215 pinfo->private_data = saved_private_data;
2219 /* All else failed; dissect it as raw data */
2220 call_dissector(data_handle, next_tvb, pinfo, tree);
2221 pinfo->private_data = saved_private_data;
2225 * X.25 dissector for use when "pinfo->pseudo_header" points to a
2226 * "struct x25_phdr".
2229 dissect_x25_dir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2231 dissect_x25_common(tvb, pinfo, tree,
2232 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? X25_FROM_DCE :
2237 * X.25 dissector for use when "pinfo->pseudo_header" doesn't point to a
2238 * "struct x25_phdr".
2241 dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2244 * We don't know if this packet is DTE->DCE or DCE->DCE.
2246 dissect_x25_common(tvb, pinfo, tree, X25_UNKNOWN);
2250 proto_register_x25(void)
2252 static hf_register_info hf[] = {
2254 { "GFI", "x.25.gfi", FT_UINT16, BASE_DEC, NULL, 0xF000,
2255 "General format identifier", HFILL }},
2257 { "A Bit", "x.25.a", FT_BOOLEAN, 16, NULL, 0x8000,
2258 "Address Bit", HFILL }},
2260 { "Q Bit", "x.25.q", FT_BOOLEAN, 16, NULL, 0x8000,
2261 "Qualifier Bit", HFILL }},
2263 { "D Bit", "x.25.d", FT_BOOLEAN, 16, NULL, 0x4000,
2264 "Delivery Confirmation Bit", HFILL }},
2266 { "Modulo", "x.25.mod", FT_UINT16, BASE_DEC, VALS(vals_modulo), 0x3000,
2267 "Specifies whether the frame is modulo 8 or 128", HFILL }},
2269 { "Logical Channel", "x.25.lcn", FT_UINT16, BASE_DEC, NULL, 0x0FFF,
2270 "Logical Channel Number", HFILL }},
2272 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x0,
2273 "Packet Type", HFILL }},
2274 { &hf_x25_type_fc_mod8,
2275 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x1F,
2276 "Packet Type", HFILL }},
2277 { &hf_x25_type_data,
2278 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x01,
2279 "Packet Type", HFILL }},
2281 { "P(R)", "x.25.p_r", FT_UINT8, BASE_DEC, NULL, 0xE0,
2282 "Packet Receive Sequence Number", HFILL }},
2283 { &hf_x25_p_r_mod128,
2284 { "P(R)", "x.25.p_r", FT_UINT8, BASE_DEC, NULL, 0xFE,
2285 "Packet Receive Sequence Number", HFILL }},
2286 { &hf_x25_mbit_mod8,
2287 { "M Bit", "x.25.m", FT_BOOLEAN, 8, TFS(&m_bit_tfs), 0x10,
2288 "More Bit", HFILL }},
2289 { &hf_x25_mbit_mod128,
2290 { "M Bit", "x.25.m", FT_BOOLEAN, 8, TFS(&m_bit_tfs), 0x01,
2291 "More Bit", HFILL }},
2293 { "P(S)", "x.25.p_s", FT_UINT8, BASE_DEC, NULL, 0x0E,
2294 "Packet Send Sequence Number", HFILL }},
2295 { &hf_x25_p_s_mod128,
2296 { "P(S)", "x.25.p_s", FT_UINT8, BASE_DEC, NULL, 0xFE,
2297 "Packet Send Sequence Number", HFILL }},
2299 static gint *ett[] = {
2303 &ett_x25_fac_unknown,
2305 &ett_x25_fac_reverse,
2306 &ett_x25_fac_throughput,
2308 &ett_x25_fac_called_modif,
2309 &ett_x25_fac_cug_outgoing_acc,
2310 &ett_x25_fac_throughput_min,
2311 &ett_x25_fac_express_data,
2312 &ett_x25_fac_bilateral_cug,
2313 &ett_x25_fac_packet_size,
2314 &ett_x25_fac_window_size,
2315 &ett_x25_fac_rpoa_selection,
2316 &ett_x25_fac_transit_delay,
2317 &ett_x25_fac_call_transfer,
2318 &ett_x25_fac_called_addr_ext,
2319 &ett_x25_fac_ete_transit_delay,
2320 &ett_x25_fac_calling_addr_ext,
2321 &ett_x25_fac_call_deflect,
2322 &ett_x25_fac_priority,
2325 module_t *x25_module;
2327 proto_x25 = proto_register_protocol ("X.25", "X.25", "x.25");
2328 proto_register_field_array (proto_x25, hf, array_length(hf));
2329 proto_register_subtree_array(ett, array_length(ett));
2331 x25_subdissector_table = register_dissector_table("x.25.spi",
2332 "X.25 secondary protocol identifier", FT_UINT8, BASE_HEX);
2333 register_heur_dissector_list("x.25", &x25_heur_subdissector_list);
2335 register_dissector("x.25_dir", dissect_x25_dir, proto_x25);
2336 register_dissector("x.25", dissect_x25, proto_x25);
2339 x25_module = prefs_register_protocol(proto_x25, NULL);
2340 prefs_register_obsolete_preference(x25_module, "non_q_bit_is_sna");
2341 prefs_register_bool_preference(x25_module, "payload_is_qllc_sna",
2342 "Default to QLLC/SNA",
2343 "If CALL REQUEST not seen or didn't specify protocol, dissect as QLLC/SNA",
2344 &payload_is_qllc_sna);
2348 proto_reg_handoff_x25(void)
2350 dissector_handle_t x25_handle;
2353 * Get handles for various dissectors.
2355 ip_handle = find_dissector("ip");
2356 clnp_handle = find_dissector("clnp");
2357 ositp_handle = find_dissector("ositp");
2358 qllc_handle = find_dissector("qllc");
2359 data_handle = find_dissector("data");
2361 x25_handle = find_dissector("x.25");
2362 dissector_add("llc.dsap", SAP_X25, x25_handle);