2 * Routines for X.25 packet disassembly
3 * Olivier Abad <oabad@noos.fr>
5 * $Id: packet-x25.c,v 1.85 2003/10/07 18:19:59 oabad 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>
37 #include "reassemble.h"
40 #include "x264_prt_id.h"
43 * Direction of packet.
46 X25_FROM_DCE, /* DCE->DTE */
47 X25_FROM_DTE, /* DTE->DCE */
48 X25_UNKNOWN /* direction unknown */
52 * 0 for data packets, 1 for non-data packets.
54 #define X25_NONDATA_BIT 0x01
56 #define X25_CALL_REQUEST 0x0B
57 #define X25_CALL_ACCEPTED 0x0F
58 #define X25_CLEAR_REQUEST 0x13
59 #define X25_CLEAR_CONFIRMATION 0x17
60 #define X25_INTERRUPT 0x23
61 #define X25_INTERRUPT_CONFIRMATION 0x27
62 #define X25_RESET_REQUEST 0x1B
63 #define X25_RESET_CONFIRMATION 0x1F
64 #define X25_RESTART_REQUEST 0xFB
65 #define X25_RESTART_CONFIRMATION 0xFF
66 #define X25_REGISTRATION_REQUEST 0xF3
67 #define X25_REGISTRATION_CONFIRMATION 0xF7
68 #define X25_DIAGNOSTIC 0xF1
74 #define PACKET_IS_DATA(type) (!(type & X25_NONDATA_BIT))
75 #define PACKET_TYPE_FC(type) (type & 0x1F)
77 #define X25_MBIT_MOD8 0x10
78 #define X25_MBIT_MOD128 0x01
80 #define X25_ABIT 0x8000
82 #define X25_QBIT 0x8000
83 #define X25_DBIT 0x4000
85 #define X25_FAC_CLASS_MASK 0xC0
87 #define X25_FAC_CLASS_A 0x00
88 #define X25_FAC_CLASS_B 0x40
89 #define X25_FAC_CLASS_C 0x80
90 #define X25_FAC_CLASS_D 0xC0
92 #define X25_FAC_COMP_MARK 0x00
93 #define X25_FAC_REVERSE 0x01
94 #define X25_FAC_THROUGHPUT 0x02
95 #define X25_FAC_CUG 0x03
96 #define X25_FAC_CALLED_MODIF 0x08
97 #define X25_FAC_CUG_OUTGOING_ACC 0x09
98 #define X25_FAC_THROUGHPUT_MIN 0x0A
99 #define X25_FAC_EXPRESS_DATA 0x0B
100 #define X25_FAC_BILATERAL_CUG 0x41
101 #define X25_FAC_PACKET_SIZE 0x42
102 #define X25_FAC_WINDOW_SIZE 0x43
103 #define X25_FAC_RPOA_SELECTION 0x44
104 #define X25_FAC_TRANSIT_DELAY 0x49
105 #define X25_FAC_CALL_TRANSFER 0xC3
106 #define X25_FAC_CALLED_ADDR_EXT 0xC9
107 #define X25_FAC_ETE_TRANSIT_DELAY 0xCA
108 #define X25_FAC_CALLING_ADDR_EXT 0xCB
109 #define X25_FAC_CALL_DEFLECT 0xD1
110 #define X25_FAC_PRIORITY 0xD2
112 static int proto_x25 = -1;
113 static int hf_x25_gfi = -1;
114 static int hf_x25_abit = -1;
115 static int hf_x25_qbit = -1;
116 static int hf_x25_dbit = -1;
117 static int hf_x25_mod = -1;
118 static int hf_x25_lcn = -1;
119 static int hf_x25_type = -1;
120 static int hf_x25_type_fc_mod8 = -1;
121 static int hf_x25_type_data = -1;
122 static int hf_x25_p_r_mod8 = -1;
123 static int hf_x25_p_r_mod128 = -1;
124 static int hf_x25_mbit_mod8 = -1;
125 static int hf_x25_mbit_mod128 = -1;
126 static int hf_x25_p_s_mod8 = -1;
127 static int hf_x25_p_s_mod128 = -1;
129 static gint ett_x25 = -1;
130 static gint ett_x25_gfi = -1;
131 static gint ett_x25_fac = -1;
132 static gint ett_x25_fac_unknown = -1;
133 static gint ett_x25_fac_mark = -1;
134 static gint ett_x25_fac_reverse = -1;
135 static gint ett_x25_fac_throughput = -1;
136 static gint ett_x25_fac_cug = -1;
137 static gint ett_x25_fac_called_modif = -1;
138 static gint ett_x25_fac_cug_outgoing_acc = -1;
139 static gint ett_x25_fac_throughput_min = -1;
140 static gint ett_x25_fac_express_data = -1;
141 static gint ett_x25_fac_bilateral_cug = -1;
142 static gint ett_x25_fac_packet_size = -1;
143 static gint ett_x25_fac_window_size = -1;
144 static gint ett_x25_fac_rpoa_selection = -1;
145 static gint ett_x25_fac_transit_delay = -1;
146 static gint ett_x25_fac_call_transfer = -1;
147 static gint ett_x25_fac_called_addr_ext = -1;
148 static gint ett_x25_fac_ete_transit_delay = -1;
149 static gint ett_x25_fac_calling_addr_ext = -1;
150 static gint ett_x25_fac_call_deflect = -1;
151 static gint ett_x25_fac_priority = -1;
152 static gint ett_x25_user_data = -1;
154 static gint ett_x25_segment = -1;
155 static gint ett_x25_segments = -1;
156 static gint hf_x25_segments = -1;
157 static gint hf_x25_segment = -1;
158 static gint hf_x25_segment_overlap = -1;
159 static gint hf_x25_segment_overlap_conflict = -1;
160 static gint hf_x25_segment_multiple_tails = -1;
161 static gint hf_x25_segment_too_long_segment = -1;
162 static gint hf_x25_segment_error = -1;
164 static const value_string vals_modulo[] = {
170 static const value_string vals_x25_type[] = {
171 { X25_CALL_REQUEST, "Call" },
172 { X25_CALL_ACCEPTED, "Call Accepted" },
173 { X25_CLEAR_REQUEST, "Clear" },
174 { X25_CLEAR_CONFIRMATION, "Clear Confirmation" },
175 { X25_INTERRUPT, "Interrupt" },
176 { X25_INTERRUPT_CONFIRMATION, "Interrupt Confirmation" },
177 { X25_RESET_REQUEST, "Reset" },
178 { X25_RESET_CONFIRMATION, "Reset Confirmation" },
179 { X25_RESTART_REQUEST, "Restart" },
180 { X25_RESTART_CONFIRMATION, "Restart Confirmation" },
181 { X25_REGISTRATION_REQUEST, "Registration" },
182 { X25_REGISTRATION_CONFIRMATION, "Registration Confirmation" },
183 { X25_DIAGNOSTIC, "Diagnostic" },
187 { X25_DATA, "Data" },
191 static struct true_false_string m_bit_tfs = {
196 static const fragment_items x25_frag_items = {
201 &hf_x25_segment_overlap,
202 &hf_x25_segment_overlap_conflict,
203 &hf_x25_segment_multiple_tails,
204 &hf_x25_segment_too_long_segment,
205 &hf_x25_segment_error,
210 static dissector_handle_t ip_handle;
211 static dissector_handle_t clnp_handle;
212 static dissector_handle_t ositp_handle;
213 static dissector_handle_t qllc_handle;
214 static dissector_handle_t data_handle;
217 static gboolean payload_is_qllc_sna = FALSE;
218 static gboolean reassemble_x25 = FALSE;
220 /* Reassembly of X.25 */
222 static GHashTable *x25_segment_table = NULL;
223 static GHashTable *x25_reassembled_table = NULL;
225 static dissector_table_t x25_subdissector_table;
226 static heur_dissector_list_t x25_heur_subdissector_list;
229 x25_hash_add_proto_start(guint16 vc, guint32 frame, dissector_handle_t dissect)
234 * Is there already a circuit with this VC number?
236 circuit = find_circuit(CT_X25, vc, frame);
237 if (circuit != NULL) {
239 * Yes - close it, as we're creating a new one.
241 close_circuit(circuit, frame - 1);
245 * Set up a new circuit.
247 circuit = circuit_new(CT_X25, vc, frame);
252 circuit_set_dissector(circuit, dissect);
256 x25_hash_add_proto_end(guint16 vc, guint32 frame)
261 * Try to find the circuit.
263 circuit = find_circuit(CT_X25, vc, frame);
266 * If we succeeded, close it.
269 close_circuit(circuit, frame);
272 static char *clear_code(unsigned char code)
274 static char buffer[25];
276 if (code == 0x00 || (code & 0x80) == 0x80)
277 return "DTE Originated";
279 return "Number Busy";
281 return "Invalid Facility Requested";
283 return "Network Congestion";
285 return "Out Of Order";
287 return "Access Barred";
289 return "Not Obtainable";
291 return "Remote Procedure Error";
293 return "Local Procedure Error";
295 return "RPOA Out Of Order";
297 return "Reverse Charging Acceptance Not Subscribed";
299 return "Incompatible Destination";
301 return "Fast Select Acceptance Not Subscribed";
303 return "Destination Absent";
305 sprintf(buffer, "Unknown %02X", code);
310 static char *clear_diag(unsigned char code)
312 static char buffer[25];
315 return "No additional information";
317 return "Invalid P(S)";
319 return "Invalid P(R)";
321 return "Packet type invalid";
323 return "Packet type invalid for state r1";
325 return "Packet type invalid for state r2";
327 return "Packet type invalid for state r3";
329 return "Packet type invalid for state p1";
331 return "Packet type invalid for state p2";
333 return "Packet type invalid for state p3";
335 return "Packet type invalid for state p4";
337 return "Packet type invalid for state p5";
339 return "Packet type invalid for state p6";
341 return "Packet type invalid for state p7";
343 return "Packet type invalid for state d1";
345 return "Packet type invalid for state d2";
347 return "Packet type invalid for state d3";
349 return "Packet not allowed";
351 return "Unidentifiable packet";
353 return "Call on one-way logical channel";
355 return "Invalid packet type on a PVC";
357 return "Packet on unassigned LC";
359 return "Reject not subscribed to";
361 return "Packet too short";
363 return "Packet too long";
365 return "Invalid general format identifier";
367 return "Restart/registration packet with nonzero bits";
369 return "Packet type not compatible with facility";
371 return "Unauthorised interrupt confirmation";
373 return "Unauthorised interrupt";
375 return "Unauthorised reject";
377 return "Time expired";
379 return "Time expired for incoming call";
381 return "Time expired for clear indication";
383 return "Time expired for reset indication";
385 return "Time expired for restart indication";
387 return "Time expired for call deflection";
389 return "Call set-up/clearing or registration pb.";
391 return "Facility/registration code not allowed";
393 return "Facility parameter not allowed";
395 return "Invalid called DTE address";
397 return "Invalid calling DTE address";
399 return "Invalid facility/registration length";
401 return "Incoming call barred";
403 return "No logical channel available";
405 return "Call collision";
407 return "Duplicate facility requested";
409 return "Non zero address length";
411 return "Non zero facility length";
413 return "Facility not provided when expected";
415 return "Invalid CCITT-specified DTE facility";
417 return "Max. nb of call redir/defl. exceeded";
419 return "Miscellaneous";
421 return "Improper cause code from DTE";
423 return "Not aligned octet";
425 return "Inconsistent Q bit setting";
427 return "NUI problem";
429 return "International problem";
431 return "Remote network problem";
433 return "International protocol problem";
435 return "International link out of order";
437 return "International link busy";
439 return "Transit network facility problem";
441 return "Remote network facility problem";
443 return "International routing problem";
445 return "Temporary routing problem";
447 return "Unknown called DNIC";
449 return "Maintenance action";
451 return "Timer expired or retransmission count surpassed";
453 return "Timer expired or retransmission count surpassed for INTERRUPT";
455 return "Timer expired or retransmission count surpassed for DATA "
456 "packet transmission";
458 return "Timer expired or retransmission count surpassed for REJECT";
460 return "DTE-specific signals";
462 return "DTE operational";
464 return "DTE not operational";
466 return "DTE resource constraint";
468 return "Fast select not subscribed";
470 return "Invalid partially full DATA packet";
472 return "D-bit procedure not supported";
474 return "Registration/Cancellation confirmed";
476 return "OSI network service problem";
478 return "Disconnection (transient condition)";
480 return "Disconnection (permanent condition)";
482 return "Connection rejection - reason unspecified (transient "
485 return "Connection rejection - reason unspecified (permanent "
488 return "Connection rejection - quality of service not available "
489 "transient condition)";
491 return "Connection rejection - quality of service not available "
492 "permanent condition)";
494 return "Connection rejection - NSAP unreachable (transient condition)";
496 return "Connection rejection - NSAP unreachable (permanent condition)";
498 return "reset - reason unspecified";
500 return "reset - congestion";
502 return "Connection rejection - NSAP address unknown (permanent "
505 return "Higher layer initiated";
507 return "Disconnection - normal";
509 return "Disconnection - abnormal";
511 return "Disconnection - incompatible information in user data";
513 return "Connection rejection - reason unspecified (transient "
516 return "Connection rejection - reason unspecified (permanent "
519 return "Connection rejection - quality of service not available "
520 "(transient condition)";
522 return "Connection rejection - quality of service not available "
523 "(permanent condition)";
525 return "Connection rejection - incompatible information in user data";
527 return "Connection rejection - unrecognizable protocol indentifier "
530 return "Reset - user resynchronization";
532 sprintf(buffer, "Unknown %d", code);
537 static char *reset_code(unsigned char code)
539 static char buffer[25];
541 if (code == 0x00 || (code & 0x80) == 0x80)
542 return "DTE Originated";
544 return "Out of order";
546 return "Remote Procedure Error";
548 return "Local Procedure Error";
550 return "Network Congestion";
552 return "Remote DTE operational";
554 return "Network operational";
556 return "Incompatible Destination";
558 return "Network out of order";
560 sprintf(buffer, "Unknown %02X", code);
565 static char *restart_code(unsigned char code)
567 static char buffer[25];
569 if (code == 0x00 || (code & 0x80) == 0x80)
570 return "DTE Originated";
572 return "Local Procedure Error";
574 return "Network Congestion";
576 return "Network Operational";
578 return "Registration/cancellation confirmed";
580 sprintf(buffer, "Unknown %02X", code);
585 static char *registration_code(unsigned char code)
587 static char buffer[25];
590 return "Invalid facility request";
592 return "Network congestion";
594 return "Local procedure error";
596 return "Registration/cancellation confirmed";
598 sprintf(buffer, "Unknown %02X", code);
604 dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb)
606 guint8 fac, byte1, byte2, byte3;
607 guint32 len; /* facilities length */
609 proto_tree *fac_tree = 0;
610 proto_tree *fac_subtree;
612 len = tvb_get_guint8(tvb, *offset);
614 ti = proto_tree_add_text(tree, tvb, *offset, len + 1,
616 fac_tree = proto_item_add_subtree(ti, ett_x25_fac);
617 proto_tree_add_text(fac_tree, tvb, *offset, 1,
618 "Facilities length: %d", len);
623 fac = tvb_get_guint8(tvb, *offset);
624 switch(fac & X25_FAC_CLASS_MASK) {
625 case X25_FAC_CLASS_A:
627 case X25_FAC_COMP_MARK:
629 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
630 "Code : 00 (Marker)");
631 switch (tvb_get_guint8(tvb, *offset + 1)) {
634 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
635 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
636 "Parameter : 00 (Network complementary "
637 "services - calling DTE)");
642 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
643 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
644 "Parameter : FF (Network complementary "
645 "services - called DTE)");
650 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
651 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
652 "Parameter : 0F (DTE complementary "
658 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
659 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
660 "Parameter : %02X (Unknown marker)",
661 tvb_get_guint8(tvb, *offset+1));
666 case X25_FAC_REVERSE:
668 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
669 "(Reverse charging / Fast select)", fac);
670 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_reverse);
671 byte1 = tvb_get_guint8(tvb, *offset + 1);
672 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
673 "Parameter : %02X", byte1);
675 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
676 "11.. .... = Fast select with restriction");
677 else if (byte1 & 0x80)
678 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
679 "10.. .... = Fast select - no restriction");
681 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
682 "00.. .... = Fast select not requested");
683 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
684 decode_boolean_bitfield(byte1, 0x01, 1*8,
685 "Reverse charging requested",
686 "Reverse charging not requested"));
689 case X25_FAC_THROUGHPUT:
693 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
694 "(Throughput class negociation)", fac);
695 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_throughput);
696 byte1 = tvb_get_guint8(tvb, *offset + 1);
708 sprintf(tmpbuf, "From the called DTE : %%u (%d bps)",
709 75*(1<<((byte1 >> 4)-3)));
712 sprintf(tmpbuf, "From the called DTE : %%u (48000 bps)");
715 sprintf(tmpbuf, "From the called DTE : %%u (64000 bps)");
718 sprintf(tmpbuf, "From the called DTE : %%u (Reserved)");
720 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
721 decode_numeric_bitfield(byte1, 0xF0, 1*8, tmpbuf));
722 switch (byte1 & 0x0F)
733 sprintf(tmpbuf, "From the calling DTE : %%u (%d bps)",
734 75*(1<<((byte1 & 0x0F)-3)));
737 sprintf(tmpbuf, "From the calling DTE : %%u (48000 bps)");
740 sprintf(tmpbuf, "From the calling DTE : %%u (64000 bps)");
743 sprintf(tmpbuf, "From the calling DTE : %%u (Reserved)");
745 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
746 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
751 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
752 "(Closed user group selection)", fac);
753 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_cug);
754 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
755 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
758 case X25_FAC_CALLED_MODIF:
760 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
761 "(Called address modified)", fac);
762 fac_subtree = proto_item_add_subtree(ti,
763 ett_x25_fac_called_modif);
764 proto_tree_add_text(fac_tree, tvb, *offset+1, 1,
765 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
768 case X25_FAC_CUG_OUTGOING_ACC:
770 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
771 "(Closed user group with outgoing access selection)",
773 fac_subtree = proto_item_add_subtree(ti,
774 ett_x25_fac_cug_outgoing_acc);
775 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
776 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
779 case X25_FAC_THROUGHPUT_MIN:
781 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
782 "(Minimum throughput class)", fac);
783 fac_subtree = proto_item_add_subtree(ti,
784 ett_x25_fac_throughput_min);
785 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
786 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
789 case X25_FAC_EXPRESS_DATA:
791 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
792 "(Negociation of express data)", fac);
793 fac_subtree = proto_item_add_subtree(ti,
794 ett_x25_fac_express_data);
795 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
796 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
801 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
802 "Code : %02X (Unknown class A)", fac);
803 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
804 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
805 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
812 case X25_FAC_CLASS_B:
814 case X25_FAC_BILATERAL_CUG:
816 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
817 "(Bilateral closed user group selection)", fac);
818 fac_subtree = proto_item_add_subtree(ti,
819 ett_x25_fac_bilateral_cug);
820 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
821 "Bilateral CUG: %04X",
822 tvb_get_ntohs(tvb, *offset+1));
825 case X25_FAC_PACKET_SIZE:
830 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
831 "(Packet size)", fac);
832 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_packet_size);
833 byte1 = tvb_get_guint8(tvb, *offset + 1);
837 sprintf(tmpbuf, "From the called DTE : %%u (16)");
840 sprintf(tmpbuf, "From the called DTE : %%u (32)");
843 sprintf(tmpbuf, "From the called DTE : %%u (64)");
846 sprintf(tmpbuf, "From the called DTE : %%u (128)");
849 sprintf(tmpbuf, "From the called DTE : %%u (256)");
852 sprintf(tmpbuf, "From the called DTE : %%u (512)");
855 sprintf(tmpbuf, "From the called DTE : %%u (1024)");
858 sprintf(tmpbuf, "From the called DTE : %%u (2048)");
861 sprintf(tmpbuf, "From the called DTE : %%u (4096)");
864 sprintf(tmpbuf, "From the called DTE : %%u (Unknown)");
867 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
868 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
870 byte2 = tvb_get_guint8(tvb, *offset + 1);
874 sprintf(tmpbuf, "From the calling DTE : %%u (16)");
877 sprintf(tmpbuf, "From the calling DTE : %%u (32)");
880 sprintf(tmpbuf, "From the calling DTE : %%u (64)");
883 sprintf(tmpbuf, "From the calling DTE : %%u (128)");
886 sprintf(tmpbuf, "From the calling DTE : %%u (256)");
889 sprintf(tmpbuf, "From the calling DTE : %%u (512)");
892 sprintf(tmpbuf, "From the calling DTE : %%u (1024)");
895 sprintf(tmpbuf, "From the calling DTE : %%u (2048)");
898 sprintf(tmpbuf, "From the calling DTE : %%u (4096)");
901 sprintf(tmpbuf, "From the calling DTE : %%u (Unknown)");
904 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
905 decode_numeric_bitfield(byte2, 0x0F, 1*8, tmpbuf));
908 case X25_FAC_WINDOW_SIZE:
910 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
911 "(Window size)", fac);
912 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_window_size);
913 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
914 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+1),
915 0x7F, 1*8, "From the called DTE: %u"));
916 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
917 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+2),
918 0x7F, 1*8, "From the calling DTE: %u"));
921 case X25_FAC_RPOA_SELECTION:
923 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
924 "(RPOA selection)", fac);
925 fac_subtree = proto_item_add_subtree(ti,
926 ett_x25_fac_rpoa_selection);
927 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
928 "Data network identification code : %04X",
929 tvb_get_ntohs(tvb, *offset+1));
932 case X25_FAC_TRANSIT_DELAY:
934 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
935 "(Transit delay selection and indication)", fac);
936 fac_subtree = proto_item_add_subtree(ti,
937 ett_x25_fac_transit_delay);
938 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
939 "Transit delay: %d ms",
940 tvb_get_ntohs(tvb, *offset+1));
945 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
946 "Code : %02X (Unknown class B)", fac);
947 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
948 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
949 "Parameter %04X", tvb_get_ntohs(tvb, *offset+1));
956 case X25_FAC_CLASS_C:
958 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
959 "Code : %02X (Unknown class C)", fac);
960 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
961 proto_tree_add_text(fac_subtree, tvb, *offset+1, 3,
963 tvb_get_ntoh24(tvb, *offset+1));
968 case X25_FAC_CLASS_D:
970 case X25_FAC_CALL_TRANSFER:
975 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
976 "(Call redirection or deflection notification)", fac);
977 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_call_transfer);
978 byte1 = tvb_get_guint8(tvb, *offset+1);
979 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
980 "Length : %u", byte1);
981 byte2 = tvb_get_guint8(tvb, *offset+2);
982 if ((byte2 & 0xC0) == 0xC0) {
983 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
984 "Reason : call deflection by the originally "
985 "called DTE address");
990 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
991 "Reason : originally called DTE busy");
994 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
995 "Reason : call dist. within a hunt group");
998 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
999 "Reason : originally called DTE out of order");
1002 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1003 "Reason : systematic call redirection");
1006 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1007 "Reason : unknown");
1011 byte3 = tvb_get_guint8(tvb, *offset+3);
1012 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1013 "Number of semi-octets in DTE address : %u",
1015 for (i = 0; i < byte3; i++) {
1017 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1019 /* if > 9, convert to the right hexadecimal letter */
1020 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1022 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1024 /* if > 9, convert to the right hexadecimal letter */
1025 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1029 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1030 "DTE address : %s", tmpbuf);
1033 case X25_FAC_CALLING_ADDR_EXT:
1038 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1039 "(Calling address extension)", fac);
1040 fac_subtree = proto_item_add_subtree(ti,
1041 ett_x25_fac_calling_addr_ext);
1042 byte1 = tvb_get_guint8(tvb, *offset+1);
1043 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1044 "Length : %u", byte1);
1045 byte2 = tvb_get_guint8(tvb, *offset+2) & 0x3F;
1046 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1047 "Number of semi-octets in DTE address : %u", byte2);
1048 for (i = 0; i < byte2; i++) {
1050 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1052 /* if > 9, convert to the right hexadecimal letter */
1053 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1055 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1057 /* if > 9, convert to the right hexadecimal letter */
1058 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1062 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1063 "DTE address : %s", tmpbuf);
1066 case X25_FAC_CALLED_ADDR_EXT:
1071 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1072 "(Called address extension)", fac);
1073 fac_subtree = proto_item_add_subtree(ti,
1074 ett_x25_fac_called_addr_ext);
1075 byte1 = tvb_get_guint8(tvb, *offset+1);
1076 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1077 "Length : %u", byte1);
1078 byte2 = tvb_get_guint8(tvb, *offset+2) & 0x3F;
1079 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1080 "Number of semi-octets in DTE address : %u", byte2);
1081 for (i = 0; i < byte2; i++) {
1083 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1085 /* if > 9, convert to the right hexadecimal letter */
1086 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1088 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1090 /* if > 9, convert to the right hexadecimal letter */
1091 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1095 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1096 "DTE address : %s", tmpbuf);
1099 case X25_FAC_ETE_TRANSIT_DELAY:
1101 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1102 "(End to end transit delay)", fac);
1103 fac_subtree = proto_item_add_subtree(ti,
1104 ett_x25_fac_ete_transit_delay);
1105 byte1 = tvb_get_guint8(tvb, *offset+1);
1106 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1107 "Length : %u", byte1);
1108 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1111 case X25_FAC_CALL_DEFLECT:
1116 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1117 "(Call deflection selection)", fac);
1118 fac_subtree = proto_item_add_subtree(ti,
1119 ett_x25_fac_call_deflect);
1120 byte1 = tvb_get_guint8(tvb, *offset+1);
1121 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1122 "Length : %u", byte1);
1123 byte2 = tvb_get_guint8(tvb, *offset+2);
1124 if ((byte2 & 0xC0) == 0xC0)
1125 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1126 "Reason : call DTE originated");
1128 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1129 "Reason : unknown");
1130 byte3 = tvb_get_guint8(tvb, *offset+3);
1131 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1132 "Number of semi-octets in the alternative DTE address : %u",
1134 for (i = 0; i < byte3; i++) {
1136 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1138 /* if > 9, convert to the right hexadecimal letter */
1139 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1141 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1143 /* if > 9, convert to the right hexadecimal letter */
1144 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1148 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1149 "Alternative DTE address : %s", tmpbuf);
1152 case X25_FAC_PRIORITY:
1154 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1155 "Code : %02X (Priority)", fac);
1156 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_priority);
1157 byte1 = tvb_get_guint8(tvb, *offset+1);
1158 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1159 "Length : %u", byte1);
1160 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1165 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1166 "Code : %02X (Unknown class D)", fac);
1167 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1168 byte1 = tvb_get_guint8(tvb, *offset+1);
1169 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1170 "Length : %u", byte1);
1171 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1174 byte1 = tvb_get_guint8(tvb, *offset+1);
1175 (*offset) += byte1+2;
1183 x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1184 packet_info *pinfo, gboolean is_registration)
1188 char addr1[16], addr2[16];
1189 char *first, *second;
1193 byte = tvb_get_guint8(tvb, *offset);
1194 len1 = (byte >> 0) & 0x0F;
1195 len2 = (byte >> 4) & 0x0F;
1198 proto_tree_add_text(tree, tvb, *offset, 1,
1199 decode_numeric_bitfield(byte, 0xF0, 1*8,
1201 "DTE address length : %u" :
1202 "Calling address length : %u"));
1203 proto_tree_add_text(tree, tvb, *offset, 1,
1204 decode_numeric_bitfield(byte, 0x0F, 1*8,
1206 "DCE address length : %u" :
1207 "Called address length : %u"));
1211 localoffset = *offset;
1212 byte = tvb_get_guint8(tvb, localoffset);
1216 for (i = 0; i < (len1 + len2); i++) {
1219 *first++ = ((byte >> 0) & 0x0F) + '0';
1221 byte = tvb_get_guint8(tvb, localoffset);
1223 *first++ = ((byte >> 4) & 0x0F) + '0';
1227 *second++ = ((byte >> 0) & 0x0F) + '0';
1229 byte = tvb_get_guint8(tvb, localoffset);
1231 *second++ = ((byte >> 4) & 0x0F) + '0';
1240 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1241 col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1);
1243 proto_tree_add_text(tree, tvb, *offset,
1246 "DCE address : %s" :
1247 "Called address : %s",
1251 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1252 col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2);
1254 proto_tree_add_text(tree, tvb, *offset + len1/2,
1255 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1257 "DTE address : %s" :
1258 "Calling address : %s",
1261 (*offset) += ((len1 + len2 + 1) / 2);
1265 x25_toa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1270 char addr1[256], addr2[256];
1271 char *first, *second;
1275 len1 = tvb_get_guint8(tvb, *offset);
1277 proto_tree_add_text(tree, tvb, *offset, 1,
1278 "Called address length : %u",
1283 len2 = tvb_get_guint8(tvb, *offset);
1285 proto_tree_add_text(tree, tvb, *offset, 1,
1286 "Calling address length : %u",
1291 localoffset = *offset;
1292 byte = tvb_get_guint8(tvb, localoffset);
1295 * XXX - the first two half-octets of the address are the TOA and
1296 * NPI; process them as such and, if the TOA says an address is
1297 * an alternative address, process it correctly (i.e., not as a
1298 * sequence of half-octets containing digit values).
1302 for (i = 0; i < (len1 + len2); i++) {
1305 *first++ = ((byte >> 0) & 0x0F) + '0';
1307 byte = tvb_get_guint8(tvb, localoffset);
1309 *first++ = ((byte >> 4) & 0x0F) + '0';
1313 *second++ = ((byte >> 0) & 0x0F) + '0';
1315 byte = tvb_get_guint8(tvb, localoffset);
1317 *second++ = ((byte >> 4) & 0x0F) + '0';
1326 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1327 col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1);
1329 proto_tree_add_text(tree, tvb, *offset,
1331 "Called address : %s",
1335 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1336 col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2);
1338 proto_tree_add_text(tree, tvb, *offset + len1/2,
1339 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1340 "Calling address : %s",
1343 (*offset) += ((len1 + len2 + 1) / 2);
1347 get_x25_pkt_len(tvbuff_t *tvb)
1349 guint length, called_len, calling_len, dte_len, dce_len;
1350 guint8 byte2, bytex;
1352 byte2 = tvb_get_guint8(tvb, 2);
1355 case X25_CALL_REQUEST:
1356 bytex = tvb_get_guint8(tvb, 3);
1357 called_len = (bytex >> 0) & 0x0F;
1358 calling_len = (bytex >> 4) & 0x0F;
1359 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1360 if (length < tvb_reported_length(tvb))
1361 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1363 return MIN(tvb_reported_length(tvb),length);
1365 case X25_CALL_ACCEPTED:
1366 /* The calling/called address length byte (following the packet type)
1367 * is not mandatory, so we must check the packet length before trying
1369 if (tvb_reported_length(tvb) == 3)
1371 bytex = tvb_get_guint8(tvb, 3);
1372 called_len = (bytex >> 0) & 0x0F;
1373 calling_len = (bytex >> 4) & 0x0F;
1374 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1375 if (length < tvb_reported_length(tvb))
1376 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1378 return MIN(tvb_reported_length(tvb),length);
1380 case X25_CLEAR_REQUEST:
1381 case X25_RESET_REQUEST:
1382 case X25_RESTART_REQUEST:
1383 return MIN(tvb_reported_length(tvb),5);
1385 case X25_DIAGNOSTIC:
1386 return MIN(tvb_reported_length(tvb),4);
1388 case X25_CLEAR_CONFIRMATION:
1390 case X25_INTERRUPT_CONFIRMATION:
1391 case X25_RESET_CONFIRMATION:
1392 case X25_RESTART_CONFIRMATION:
1393 return MIN(tvb_reported_length(tvb),3);
1395 case X25_REGISTRATION_REQUEST:
1396 bytex = tvb_get_guint8(tvb, 3);
1397 dce_len = (bytex >> 0) & 0x0F;
1398 dte_len = (bytex >> 4) & 0x0F;
1399 length = 4 + (dte_len + dce_len + 1) / 2; /* addr */
1400 if (length < tvb_reported_length(tvb))
1401 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1403 return MIN(tvb_reported_length(tvb),length);
1405 case X25_REGISTRATION_CONFIRMATION:
1406 bytex = tvb_get_guint8(tvb, 5);
1407 dce_len = (bytex >> 0) & 0x0F;
1408 dte_len = (bytex >> 4) & 0x0F;
1409 length = 6 + (dte_len + dce_len + 1) / 2; /* addr */
1410 if (length < tvb_reported_length(tvb))
1411 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1413 return MIN(tvb_reported_length(tvb),length);
1416 if (PACKET_IS_DATA(byte2))
1417 return MIN(tvb_reported_length(tvb),3);
1419 switch (PACKET_TYPE_FC(byte2))
1422 return MIN(tvb_reported_length(tvb),3);
1425 return MIN(tvb_reported_length(tvb),3);
1428 return MIN(tvb_reported_length(tvb),3);
1434 static const value_string prt_id_vals[] = {
1435 {PRT_ID_ISO_8073, "ISO 8073 COTP"},
1436 {PRT_ID_ISO_8602, "ISO 8602 CLTP"},
1437 {PRT_ID_ISO_10736_ISO_8073, "ISO 10736 in conjunction with ISO 8073 COTP"},
1438 {PRT_ID_ISO_10736_ISO_8602, "ISO 10736 in conjunction with ISO 8602 CLTP"},
1442 static const value_string sharing_strategy_vals[] = {
1443 {0x00, "No sharing"},
1448 dissect_x25_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1449 x25_dir_t dir, gboolean side)
1451 proto_tree *x25_tree=0, *gfi_tree=0, *userdata_tree=0;
1453 guint localoffset=0;
1457 dissector_handle_t dissect = NULL;
1458 gboolean toa; /* TOA/NPI address format */
1461 char *short_name = NULL, *long_name = NULL;
1462 tvbuff_t *next_tvb = NULL;
1463 gboolean q_bit_set = FALSE;
1467 void *saved_private_data;
1468 fragment_data *fd_head;
1470 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1471 col_set_str(pinfo->cinfo, COL_PROTOCOL, "X.25");
1473 bytes0_1 = tvb_get_ntohs(tvb, 0);
1475 modulo = ((bytes0_1 & 0x2000) ? 128 : 8);
1476 vc = (int)(bytes0_1 & 0x0FFF);
1478 pinfo->ctype = CT_X25;
1479 pinfo->circuit_id = vc;
1481 if (bytes0_1 & X25_ABIT) toa = TRUE;
1484 x25_pkt_len = get_x25_pkt_len(tvb);
1485 if (x25_pkt_len < 3) /* packet too short */
1487 if (check_col(pinfo->cinfo, COL_INFO))
1488 col_set_str(pinfo->cinfo, COL_INFO, "Invalid/short X.25 packet");
1490 proto_tree_add_protocol_format(tree, proto_x25, tvb, 0, -1,
1491 "Invalid/short X.25 packet");
1495 pkt_type = tvb_get_guint8(tvb, 2);
1496 if (PACKET_IS_DATA(pkt_type)) {
1497 if (bytes0_1 & X25_QBIT)
1502 ti = proto_tree_add_item(tree, proto_x25, tvb, 0, x25_pkt_len, FALSE);
1503 x25_tree = proto_item_add_subtree(ti, ett_x25);
1504 ti = proto_tree_add_item(x25_tree, hf_x25_gfi, tvb, 0, 2, FALSE);
1505 gfi_tree = proto_item_add_subtree(ti, ett_x25_gfi);
1507 if (PACKET_IS_DATA(pkt_type)) {
1508 proto_tree_add_boolean(gfi_tree, hf_x25_qbit, tvb, 0, 2,
1511 else if (pkt_type == X25_CALL_REQUEST ||
1512 pkt_type == X25_CALL_ACCEPTED ||
1513 pkt_type == X25_CLEAR_REQUEST ||
1514 pkt_type == X25_CLEAR_CONFIRMATION) {
1515 proto_tree_add_boolean(gfi_tree, hf_x25_abit, tvb, 0, 2,
1519 if (pkt_type == X25_CALL_REQUEST || pkt_type == X25_CALL_ACCEPTED ||
1520 PACKET_IS_DATA(pkt_type)) {
1521 proto_tree_add_boolean(gfi_tree, hf_x25_dbit, tvb, 0, 2,
1524 proto_tree_add_uint(gfi_tree, hf_x25_mod, tvb, 0, 2, bytes0_1);
1528 case X25_CALL_REQUEST:
1532 short_name = "Inc. call";
1533 long_name = "Incoming call";
1537 short_name = "Call req.";
1538 long_name = "Call request";
1542 short_name = "Inc. call/Call req.";
1543 long_name = "Incoming call/Call request";
1546 if (check_col(pinfo->cinfo, COL_INFO))
1547 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
1549 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb,
1551 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1552 X25_CALL_REQUEST, "Packet Type: %s", long_name);
1555 if (localoffset < x25_pkt_len) { /* calling/called addresses */
1557 x25_toa(x25_tree, &localoffset, tvb, pinfo);
1559 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
1562 if (localoffset < x25_pkt_len) /* facilities */
1563 dump_facilities(x25_tree, &localoffset, tvb);
1565 if (localoffset < tvb_reported_length(tvb)) /* user data */
1572 ti = proto_tree_add_text(x25_tree, tvb, localoffset, -1,
1574 userdata_tree = proto_item_add_subtree(ti, ett_x25_user_data);
1577 /* X.263/ISO 9577 says that:
1579 When CLNP or ESIS are run over X.25, the SPI
1580 is 0x81 or 0x82, respectively; those are the
1581 NLPIDs for those protocol.
1583 When X.224/ISO 8073 COTP is run over X.25, and
1584 when ISO 11570 explicit identification is being
1585 used, the first octet of the user data field is
1586 a TPDU length field, and the rest is "as defined
1587 in ITU-T Rec. X.225 | ISO/IEC 8073, Annex B,
1588 or ITU-T Rec. X.264 and ISO/IEC 11570".
1590 When X.264/ISO 11570 default identification is
1591 being used, there is no user data field in the
1592 CALL REQUEST packet. This is for X.225/ISO 8073
1595 It also says that SPI values from 0x03 through 0x3f are
1596 reserved and are in use by X.224/ISO 8073 Annex B and
1597 X.264/ISO 11570. The note says that those values are
1598 not NLPIDs, they're "used by the respective higher layer
1599 protocol" and "not used for higher layer protocol
1600 identification". I infer from this and from what
1601 X.264/ISO 11570 says that this means that values in those
1602 range are valid values for the first octet of an
1603 X.224/ISO 8073 packet or for X.264/ISO 11570.
1605 Annex B of X.225/ISO 8073 mentions some additional TPDU
1606 types that can be put in what I presume is the user
1607 data of connect requests. It says that:
1609 The sending transport entity shall:
1611 a) either not transmit any TPDU in the NS-user data
1612 parameter of the N-CONNECT request primitive; or
1614 b) transmit the UN-TPDU (see ITU-T Rec. X.264 and
1615 ISO/IEC 11570) followed by the NCM-TPDU in the
1616 NS-user data parameter of the N-CONNECT request
1619 I don't know if this means that the user data field
1620 will contain a UN TPDU followed by an NCM TPDU or not.
1622 X.264/ISO 11570 says that:
1624 When default identification is being used,
1625 X.225/ISO 8073 COTP is identified. No user data
1626 is sent in the network-layer connection request.
1628 When explicit identification is being used,
1629 the user data is a UN TPDU ("Use of network
1630 connection TPDU"), which specifies the transport
1631 protocol to use over this network connection.
1632 It also says that the length of a UN TPDU shall
1633 not exceed 32 octets, i.e. shall not exceed 0x20;
1634 it says this is "due to the desire not to conflict
1635 with the protocol identifier field carried by X.25
1636 CALL REQUEST/INCOMING CALL packets", and says that
1637 field has values specified in X.244. X.244 has been
1638 superseded by X.263/ISO 9577, so that presumably
1639 means the goal is to allow a UN TPDU's length
1640 field to be distinguished from an NLPID, allowing
1641 you to tell whether X.264/ISO 11570 explicit
1642 identification is being used or an NLPID is
1643 being used as the SPI.
1645 I read this as meaning that, if the ISO mechanisms are
1646 used to identify the protocol being carried over X.25:
1648 if there's no user data in the CALL REQUEST/
1649 INCOMING CALL packet, it's COTP;
1651 if there is user data, then:
1653 if the first octet is less than or equal to
1654 32, it might be a UN TPDU, and that identifies
1655 the transport protocol being used, and
1656 it may be followed by more data, such
1657 as a COTP NCM TPDU if it's COTP;
1659 if the first octet is greater than 32, it's
1660 an NLPID, *not* a TPDU length, and the
1661 stuff following it is *not* a TPDU.
1663 Figure A.2 of X.263/ISO 9577 seems to say that the
1664 first octet of the user data is a TPDU length field,
1665 in the range 0x03 through 0x82, and says they are
1666 for X.225/ISO 8073 Annex B or X.264/ISO 11570.
1668 However, X.264/ISO 11570 seems to imply that the length
1669 field would be that of a UN TPDU, which must be less
1670 than or equal to 0x20, and X.225/ISO 8073 Annex B seems
1671 to indicate that the user data must begin with
1672 an X.264/ISO 11570 UN TPDU, so I'd say that A.2 should
1673 have said "in the range 0x03 through 0x20", instead
1674 (the length value doesn't include the length field,
1675 and the minimum UN TPDU has length, type, PRT-ID,
1676 and SHARE, so that's 3 bytes without the length). */
1677 spi = tvb_get_guint8(tvb, localoffset);
1678 if (spi > 32 || spi < 3) {
1679 /* First octet is > 32, or < 3, so the user data isn't an
1680 X.264/ISO 11570 UN TPDU */
1683 /* First octet is >= 3 and <= 32, so the user data *might*
1684 be an X.264/ISO 11570 UN TPDU. Check whether we have
1685 enough data to see if it is. */
1686 if (tvb_bytes_exist(tvb, localoffset+1, 1)) {
1687 /* We do; check whether the second octet is 1. */
1688 if (tvb_get_guint8(tvb, localoffset+1) == 0x01) {
1689 /* Yes, the second byte is 1, so it looks like
1693 /* No, the second byte is not 1, so it's not a
1698 /* We can't see the second byte of the putative UN
1699 TPDU, so we don't know if that's what it is. */
1703 if (is_x_264 == -1) {
1705 * We don't know what it is; just skip it.
1707 localoffset = tvb_length(tvb);
1708 } else if (is_x_264) {
1709 /* It looks like an X.264 UN TPDU, so show it as such. */
1710 if (userdata_tree) {
1711 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1712 "X.264 length indicator: %u",
1714 proto_tree_add_text(userdata_tree, tvb, localoffset+1, 1,
1715 "X.264 UN TPDU identifier: 0x%02X",
1716 tvb_get_guint8(tvb, localoffset+1));
1718 prt_id = tvb_get_guint8(tvb, localoffset+2);
1719 if (userdata_tree) {
1720 proto_tree_add_text(userdata_tree, tvb, localoffset+2, 1,
1721 "X.264 protocol identifier: %s",
1722 val_to_str(prt_id, prt_id_vals,
1723 "Unknown (0x%02X)"));
1724 proto_tree_add_text(userdata_tree, tvb, localoffset+3, 1,
1725 "X.264 sharing strategy: %s",
1726 val_to_str(tvb_get_guint8(tvb, localoffset+3),
1727 sharing_strategy_vals, "Unknown (0x%02X)"));
1730 /* XXX - dissect the variable part? */
1732 /* The length doesn't include the length octet itself. */
1733 localoffset += spi + 1;
1737 case PRT_ID_ISO_8073:
1739 if (!pinfo->fd->flags.visited)
1740 x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
1741 /* XXX - dissect the rest of the user data as COTP?
1742 That needs support for NCM TPDUs, etc. */
1745 case PRT_ID_ISO_8602:
1747 if (!pinfo->fd->flags.visited)
1748 x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
1751 } else if (is_x_264 == 0) {
1752 /* It doesn't look like a UN TPDU, so compare the first
1753 octet of the CALL REQUEST packet with various X.263/
1754 ISO 9577 NLPIDs, as per Annex A of X.263/ISO 9577. */
1756 if (userdata_tree) {
1757 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1758 "X.263 secondary protocol ID: %s",
1759 val_to_str(spi, nlpid_vals, "Unknown (0x%02x)"));
1762 if (!pinfo->fd->flags.visited) {
1764 * Is there a dissector handle for this SPI?
1765 * If so, assign it to this virtual circuit.
1767 dissect = dissector_get_port_handle(x25_subdissector_table, spi);
1768 if (dissect != NULL)
1769 x25_hash_add_proto_start(vc, pinfo->fd->num, dissect);
1773 * If there's only one octet of user data, it's just
1774 * an NLPID; don't try to dissect it.
1776 if (localoffset + 1 == tvb_reported_length(tvb))
1780 * There's more than one octet of user data, so we'll
1781 * dissect it; for some protocols, the NLPID is considered
1782 * to be part of the PDU, so, for those cases, we don't
1783 * skip past it. For other protocols, we skip the NLPID.
1787 case NLPID_ISO8473_CLNP:
1788 case NLPID_ISO9542_ESIS:
1789 case NLPID_ISO10589_ISIS:
1790 case NLPID_ISO10747_IDRP:
1793 * The NLPID is part of the PDU. Don't skip it.
1794 * But if it's all there is to the PDU, don't
1795 * bother dissecting it.
1799 case NLPID_SPI_X_29:
1801 * The first 4 bytes of the call user data are
1802 * the SPI plus 3 reserved bytes; they are not
1803 * part of the data to be dissected as X.29 data.
1810 * The NLPID isn't part of the PDU - skip it.
1811 * If that means there's nothing to dissect
1818 case X25_CALL_ACCEPTED:
1822 short_name = "Call conn.";
1823 long_name = "Call connected";
1827 short_name = "Call acc.";
1828 long_name = "Call accepted";
1832 short_name = "Call conn./Call acc.";
1833 long_name = "Call connected/Call accepted";
1836 if(check_col(pinfo->cinfo, COL_INFO))
1837 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
1839 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1840 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1841 X25_CALL_ACCEPTED, "Packet Type: %s", long_name);
1844 if (localoffset < x25_pkt_len) { /* calling/called addresses */
1846 x25_toa(x25_tree, &localoffset, tvb, pinfo);
1848 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
1851 if (localoffset < x25_pkt_len) /* facilities */
1852 dump_facilities(x25_tree, &localoffset, tvb);
1854 case X25_CLEAR_REQUEST:
1858 short_name = "Clear ind.";
1859 long_name = "Clear indication";
1863 short_name = "Clear req.";
1864 long_name = "Clear request";
1868 short_name = "Clear ind./Clear req.";
1869 long_name = "Clear indication/Clear request";
1872 if(check_col(pinfo->cinfo, COL_INFO)) {
1873 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - %s", short_name,
1874 vc, clear_code(tvb_get_guint8(tvb, 3)),
1875 clear_diag(tvb_get_guint8(tvb, 4)));
1877 x25_hash_add_proto_end(vc, pinfo->fd->num);
1879 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1880 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb,
1881 localoffset+2, 1, X25_CLEAR_REQUEST, "Packet Type: %s",
1883 proto_tree_add_text(x25_tree, tvb, 3, 1,
1884 "Cause : %s", clear_code(tvb_get_guint8(tvb, 3)));
1885 proto_tree_add_text(x25_tree, tvb, 4, 1,
1886 "Diagnostic : %s", clear_diag(tvb_get_guint8(tvb, 4)));
1888 localoffset = x25_pkt_len;
1890 case X25_CLEAR_CONFIRMATION:
1891 if(check_col(pinfo->cinfo, COL_INFO))
1892 col_add_fstr(pinfo->cinfo, COL_INFO, "Clear 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_CLEAR_CONFIRMATION);
1898 localoffset = x25_pkt_len;
1900 if (localoffset < tvb_reported_length(tvb)) { /* extended clear conf format */
1902 x25_toa(x25_tree, &localoffset, tvb, pinfo);
1904 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
1907 if (localoffset < tvb_reported_length(tvb)) /* facilities */
1908 dump_facilities(x25_tree, &localoffset, tvb);
1910 case X25_DIAGNOSTIC:
1911 if(check_col(pinfo->cinfo, COL_INFO)) {
1912 col_add_fstr(pinfo->cinfo, COL_INFO, "Diag. %d",
1913 (int)tvb_get_guint8(tvb, 3));
1916 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1918 proto_tree_add_text(x25_tree, tvb, 3, 1,
1919 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 3));
1921 localoffset = x25_pkt_len;
1924 if(check_col(pinfo->cinfo, COL_INFO))
1925 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt VC:%d", vc);
1927 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1928 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1931 localoffset = x25_pkt_len;
1933 case X25_INTERRUPT_CONFIRMATION:
1934 if(check_col(pinfo->cinfo, COL_INFO))
1935 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt Conf. VC:%d", vc);
1937 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1938 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1939 X25_INTERRUPT_CONFIRMATION);
1941 localoffset = x25_pkt_len;
1943 case X25_RESET_REQUEST:
1947 short_name = "Reset ind.";
1948 long_name = "Reset indication";
1952 short_name = "Reset req.";
1953 long_name = "Reset request";
1957 short_name = "Reset ind./Reset req.";
1958 long_name = "Reset indication/Reset request";
1961 if(check_col(pinfo->cinfo, COL_INFO)) {
1962 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - Diag.:%d",
1963 short_name, vc, reset_code(tvb_get_guint8(tvb, 3)),
1964 (int)tvb_get_guint8(tvb, 4));
1966 x25_hash_add_proto_end(vc, pinfo->fd->num);
1968 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1969 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1970 X25_RESET_REQUEST, "Packet Type: %s", long_name);
1971 proto_tree_add_text(x25_tree, tvb, 3, 1,
1972 "Cause : %s", reset_code(tvb_get_guint8(tvb, 3)));
1973 proto_tree_add_text(x25_tree, tvb, 4, 1,
1974 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
1976 localoffset = x25_pkt_len;
1978 case X25_RESET_CONFIRMATION:
1979 if(check_col(pinfo->cinfo, COL_INFO))
1980 col_add_fstr(pinfo->cinfo, COL_INFO, "Reset conf. VC:%d", vc);
1982 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1983 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1984 X25_RESET_CONFIRMATION);
1986 localoffset = x25_pkt_len;
1988 case X25_RESTART_REQUEST:
1992 short_name = "Restart ind.";
1993 long_name = "Restart indication";
1997 short_name = "Restart req.";
1998 long_name = "Restart request";
2002 short_name = "Restart ind./Restart req.";
2003 long_name = "Restart indication/Restart request";
2006 if(check_col(pinfo->cinfo, COL_INFO)) {
2007 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s - Diag.:%d",
2009 restart_code(tvb_get_guint8(tvb, 3)),
2010 (int)tvb_get_guint8(tvb, 3));
2013 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
2014 X25_RESTART_REQUEST, "Packet Type: %s", long_name);
2015 proto_tree_add_text(x25_tree, tvb, 3, 1,
2016 "Cause : %s", restart_code(tvb_get_guint8(tvb, 3)));
2017 proto_tree_add_text(x25_tree, tvb, 4, 1,
2018 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
2020 localoffset = x25_pkt_len;
2022 case X25_RESTART_CONFIRMATION:
2023 if(check_col(pinfo->cinfo, COL_INFO))
2024 col_set_str(pinfo->cinfo, COL_INFO, "Restart conf.");
2026 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2027 X25_RESTART_CONFIRMATION);
2028 localoffset = x25_pkt_len;
2030 case X25_REGISTRATION_REQUEST:
2031 if(check_col(pinfo->cinfo, COL_INFO))
2032 col_set_str(pinfo->cinfo, COL_INFO, "Registration req.");
2034 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2035 X25_REGISTRATION_REQUEST);
2037 if (localoffset < x25_pkt_len)
2038 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, TRUE);
2041 if (localoffset < x25_pkt_len)
2042 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
2043 "Registration length: %d",
2044 tvb_get_guint8(tvb, localoffset) & 0x7F);
2045 if (localoffset+1 < x25_pkt_len)
2046 proto_tree_add_text(x25_tree, tvb, localoffset+1,
2047 tvb_get_guint8(tvb, localoffset) & 0x7F,
2050 localoffset = tvb_reported_length(tvb);
2052 case X25_REGISTRATION_CONFIRMATION:
2053 if(check_col(pinfo->cinfo, COL_INFO))
2054 col_set_str(pinfo->cinfo, COL_INFO, "Registration conf.");
2056 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2057 X25_REGISTRATION_CONFIRMATION);
2058 proto_tree_add_text(x25_tree, tvb, 3, 1,
2059 "Cause: %s", registration_code(tvb_get_guint8(tvb, 3)));
2060 proto_tree_add_text(x25_tree, tvb, 4, 1,
2061 "Diagnostic: %s", registration_code(tvb_get_guint8(tvb, 4)));
2064 if (localoffset < x25_pkt_len)
2065 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, TRUE);
2068 if (localoffset < x25_pkt_len)
2069 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
2070 "Registration length: %d",
2071 tvb_get_guint8(tvb, localoffset) & 0x7F);
2072 if (localoffset+1 < x25_pkt_len)
2073 proto_tree_add_text(x25_tree, tvb, localoffset+1,
2074 tvb_get_guint8(tvb, localoffset) & 0x7F,
2077 localoffset = tvb_reported_length(tvb);
2081 if (PACKET_IS_DATA(pkt_type))
2083 if(check_col(pinfo->cinfo, COL_INFO)) {
2085 col_add_fstr(pinfo->cinfo, COL_INFO,
2086 "Data VC:%d P(S):%d P(R):%d %s", vc,
2087 (pkt_type >> 1) & 0x07,
2088 (pkt_type >> 5) & 0x07,
2089 (pkt_type & X25_MBIT_MOD8) ? " M" : "");
2091 col_add_fstr(pinfo->cinfo, COL_INFO,
2092 "Data VC:%d P(S):%d P(R):%d %s", vc,
2093 tvb_get_guint8(tvb, localoffset+1) >> 1,
2095 (tvb_get_guint8(tvb, localoffset+1) & X25_MBIT_MOD128) ? " M" : "");
2098 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2101 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2102 localoffset, 1, pkt_type);
2103 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod8, tvb,
2104 localoffset, 1, pkt_type);
2105 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod8, tvb,
2106 localoffset, 1, pkt_type);
2107 proto_tree_add_uint(x25_tree, hf_x25_type_data, tvb,
2108 localoffset, 1, pkt_type);
2111 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod128, tvb,
2112 localoffset, 1, pkt_type);
2113 proto_tree_add_uint(x25_tree, hf_x25_type_data, tvb,
2114 localoffset, 1, pkt_type);
2115 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod128, tvb,
2117 tvb_get_guint8(tvb, localoffset+1));
2118 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod128, tvb,
2120 tvb_get_guint8(tvb, localoffset+1));
2124 m_bit_set = pkt_type & X25_MBIT_MOD8;
2127 m_bit_set = tvb_get_guint8(tvb, localoffset+1) & X25_MBIT_MOD128;
2130 payload_len = tvb_reported_length_remaining(tvb, localoffset);
2131 if (reassemble_x25) {
2133 * Reassemble received and sent traffic separately.
2134 * We don't reassemble traffic with an unknown direction
2140 * OR in an extra bit to distinguish from traffic
2141 * in the other direction.
2143 frag_key |= 0x10000;
2145 fd_head = fragment_add_seq_next(tvb, localoffset,
2148 x25_reassembled_table,
2149 payload_len, m_bit_set);
2150 pinfo->fragmented = m_bit_set;
2153 if (fd_head->next) {
2154 /* This is the last packet */
2155 next_tvb = tvb_new_real_data(fd_head->data,
2158 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
2159 add_new_data_source(pinfo, next_tvb, "Reassembled X.25");
2160 show_fragment_seq_tree(fd_head,
2167 if (m_bit_set && next_tvb == NULL) {
2169 * This isn't the last packet, so just
2170 * show it as X.25 user data.
2172 proto_tree_add_text(x25_tree, tvb, localoffset, -1,
2173 "User data (%u byte%s)", payload_len,
2174 plurality(payload_len, "", "s"));
2182 * Non-data packets (RR, RNR, REJ).
2184 switch (PACKET_TYPE_FC(pkt_type))
2187 if(check_col(pinfo->cinfo, COL_INFO)) {
2189 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2190 vc, (pkt_type >> 5) & 0x07);
2192 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2193 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2196 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2199 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2200 localoffset, 1, pkt_type);
2201 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2202 localoffset, 1, X25_RR);
2205 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2206 localoffset, 1, X25_RR);
2207 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2208 localoffset+1, 1, FALSE);
2214 if(check_col(pinfo->cinfo, COL_INFO)) {
2216 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2217 vc, (pkt_type >> 5) & 0x07);
2219 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2220 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2223 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2226 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2227 localoffset, 1, pkt_type);
2228 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2229 localoffset, 1, X25_RNR);
2232 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2233 localoffset, 1, X25_RNR);
2234 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2235 localoffset+1, 1, FALSE);
2241 if(check_col(pinfo->cinfo, COL_INFO)) {
2243 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2244 vc, (pkt_type >> 5) & 0x07);
2246 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2247 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2250 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2253 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2254 localoffset, 1, pkt_type);
2255 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2256 localoffset, 1, X25_REJ);
2259 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2260 localoffset, 1, X25_REJ);
2261 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2262 localoffset+1, 1, FALSE);
2266 localoffset += (modulo == 8) ? 1 : 2;
2269 if (localoffset >= tvb_reported_length(tvb))
2271 if (pinfo->fragmented)
2275 next_tvb = tvb_new_subset(tvb, localoffset, -1, -1);
2277 saved_private_data = pinfo->private_data;
2278 pinfo->private_data = &q_bit_set;
2280 /* See if there's already a dissector for this circuit. */
2281 if (try_circuit_dissector(CT_X25, vc, pinfo->fd->num, next_tvb, pinfo,
2283 pinfo->private_data = saved_private_data;
2284 return; /* found it and dissected it */
2287 /* Did the user suggest QLLC/SNA? */
2288 if (payload_is_qllc_sna) {
2289 /* Yes - dissect it as QLLC/SNA. */
2290 if (!pinfo->fd->flags.visited)
2291 x25_hash_add_proto_start(vc, pinfo->fd->num, qllc_handle);
2292 call_dissector(qllc_handle, next_tvb, pinfo, tree);
2293 pinfo->private_data = saved_private_data;
2297 /* If the Call Req. has not been captured, let's look at the first
2298 byte of the payload to see if this looks like IP or CLNP. */
2299 switch (tvb_get_guint8(tvb, localoffset)) {
2302 /* Looks like an IP header */
2303 if (!pinfo->fd->flags.visited)
2304 x25_hash_add_proto_start(vc, pinfo->fd->num, ip_handle);
2305 call_dissector(ip_handle, next_tvb, pinfo, tree);
2306 pinfo->private_data = saved_private_data;
2309 case NLPID_ISO8473_CLNP:
2310 if (!pinfo->fd->flags.visited)
2311 x25_hash_add_proto_start(vc, pinfo->fd->num, clnp_handle);
2312 call_dissector(clnp_handle, next_tvb, pinfo, tree);
2313 pinfo->private_data = saved_private_data;
2317 /* Try the heuristic dissectors. */
2318 if (dissector_try_heuristic(x25_heur_subdissector_list, next_tvb, pinfo,
2320 pinfo->private_data = saved_private_data;
2324 /* All else failed; dissect it as raw data */
2325 call_dissector(data_handle, next_tvb, pinfo, tree);
2326 pinfo->private_data = saved_private_data;
2330 * X.25 dissector for use when "pinfo->pseudo_header" points to a
2331 * "struct x25_phdr".
2334 dissect_x25_dir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2336 dissect_x25_common(tvb, pinfo, tree,
2337 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? X25_FROM_DCE :
2339 pinfo->pseudo_header->x25.flags & FROM_DCE);
2343 * X.25 dissector for use when "pinfo->pseudo_header" doesn't point to a
2344 * "struct x25_phdr".
2347 dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2352 * We don't know if this packet is DTE->DCE or DCE->DCE.
2353 * However, we can, at least, distinguish between the two
2354 * sides of the conversation, based on the addresses and
2357 direction = CMP_ADDRESS(&pinfo->src, &pinfo->dst);
2359 direction = (pinfo->srcport > pinfo->destport)*2 - 1;
2360 dissect_x25_common(tvb, pinfo, tree, X25_UNKNOWN, direction > 0);
2364 x25_reassemble_init(void)
2366 fragment_table_init(&x25_segment_table);
2367 reassembled_table_init(&x25_reassembled_table);
2371 proto_register_x25(void)
2373 static hf_register_info hf[] = {
2375 { "GFI", "x.25.gfi", FT_UINT16, BASE_DEC, NULL, 0xF000,
2376 "General format identifier", HFILL }},
2378 { "A Bit", "x.25.a", FT_BOOLEAN, 16, NULL, X25_ABIT,
2379 "Address Bit", HFILL }},
2381 { "Q Bit", "x.25.q", FT_BOOLEAN, 16, NULL, X25_QBIT,
2382 "Qualifier Bit", HFILL }},
2384 { "D Bit", "x.25.d", FT_BOOLEAN, 16, NULL, X25_DBIT,
2385 "Delivery Confirmation Bit", HFILL }},
2387 { "Modulo", "x.25.mod", FT_UINT16, BASE_DEC, VALS(vals_modulo), 0x3000,
2388 "Specifies whether the frame is modulo 8 or 128", HFILL }},
2390 { "Logical Channel", "x.25.lcn", FT_UINT16, BASE_DEC, NULL, 0x0FFF,
2391 "Logical Channel Number", HFILL }},
2393 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x0,
2394 "Packet Type", HFILL }},
2395 { &hf_x25_type_fc_mod8,
2396 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x1F,
2397 "Packet Type", HFILL }},
2398 { &hf_x25_type_data,
2399 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x01,
2400 "Packet Type", HFILL }},
2402 { "P(R)", "x.25.p_r", FT_UINT8, BASE_DEC, NULL, 0xE0,
2403 "Packet Receive Sequence Number", HFILL }},
2404 { &hf_x25_p_r_mod128,
2405 { "P(R)", "x.25.p_r", FT_UINT8, BASE_DEC, NULL, 0xFE,
2406 "Packet Receive Sequence Number", HFILL }},
2407 { &hf_x25_mbit_mod8,
2408 { "M Bit", "x.25.m", FT_BOOLEAN, 8, TFS(&m_bit_tfs), X25_MBIT_MOD8,
2409 "More Bit", HFILL }},
2410 { &hf_x25_mbit_mod128,
2411 { "M Bit", "x.25.m", FT_BOOLEAN, 8, TFS(&m_bit_tfs), X25_MBIT_MOD128,
2412 "More Bit", HFILL }},
2414 { "P(S)", "x.25.p_s", FT_UINT8, BASE_DEC, NULL, 0x0E,
2415 "Packet Send Sequence Number", HFILL }},
2416 { &hf_x25_p_s_mod128,
2417 { "P(S)", "x.25.p_s", FT_UINT8, BASE_DEC, NULL, 0xFE,
2418 "Packet Send Sequence Number", HFILL }},
2419 { &hf_x25_segment_overlap,
2420 { "Fragment overlap", "x25.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2421 "Fragment overlaps with other fragments", HFILL }},
2423 { &hf_x25_segment_overlap_conflict,
2424 { "Conflicting data in fragment overlap", "x25.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2425 "Overlapping fragments contained conflicting data", HFILL }},
2427 { &hf_x25_segment_multiple_tails,
2428 { "Multiple tail fragments found", "x25.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2429 "Several tails were found when defragmenting the packet", HFILL }},
2431 { &hf_x25_segment_too_long_segment,
2432 { "Fragment too long", "x25.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2433 "Fragment contained data past end of packet", HFILL }},
2435 { &hf_x25_segment_error,
2436 { "Defragmentation error", "x25.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2437 "Defragmentation error due to illegal fragments", HFILL }},
2440 { "X.25 Fragment", "x25.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2441 "X25 Fragment", HFILL }},
2444 { "X.25 Fragments", "x25.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
2445 "X.25 Fragments", HFILL }},
2447 static gint *ett[] = {
2451 &ett_x25_fac_unknown,
2453 &ett_x25_fac_reverse,
2454 &ett_x25_fac_throughput,
2456 &ett_x25_fac_called_modif,
2457 &ett_x25_fac_cug_outgoing_acc,
2458 &ett_x25_fac_throughput_min,
2459 &ett_x25_fac_express_data,
2460 &ett_x25_fac_bilateral_cug,
2461 &ett_x25_fac_packet_size,
2462 &ett_x25_fac_window_size,
2463 &ett_x25_fac_rpoa_selection,
2464 &ett_x25_fac_transit_delay,
2465 &ett_x25_fac_call_transfer,
2466 &ett_x25_fac_called_addr_ext,
2467 &ett_x25_fac_ete_transit_delay,
2468 &ett_x25_fac_calling_addr_ext,
2469 &ett_x25_fac_call_deflect,
2470 &ett_x25_fac_priority,
2475 module_t *x25_module;
2477 proto_x25 = proto_register_protocol ("X.25", "X.25", "x.25");
2478 proto_register_field_array (proto_x25, hf, array_length(hf));
2479 proto_register_subtree_array(ett, array_length(ett));
2481 x25_subdissector_table = register_dissector_table("x.25.spi",
2482 "X.25 secondary protocol identifier", FT_UINT8, BASE_HEX);
2483 register_heur_dissector_list("x.25", &x25_heur_subdissector_list);
2485 register_dissector("x.25_dir", dissect_x25_dir, proto_x25);
2486 register_dissector("x.25", dissect_x25, proto_x25);
2489 x25_module = prefs_register_protocol(proto_x25, NULL);
2490 prefs_register_obsolete_preference(x25_module, "non_q_bit_is_sna");
2491 prefs_register_bool_preference(x25_module, "payload_is_qllc_sna",
2492 "Default to QLLC/SNA",
2493 "If CALL REQUEST not seen or didn't specify protocol, dissect as QLLC/SNA",
2494 &payload_is_qllc_sna);
2495 prefs_register_bool_preference(x25_module, "reassemble",
2496 "Reassemble fragmented X.25 packets",
2497 "Reassemble fragmented X.25 packets",
2499 register_init_routine(&x25_reassemble_init);
2503 proto_reg_handoff_x25(void)
2505 dissector_handle_t x25_handle;
2508 * Get handles for various dissectors.
2510 ip_handle = find_dissector("ip");
2511 clnp_handle = find_dissector("clnp");
2512 ositp_handle = find_dissector("ositp");
2513 qllc_handle = find_dissector("qllc");
2514 data_handle = find_dissector("data");
2516 x25_handle = find_dissector("x.25");
2517 dissector_add("llc.dsap", SAP_X25, x25_handle);