2 * Routines for X.25 packet disassembly
3 * Olivier Abad <oabad@noos.fr>
5 * $Id: packet-x25.c,v 1.81 2003/03/04 19:50:20 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>
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_FAC_CLASS_MASK 0xC0
79 #define X25_FAC_CLASS_A 0x00
80 #define X25_FAC_CLASS_B 0x40
81 #define X25_FAC_CLASS_C 0x80
82 #define X25_FAC_CLASS_D 0xC0
84 #define X25_FAC_COMP_MARK 0x00
85 #define X25_FAC_REVERSE 0x01
86 #define X25_FAC_THROUGHPUT 0x02
87 #define X25_FAC_CUG 0x03
88 #define X25_FAC_CALLED_MODIF 0x08
89 #define X25_FAC_CUG_OUTGOING_ACC 0x09
90 #define X25_FAC_THROUGHPUT_MIN 0x0A
91 #define X25_FAC_EXPRESS_DATA 0x0B
92 #define X25_FAC_BILATERAL_CUG 0x41
93 #define X25_FAC_PACKET_SIZE 0x42
94 #define X25_FAC_WINDOW_SIZE 0x43
95 #define X25_FAC_RPOA_SELECTION 0x44
96 #define X25_FAC_TRANSIT_DELAY 0x49
97 #define X25_FAC_CALL_TRANSFER 0xC3
98 #define X25_FAC_CALLED_ADDR_EXT 0xC9
99 #define X25_FAC_ETE_TRANSIT_DELAY 0xCA
100 #define X25_FAC_CALLING_ADDR_EXT 0xCB
101 #define X25_FAC_CALL_DEFLECT 0xD1
102 #define X25_FAC_PRIORITY 0xD2
104 static int proto_x25 = -1;
105 static int hf_x25_gfi = -1;
106 static int hf_x25_abit = -1;
107 static int hf_x25_qbit = -1;
108 static int hf_x25_dbit = -1;
109 static int hf_x25_mod = -1;
110 static int hf_x25_lcn = -1;
111 static int hf_x25_type = -1;
112 static int hf_x25_type_fc_mod8 = -1;
113 static int hf_x25_type_data = -1;
114 static int hf_x25_p_r_mod8 = -1;
115 static int hf_x25_p_r_mod128 = -1;
116 static int hf_x25_mbit_mod8 = -1;
117 static int hf_x25_mbit_mod128 = -1;
118 static int hf_x25_p_s_mod8 = -1;
119 static int hf_x25_p_s_mod128 = -1;
121 static gint ett_x25 = -1;
122 static gint ett_x25_gfi = -1;
123 static gint ett_x25_fac = -1;
124 static gint ett_x25_fac_unknown = -1;
125 static gint ett_x25_fac_mark = -1;
126 static gint ett_x25_fac_reverse = -1;
127 static gint ett_x25_fac_throughput = -1;
128 static gint ett_x25_fac_cug = -1;
129 static gint ett_x25_fac_called_modif = -1;
130 static gint ett_x25_fac_cug_outgoing_acc = -1;
131 static gint ett_x25_fac_throughput_min = -1;
132 static gint ett_x25_fac_express_data = -1;
133 static gint ett_x25_fac_bilateral_cug = -1;
134 static gint ett_x25_fac_packet_size = -1;
135 static gint ett_x25_fac_window_size = -1;
136 static gint ett_x25_fac_rpoa_selection = -1;
137 static gint ett_x25_fac_transit_delay = -1;
138 static gint ett_x25_fac_call_transfer = -1;
139 static gint ett_x25_fac_called_addr_ext = -1;
140 static gint ett_x25_fac_ete_transit_delay = -1;
141 static gint ett_x25_fac_calling_addr_ext = -1;
142 static gint ett_x25_fac_call_deflect = -1;
143 static gint ett_x25_fac_priority = -1;
144 static gint ett_x25_user_data = -1;
146 static gint ett_x25_segment = -1;
147 static gint ett_x25_segments = -1;
148 static gint hf_x25_segments = -1;
149 static gint hf_x25_segment = -1;
150 static gint hf_x25_segment_overlap = -1;
151 static gint hf_x25_segment_overlap_conflict = -1;
152 static gint hf_x25_segment_multiple_tails = -1;
153 static gint hf_x25_segment_too_long_segment = -1;
154 static gint hf_x25_segment_error = -1;
156 static const value_string vals_modulo[] = {
162 static const value_string vals_x25_type[] = {
163 { X25_CALL_REQUEST, "Call" },
164 { X25_CALL_ACCEPTED, "Call Accepted" },
165 { X25_CLEAR_REQUEST, "Clear" },
166 { X25_CLEAR_CONFIRMATION, "Clear Confirmation" },
167 { X25_INTERRUPT, "Interrupt" },
168 { X25_INTERRUPT_CONFIRMATION, "Interrupt Confirmation" },
169 { X25_RESET_REQUEST, "Reset" },
170 { X25_RESET_CONFIRMATION, "Reset Confirmation" },
171 { X25_RESTART_REQUEST, "Restart" },
172 { X25_RESTART_CONFIRMATION, "Restart Confirmation" },
173 { X25_REGISTRATION_REQUEST, "Registration" },
174 { X25_REGISTRATION_CONFIRMATION, "Registration Confirmation" },
175 { X25_DIAGNOSTIC, "Diagnostic" },
179 { X25_DATA, "Data" },
183 static struct true_false_string m_bit_tfs = {
188 static const fragment_items x25_frag_items = {
193 &hf_x25_segment_overlap,
194 &hf_x25_segment_overlap_conflict,
195 &hf_x25_segment_multiple_tails,
196 &hf_x25_segment_too_long_segment,
197 &hf_x25_segment_error,
201 static dissector_handle_t ip_handle;
202 static dissector_handle_t clnp_handle;
203 static dissector_handle_t ositp_handle;
204 static dissector_handle_t qllc_handle;
205 static dissector_handle_t data_handle;
208 static gboolean payload_is_qllc_sna = FALSE;
209 static gboolean reassemble_x25 = FALSE;
211 /* Reassembly of X.25 */
213 static GHashTable *x25_segment_table = NULL;
214 static GHashTable *x25_reassembled_table = NULL;
216 static dissector_table_t x25_subdissector_table;
217 static heur_dissector_list_t x25_heur_subdissector_list;
220 x25_hash_add_proto_start(guint16 vc, guint32 frame, dissector_handle_t dissect)
225 * Is there already a circuit with this VC number?
227 circuit = find_circuit(CT_X25, vc, frame);
228 if (circuit != NULL) {
230 * Yes - close it, as we're creating a new one.
232 close_circuit(circuit, frame - 1);
236 * Set up a new circuit.
238 circuit = circuit_new(CT_X25, vc, frame);
243 circuit_set_dissector(circuit, dissect);
247 x25_hash_add_proto_end(guint16 vc, guint32 frame)
252 * Try to find the circuit.
254 circuit = find_circuit(CT_X25, vc, frame);
257 * If we succeeded, close it.
260 close_circuit(circuit, frame);
263 static char *clear_code(unsigned char code)
265 static char buffer[25];
267 if (code == 0x00 || (code & 0x80) == 0x80)
268 return "DTE Originated";
270 return "Number Busy";
272 return "Invalid Facility Requested";
274 return "Network Congestion";
276 return "Out Of Order";
278 return "Access Barred";
280 return "Not Obtainable";
282 return "Remote Procedure Error";
284 return "Local Procedure Error";
286 return "RPOA Out Of Order";
288 return "Reverse Charging Acceptance Not Subscribed";
290 return "Incompatible Destination";
292 return "Fast Select Acceptance Not Subscribed";
294 return "Destination Absent";
296 sprintf(buffer, "Unknown %02X", code);
301 static char *clear_diag(unsigned char code)
303 static char buffer[25];
306 return "No additional information";
308 return "Invalid P(S)";
310 return "Invalid P(R)";
312 return "Packet type invalid";
314 return "Packet type invalid for state r1";
316 return "Packet type invalid for state r2";
318 return "Packet type invalid for state r3";
320 return "Packet type invalid for state p1";
322 return "Packet type invalid for state p2";
324 return "Packet type invalid for state p3";
326 return "Packet type invalid for state p4";
328 return "Packet type invalid for state p5";
330 return "Packet type invalid for state p6";
332 return "Packet type invalid for state p7";
334 return "Packet type invalid for state d1";
336 return "Packet type invalid for state d2";
338 return "Packet type invalid for state d3";
340 return "Packet not allowed";
342 return "Unidentifiable packet";
344 return "Call on one-way logical channel";
346 return "Invalid packet type on a PVC";
348 return "Packet on unassigned LC";
350 return "Reject not subscribed to";
352 return "Packet too short";
354 return "Packet too long";
356 return "Invalid general format identifier";
358 return "Restart/registration packet with nonzero bits";
360 return "Packet type not compatible with facility";
362 return "Unauthorised interrupt confirmation";
364 return "Unauthorised interrupt";
366 return "Unauthorised reject";
368 return "Time expired";
370 return "Time expired for incoming call";
372 return "Time expired for clear indication";
374 return "Time expired for reset indication";
376 return "Time expired for restart indication";
378 return "Time expired for call deflection";
380 return "Call set-up/clearing or registration pb.";
382 return "Facility/registration code not allowed";
384 return "Facility parameter not allowed";
386 return "Invalid called DTE address";
388 return "Invalid calling DTE address";
390 return "Invalid facility/registration length";
392 return "Incoming call barred";
394 return "No logical channel available";
396 return "Call collision";
398 return "Duplicate facility requested";
400 return "Non zero address length";
402 return "Non zero facility length";
404 return "Facility not provided when expected";
406 return "Invalid CCITT-specified DTE facility";
408 return "Max. nb of call redir/defl. exceeded";
410 return "Miscellaneous";
412 return "Improper cause code from DTE";
414 return "Not aligned octet";
416 return "Inconsistent Q bit setting";
418 return "NUI problem";
420 return "International problem";
422 return "Remote network problem";
424 return "International protocol problem";
426 return "International link out of order";
428 return "International link busy";
430 return "Transit network facility problem";
432 return "Remote network facility problem";
434 return "International routing problem";
436 return "Temporary routing problem";
438 return "Unknown called DNIC";
440 return "Maintenance action";
442 return "Timer expired or retransmission count surpassed";
444 return "Timer expired or retransmission count surpassed for INTERRUPT";
446 return "Timer expired or retransmission count surpassed for DATA "
447 "packet transmission";
449 return "Timer expired or retransmission count surpassed for REJECT";
451 return "DTE-specific signals";
453 return "DTE operational";
455 return "DTE not operational";
457 return "DTE resource constraint";
459 return "Fast select not subscribed";
461 return "Invalid partially full DATA packet";
463 return "D-bit procedure not supported";
465 return "Registration/Cancellation confirmed";
467 return "OSI network service problem";
469 return "Disconnection (transient condition)";
471 return "Disconnection (permanent condition)";
473 return "Connection rejection - reason unspecified (transient "
476 return "Connection rejection - reason unspecified (permanent "
479 return "Connection rejection - quality of service not available "
480 "transient condition)";
482 return "Connection rejection - quality of service not available "
483 "permanent condition)";
485 return "Connection rejection - NSAP unreachable (transient condition)";
487 return "Connection rejection - NSAP unreachable (permanent condition)";
489 return "reset - reason unspecified";
491 return "reset - congestion";
493 return "Connection rejection - NSAP address unknown (permanent "
496 return "Higher layer initiated";
498 return "Disconnection - normal";
500 return "Disconnection - abnormal";
502 return "Disconnection - incompatible information in user data";
504 return "Connection rejection - reason unspecified (transient "
507 return "Connection rejection - reason unspecified (permanent "
510 return "Connection rejection - quality of service not available "
511 "(transient condition)";
513 return "Connection rejection - quality of service not available "
514 "(permanent condition)";
516 return "Connection rejection - incompatible information in user data";
518 return "Connection rejection - unrecognizable protocol indentifier "
521 return "Reset - user resynchronization";
523 sprintf(buffer, "Unknown %d", code);
528 static char *reset_code(unsigned char code)
530 static char buffer[25];
532 if (code == 0x00 || (code & 0x80) == 0x80)
533 return "DTE Originated";
535 return "Out of order";
537 return "Remote Procedure Error";
539 return "Local Procedure Error";
541 return "Network Congestion";
543 return "Remote DTE operational";
545 return "Network operational";
547 return "Incompatible Destination";
549 return "Network out of order";
551 sprintf(buffer, "Unknown %02X", code);
556 static char *restart_code(unsigned char code)
558 static char buffer[25];
560 if (code == 0x00 || (code & 0x80) == 0x80)
561 return "DTE Originated";
563 return "Local Procedure Error";
565 return "Network Congestion";
567 return "Network Operational";
569 return "Registration/cancellation confirmed";
571 sprintf(buffer, "Unknown %02X", code);
576 static char *registration_code(unsigned char code)
578 static char buffer[25];
581 return "Invalid facility request";
583 return "Network congestion";
585 return "Local procedure error";
587 return "Registration/cancellation confirmed";
589 sprintf(buffer, "Unknown %02X", code);
595 dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb)
597 guint8 fac, byte1, byte2, byte3;
598 guint32 len; /* facilities length */
600 proto_tree *fac_tree = 0;
601 proto_tree *fac_subtree;
603 len = tvb_get_guint8(tvb, *offset);
605 ti = proto_tree_add_text(tree, tvb, *offset, len + 1,
607 fac_tree = proto_item_add_subtree(ti, ett_x25_fac);
608 proto_tree_add_text(fac_tree, tvb, *offset, 1,
609 "Facilities length: %d", len);
614 fac = tvb_get_guint8(tvb, *offset);
615 switch(fac & X25_FAC_CLASS_MASK) {
616 case X25_FAC_CLASS_A:
618 case X25_FAC_COMP_MARK:
620 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
621 "Code : 00 (Marker)");
622 switch (tvb_get_guint8(tvb, *offset + 1)) {
625 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
626 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
627 "Parameter : 00 (Network complementary "
628 "services - calling DTE)");
633 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
634 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
635 "Parameter : FF (Network complementary "
636 "services - called DTE)");
641 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
642 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
643 "Parameter : 0F (DTE complementary "
649 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
650 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
651 "Parameter : %02X (Unknown marker)",
652 tvb_get_guint8(tvb, *offset+1));
657 case X25_FAC_REVERSE:
659 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
660 "(Reverse charging / Fast select)", fac);
661 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_reverse);
662 byte1 = tvb_get_guint8(tvb, *offset + 1);
663 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
664 "Parameter : %02X", byte1);
666 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
667 "11.. .... = Fast select with restriction");
668 else if (byte1 & 0x80)
669 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
670 "10.. .... = Fast select - no restriction");
672 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
673 "00.. .... = Fast select not requested");
674 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
675 decode_boolean_bitfield(byte1, 0x01, 1*8,
676 "Reverse charging requested",
677 "Reverse charging not requested"));
680 case X25_FAC_THROUGHPUT:
684 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
685 "(Throughput class negociation)", fac);
686 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_throughput);
687 byte1 = tvb_get_guint8(tvb, *offset + 1);
699 sprintf(tmpbuf, "From the called DTE : %%u (%d bps)",
700 75*(1<<((byte1 >> 4)-3)));
703 sprintf(tmpbuf, "From the called DTE : %%u (48000 bps)");
706 sprintf(tmpbuf, "From the called DTE : %%u (64000 bps)");
709 sprintf(tmpbuf, "From the called DTE : %%u (Reserved)");
711 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
712 decode_numeric_bitfield(byte1, 0xF0, 1*8, tmpbuf));
713 switch (byte1 & 0x0F)
724 sprintf(tmpbuf, "From the calling DTE : %%u (%d bps)",
725 75*(1<<((byte1 & 0x0F)-3)));
728 sprintf(tmpbuf, "From the calling DTE : %%u (48000 bps)");
731 sprintf(tmpbuf, "From the calling DTE : %%u (64000 bps)");
734 sprintf(tmpbuf, "From the calling DTE : %%u (Reserved)");
736 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
737 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
742 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
743 "(Closed user group selection)", fac);
744 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_cug);
745 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
746 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
749 case X25_FAC_CALLED_MODIF:
751 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
752 "(Called address modified)", fac);
753 fac_subtree = proto_item_add_subtree(ti,
754 ett_x25_fac_called_modif);
755 proto_tree_add_text(fac_tree, tvb, *offset+1, 1,
756 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
759 case X25_FAC_CUG_OUTGOING_ACC:
761 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
762 "(Closed user group with outgoing access selection)",
764 fac_subtree = proto_item_add_subtree(ti,
765 ett_x25_fac_cug_outgoing_acc);
766 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
767 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
770 case X25_FAC_THROUGHPUT_MIN:
772 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
773 "(Minimum throughput class)", fac);
774 fac_subtree = proto_item_add_subtree(ti,
775 ett_x25_fac_throughput_min);
776 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
777 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
780 case X25_FAC_EXPRESS_DATA:
782 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
783 "(Negociation of express data)", fac);
784 fac_subtree = proto_item_add_subtree(ti,
785 ett_x25_fac_express_data);
786 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
787 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
792 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
793 "Code : %02X (Unknown class A)", fac);
794 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
795 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
796 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
803 case X25_FAC_CLASS_B:
805 case X25_FAC_BILATERAL_CUG:
807 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
808 "(Bilateral closed user group selection)", fac);
809 fac_subtree = proto_item_add_subtree(ti,
810 ett_x25_fac_bilateral_cug);
811 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
812 "Bilateral CUG: %04X",
813 tvb_get_ntohs(tvb, *offset+1));
816 case X25_FAC_PACKET_SIZE:
821 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
822 "(Packet size)", fac);
823 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_packet_size);
824 byte1 = tvb_get_guint8(tvb, *offset + 1);
828 sprintf(tmpbuf, "From the called DTE : %%u (16)");
831 sprintf(tmpbuf, "From the called DTE : %%u (32)");
834 sprintf(tmpbuf, "From the called DTE : %%u (64)");
837 sprintf(tmpbuf, "From the called DTE : %%u (128)");
840 sprintf(tmpbuf, "From the called DTE : %%u (256)");
843 sprintf(tmpbuf, "From the called DTE : %%u (512)");
846 sprintf(tmpbuf, "From the called DTE : %%u (1024)");
849 sprintf(tmpbuf, "From the called DTE : %%u (2048)");
852 sprintf(tmpbuf, "From the called DTE : %%u (4096)");
855 sprintf(tmpbuf, "From the called DTE : %%u (Unknown)");
858 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
859 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
861 byte2 = tvb_get_guint8(tvb, *offset + 1);
865 sprintf(tmpbuf, "From the calling DTE : %%u (16)");
868 sprintf(tmpbuf, "From the calling DTE : %%u (32)");
871 sprintf(tmpbuf, "From the calling DTE : %%u (64)");
874 sprintf(tmpbuf, "From the calling DTE : %%u (128)");
877 sprintf(tmpbuf, "From the calling DTE : %%u (256)");
880 sprintf(tmpbuf, "From the calling DTE : %%u (512)");
883 sprintf(tmpbuf, "From the calling DTE : %%u (1024)");
886 sprintf(tmpbuf, "From the calling DTE : %%u (2048)");
889 sprintf(tmpbuf, "From the calling DTE : %%u (4096)");
892 sprintf(tmpbuf, "From the calling DTE : %%u (Unknown)");
895 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
896 decode_numeric_bitfield(byte2, 0x0F, 1*8, tmpbuf));
899 case X25_FAC_WINDOW_SIZE:
901 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
902 "(Window size)", fac);
903 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_window_size);
904 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
905 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+1),
906 0x7F, 1*8, "From the called DTE: %u"));
907 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
908 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+2),
909 0x7F, 1*8, "From the calling DTE: %u"));
912 case X25_FAC_RPOA_SELECTION:
914 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
915 "(RPOA selection)", fac);
916 fac_subtree = proto_item_add_subtree(ti,
917 ett_x25_fac_rpoa_selection);
918 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
919 "Data network identification code : %04X",
920 tvb_get_ntohs(tvb, *offset+1));
923 case X25_FAC_TRANSIT_DELAY:
925 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
926 "(Transit delay selection and indication)", fac);
927 fac_subtree = proto_item_add_subtree(ti,
928 ett_x25_fac_transit_delay);
929 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
930 "Transit delay: %d ms",
931 tvb_get_ntohs(tvb, *offset+1));
936 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
937 "Code : %02X (Unknown class B)", fac);
938 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
939 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
940 "Parameter %04X", tvb_get_ntohs(tvb, *offset+1));
947 case X25_FAC_CLASS_C:
949 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
950 "Code : %02X (Unknown class C)", fac);
951 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
952 proto_tree_add_text(fac_subtree, tvb, *offset+1, 3,
954 tvb_get_ntoh24(tvb, *offset+1));
959 case X25_FAC_CLASS_D:
961 case X25_FAC_CALL_TRANSFER:
966 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
967 "(Call redirection or deflection notification)", fac);
968 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_call_transfer);
969 byte1 = tvb_get_guint8(tvb, *offset+1);
970 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
971 "Length : %u", byte1);
972 byte2 = tvb_get_guint8(tvb, *offset+2);
973 if ((byte2 & 0xC0) == 0xC0) {
974 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
975 "Reason : call deflection by the originally "
976 "called DTE address");
981 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
982 "Reason : originally called DTE busy");
985 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
986 "Reason : call dist. within a hunt group");
989 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
990 "Reason : originally called DTE out of order");
993 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
994 "Reason : systematic call redirection");
997 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1002 byte3 = tvb_get_guint8(tvb, *offset+3);
1003 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1004 "Number of semi-octets in DTE address : %u",
1006 for (i = 0; i < byte3; i++) {
1008 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1010 /* if > 9, convert to the right hexadecimal letter */
1011 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1013 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1015 /* if > 9, convert to the right hexadecimal letter */
1016 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1020 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1021 "DTE address : %s", tmpbuf);
1024 case X25_FAC_CALLING_ADDR_EXT:
1029 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1030 "(Calling address extension)", fac);
1031 fac_subtree = proto_item_add_subtree(ti,
1032 ett_x25_fac_calling_addr_ext);
1033 byte1 = tvb_get_guint8(tvb, *offset+1);
1034 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1035 "Length : %u", byte1);
1036 byte2 = tvb_get_guint8(tvb, *offset+2) & 0x3F;
1037 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1038 "Number of semi-octets in DTE address : %u", byte2);
1039 for (i = 0; i < byte2; i++) {
1041 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1043 /* if > 9, convert to the right hexadecimal letter */
1044 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1046 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1048 /* if > 9, convert to the right hexadecimal letter */
1049 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1053 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1054 "DTE address : %s", tmpbuf);
1057 case X25_FAC_CALLED_ADDR_EXT:
1062 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1063 "(Called address extension)", fac);
1064 fac_subtree = proto_item_add_subtree(ti,
1065 ett_x25_fac_called_addr_ext);
1066 byte1 = tvb_get_guint8(tvb, *offset+1);
1067 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1068 "Length : %u", byte1);
1069 byte2 = tvb_get_guint8(tvb, *offset+2) & 0x3F;
1070 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1071 "Number of semi-octets in DTE address : %u", byte2);
1072 for (i = 0; i < byte2; i++) {
1074 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1076 /* if > 9, convert to the right hexadecimal letter */
1077 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1079 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1081 /* if > 9, convert to the right hexadecimal letter */
1082 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1086 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1087 "DTE address : %s", tmpbuf);
1090 case X25_FAC_ETE_TRANSIT_DELAY:
1092 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1093 "(End to end transit delay)", fac);
1094 fac_subtree = proto_item_add_subtree(ti,
1095 ett_x25_fac_ete_transit_delay);
1096 byte1 = tvb_get_guint8(tvb, *offset+1);
1097 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1098 "Length : %u", byte1);
1099 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1102 case X25_FAC_CALL_DEFLECT:
1107 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1108 "(Call deflection selection)", fac);
1109 fac_subtree = proto_item_add_subtree(ti,
1110 ett_x25_fac_call_deflect);
1111 byte1 = tvb_get_guint8(tvb, *offset+1);
1112 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1113 "Length : %u", byte1);
1114 byte2 = tvb_get_guint8(tvb, *offset+2);
1115 if ((byte2 & 0xC0) == 0xC0)
1116 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1117 "Reason : call DTE originated");
1119 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1120 "Reason : unknown");
1121 byte3 = tvb_get_guint8(tvb, *offset+3);
1122 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1123 "Number of semi-octets in the alternative DTE address : %u",
1125 for (i = 0; i < byte3; i++) {
1127 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1129 /* if > 9, convert to the right hexadecimal letter */
1130 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1132 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1134 /* if > 9, convert to the right hexadecimal letter */
1135 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1139 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1140 "Alternative DTE address : %s", tmpbuf);
1143 case X25_FAC_PRIORITY:
1145 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1146 "Code : %02X (Priority)", fac);
1147 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_priority);
1148 byte1 = tvb_get_guint8(tvb, *offset+1);
1149 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1150 "Length : %u", byte1);
1151 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1156 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1157 "Code : %02X (Unknown class D)", fac);
1158 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1159 byte1 = tvb_get_guint8(tvb, *offset+1);
1160 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1161 "Length : %u", byte1);
1162 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1165 byte1 = tvb_get_guint8(tvb, *offset+1);
1166 (*offset) += byte1+2;
1174 x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1175 packet_info *pinfo, gboolean is_registration)
1179 char addr1[16], addr2[16];
1180 char *first, *second;
1184 byte = tvb_get_guint8(tvb, *offset);
1185 len1 = (byte >> 0) & 0x0F;
1186 len2 = (byte >> 4) & 0x0F;
1189 proto_tree_add_text(tree, tvb, *offset, 1,
1190 decode_numeric_bitfield(byte, 0xF0, 1*8,
1192 "DTE address length : %u" :
1193 "Calling address length : %u"));
1194 proto_tree_add_text(tree, tvb, *offset, 1,
1195 decode_numeric_bitfield(byte, 0x0F, 1*8,
1197 "DCE address length : %u" :
1198 "Called address length : %u"));
1202 localoffset = *offset;
1203 byte = tvb_get_guint8(tvb, localoffset);
1207 for (i = 0; i < (len1 + len2); i++) {
1210 *first++ = ((byte >> 0) & 0x0F) + '0';
1212 byte = tvb_get_guint8(tvb, localoffset);
1214 *first++ = ((byte >> 4) & 0x0F) + '0';
1218 *second++ = ((byte >> 0) & 0x0F) + '0';
1220 byte = tvb_get_guint8(tvb, localoffset);
1222 *second++ = ((byte >> 4) & 0x0F) + '0';
1231 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1232 col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1);
1234 proto_tree_add_text(tree, tvb, *offset,
1237 "DCE address : %s" :
1238 "Called address : %s",
1242 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1243 col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2);
1245 proto_tree_add_text(tree, tvb, *offset + len1/2,
1246 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1248 "DTE address : %s" :
1249 "Calling address : %s",
1252 (*offset) += ((len1 + len2 + 1) / 2);
1256 x25_toa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1261 char addr1[256], addr2[256];
1262 char *first, *second;
1266 len1 = tvb_get_guint8(tvb, *offset);
1268 proto_tree_add_text(tree, tvb, *offset, 1,
1269 "Called address length : %u",
1274 len2 = tvb_get_guint8(tvb, *offset);
1276 proto_tree_add_text(tree, tvb, *offset, 1,
1277 "Calling address length : %u",
1282 localoffset = *offset;
1283 byte = tvb_get_guint8(tvb, localoffset);
1286 * XXX - the first two half-octets of the address are the TOA and
1287 * NPI; process them as such and, if the TOA says an address is
1288 * an alternative address, process it correctly (i.e., not as a
1289 * sequence of half-octets containing digit values).
1293 for (i = 0; i < (len1 + len2); i++) {
1296 *first++ = ((byte >> 0) & 0x0F) + '0';
1298 byte = tvb_get_guint8(tvb, localoffset);
1300 *first++ = ((byte >> 4) & 0x0F) + '0';
1304 *second++ = ((byte >> 0) & 0x0F) + '0';
1306 byte = tvb_get_guint8(tvb, localoffset);
1308 *second++ = ((byte >> 4) & 0x0F) + '0';
1317 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1318 col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1);
1320 proto_tree_add_text(tree, tvb, *offset,
1322 "Called address : %s",
1326 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1327 col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2);
1329 proto_tree_add_text(tree, tvb, *offset + len1/2,
1330 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1331 "Calling address : %s",
1334 (*offset) += ((len1 + len2 + 1) / 2);
1338 get_x25_pkt_len(tvbuff_t *tvb)
1340 guint length, called_len, calling_len, dte_len, dce_len;
1341 guint8 byte2, bytex;
1343 byte2 = tvb_get_guint8(tvb, 2);
1346 case X25_CALL_REQUEST:
1347 bytex = tvb_get_guint8(tvb, 3);
1348 called_len = (bytex >> 0) & 0x0F;
1349 calling_len = (bytex >> 4) & 0x0F;
1350 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1351 if (length < tvb_reported_length(tvb))
1352 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1354 return MIN(tvb_reported_length(tvb),length);
1356 case X25_CALL_ACCEPTED:
1357 /* The calling/called address length byte (following the packet type)
1358 * is not mandatory, so we must check the packet length before trying
1360 if (tvb_reported_length(tvb) == 3)
1362 bytex = tvb_get_guint8(tvb, 3);
1363 called_len = (bytex >> 0) & 0x0F;
1364 calling_len = (bytex >> 4) & 0x0F;
1365 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1366 if (length < tvb_reported_length(tvb))
1367 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1369 return MIN(tvb_reported_length(tvb),length);
1371 case X25_CLEAR_REQUEST:
1372 case X25_RESET_REQUEST:
1373 case X25_RESTART_REQUEST:
1374 return MIN(tvb_reported_length(tvb),5);
1376 case X25_DIAGNOSTIC:
1377 return MIN(tvb_reported_length(tvb),4);
1379 case X25_CLEAR_CONFIRMATION:
1381 case X25_INTERRUPT_CONFIRMATION:
1382 case X25_RESET_CONFIRMATION:
1383 case X25_RESTART_CONFIRMATION:
1384 return MIN(tvb_reported_length(tvb),3);
1386 case X25_REGISTRATION_REQUEST:
1387 bytex = tvb_get_guint8(tvb, 3);
1388 dce_len = (bytex >> 0) & 0x0F;
1389 dte_len = (bytex >> 4) & 0x0F;
1390 length = 4 + (dte_len + dce_len + 1) / 2; /* addr */
1391 if (length < tvb_reported_length(tvb))
1392 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1394 return MIN(tvb_reported_length(tvb),length);
1396 case X25_REGISTRATION_CONFIRMATION:
1397 bytex = tvb_get_guint8(tvb, 5);
1398 dce_len = (bytex >> 0) & 0x0F;
1399 dte_len = (bytex >> 4) & 0x0F;
1400 length = 6 + (dte_len + dce_len + 1) / 2; /* addr */
1401 if (length < tvb_reported_length(tvb))
1402 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1404 return MIN(tvb_reported_length(tvb),length);
1407 if (PACKET_IS_DATA(byte2))
1408 return MIN(tvb_reported_length(tvb),3);
1410 switch (PACKET_TYPE_FC(byte2))
1413 return MIN(tvb_reported_length(tvb),3);
1416 return MIN(tvb_reported_length(tvb),3);
1419 return MIN(tvb_reported_length(tvb),3);
1425 static const value_string prt_id_vals[] = {
1426 {PRT_ID_ISO_8073, "ISO 8073 COTP"},
1427 {PRT_ID_ISO_8602, "ISO 8602 CLTP"},
1428 {PRT_ID_ISO_10736_ISO_8073, "ISO 10736 in conjunction with ISO 8073 COTP"},
1429 {PRT_ID_ISO_10736_ISO_8602, "ISO 10736 in conjunction with ISO 8602 CLTP"},
1433 static const value_string sharing_strategy_vals[] = {
1434 {0x00, "No sharing"},
1439 dissect_x25_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1442 proto_tree *x25_tree=0, *gfi_tree=0, *userdata_tree=0;
1444 guint localoffset=0;
1448 dissector_handle_t dissect = NULL;
1449 gboolean toa; /* TOA/NPI address format */
1452 char *short_name = NULL, *long_name = NULL;
1453 tvbuff_t *next_tvb = NULL;
1454 gboolean q_bit_set = FALSE;
1455 void *saved_private_data;
1456 fragment_data *fd_head;
1458 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1459 col_set_str(pinfo->cinfo, COL_PROTOCOL, "X.25");
1461 bytes0_1 = tvb_get_ntohs(tvb, 0);
1463 modulo = ((bytes0_1 & 0x2000) ? 128 : 8);
1464 vc = (int)(bytes0_1 & 0x0FFF);
1466 pinfo->ctype = CT_X25;
1467 pinfo->circuit_id = vc;
1469 if (bytes0_1 & 0x8000) toa = TRUE;
1472 x25_pkt_len = get_x25_pkt_len(tvb);
1473 if (x25_pkt_len < 3) /* packet too short */
1475 if (check_col(pinfo->cinfo, COL_INFO))
1476 col_set_str(pinfo->cinfo, COL_INFO, "Invalid/short X.25 packet");
1478 proto_tree_add_protocol_format(tree, proto_x25, tvb, 0, -1,
1479 "Invalid/short X.25 packet");
1483 pkt_type = tvb_get_guint8(tvb, 2);
1484 if (PACKET_IS_DATA(pkt_type)) {
1485 if (bytes0_1 & 0x8000)
1490 ti = proto_tree_add_item(tree, proto_x25, tvb, 0, x25_pkt_len, FALSE);
1491 x25_tree = proto_item_add_subtree(ti, ett_x25);
1492 ti = proto_tree_add_item(x25_tree, hf_x25_gfi, tvb, 0, 2, FALSE);
1493 gfi_tree = proto_item_add_subtree(ti, ett_x25_gfi);
1495 if (PACKET_IS_DATA(pkt_type)) {
1496 proto_tree_add_boolean(gfi_tree, hf_x25_qbit, tvb, 0, 2,
1499 else if (pkt_type == X25_CALL_REQUEST ||
1500 pkt_type == X25_CALL_ACCEPTED ||
1501 pkt_type == X25_CLEAR_REQUEST ||
1502 pkt_type == X25_CLEAR_CONFIRMATION) {
1503 proto_tree_add_boolean(gfi_tree, hf_x25_abit, tvb, 0, 2,
1507 if (pkt_type == X25_CALL_REQUEST || pkt_type == X25_CALL_ACCEPTED ||
1508 PACKET_IS_DATA(pkt_type)) {
1509 proto_tree_add_boolean(gfi_tree, hf_x25_dbit, tvb, 0, 2,
1512 proto_tree_add_uint(gfi_tree, hf_x25_mod, tvb, 0, 2, bytes0_1);
1516 case X25_CALL_REQUEST:
1520 short_name = "Inc. call";
1521 long_name = "Incoming call";
1525 short_name = "Call req.";
1526 long_name = "Call request";
1530 short_name = "Inc. call/Call req.";
1531 long_name = "Incoming call/Call request";
1534 if (check_col(pinfo->cinfo, COL_INFO))
1535 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
1537 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb,
1539 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1540 X25_CALL_REQUEST, "Packet Type: %s", long_name);
1543 if (localoffset < x25_pkt_len) { /* calling/called addresses */
1545 x25_toa(x25_tree, &localoffset, tvb, pinfo);
1547 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
1550 if (localoffset < x25_pkt_len) /* facilities */
1551 dump_facilities(x25_tree, &localoffset, tvb);
1553 if (localoffset < tvb_reported_length(tvb)) /* user data */
1560 ti = proto_tree_add_text(x25_tree, tvb, localoffset, -1,
1562 userdata_tree = proto_item_add_subtree(ti, ett_x25_user_data);
1565 /* X.263/ISO 9577 says that:
1567 When CLNP or ESIS are run over X.25, the SPI
1568 is 0x81 or 0x82, respectively; those are the
1569 NLPIDs for those protocol.
1571 When X.224/ISO 8073 COTP is run over X.25, and
1572 when ISO 11570 explicit identification is being
1573 used, the first octet of the user data field is
1574 a TPDU length field, and the rest is "as defined
1575 in ITU-T Rec. X.225 | ISO/IEC 8073, Annex B,
1576 or ITU-T Rec. X.264 and ISO/IEC 11570".
1578 When X.264/ISO 11570 default identification is
1579 being used, there is no user data field in the
1580 CALL REQUEST packet. This is for X.225/ISO 8073
1583 It also says that SPI values from 0x03 through 0x3f are
1584 reserved and are in use by X.224/ISO 8073 Annex B and
1585 X.264/ISO 11570. The note says that those values are
1586 not NLPIDs, they're "used by the respective higher layer
1587 protocol" and "not used for higher layer protocol
1588 identification". I infer from this and from what
1589 X.264/ISO 11570 says that this means that values in those
1590 range are valid values for the first octet of an
1591 X.224/ISO 8073 packet or for X.264/ISO 11570.
1593 Annex B of X.225/ISO 8073 mentions some additional TPDU
1594 types that can be put in what I presume is the user
1595 data of connect requests. It says that:
1597 The sending transport entity shall:
1599 a) either not transmit any TPDU in the NS-user data
1600 parameter of the N-CONNECT request primitive; or
1602 b) transmit the UN-TPDU (see ITU-T Rec. X.264 and
1603 ISO/IEC 11570) followed by the NCM-TPDU in the
1604 NS-user data parameter of the N-CONNECT request
1607 I don't know if this means that the user data field
1608 will contain a UN TPDU followed by an NCM TPDU or not.
1610 X.264/ISO 11570 says that:
1612 When default identification is being used,
1613 X.225/ISO 8073 COTP is identified. No user data
1614 is sent in the network-layer connection request.
1616 When explicit identification is being used,
1617 the user data is a UN TPDU ("Use of network
1618 connection TPDU"), which specifies the transport
1619 protocol to use over this network connection.
1620 It also says that the length of a UN TPDU shall
1621 not exceed 32 octets, i.e. shall not exceed 0x20;
1622 it says this is "due to the desire not to conflict
1623 with the protocol identifier field carried by X.25
1624 CALL REQUEST/INCOMING CALL packets", and says that
1625 field has values specified in X.244. X.244 has been
1626 superseded by X.263/ISO 9577, so that presumably
1627 means the goal is to allow a UN TPDU's length
1628 field to be distinguished from an NLPID, allowing
1629 you to tell whether X.264/ISO 11570 explicit
1630 identification is being used or an NLPID is
1631 being used as the SPI.
1633 I read this as meaning that, if the ISO mechanisms are
1634 used to identify the protocol being carried over X.25:
1636 if there's no user data in the CALL REQUEST/
1637 INCOMING CALL packet, it's COTP;
1639 if there is user data, then:
1641 if the first octet is less than or equal to
1642 32, it might be a UN TPDU, and that identifies
1643 the transport protocol being used, and
1644 it may be followed by more data, such
1645 as a COTP NCM TPDU if it's COTP;
1647 if the first octet is greater than 32, it's
1648 an NLPID, *not* a TPDU length, and the
1649 stuff following it is *not* a TPDU.
1651 Figure A.2 of X.263/ISO 9577 seems to say that the
1652 first octet of the user data is a TPDU length field,
1653 in the range 0x03 through 0x82, and says they are
1654 for X.225/ISO 8073 Annex B or X.264/ISO 11570.
1656 However, X.264/ISO 11570 seems to imply that the length
1657 field would be that of a UN TPDU, which must be less
1658 than or equal to 0x20, and X.225/ISO 8073 Annex B seems
1659 to indicate that the user data must begin with
1660 an X.264/ISO 11570 UN TPDU, so I'd say that A.2 should
1661 have said "in the range 0x03 through 0x20", instead
1662 (the length value doesn't include the length field,
1663 and the minimum UN TPDU has length, type, PRT-ID,
1664 and SHARE, so that's 3 bytes without the length). */
1665 spi = tvb_get_guint8(tvb, localoffset);
1666 if (spi > 32 || spi < 3) {
1667 /* First octet is > 32, or < 3, so the user data isn't an
1668 X.264/ISO 11570 UN TPDU */
1671 /* First octet is >= 3 and <= 32, so the user data *might*
1672 be an X.264/ISO 11570 UN TPDU. Check whether we have
1673 enough data to see if it is. */
1674 if (tvb_bytes_exist(tvb, localoffset+1, 1)) {
1675 /* We do; check whether the second octet is 1. */
1676 if (tvb_get_guint8(tvb, localoffset+1) == 0x01) {
1677 /* Yes, the second byte is 1, so it looks like
1681 /* No, the second byte is not 1, so it's not a
1686 /* We can't see the second byte of the putative UN
1687 TPDU, so we don't know if that's what it is. */
1691 if (is_x_264 == -1) {
1693 * We don't know what it is; just skip it.
1695 localoffset = tvb_length(tvb);
1696 } else if (is_x_264) {
1697 /* It looks like an X.264 UN TPDU, so show it as such. */
1698 if (userdata_tree) {
1699 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1700 "X.264 length indicator: %u",
1702 proto_tree_add_text(userdata_tree, tvb, localoffset+1, 1,
1703 "X.264 UN TPDU identifier: 0x%02X",
1704 tvb_get_guint8(tvb, localoffset+1));
1706 prt_id = tvb_get_guint8(tvb, localoffset+2);
1707 if (userdata_tree) {
1708 proto_tree_add_text(x25_tree, tvb, localoffset+2, 1,
1709 "X.264 protocol identifier: %s",
1710 val_to_str(prt_id, prt_id_vals,
1711 "Unknown (0x%02X)"));
1712 proto_tree_add_text(x25_tree, tvb, localoffset+3, 1,
1713 "X.264 sharing strategy: %s",
1714 val_to_str(tvb_get_guint8(tvb, localoffset+3),
1715 sharing_strategy_vals, "Unknown (0x%02X)"));
1718 /* XXX - dissect the variable part? */
1720 /* The length doesn't include the length octet itself. */
1721 localoffset += spi + 1;
1725 case PRT_ID_ISO_8073:
1727 if (!pinfo->fd->flags.visited)
1728 x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
1729 /* XXX - dissect the rest of the user data as COTP?
1730 That needs support for NCM TPDUs, etc. */
1733 case PRT_ID_ISO_8602:
1735 if (!pinfo->fd->flags.visited)
1736 x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
1739 } else if (is_x_264 == 0) {
1740 /* It doesn't look like a UN TPDU, so compare the first
1741 octet of the CALL REQUEST packet with various X.263/
1742 ISO 9577 NLPIDs, as per Annex A of X.263/ISO 9577. */
1744 if (userdata_tree) {
1745 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1746 "X.263 secondary protocol ID: %s",
1747 val_to_str(spi, nlpid_vals, "Unknown (0x%02x)"));
1750 if (!pinfo->fd->flags.visited) {
1752 * Is there a dissector handle for this SPI?
1753 * If so, assign it to this virtual circuit.
1755 dissect = dissector_get_port_handle(x25_subdissector_table, spi);
1756 if (dissect != NULL)
1757 x25_hash_add_proto_start(vc, pinfo->fd->num, dissect);
1761 * If there's only one octet of user data, it's just
1762 * an NLPID; don't try to dissect it.
1764 if (localoffset + 1 == tvb_reported_length(tvb))
1768 * There's more than one octet of user data, so we'll
1769 * dissect it; for some protocols, the NLPID is considered
1770 * to be part of the PDU, so, for those cases, we don't
1771 * skip past it. For other protocols, we skip the NLPID.
1775 case NLPID_ISO8473_CLNP:
1776 case NLPID_ISO9542_ESIS:
1777 case NLPID_ISO10589_ISIS:
1778 case NLPID_ISO10747_IDRP:
1781 * The NLPID is part of the PDU. Don't skip it.
1782 * But if it's all there is to the PDU, don't
1783 * bother dissecting it.
1787 case NLPID_SPI_X_29:
1789 * The first 4 bytes of the call user data are
1790 * the SPI plus 3 reserved bytes; they are not
1791 * part of the data to be dissected as X.29 data.
1798 * The NLPID isn't part of the PDU - skip it.
1799 * If that means there's nothing to dissect
1806 case X25_CALL_ACCEPTED:
1810 short_name = "Call conn.";
1811 long_name = "Call connected";
1815 short_name = "Call acc.";
1816 long_name = "Call accepted";
1820 short_name = "Call conn./Call acc.";
1821 long_name = "Call connected/Call accepted";
1824 if(check_col(pinfo->cinfo, COL_INFO))
1825 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
1827 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1828 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1829 X25_CALL_ACCEPTED, "Packet Type: %s", long_name);
1832 if (localoffset < x25_pkt_len) { /* calling/called addresses */
1834 x25_toa(x25_tree, &localoffset, tvb, pinfo);
1836 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
1839 if (localoffset < x25_pkt_len) /* facilities */
1840 dump_facilities(x25_tree, &localoffset, tvb);
1842 case X25_CLEAR_REQUEST:
1846 short_name = "Clear ind.";
1847 long_name = "Clear indication";
1851 short_name = "Clear req.";
1852 long_name = "Clear request";
1856 short_name = "Clear ind./Clear req.";
1857 long_name = "Clear indication/Clear request";
1860 if(check_col(pinfo->cinfo, COL_INFO)) {
1861 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - %s", short_name,
1862 vc, clear_code(tvb_get_guint8(tvb, 3)),
1863 clear_diag(tvb_get_guint8(tvb, 4)));
1865 x25_hash_add_proto_end(vc, pinfo->fd->num);
1867 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1868 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb,
1869 localoffset+2, 1, X25_CLEAR_REQUEST, "Packet Type: %s",
1871 proto_tree_add_text(x25_tree, tvb, 3, 1,
1872 "Cause : %s", clear_code(tvb_get_guint8(tvb, 3)));
1873 proto_tree_add_text(x25_tree, tvb, 4, 1,
1874 "Diagnostic : %s", clear_diag(tvb_get_guint8(tvb, 4)));
1876 localoffset = x25_pkt_len;
1878 case X25_CLEAR_CONFIRMATION:
1879 if(check_col(pinfo->cinfo, COL_INFO))
1880 col_add_fstr(pinfo->cinfo, COL_INFO, "Clear Conf. VC:%d", vc);
1882 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1883 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1884 X25_CLEAR_CONFIRMATION);
1886 localoffset = x25_pkt_len;
1888 if (localoffset < tvb_reported_length(tvb)) { /* extended clear conf format */
1890 x25_toa(x25_tree, &localoffset, tvb, pinfo);
1892 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
1895 if (localoffset < tvb_reported_length(tvb)) /* facilities */
1896 dump_facilities(x25_tree, &localoffset, tvb);
1898 case X25_DIAGNOSTIC:
1899 if(check_col(pinfo->cinfo, COL_INFO)) {
1900 col_add_fstr(pinfo->cinfo, COL_INFO, "Diag. %d",
1901 (int)tvb_get_guint8(tvb, 3));
1904 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1906 proto_tree_add_text(x25_tree, tvb, 3, 1,
1907 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 3));
1909 localoffset = x25_pkt_len;
1912 if(check_col(pinfo->cinfo, COL_INFO))
1913 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt VC:%d", vc);
1915 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1916 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1919 localoffset = x25_pkt_len;
1921 case X25_INTERRUPT_CONFIRMATION:
1922 if(check_col(pinfo->cinfo, COL_INFO))
1923 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt Conf. VC:%d", vc);
1925 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1926 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1927 X25_INTERRUPT_CONFIRMATION);
1929 localoffset = x25_pkt_len;
1931 case X25_RESET_REQUEST:
1935 short_name = "Reset ind.";
1936 long_name = "Reset indication";
1940 short_name = "Reset req.";
1941 long_name = "Reset request";
1945 short_name = "Reset ind./Reset req.";
1946 long_name = "Reset indication/Reset request";
1949 if(check_col(pinfo->cinfo, COL_INFO)) {
1950 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - Diag.:%d",
1951 short_name, vc, reset_code(tvb_get_guint8(tvb, 3)),
1952 (int)tvb_get_guint8(tvb, 4));
1954 x25_hash_add_proto_end(vc, pinfo->fd->num);
1956 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1957 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1958 X25_RESET_REQUEST, "Packet Type: %s", long_name);
1959 proto_tree_add_text(x25_tree, tvb, 3, 1,
1960 "Cause : %s", reset_code(tvb_get_guint8(tvb, 3)));
1961 proto_tree_add_text(x25_tree, tvb, 4, 1,
1962 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
1964 localoffset = x25_pkt_len;
1966 case X25_RESET_CONFIRMATION:
1967 if(check_col(pinfo->cinfo, COL_INFO))
1968 col_add_fstr(pinfo->cinfo, COL_INFO, "Reset conf. VC:%d", vc);
1970 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1971 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1972 X25_RESET_CONFIRMATION);
1974 localoffset = x25_pkt_len;
1976 case X25_RESTART_REQUEST:
1980 short_name = "Restart ind.";
1981 long_name = "Restart indication";
1985 short_name = "Restart req.";
1986 long_name = "Restart request";
1990 short_name = "Restart ind./Restart req.";
1991 long_name = "Restart indication/Restart request";
1994 if(check_col(pinfo->cinfo, COL_INFO)) {
1995 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s - Diag.:%d",
1997 restart_code(tvb_get_guint8(tvb, 3)),
1998 (int)tvb_get_guint8(tvb, 3));
2001 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
2002 X25_RESTART_REQUEST, "Packet Type: %s", long_name);
2003 proto_tree_add_text(x25_tree, tvb, 3, 1,
2004 "Cause : %s", restart_code(tvb_get_guint8(tvb, 3)));
2005 proto_tree_add_text(x25_tree, tvb, 4, 1,
2006 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
2008 localoffset = x25_pkt_len;
2010 case X25_RESTART_CONFIRMATION:
2011 if(check_col(pinfo->cinfo, COL_INFO))
2012 col_set_str(pinfo->cinfo, COL_INFO, "Restart conf.");
2014 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2015 X25_RESTART_CONFIRMATION);
2016 localoffset = x25_pkt_len;
2018 case X25_REGISTRATION_REQUEST:
2019 if(check_col(pinfo->cinfo, COL_INFO))
2020 col_set_str(pinfo->cinfo, COL_INFO, "Registration req.");
2022 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2023 X25_REGISTRATION_REQUEST);
2025 if (localoffset < x25_pkt_len)
2026 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, TRUE);
2029 if (localoffset < x25_pkt_len)
2030 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
2031 "Registration length: %d",
2032 tvb_get_guint8(tvb, localoffset) & 0x7F);
2033 if (localoffset+1 < x25_pkt_len)
2034 proto_tree_add_text(x25_tree, tvb, localoffset+1,
2035 tvb_get_guint8(tvb, localoffset) & 0x7F,
2038 localoffset = tvb_reported_length(tvb);
2040 case X25_REGISTRATION_CONFIRMATION:
2041 if(check_col(pinfo->cinfo, COL_INFO))
2042 col_set_str(pinfo->cinfo, COL_INFO, "Registration conf.");
2044 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2045 X25_REGISTRATION_CONFIRMATION);
2046 proto_tree_add_text(x25_tree, tvb, 3, 1,
2047 "Cause: %s", registration_code(tvb_get_guint8(tvb, 3)));
2048 proto_tree_add_text(x25_tree, tvb, 4, 1,
2049 "Diagnostic: %s", registration_code(tvb_get_guint8(tvb, 4)));
2052 if (localoffset < x25_pkt_len)
2053 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, TRUE);
2056 if (localoffset < x25_pkt_len)
2057 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
2058 "Registration length: %d",
2059 tvb_get_guint8(tvb, localoffset) & 0x7F);
2060 if (localoffset+1 < x25_pkt_len)
2061 proto_tree_add_text(x25_tree, tvb, localoffset+1,
2062 tvb_get_guint8(tvb, localoffset) & 0x7F,
2065 localoffset = tvb_reported_length(tvb);
2069 if (PACKET_IS_DATA(pkt_type))
2071 if(check_col(pinfo->cinfo, COL_INFO)) {
2073 col_add_fstr(pinfo->cinfo, COL_INFO,
2074 "Data VC:%d P(S):%d P(R):%d %s", vc,
2075 (pkt_type >> 1) & 0x07,
2076 (pkt_type >> 5) & 0x07,
2077 ((pkt_type >> 4) & 0x01) ? " M" : "");
2079 col_add_fstr(pinfo->cinfo, COL_INFO,
2080 "Data VC:%d P(S):%d P(R):%d %s", vc,
2081 tvb_get_guint8(tvb, localoffset+1) >> 1,
2083 (tvb_get_guint8(tvb, localoffset+1) & 0x01) ? " M" : "");
2086 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2089 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2090 localoffset, 1, pkt_type);
2091 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod8, tvb,
2092 localoffset, 1, pkt_type);
2093 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod8, tvb,
2094 localoffset, 1, pkt_type);
2095 proto_tree_add_uint(x25_tree, hf_x25_type_data, tvb,
2096 localoffset, 1, pkt_type);
2099 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod128, tvb,
2100 localoffset, 1, pkt_type);
2101 proto_tree_add_uint(x25_tree, hf_x25_type_data, tvb,
2102 localoffset, 1, pkt_type);
2103 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod128, tvb,
2105 tvb_get_guint8(tvb, localoffset+1));
2106 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod128, tvb,
2108 tvb_get_guint8(tvb, localoffset+1));
2111 localoffset += (modulo == 8) ? 1 : 2;
2114 fd_head = fragment_add_seq_next(tvb, localoffset,
2115 pinfo, vc, x25_segment_table,
2116 x25_reassembled_table,
2117 tvb_reported_length(tvb) - localoffset,
2118 (pkt_type >> 4) & 0x01);
2119 pinfo->fragmented = (pkt_type >> 4) & 0x01;
2124 /* This is the last packet */
2125 next_tvb = tvb_new_real_data(fd_head->data,
2128 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
2129 add_new_data_source(pinfo, next_tvb, "Reassembled X25");
2130 show_fragment_seq_tree(fd_head,
2138 switch (PACKET_TYPE_FC(pkt_type))
2141 if(check_col(pinfo->cinfo, COL_INFO)) {
2143 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2144 vc, (pkt_type >> 5) & 0x07);
2146 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2147 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2150 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2153 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2154 localoffset, 1, pkt_type);
2155 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2156 localoffset, 1, X25_RR);
2159 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2160 localoffset, 1, X25_RR);
2161 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2162 localoffset+1, 1, FALSE);
2168 if(check_col(pinfo->cinfo, COL_INFO)) {
2170 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2171 vc, (pkt_type >> 5) & 0x07);
2173 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2174 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2177 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2180 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2181 localoffset, 1, pkt_type);
2182 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2183 localoffset, 1, X25_RNR);
2186 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2187 localoffset, 1, X25_RNR);
2188 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2189 localoffset+1, 1, FALSE);
2195 if(check_col(pinfo->cinfo, COL_INFO)) {
2197 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2198 vc, (pkt_type >> 5) & 0x07);
2200 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2201 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2204 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2207 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2208 localoffset, 1, pkt_type);
2209 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2210 localoffset, 1, X25_REJ);
2213 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2214 localoffset, 1, X25_REJ);
2215 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2216 localoffset+1, 1, FALSE);
2220 localoffset += (modulo == 8) ? 1 : 2;
2223 if (localoffset >= tvb_reported_length(tvb)) return;
2224 if (pinfo->fragmented)
2228 next_tvb = tvb_new_subset(tvb, localoffset, -1, -1);
2230 saved_private_data = pinfo->private_data;
2231 pinfo->private_data = &q_bit_set;
2233 /* See if there's already a dissector for this circuit. */
2234 if (try_circuit_dissector(CT_X25, vc, pinfo->fd->num, next_tvb, pinfo,
2236 pinfo->private_data = saved_private_data;
2237 return; /* found it and dissected it */
2240 /* Did the user suggest QLLC/SNA? */
2241 if (payload_is_qllc_sna) {
2242 /* Yes - dissect it as QLLC/SNA. */
2243 if (!pinfo->fd->flags.visited)
2244 x25_hash_add_proto_start(vc, pinfo->fd->num, qllc_handle);
2245 call_dissector(qllc_handle, next_tvb, pinfo, tree);
2246 pinfo->private_data = saved_private_data;
2250 /* If the Call Req. has not been captured, let's look at the first
2251 byte of the payload to see if this looks like IP or CLNP. */
2252 switch (tvb_get_guint8(tvb, localoffset)) {
2255 /* Looks like an IP header */
2256 if (!pinfo->fd->flags.visited)
2257 x25_hash_add_proto_start(vc, pinfo->fd->num, ip_handle);
2258 call_dissector(ip_handle, next_tvb, pinfo, tree);
2259 pinfo->private_data = saved_private_data;
2262 case NLPID_ISO8473_CLNP:
2263 if (!pinfo->fd->flags.visited)
2264 x25_hash_add_proto_start(vc, pinfo->fd->num, clnp_handle);
2265 call_dissector(clnp_handle, next_tvb, pinfo, tree);
2266 pinfo->private_data = saved_private_data;
2270 /* Try the heuristic dissectors. */
2271 if (dissector_try_heuristic(x25_heur_subdissector_list, next_tvb, pinfo,
2273 pinfo->private_data = saved_private_data;
2277 /* All else failed; dissect it as raw data */
2278 call_dissector(data_handle, next_tvb, pinfo, tree);
2279 pinfo->private_data = saved_private_data;
2283 * X.25 dissector for use when "pinfo->pseudo_header" points to a
2284 * "struct x25_phdr".
2287 dissect_x25_dir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2289 dissect_x25_common(tvb, pinfo, tree,
2290 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? X25_FROM_DCE :
2295 * X.25 dissector for use when "pinfo->pseudo_header" doesn't point to a
2296 * "struct x25_phdr".
2299 dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2302 * We don't know if this packet is DTE->DCE or DCE->DCE.
2304 dissect_x25_common(tvb, pinfo, tree, X25_UNKNOWN);
2308 x25_reassemble_init(void)
2310 fragment_table_init(&x25_segment_table);
2311 reassembled_table_init(&x25_reassembled_table);
2315 proto_register_x25(void)
2317 static hf_register_info hf[] = {
2319 { "GFI", "x.25.gfi", FT_UINT16, BASE_DEC, NULL, 0xF000,
2320 "General format identifier", HFILL }},
2322 { "A Bit", "x.25.a", FT_BOOLEAN, 16, NULL, 0x8000,
2323 "Address Bit", HFILL }},
2325 { "Q Bit", "x.25.q", FT_BOOLEAN, 16, NULL, 0x8000,
2326 "Qualifier Bit", HFILL }},
2328 { "D Bit", "x.25.d", FT_BOOLEAN, 16, NULL, 0x4000,
2329 "Delivery Confirmation Bit", HFILL }},
2331 { "Modulo", "x.25.mod", FT_UINT16, BASE_DEC, VALS(vals_modulo), 0x3000,
2332 "Specifies whether the frame is modulo 8 or 128", HFILL }},
2334 { "Logical Channel", "x.25.lcn", FT_UINT16, BASE_DEC, NULL, 0x0FFF,
2335 "Logical Channel Number", HFILL }},
2337 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x0,
2338 "Packet Type", HFILL }},
2339 { &hf_x25_type_fc_mod8,
2340 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x1F,
2341 "Packet Type", HFILL }},
2342 { &hf_x25_type_data,
2343 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x01,
2344 "Packet Type", HFILL }},
2346 { "P(R)", "x.25.p_r", FT_UINT8, BASE_DEC, NULL, 0xE0,
2347 "Packet Receive Sequence Number", HFILL }},
2348 { &hf_x25_p_r_mod128,
2349 { "P(R)", "x.25.p_r", FT_UINT8, BASE_DEC, NULL, 0xFE,
2350 "Packet Receive Sequence Number", HFILL }},
2351 { &hf_x25_mbit_mod8,
2352 { "M Bit", "x.25.m", FT_BOOLEAN, 8, TFS(&m_bit_tfs), 0x10,
2353 "More Bit", HFILL }},
2354 { &hf_x25_mbit_mod128,
2355 { "M Bit", "x.25.m", FT_BOOLEAN, 8, TFS(&m_bit_tfs), 0x01,
2356 "More Bit", HFILL }},
2358 { "P(S)", "x.25.p_s", FT_UINT8, BASE_DEC, NULL, 0x0E,
2359 "Packet Send Sequence Number", HFILL }},
2360 { &hf_x25_p_s_mod128,
2361 { "P(S)", "x.25.p_s", FT_UINT8, BASE_DEC, NULL, 0xFE,
2362 "Packet Send Sequence Number", HFILL }},
2363 { &hf_x25_segment_overlap,
2364 { "Fragment overlap", "x25.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2365 "Fragment overlaps with other fragments", HFILL }},
2367 { &hf_x25_segment_overlap_conflict,
2368 { "Conflicting data in fragment overlap", "x25.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2369 "Overlapping fragments contained conflicting data", HFILL }},
2371 { &hf_x25_segment_multiple_tails,
2372 { "Multiple tail fragments found", "x25.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2373 "Several tails were found when defragmenting the packet", HFILL }},
2375 { &hf_x25_segment_too_long_segment,
2376 { "Fragment too long", "x25.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2377 "Fragment contained data past end of packet", HFILL }},
2379 { &hf_x25_segment_error,
2380 { "Defragmentation error", "x25.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2381 "Defragmentation error due to illegal fragments", HFILL }},
2384 { "X.25 Fragment", "x25.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2385 "X25 Fragment", HFILL }},
2388 { "X.25 Fragments", "x25.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
2389 "X.25 Fragments", HFILL }},
2391 static gint *ett[] = {
2395 &ett_x25_fac_unknown,
2397 &ett_x25_fac_reverse,
2398 &ett_x25_fac_throughput,
2400 &ett_x25_fac_called_modif,
2401 &ett_x25_fac_cug_outgoing_acc,
2402 &ett_x25_fac_throughput_min,
2403 &ett_x25_fac_express_data,
2404 &ett_x25_fac_bilateral_cug,
2405 &ett_x25_fac_packet_size,
2406 &ett_x25_fac_window_size,
2407 &ett_x25_fac_rpoa_selection,
2408 &ett_x25_fac_transit_delay,
2409 &ett_x25_fac_call_transfer,
2410 &ett_x25_fac_called_addr_ext,
2411 &ett_x25_fac_ete_transit_delay,
2412 &ett_x25_fac_calling_addr_ext,
2413 &ett_x25_fac_call_deflect,
2414 &ett_x25_fac_priority,
2419 module_t *x25_module;
2421 proto_x25 = proto_register_protocol ("X.25", "X.25", "x.25");
2422 proto_register_field_array (proto_x25, hf, array_length(hf));
2423 proto_register_subtree_array(ett, array_length(ett));
2425 x25_subdissector_table = register_dissector_table("x.25.spi",
2426 "X.25 secondary protocol identifier", FT_UINT8, BASE_HEX);
2427 register_heur_dissector_list("x.25", &x25_heur_subdissector_list);
2429 register_dissector("x.25_dir", dissect_x25_dir, proto_x25);
2430 register_dissector("x.25", dissect_x25, proto_x25);
2433 x25_module = prefs_register_protocol(proto_x25, NULL);
2434 prefs_register_obsolete_preference(x25_module, "non_q_bit_is_sna");
2435 prefs_register_bool_preference(x25_module, "payload_is_qllc_sna",
2436 "Default to QLLC/SNA",
2437 "If CALL REQUEST not seen or didn't specify protocol, dissect as QLLC/SNA",
2438 &payload_is_qllc_sna);
2439 prefs_register_bool_preference(x25_module, "reassemble_x25",
2440 "Reassemble fragmented X.25 packets",
2441 "Reassemble fragmented X.25 packets",
2443 register_init_routine(&x25_reassemble_init);
2447 proto_reg_handoff_x25(void)
2449 dissector_handle_t x25_handle;
2452 * Get handles for various dissectors.
2454 ip_handle = find_dissector("ip");
2455 clnp_handle = find_dissector("clnp");
2456 ositp_handle = find_dissector("ositp");
2457 qllc_handle = find_dissector("qllc");
2458 data_handle = find_dissector("data");
2460 x25_handle = find_dissector("x.25");
2461 dissector_add("llc.dsap", SAP_X25, x25_handle);