2 * Routines for X.25 packet disassembly
3 * Olivier Abad <oabad@noos.fr>
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 <epan/reassemble.h>
38 #include <epan/prefs.h>
39 #include <epan/emem.h>
41 #include "x264_prt_id.h"
44 * Direction of packet.
47 X25_FROM_DCE, /* DCE->DTE */
48 X25_FROM_DTE, /* DTE->DCE */
49 X25_UNKNOWN /* direction unknown */
53 * 0 for data packets, 1 for non-data packets.
55 #define X25_NONDATA_BIT 0x01
57 #define X25_CALL_REQUEST 0x0B
58 #define X25_CALL_ACCEPTED 0x0F
59 #define X25_CLEAR_REQUEST 0x13
60 #define X25_CLEAR_CONFIRMATION 0x17
61 #define X25_INTERRUPT 0x23
62 #define X25_INTERRUPT_CONFIRMATION 0x27
63 #define X25_RESET_REQUEST 0x1B
64 #define X25_RESET_CONFIRMATION 0x1F
65 #define X25_RESTART_REQUEST 0xFB
66 #define X25_RESTART_CONFIRMATION 0xFF
67 #define X25_REGISTRATION_REQUEST 0xF3
68 #define X25_REGISTRATION_CONFIRMATION 0xF7
69 #define X25_DIAGNOSTIC 0xF1
75 #define PACKET_IS_DATA(type) (!(type & X25_NONDATA_BIT))
76 #define PACKET_TYPE_FC(type) (type & 0x1F)
78 #define X25_MBIT_MOD8 0x10
79 #define X25_MBIT_MOD128 0x01
81 #define X25_ABIT 0x8000
83 #define X25_QBIT 0x8000
84 #define X25_DBIT 0x4000
86 #define X25_FAC_CLASS_MASK 0xC0
88 #define X25_FAC_CLASS_A 0x00
89 #define X25_FAC_CLASS_B 0x40
90 #define X25_FAC_CLASS_C 0x80
91 #define X25_FAC_CLASS_D 0xC0
93 #define X25_FAC_COMP_MARK 0x00
94 #define X25_FAC_REVERSE 0x01
95 #define X25_FAC_THROUGHPUT 0x02
96 #define X25_FAC_CUG 0x03
97 #define X25_FAC_CALLED_MODIF 0x08
98 #define X25_FAC_CUG_OUTGOING_ACC 0x09
99 #define X25_FAC_THROUGHPUT_MIN 0x0A
100 #define X25_FAC_EXPRESS_DATA 0x0B
101 #define X25_FAC_BILATERAL_CUG 0x41
102 #define X25_FAC_PACKET_SIZE 0x42
103 #define X25_FAC_WINDOW_SIZE 0x43
104 #define X25_FAC_RPOA_SELECTION 0x44
105 #define X25_FAC_TRANSIT_DELAY 0x49
106 #define X25_FAC_CALL_TRANSFER 0xC3
107 #define X25_FAC_CALLED_ADDR_EXT 0xC9
108 #define X25_FAC_ETE_TRANSIT_DELAY 0xCA
109 #define X25_FAC_CALLING_ADDR_EXT 0xCB
110 #define X25_FAC_CALL_DEFLECT 0xD1
111 #define X25_FAC_PRIORITY 0xD2
113 static int proto_x25 = -1;
114 static int hf_x25_gfi = -1;
115 static int hf_x25_abit = -1;
116 static int hf_x25_qbit = -1;
117 static int hf_x25_dbit = -1;
118 static int hf_x25_mod = -1;
119 static int hf_x25_lcn = -1;
120 static int hf_x25_type = -1;
121 static int hf_x25_type_fc_mod8 = -1;
122 static int hf_x25_type_data = -1;
123 static int hf_x25_p_r_mod8 = -1;
124 static int hf_x25_p_r_mod128 = -1;
125 static int hf_x25_mbit_mod8 = -1;
126 static int hf_x25_mbit_mod128 = -1;
127 static int hf_x25_p_s_mod8 = -1;
128 static int hf_x25_p_s_mod128 = -1;
130 static gint ett_x25 = -1;
131 static gint ett_x25_gfi = -1;
132 static gint ett_x25_fac = -1;
133 static gint ett_x25_fac_unknown = -1;
134 static gint ett_x25_fac_mark = -1;
135 static gint ett_x25_fac_reverse = -1;
136 static gint ett_x25_fac_throughput = -1;
137 static gint ett_x25_fac_cug = -1;
138 static gint ett_x25_fac_called_modif = -1;
139 static gint ett_x25_fac_cug_outgoing_acc = -1;
140 static gint ett_x25_fac_throughput_min = -1;
141 static gint ett_x25_fac_express_data = -1;
142 static gint ett_x25_fac_bilateral_cug = -1;
143 static gint ett_x25_fac_packet_size = -1;
144 static gint ett_x25_fac_window_size = -1;
145 static gint ett_x25_fac_rpoa_selection = -1;
146 static gint ett_x25_fac_transit_delay = -1;
147 static gint ett_x25_fac_call_transfer = -1;
148 static gint ett_x25_fac_called_addr_ext = -1;
149 static gint ett_x25_fac_ete_transit_delay = -1;
150 static gint ett_x25_fac_calling_addr_ext = -1;
151 static gint ett_x25_fac_call_deflect = -1;
152 static gint ett_x25_fac_priority = -1;
153 static gint ett_x25_user_data = -1;
155 static gint ett_x25_segment = -1;
156 static gint ett_x25_segments = -1;
157 static gint hf_x25_segments = -1;
158 static gint hf_x25_segment = -1;
159 static gint hf_x25_segment_overlap = -1;
160 static gint hf_x25_segment_overlap_conflict = -1;
161 static gint hf_x25_segment_multiple_tails = -1;
162 static gint hf_x25_segment_too_long_segment = -1;
163 static gint hf_x25_segment_error = -1;
165 static const value_string vals_modulo[] = {
171 static const value_string vals_x25_type[] = {
172 { X25_CALL_REQUEST, "Call" },
173 { X25_CALL_ACCEPTED, "Call Accepted" },
174 { X25_CLEAR_REQUEST, "Clear" },
175 { X25_CLEAR_CONFIRMATION, "Clear Confirmation" },
176 { X25_INTERRUPT, "Interrupt" },
177 { X25_INTERRUPT_CONFIRMATION, "Interrupt Confirmation" },
178 { X25_RESET_REQUEST, "Reset" },
179 { X25_RESET_CONFIRMATION, "Reset Confirmation" },
180 { X25_RESTART_REQUEST, "Restart" },
181 { X25_RESTART_CONFIRMATION, "Restart Confirmation" },
182 { X25_REGISTRATION_REQUEST, "Registration" },
183 { X25_REGISTRATION_CONFIRMATION, "Registration Confirmation" },
184 { X25_DIAGNOSTIC, "Diagnostic" },
188 { X25_DATA, "Data" },
192 static struct true_false_string m_bit_tfs = {
197 static const fragment_items x25_frag_items = {
202 &hf_x25_segment_overlap,
203 &hf_x25_segment_overlap_conflict,
204 &hf_x25_segment_multiple_tails,
205 &hf_x25_segment_too_long_segment,
206 &hf_x25_segment_error,
211 static dissector_handle_t ip_handle;
212 static dissector_handle_t clnp_handle;
213 static dissector_handle_t ositp_handle;
214 static dissector_handle_t qllc_handle;
215 static dissector_handle_t data_handle;
218 static gboolean payload_is_qllc_sna = FALSE;
219 static gboolean reassemble_x25 = FALSE;
221 /* Reassembly of X.25 */
223 static GHashTable *x25_segment_table = NULL;
224 static GHashTable *x25_reassembled_table = NULL;
226 static dissector_table_t x25_subdissector_table;
227 static heur_dissector_list_t x25_heur_subdissector_list;
230 x25_hash_add_proto_start(guint16 vc, guint32 frame, dissector_handle_t dissect)
235 * Is there already a circuit with this VC number?
237 circuit = find_circuit(CT_X25, vc, frame);
238 if (circuit != NULL) {
240 * Yes - close it, as we're creating a new one.
242 close_circuit(circuit, frame - 1);
246 * Set up a new circuit.
248 circuit = circuit_new(CT_X25, vc, frame);
253 circuit_set_dissector(circuit, dissect);
257 x25_hash_add_proto_end(guint16 vc, guint32 frame)
262 * Try to find the circuit.
264 circuit = find_circuit(CT_X25, vc, frame);
267 * If we succeeded, close it.
270 close_circuit(circuit, frame);
273 static const char *clear_code(unsigned char code)
277 if (code == 0x00 || (code & 0x80) == 0x80)
278 return "DTE Originated";
280 return "Number Busy";
282 return "Invalid Facility Requested";
284 return "Network Congestion";
286 return "Out Of Order";
288 return "Access Barred";
290 return "Not Obtainable";
292 return "Remote Procedure Error";
294 return "Local Procedure Error";
296 return "RPOA Out Of Order";
298 return "Reverse Charging Acceptance Not Subscribed";
300 return "Incompatible Destination";
302 return "Fast Select Acceptance Not Subscribed";
304 return "Destination Absent";
307 g_snprintf(buffer, 32, "Unknown %02X", code);
312 static const char *clear_diag(unsigned char code)
317 return "No additional information";
319 return "Invalid P(S)";
321 return "Invalid P(R)";
323 return "Packet type invalid";
325 return "Packet type invalid for state r1";
327 return "Packet type invalid for state r2";
329 return "Packet type invalid for state r3";
331 return "Packet type invalid for state p1";
333 return "Packet type invalid for state p2";
335 return "Packet type invalid for state p3";
337 return "Packet type invalid for state p4";
339 return "Packet type invalid for state p5";
341 return "Packet type invalid for state p6";
343 return "Packet type invalid for state p7";
345 return "Packet type invalid for state d1";
347 return "Packet type invalid for state d2";
349 return "Packet type invalid for state d3";
351 return "Packet not allowed";
353 return "Unidentifiable packet";
355 return "Call on one-way logical channel";
357 return "Invalid packet type on a PVC";
359 return "Packet on unassigned LC";
361 return "Reject not subscribed to";
363 return "Packet too short";
365 return "Packet too long";
367 return "Invalid general format identifier";
369 return "Restart/registration packet with nonzero bits";
371 return "Packet type not compatible with facility";
373 return "Unauthorised interrupt confirmation";
375 return "Unauthorised interrupt";
377 return "Unauthorised reject";
379 return "Time expired";
381 return "Time expired for incoming call";
383 return "Time expired for clear indication";
385 return "Time expired for reset indication";
387 return "Time expired for restart indication";
389 return "Time expired for call deflection";
391 return "Call set-up/clearing or registration pb.";
393 return "Facility/registration code not allowed";
395 return "Facility parameter not allowed";
397 return "Invalid called DTE address";
399 return "Invalid calling DTE address";
401 return "Invalid facility/registration length";
403 return "Incoming call barred";
405 return "No logical channel available";
407 return "Call collision";
409 return "Duplicate facility requested";
411 return "Non zero address length";
413 return "Non zero facility length";
415 return "Facility not provided when expected";
417 return "Invalid CCITT-specified DTE facility";
419 return "Max. nb of call redir/defl. exceeded";
421 return "Miscellaneous";
423 return "Improper cause code from DTE";
425 return "Not aligned octet";
427 return "Inconsistent Q bit setting";
429 return "NUI problem";
431 return "International problem";
433 return "Remote network problem";
435 return "International protocol problem";
437 return "International link out of order";
439 return "International link busy";
441 return "Transit network facility problem";
443 return "Remote network facility problem";
445 return "International routing problem";
447 return "Temporary routing problem";
449 return "Unknown called DNIC";
451 return "Maintenance action";
453 return "Timer expired or retransmission count surpassed";
455 return "Timer expired or retransmission count surpassed for INTERRUPT";
457 return "Timer expired or retransmission count surpassed for DATA "
458 "packet transmission";
460 return "Timer expired or retransmission count surpassed for REJECT";
462 return "DTE-specific signals";
464 return "DTE operational";
466 return "DTE not operational";
468 return "DTE resource constraint";
470 return "Fast select not subscribed";
472 return "Invalid partially full DATA packet";
474 return "D-bit procedure not supported";
476 return "Registration/Cancellation confirmed";
478 return "OSI network service problem";
480 return "Disconnection (transient condition)";
482 return "Disconnection (permanent condition)";
484 return "Connection rejection - reason unspecified (transient "
487 return "Connection rejection - reason unspecified (permanent "
490 return "Connection rejection - quality of service not available "
491 "transient condition)";
493 return "Connection rejection - quality of service not available "
494 "permanent condition)";
496 return "Connection rejection - NSAP unreachable (transient condition)";
498 return "Connection rejection - NSAP unreachable (permanent condition)";
500 return "reset - reason unspecified";
502 return "reset - congestion";
504 return "Connection rejection - NSAP address unknown (permanent "
507 return "Higher layer initiated";
509 return "Disconnection - normal";
511 return "Disconnection - abnormal";
513 return "Disconnection - incompatible information in user data";
515 return "Connection rejection - reason unspecified (transient "
518 return "Connection rejection - reason unspecified (permanent "
521 return "Connection rejection - quality of service not available "
522 "(transient condition)";
524 return "Connection rejection - quality of service not available "
525 "(permanent condition)";
527 return "Connection rejection - incompatible information in user data";
529 return "Connection rejection - unrecognizable protocol indentifier "
532 return "Reset - user resynchronization";
535 g_snprintf(buffer, 32, "Unknown %d", code);
540 static const char *reset_code(unsigned char code)
544 if (code == 0x00 || (code & 0x80) == 0x80)
545 return "DTE Originated";
547 return "Out of order";
549 return "Remote Procedure Error";
551 return "Local Procedure Error";
553 return "Network Congestion";
555 return "Remote DTE operational";
557 return "Network operational";
559 return "Incompatible Destination";
561 return "Network out of order";
564 g_snprintf(buffer, 32, "Unknown %02X", code);
569 static const char *restart_code(unsigned char code)
573 if (code == 0x00 || (code & 0x80) == 0x80)
574 return "DTE Originated";
576 return "Local Procedure Error";
578 return "Network Congestion";
580 return "Network Operational";
582 return "Registration/cancellation confirmed";
585 g_snprintf(buffer, 32, "Unknown %02X", code);
590 static const char *registration_code(unsigned char code)
595 return "Invalid facility request";
597 return "Network congestion";
599 return "Local procedure error";
601 return "Registration/cancellation confirmed";
604 g_snprintf(buffer, 32, "Unknown %02X", code);
610 dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb)
612 guint8 fac, byte1, byte2, byte3;
613 guint32 len; /* facilities length */
615 proto_tree *fac_tree = 0;
616 proto_tree *fac_subtree;
618 len = tvb_get_guint8(tvb, *offset);
620 ti = proto_tree_add_text(tree, tvb, *offset, len + 1,
622 fac_tree = proto_item_add_subtree(ti, ett_x25_fac);
623 proto_tree_add_text(fac_tree, tvb, *offset, 1,
624 "Facilities length: %d", len);
629 fac = tvb_get_guint8(tvb, *offset);
630 switch(fac & X25_FAC_CLASS_MASK) {
631 case X25_FAC_CLASS_A:
633 case X25_FAC_COMP_MARK:
635 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
636 "Code : 00 (Marker)");
637 switch (tvb_get_guint8(tvb, *offset + 1)) {
640 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
641 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
642 "Parameter : 00 (Network complementary "
643 "services - calling DTE)");
648 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
649 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
650 "Parameter : FF (Network complementary "
651 "services - called DTE)");
656 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
657 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
658 "Parameter : 0F (DTE complementary "
664 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
665 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
666 "Parameter : %02X (Unknown marker)",
667 tvb_get_guint8(tvb, *offset+1));
672 case X25_FAC_REVERSE:
674 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
675 "(Reverse charging / Fast select)", fac);
676 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_reverse);
677 byte1 = tvb_get_guint8(tvb, *offset + 1);
678 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
679 "Parameter : %02X", byte1);
681 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
682 "11.. .... = Fast select with restriction");
683 else if (byte1 & 0x80)
684 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
685 "10.. .... = Fast select - no restriction");
687 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
688 "00.. .... = Fast select not requested");
689 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
690 decode_boolean_bitfield(byte1, 0x01, 1*8,
691 "Reverse charging requested",
692 "Reverse charging not requested"));
695 case X25_FAC_THROUGHPUT:
700 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
701 "(Throughput class negociation)", fac);
702 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_throughput);
703 byte1 = tvb_get_guint8(tvb, *offset + 1);
715 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (%d bps)",
716 75*(1<<((byte1 >> 4)-3)));
719 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (48000 bps)");
722 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (64000 bps)");
725 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (Reserved)");
727 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
728 decode_numeric_bitfield(byte1, 0xF0, 1*8, tmpbuf));
729 switch (byte1 & 0x0F)
740 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (%d bps)",
741 75*(1<<((byte1 & 0x0F)-3)));
744 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (48000 bps)");
747 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (64000 bps)");
750 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (Reserved)");
752 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
753 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
758 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
759 "(Closed user group selection)", fac);
760 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_cug);
761 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
762 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
765 case X25_FAC_CALLED_MODIF:
767 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
768 "(Called address modified)", fac);
769 fac_subtree = proto_item_add_subtree(ti,
770 ett_x25_fac_called_modif);
771 proto_tree_add_text(fac_tree, tvb, *offset+1, 1,
772 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
775 case X25_FAC_CUG_OUTGOING_ACC:
777 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
778 "(Closed user group with outgoing access selection)",
780 fac_subtree = proto_item_add_subtree(ti,
781 ett_x25_fac_cug_outgoing_acc);
782 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
783 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
786 case X25_FAC_THROUGHPUT_MIN:
788 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
789 "(Minimum throughput class)", fac);
790 fac_subtree = proto_item_add_subtree(ti,
791 ett_x25_fac_throughput_min);
792 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
793 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
796 case X25_FAC_EXPRESS_DATA:
798 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
799 "(Negociation of express data)", fac);
800 fac_subtree = proto_item_add_subtree(ti,
801 ett_x25_fac_express_data);
802 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
803 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
808 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
809 "Code : %02X (Unknown class A)", fac);
810 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
811 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
812 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
819 case X25_FAC_CLASS_B:
821 case X25_FAC_BILATERAL_CUG:
823 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
824 "(Bilateral closed user group selection)", fac);
825 fac_subtree = proto_item_add_subtree(ti,
826 ett_x25_fac_bilateral_cug);
827 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
828 "Bilateral CUG: %04X",
829 tvb_get_ntohs(tvb, *offset+1));
832 case X25_FAC_PACKET_SIZE:
838 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
839 "(Packet size)", fac);
840 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_packet_size);
841 byte1 = tvb_get_guint8(tvb, *offset + 1);
845 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (16)");
848 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (32)");
851 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (64)");
854 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (128)");
857 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (256)");
860 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (512)");
863 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (1024)");
866 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (2048)");
869 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (4096)");
872 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (Unknown)");
875 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
876 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
878 byte2 = tvb_get_guint8(tvb, *offset + 1);
882 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (16)");
885 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (32)");
888 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (64)");
891 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (128)");
894 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (256)");
897 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (512)");
900 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (1024)");
903 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (2048)");
906 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (4096)");
909 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (Unknown)");
912 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
913 decode_numeric_bitfield(byte2, 0x0F, 1*8, tmpbuf));
916 case X25_FAC_WINDOW_SIZE:
918 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
919 "(Window size)", fac);
920 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_window_size);
921 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
922 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+1),
923 0x7F, 1*8, "From the called DTE: %u"));
924 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
925 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+2),
926 0x7F, 1*8, "From the calling DTE: %u"));
929 case X25_FAC_RPOA_SELECTION:
931 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
932 "(RPOA selection)", fac);
933 fac_subtree = proto_item_add_subtree(ti,
934 ett_x25_fac_rpoa_selection);
935 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
936 "Data network identification code : %04X",
937 tvb_get_ntohs(tvb, *offset+1));
940 case X25_FAC_TRANSIT_DELAY:
942 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
943 "(Transit delay selection and indication)", fac);
944 fac_subtree = proto_item_add_subtree(ti,
945 ett_x25_fac_transit_delay);
946 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
947 "Transit delay: %d ms",
948 tvb_get_ntohs(tvb, *offset+1));
953 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
954 "Code : %02X (Unknown class B)", fac);
955 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
956 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
957 "Parameter %04X", tvb_get_ntohs(tvb, *offset+1));
964 case X25_FAC_CLASS_C:
966 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
967 "Code : %02X (Unknown class C)", fac);
968 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
969 proto_tree_add_text(fac_subtree, tvb, *offset+1, 3,
971 tvb_get_ntoh24(tvb, *offset+1));
976 case X25_FAC_CLASS_D:
978 case X25_FAC_CALL_TRANSFER:
983 tmpbuf=ep_alloc(258);
984 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
985 "(Call redirection or deflection notification)", fac);
986 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_call_transfer);
987 byte1 = tvb_get_guint8(tvb, *offset+1);
989 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
990 "Bogus length : %d", byte1);
993 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
994 "Length : %u", byte1);
996 byte2 = tvb_get_guint8(tvb, *offset+2);
997 if ((byte2 & 0xC0) == 0xC0) {
998 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
999 "Reason : call deflection by the originally "
1000 "called DTE address");
1005 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1006 "Reason : originally called DTE busy");
1009 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1010 "Reason : call dist. within a hunt group");
1013 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1014 "Reason : originally called DTE out of order");
1017 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1018 "Reason : systematic call redirection");
1021 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1022 "Reason : unknown");
1026 byte3 = tvb_get_guint8(tvb, *offset+3);
1027 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1028 "Number of semi-octets in DTE address : %u",
1030 for (i = 0; (i<byte3)&&(i<256); i++) {
1032 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1034 /* if > 9, convert to the right hexadecimal letter */
1035 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1037 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1039 /* if > 9, convert to the right hexadecimal letter */
1040 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1044 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1045 "DTE address : %s", tmpbuf);
1048 case X25_FAC_CALLING_ADDR_EXT:
1053 tmpbuf=ep_alloc(258);
1054 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1055 "(Calling address extension)", fac);
1056 fac_subtree = proto_item_add_subtree(ti,
1057 ett_x25_fac_calling_addr_ext);
1058 byte1 = tvb_get_guint8(tvb, *offset+1);
1060 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1061 "Bogus length : %d", byte1);
1064 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1065 "Length : %u", byte1);
1067 byte2 = tvb_get_guint8(tvb, *offset+2) & 0x3F;
1068 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1069 "Number of semi-octets in DTE address : %u", byte2);
1070 for (i = 0; (i<byte2)&&(i<256) ; i++) {
1072 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1074 /* if > 9, convert to the right hexadecimal letter */
1075 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1077 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1079 /* if > 9, convert to the right hexadecimal letter */
1080 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1084 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1085 "DTE address : %s", tmpbuf);
1088 case X25_FAC_CALLED_ADDR_EXT:
1093 tmpbuf=ep_alloc(258);
1094 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1095 "(Called address extension)", fac);
1096 fac_subtree = proto_item_add_subtree(ti,
1097 ett_x25_fac_called_addr_ext);
1098 byte1 = tvb_get_guint8(tvb, *offset+1);
1100 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1101 "Bogus length : %d", byte1);
1104 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1105 "Length : %u", byte1);
1107 byte2 = tvb_get_guint8(tvb, *offset+2) & 0x3F;
1108 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1109 "Number of semi-octets in DTE address : %u", byte2);
1110 for (i = 0; (i<byte2)&&(i<256) ; i++) {
1112 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1114 /* if > 9, convert to the right hexadecimal letter */
1115 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1117 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1119 /* if > 9, convert to the right hexadecimal letter */
1120 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1124 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1125 "DTE address : %s", tmpbuf);
1128 case X25_FAC_ETE_TRANSIT_DELAY:
1130 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1131 "(End to end transit delay)", fac);
1132 fac_subtree = proto_item_add_subtree(ti,
1133 ett_x25_fac_ete_transit_delay);
1134 byte1 = tvb_get_guint8(tvb, *offset+1);
1135 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1136 "Length : %u", byte1);
1137 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1140 case X25_FAC_CALL_DEFLECT:
1145 tmpbuf=ep_alloc(258);
1146 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1147 "(Call deflection selection)", fac);
1148 fac_subtree = proto_item_add_subtree(ti,
1149 ett_x25_fac_call_deflect);
1150 byte1 = tvb_get_guint8(tvb, *offset+1);
1152 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1153 "Bogus length : %d", byte1);
1156 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1157 "Length : %u", byte1);
1159 byte2 = tvb_get_guint8(tvb, *offset+2);
1160 if ((byte2 & 0xC0) == 0xC0)
1161 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1162 "Reason : call DTE originated");
1164 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1165 "Reason : unknown");
1166 byte3 = tvb_get_guint8(tvb, *offset+3);
1167 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1168 "Number of semi-octets in the alternative DTE address : %u",
1170 for (i = 0; (i<byte3)&&(i<256) ; i++) {
1172 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1174 /* if > 9, convert to the right hexadecimal letter */
1175 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1177 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1179 /* if > 9, convert to the right hexadecimal letter */
1180 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1184 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1185 "Alternative DTE address : %s", tmpbuf);
1188 case X25_FAC_PRIORITY:
1190 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1191 "Code : %02X (Priority)", fac);
1192 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_priority);
1193 byte1 = tvb_get_guint8(tvb, *offset+1);
1194 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1195 "Length : %u", byte1);
1196 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1201 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1202 "Code : %02X (Unknown class D)", fac);
1203 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1204 byte1 = tvb_get_guint8(tvb, *offset+1);
1205 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1206 "Length : %u", byte1);
1207 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1210 byte1 = tvb_get_guint8(tvb, *offset+1);
1211 (*offset) += byte1+2;
1219 x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1220 packet_info *pinfo, gboolean is_registration)
1224 char *addr1, *addr2;
1225 char *first, *second;
1232 byte = tvb_get_guint8(tvb, *offset);
1233 len1 = (byte >> 0) & 0x0F;
1234 len2 = (byte >> 4) & 0x0F;
1237 proto_tree_add_text(tree, tvb, *offset, 1,
1238 decode_numeric_bitfield(byte, 0xF0, 1*8,
1240 "DTE address length : %u" :
1241 "Calling address length : %u"));
1242 proto_tree_add_text(tree, tvb, *offset, 1,
1243 decode_numeric_bitfield(byte, 0x0F, 1*8,
1245 "DCE address length : %u" :
1246 "Called address length : %u"));
1250 localoffset = *offset;
1251 byte = tvb_get_guint8(tvb, localoffset);
1255 for (i = 0; i < (len1 + len2); i++) {
1258 *first++ = ((byte >> 0) & 0x0F) + '0';
1260 byte = tvb_get_guint8(tvb, localoffset);
1262 *first++ = ((byte >> 4) & 0x0F) + '0';
1266 *second++ = ((byte >> 0) & 0x0F) + '0';
1268 byte = tvb_get_guint8(tvb, localoffset);
1270 *second++ = ((byte >> 4) & 0x0F) + '0';
1279 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1280 col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1);
1282 proto_tree_add_text(tree, tvb, *offset,
1285 "DCE address : %s" :
1286 "Called address : %s",
1290 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1291 col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2);
1293 proto_tree_add_text(tree, tvb, *offset + len1/2,
1294 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1296 "DTE address : %s" :
1297 "Calling address : %s",
1300 (*offset) += ((len1 + len2 + 1) / 2);
1304 x25_toa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1309 char *addr1, *addr2;
1310 char *first, *second;
1314 addr1=ep_alloc(256);
1315 addr2=ep_alloc(256);
1317 len1 = tvb_get_guint8(tvb, *offset);
1319 proto_tree_add_text(tree, tvb, *offset, 1,
1320 "Called address length : %u",
1325 len2 = tvb_get_guint8(tvb, *offset);
1327 proto_tree_add_text(tree, tvb, *offset, 1,
1328 "Calling address length : %u",
1333 localoffset = *offset;
1334 byte = tvb_get_guint8(tvb, localoffset);
1337 * XXX - the first two half-octets of the address are the TOA and
1338 * NPI; process them as such and, if the TOA says an address is
1339 * an alternative address, process it correctly (i.e., not as a
1340 * sequence of half-octets containing digit values).
1344 for (i = 0; i < (len1 + len2); i++) {
1347 *first++ = ((byte >> 0) & 0x0F) + '0';
1349 byte = tvb_get_guint8(tvb, localoffset);
1351 *first++ = ((byte >> 4) & 0x0F) + '0';
1355 *second++ = ((byte >> 0) & 0x0F) + '0';
1357 byte = tvb_get_guint8(tvb, localoffset);
1359 *second++ = ((byte >> 4) & 0x0F) + '0';
1368 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1369 col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1);
1371 proto_tree_add_text(tree, tvb, *offset,
1373 "Called address : %s",
1377 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1378 col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2);
1380 proto_tree_add_text(tree, tvb, *offset + len1/2,
1381 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1382 "Calling address : %s",
1385 (*offset) += ((len1 + len2 + 1) / 2);
1389 get_x25_pkt_len(tvbuff_t *tvb)
1391 guint length, called_len, calling_len, dte_len, dce_len;
1392 guint8 byte2, bytex;
1394 byte2 = tvb_get_guint8(tvb, 2);
1397 case X25_CALL_REQUEST:
1398 bytex = tvb_get_guint8(tvb, 3);
1399 called_len = (bytex >> 0) & 0x0F;
1400 calling_len = (bytex >> 4) & 0x0F;
1401 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1402 if (length < tvb_reported_length(tvb))
1403 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1405 return MIN(tvb_reported_length(tvb),length);
1407 case X25_CALL_ACCEPTED:
1408 /* The calling/called address length byte (following the packet type)
1409 * is not mandatory, so we must check the packet length before trying
1411 if (tvb_reported_length(tvb) == 3)
1413 bytex = tvb_get_guint8(tvb, 3);
1414 called_len = (bytex >> 0) & 0x0F;
1415 calling_len = (bytex >> 4) & 0x0F;
1416 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1417 if (length < tvb_reported_length(tvb))
1418 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1420 return MIN(tvb_reported_length(tvb),length);
1422 case X25_CLEAR_REQUEST:
1423 case X25_RESET_REQUEST:
1424 case X25_RESTART_REQUEST:
1425 return MIN(tvb_reported_length(tvb),5);
1427 case X25_DIAGNOSTIC:
1428 return MIN(tvb_reported_length(tvb),4);
1430 case X25_CLEAR_CONFIRMATION:
1432 case X25_INTERRUPT_CONFIRMATION:
1433 case X25_RESET_CONFIRMATION:
1434 case X25_RESTART_CONFIRMATION:
1435 return MIN(tvb_reported_length(tvb),3);
1437 case X25_REGISTRATION_REQUEST:
1438 bytex = tvb_get_guint8(tvb, 3);
1439 dce_len = (bytex >> 0) & 0x0F;
1440 dte_len = (bytex >> 4) & 0x0F;
1441 length = 4 + (dte_len + dce_len + 1) / 2; /* addr */
1442 if (length < tvb_reported_length(tvb))
1443 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1445 return MIN(tvb_reported_length(tvb),length);
1447 case X25_REGISTRATION_CONFIRMATION:
1448 bytex = tvb_get_guint8(tvb, 5);
1449 dce_len = (bytex >> 0) & 0x0F;
1450 dte_len = (bytex >> 4) & 0x0F;
1451 length = 6 + (dte_len + dce_len + 1) / 2; /* addr */
1452 if (length < tvb_reported_length(tvb))
1453 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1455 return MIN(tvb_reported_length(tvb),length);
1458 if (PACKET_IS_DATA(byte2))
1459 return MIN(tvb_reported_length(tvb),3);
1461 switch (PACKET_TYPE_FC(byte2))
1464 return MIN(tvb_reported_length(tvb),3);
1467 return MIN(tvb_reported_length(tvb),3);
1470 return MIN(tvb_reported_length(tvb),3);
1476 static const value_string prt_id_vals[] = {
1477 {PRT_ID_ISO_8073, "ISO 8073 COTP"},
1478 {PRT_ID_ISO_8602, "ISO 8602 CLTP"},
1479 {PRT_ID_ISO_10736_ISO_8073, "ISO 10736 in conjunction with ISO 8073 COTP"},
1480 {PRT_ID_ISO_10736_ISO_8602, "ISO 10736 in conjunction with ISO 8602 CLTP"},
1484 static const value_string sharing_strategy_vals[] = {
1485 {0x00, "No sharing"},
1490 dissect_x25_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1491 x25_dir_t dir, gboolean side)
1493 proto_tree *x25_tree=0, *gfi_tree=0, *userdata_tree=0;
1495 guint localoffset=0;
1499 dissector_handle_t dissect = NULL;
1500 gboolean toa; /* TOA/NPI address format */
1503 const char *short_name = NULL, *long_name = NULL;
1504 tvbuff_t *next_tvb = NULL;
1505 gboolean q_bit_set = FALSE;
1509 void *saved_private_data;
1510 fragment_data *fd_head;
1512 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1513 col_set_str(pinfo->cinfo, COL_PROTOCOL, "X.25");
1515 bytes0_1 = tvb_get_ntohs(tvb, 0);
1517 modulo = ((bytes0_1 & 0x2000) ? 128 : 8);
1518 vc = (int)(bytes0_1 & 0x0FFF);
1520 pinfo->ctype = CT_X25;
1521 pinfo->circuit_id = vc;
1523 if (bytes0_1 & X25_ABIT) toa = TRUE;
1526 x25_pkt_len = get_x25_pkt_len(tvb);
1527 if (x25_pkt_len < 3) /* packet too short */
1529 if (check_col(pinfo->cinfo, COL_INFO))
1530 col_set_str(pinfo->cinfo, COL_INFO, "Invalid/short X.25 packet");
1532 proto_tree_add_protocol_format(tree, proto_x25, tvb, 0, -1,
1533 "Invalid/short X.25 packet");
1537 pkt_type = tvb_get_guint8(tvb, 2);
1538 if (PACKET_IS_DATA(pkt_type)) {
1539 if (bytes0_1 & X25_QBIT)
1544 ti = proto_tree_add_item(tree, proto_x25, tvb, 0, x25_pkt_len, FALSE);
1545 x25_tree = proto_item_add_subtree(ti, ett_x25);
1546 ti = proto_tree_add_item(x25_tree, hf_x25_gfi, tvb, 0, 2, FALSE);
1547 gfi_tree = proto_item_add_subtree(ti, ett_x25_gfi);
1549 if (PACKET_IS_DATA(pkt_type)) {
1550 proto_tree_add_boolean(gfi_tree, hf_x25_qbit, tvb, 0, 2,
1553 else if (pkt_type == X25_CALL_REQUEST ||
1554 pkt_type == X25_CALL_ACCEPTED ||
1555 pkt_type == X25_CLEAR_REQUEST ||
1556 pkt_type == X25_CLEAR_CONFIRMATION) {
1557 proto_tree_add_boolean(gfi_tree, hf_x25_abit, tvb, 0, 2,
1561 if (pkt_type == X25_CALL_REQUEST || pkt_type == X25_CALL_ACCEPTED ||
1562 PACKET_IS_DATA(pkt_type)) {
1563 proto_tree_add_boolean(gfi_tree, hf_x25_dbit, tvb, 0, 2,
1566 proto_tree_add_uint(gfi_tree, hf_x25_mod, tvb, 0, 2, bytes0_1);
1570 case X25_CALL_REQUEST:
1574 short_name = "Inc. call";
1575 long_name = "Incoming call";
1579 short_name = "Call req.";
1580 long_name = "Call request";
1584 short_name = "Inc. call/Call req.";
1585 long_name = "Incoming call/Call request";
1588 if (check_col(pinfo->cinfo, COL_INFO))
1589 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
1591 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb,
1593 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1594 X25_CALL_REQUEST, "Packet Type: %s", long_name);
1597 if (localoffset < x25_pkt_len) { /* calling/called addresses */
1599 x25_toa(x25_tree, &localoffset, tvb, pinfo);
1601 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
1604 if (localoffset < x25_pkt_len) /* facilities */
1605 dump_facilities(x25_tree, &localoffset, tvb);
1607 if (localoffset < tvb_reported_length(tvb)) /* user data */
1614 ti = proto_tree_add_text(x25_tree, tvb, localoffset, -1,
1616 userdata_tree = proto_item_add_subtree(ti, ett_x25_user_data);
1619 /* X.263/ISO 9577 says that:
1621 When CLNP or ESIS are run over X.25, the SPI
1622 is 0x81 or 0x82, respectively; those are the
1623 NLPIDs for those protocol.
1625 When X.224/ISO 8073 COTP is run over X.25, and
1626 when ISO 11570 explicit identification is being
1627 used, the first octet of the user data field is
1628 a TPDU length field, and the rest is "as defined
1629 in ITU-T Rec. X.225 | ISO/IEC 8073, Annex B,
1630 or ITU-T Rec. X.264 and ISO/IEC 11570".
1632 When X.264/ISO 11570 default identification is
1633 being used, there is no user data field in the
1634 CALL REQUEST packet. This is for X.225/ISO 8073
1637 It also says that SPI values from 0x03 through 0x3f are
1638 reserved and are in use by X.224/ISO 8073 Annex B and
1639 X.264/ISO 11570. The note says that those values are
1640 not NLPIDs, they're "used by the respective higher layer
1641 protocol" and "not used for higher layer protocol
1642 identification". I infer from this and from what
1643 X.264/ISO 11570 says that this means that values in those
1644 range are valid values for the first octet of an
1645 X.224/ISO 8073 packet or for X.264/ISO 11570.
1647 Annex B of X.225/ISO 8073 mentions some additional TPDU
1648 types that can be put in what I presume is the user
1649 data of connect requests. It says that:
1651 The sending transport entity shall:
1653 a) either not transmit any TPDU in the NS-user data
1654 parameter of the N-CONNECT request primitive; or
1656 b) transmit the UN-TPDU (see ITU-T Rec. X.264 and
1657 ISO/IEC 11570) followed by the NCM-TPDU in the
1658 NS-user data parameter of the N-CONNECT request
1661 I don't know if this means that the user data field
1662 will contain a UN TPDU followed by an NCM TPDU or not.
1664 X.264/ISO 11570 says that:
1666 When default identification is being used,
1667 X.225/ISO 8073 COTP is identified. No user data
1668 is sent in the network-layer connection request.
1670 When explicit identification is being used,
1671 the user data is a UN TPDU ("Use of network
1672 connection TPDU"), which specifies the transport
1673 protocol to use over this network connection.
1674 It also says that the length of a UN TPDU shall
1675 not exceed 32 octets, i.e. shall not exceed 0x20;
1676 it says this is "due to the desire not to conflict
1677 with the protocol identifier field carried by X.25
1678 CALL REQUEST/INCOMING CALL packets", and says that
1679 field has values specified in X.244. X.244 has been
1680 superseded by X.263/ISO 9577, so that presumably
1681 means the goal is to allow a UN TPDU's length
1682 field to be distinguished from an NLPID, allowing
1683 you to tell whether X.264/ISO 11570 explicit
1684 identification is being used or an NLPID is
1685 being used as the SPI.
1687 I read this as meaning that, if the ISO mechanisms are
1688 used to identify the protocol being carried over X.25:
1690 if there's no user data in the CALL REQUEST/
1691 INCOMING CALL packet, it's COTP;
1693 if there is user data, then:
1695 if the first octet is less than or equal to
1696 32, it might be a UN TPDU, and that identifies
1697 the transport protocol being used, and
1698 it may be followed by more data, such
1699 as a COTP NCM TPDU if it's COTP;
1701 if the first octet is greater than 32, it's
1702 an NLPID, *not* a TPDU length, and the
1703 stuff following it is *not* a TPDU.
1705 Figure A.2 of X.263/ISO 9577 seems to say that the
1706 first octet of the user data is a TPDU length field,
1707 in the range 0x03 through 0x82, and says they are
1708 for X.225/ISO 8073 Annex B or X.264/ISO 11570.
1710 However, X.264/ISO 11570 seems to imply that the length
1711 field would be that of a UN TPDU, which must be less
1712 than or equal to 0x20, and X.225/ISO 8073 Annex B seems
1713 to indicate that the user data must begin with
1714 an X.264/ISO 11570 UN TPDU, so I'd say that A.2 should
1715 have said "in the range 0x03 through 0x20", instead
1716 (the length value doesn't include the length field,
1717 and the minimum UN TPDU has length, type, PRT-ID,
1718 and SHARE, so that's 3 bytes without the length). */
1719 spi = tvb_get_guint8(tvb, localoffset);
1720 if (spi > 32 || spi < 3) {
1721 /* First octet is > 32, or < 3, so the user data isn't an
1722 X.264/ISO 11570 UN TPDU */
1725 /* First octet is >= 3 and <= 32, so the user data *might*
1726 be an X.264/ISO 11570 UN TPDU. Check whether we have
1727 enough data to see if it is. */
1728 if (tvb_bytes_exist(tvb, localoffset+1, 1)) {
1729 /* We do; check whether the second octet is 1. */
1730 if (tvb_get_guint8(tvb, localoffset+1) == 0x01) {
1731 /* Yes, the second byte is 1, so it looks like
1735 /* No, the second byte is not 1, so it's not a
1740 /* We can't see the second byte of the putative UN
1741 TPDU, so we don't know if that's what it is. */
1745 if (is_x_264 == -1) {
1747 * We don't know what it is; just skip it.
1749 localoffset = tvb_length(tvb);
1750 } else if (is_x_264) {
1751 /* It looks like an X.264 UN TPDU, so show it as such. */
1752 if (userdata_tree) {
1753 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1754 "X.264 length indicator: %u",
1756 proto_tree_add_text(userdata_tree, tvb, localoffset+1, 1,
1757 "X.264 UN TPDU identifier: 0x%02X",
1758 tvb_get_guint8(tvb, localoffset+1));
1760 prt_id = tvb_get_guint8(tvb, localoffset+2);
1761 if (userdata_tree) {
1762 proto_tree_add_text(userdata_tree, tvb, localoffset+2, 1,
1763 "X.264 protocol identifier: %s",
1764 val_to_str(prt_id, prt_id_vals,
1765 "Unknown (0x%02X)"));
1766 proto_tree_add_text(userdata_tree, tvb, localoffset+3, 1,
1767 "X.264 sharing strategy: %s",
1768 val_to_str(tvb_get_guint8(tvb, localoffset+3),
1769 sharing_strategy_vals, "Unknown (0x%02X)"));
1772 /* XXX - dissect the variable part? */
1774 /* The length doesn't include the length octet itself. */
1775 localoffset += spi + 1;
1779 case PRT_ID_ISO_8073:
1781 if (!pinfo->fd->flags.visited)
1782 x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
1783 /* XXX - dissect the rest of the user data as COTP?
1784 That needs support for NCM TPDUs, etc. */
1787 case PRT_ID_ISO_8602:
1789 if (!pinfo->fd->flags.visited)
1790 x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
1793 } else if (is_x_264 == 0) {
1794 /* It doesn't look like a UN TPDU, so compare the first
1795 octet of the CALL REQUEST packet with various X.263/
1796 ISO 9577 NLPIDs, as per Annex A of X.263/ISO 9577. */
1798 if (userdata_tree) {
1799 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1800 "X.263 secondary protocol ID: %s",
1801 val_to_str(spi, nlpid_vals, "Unknown (0x%02x)"));
1804 if (!pinfo->fd->flags.visited) {
1806 * Is there a dissector handle for this SPI?
1807 * If so, assign it to this virtual circuit.
1809 dissect = dissector_get_port_handle(x25_subdissector_table, spi);
1810 if (dissect != NULL)
1811 x25_hash_add_proto_start(vc, pinfo->fd->num, dissect);
1815 * If there's only one octet of user data, it's just
1816 * an NLPID; don't try to dissect it.
1818 if (localoffset + 1 == tvb_reported_length(tvb))
1822 * There's more than one octet of user data, so we'll
1823 * dissect it; for some protocols, the NLPID is considered
1824 * to be part of the PDU, so, for those cases, we don't
1825 * skip past it. For other protocols, we skip the NLPID.
1829 case NLPID_ISO8473_CLNP:
1830 case NLPID_ISO9542_ESIS:
1831 case NLPID_ISO10589_ISIS:
1832 case NLPID_ISO10747_IDRP:
1835 * The NLPID is part of the PDU. Don't skip it.
1836 * But if it's all there is to the PDU, don't
1837 * bother dissecting it.
1841 case NLPID_SPI_X_29:
1843 * The first 4 bytes of the call user data are
1844 * the SPI plus 3 reserved bytes; they are not
1845 * part of the data to be dissected as X.29 data.
1852 * The NLPID isn't part of the PDU - skip it.
1853 * If that means there's nothing to dissect
1860 case X25_CALL_ACCEPTED:
1864 short_name = "Call conn.";
1865 long_name = "Call connected";
1869 short_name = "Call acc.";
1870 long_name = "Call accepted";
1874 short_name = "Call conn./Call acc.";
1875 long_name = "Call connected/Call accepted";
1878 if(check_col(pinfo->cinfo, COL_INFO))
1879 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
1881 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1882 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1883 X25_CALL_ACCEPTED, "Packet Type: %s", long_name);
1886 if (localoffset < x25_pkt_len) { /* calling/called addresses */
1888 x25_toa(x25_tree, &localoffset, tvb, pinfo);
1890 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
1893 if (localoffset < x25_pkt_len) /* facilities */
1894 dump_facilities(x25_tree, &localoffset, tvb);
1896 case X25_CLEAR_REQUEST:
1900 short_name = "Clear ind.";
1901 long_name = "Clear indication";
1905 short_name = "Clear req.";
1906 long_name = "Clear request";
1910 short_name = "Clear ind./Clear req.";
1911 long_name = "Clear indication/Clear request";
1914 if(check_col(pinfo->cinfo, COL_INFO)) {
1915 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - %s", short_name,
1916 vc, clear_code(tvb_get_guint8(tvb, 3)),
1917 clear_diag(tvb_get_guint8(tvb, 4)));
1919 x25_hash_add_proto_end(vc, pinfo->fd->num);
1921 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1922 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb,
1923 localoffset+2, 1, X25_CLEAR_REQUEST, "Packet Type: %s",
1925 proto_tree_add_text(x25_tree, tvb, 3, 1,
1926 "Cause : %s", clear_code(tvb_get_guint8(tvb, 3)));
1927 proto_tree_add_text(x25_tree, tvb, 4, 1,
1928 "Diagnostic : %s", clear_diag(tvb_get_guint8(tvb, 4)));
1930 localoffset = x25_pkt_len;
1932 case X25_CLEAR_CONFIRMATION:
1933 if(check_col(pinfo->cinfo, COL_INFO))
1934 col_add_fstr(pinfo->cinfo, COL_INFO, "Clear Conf. VC:%d", vc);
1936 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1937 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1938 X25_CLEAR_CONFIRMATION);
1940 localoffset = x25_pkt_len;
1942 if (localoffset < tvb_reported_length(tvb)) { /* extended clear conf format */
1944 x25_toa(x25_tree, &localoffset, tvb, pinfo);
1946 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, FALSE);
1949 if (localoffset < tvb_reported_length(tvb)) /* facilities */
1950 dump_facilities(x25_tree, &localoffset, tvb);
1952 case X25_DIAGNOSTIC:
1953 if(check_col(pinfo->cinfo, COL_INFO)) {
1954 col_add_fstr(pinfo->cinfo, COL_INFO, "Diag. %d",
1955 (int)tvb_get_guint8(tvb, 3));
1958 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1960 proto_tree_add_text(x25_tree, tvb, 3, 1,
1961 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 3));
1963 localoffset = x25_pkt_len;
1966 if(check_col(pinfo->cinfo, COL_INFO))
1967 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt VC:%d", vc);
1969 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1970 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1973 localoffset = x25_pkt_len;
1975 case X25_INTERRUPT_CONFIRMATION:
1976 if(check_col(pinfo->cinfo, COL_INFO))
1977 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt Conf. VC:%d", vc);
1979 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
1980 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
1981 X25_INTERRUPT_CONFIRMATION);
1983 localoffset = x25_pkt_len;
1985 case X25_RESET_REQUEST:
1989 short_name = "Reset ind.";
1990 long_name = "Reset indication";
1994 short_name = "Reset req.";
1995 long_name = "Reset request";
1999 short_name = "Reset ind./Reset req.";
2000 long_name = "Reset indication/Reset request";
2003 if(check_col(pinfo->cinfo, COL_INFO)) {
2004 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - Diag.:%d",
2005 short_name, vc, reset_code(tvb_get_guint8(tvb, 3)),
2006 (int)tvb_get_guint8(tvb, 4));
2008 x25_hash_add_proto_end(vc, pinfo->fd->num);
2010 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
2011 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
2012 X25_RESET_REQUEST, "Packet Type: %s", long_name);
2013 proto_tree_add_text(x25_tree, tvb, 3, 1,
2014 "Cause : %s", reset_code(tvb_get_guint8(tvb, 3)));
2015 proto_tree_add_text(x25_tree, tvb, 4, 1,
2016 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
2018 localoffset = x25_pkt_len;
2020 case X25_RESET_CONFIRMATION:
2021 if(check_col(pinfo->cinfo, COL_INFO))
2022 col_add_fstr(pinfo->cinfo, COL_INFO, "Reset conf. VC:%d", vc);
2024 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
2025 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2026 X25_RESET_CONFIRMATION);
2028 localoffset = x25_pkt_len;
2030 case X25_RESTART_REQUEST:
2034 short_name = "Restart ind.";
2035 long_name = "Restart indication";
2039 short_name = "Restart req.";
2040 long_name = "Restart request";
2044 short_name = "Restart ind./Restart req.";
2045 long_name = "Restart indication/Restart request";
2048 if(check_col(pinfo->cinfo, COL_INFO)) {
2049 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s - Diag.:%d",
2051 restart_code(tvb_get_guint8(tvb, 3)),
2052 (int)tvb_get_guint8(tvb, 3));
2055 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
2056 X25_RESTART_REQUEST, "Packet Type: %s", long_name);
2057 proto_tree_add_text(x25_tree, tvb, 3, 1,
2058 "Cause : %s", restart_code(tvb_get_guint8(tvb, 3)));
2059 proto_tree_add_text(x25_tree, tvb, 4, 1,
2060 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
2062 localoffset = x25_pkt_len;
2064 case X25_RESTART_CONFIRMATION:
2065 if(check_col(pinfo->cinfo, COL_INFO))
2066 col_set_str(pinfo->cinfo, COL_INFO, "Restart conf.");
2068 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2069 X25_RESTART_CONFIRMATION);
2070 localoffset = x25_pkt_len;
2072 case X25_REGISTRATION_REQUEST:
2073 if(check_col(pinfo->cinfo, COL_INFO))
2074 col_set_str(pinfo->cinfo, COL_INFO, "Registration req.");
2076 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2077 X25_REGISTRATION_REQUEST);
2079 if (localoffset < x25_pkt_len)
2080 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, TRUE);
2083 if (localoffset < x25_pkt_len)
2084 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
2085 "Registration length: %d",
2086 tvb_get_guint8(tvb, localoffset) & 0x7F);
2087 if (localoffset+1 < x25_pkt_len)
2088 proto_tree_add_text(x25_tree, tvb, localoffset+1,
2089 tvb_get_guint8(tvb, localoffset) & 0x7F,
2092 localoffset = tvb_reported_length(tvb);
2094 case X25_REGISTRATION_CONFIRMATION:
2095 if(check_col(pinfo->cinfo, COL_INFO))
2096 col_set_str(pinfo->cinfo, COL_INFO, "Registration conf.");
2098 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2099 X25_REGISTRATION_CONFIRMATION);
2100 proto_tree_add_text(x25_tree, tvb, 3, 1,
2101 "Cause: %s", registration_code(tvb_get_guint8(tvb, 3)));
2102 proto_tree_add_text(x25_tree, tvb, 4, 1,
2103 "Diagnostic: %s", registration_code(tvb_get_guint8(tvb, 4)));
2106 if (localoffset < x25_pkt_len)
2107 x25_ntoa(x25_tree, &localoffset, tvb, pinfo, TRUE);
2110 if (localoffset < x25_pkt_len)
2111 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
2112 "Registration length: %d",
2113 tvb_get_guint8(tvb, localoffset) & 0x7F);
2114 if (localoffset+1 < x25_pkt_len)
2115 proto_tree_add_text(x25_tree, tvb, localoffset+1,
2116 tvb_get_guint8(tvb, localoffset) & 0x7F,
2119 localoffset = tvb_reported_length(tvb);
2123 if (PACKET_IS_DATA(pkt_type))
2125 if(check_col(pinfo->cinfo, COL_INFO)) {
2127 col_add_fstr(pinfo->cinfo, COL_INFO,
2128 "Data VC:%d P(S):%d P(R):%d %s", vc,
2129 (pkt_type >> 1) & 0x07,
2130 (pkt_type >> 5) & 0x07,
2131 (pkt_type & X25_MBIT_MOD8) ? " M" : "");
2133 col_add_fstr(pinfo->cinfo, COL_INFO,
2134 "Data VC:%d P(S):%d P(R):%d %s", vc,
2135 tvb_get_guint8(tvb, localoffset+1) >> 1,
2137 (tvb_get_guint8(tvb, localoffset+1) & X25_MBIT_MOD128) ? " M" : "");
2140 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2143 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2144 localoffset, 1, pkt_type);
2145 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod8, tvb,
2146 localoffset, 1, pkt_type);
2147 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod8, tvb,
2148 localoffset, 1, pkt_type);
2149 proto_tree_add_uint(x25_tree, hf_x25_type_data, tvb,
2150 localoffset, 1, pkt_type);
2153 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod128, tvb,
2154 localoffset, 1, pkt_type);
2155 proto_tree_add_uint(x25_tree, hf_x25_type_data, tvb,
2156 localoffset, 1, pkt_type);
2157 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod128, tvb,
2159 tvb_get_guint8(tvb, localoffset+1));
2160 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod128, tvb,
2162 tvb_get_guint8(tvb, localoffset+1));
2166 m_bit_set = pkt_type & X25_MBIT_MOD8;
2169 m_bit_set = tvb_get_guint8(tvb, localoffset+1) & X25_MBIT_MOD128;
2172 payload_len = tvb_reported_length_remaining(tvb, localoffset);
2173 if (reassemble_x25) {
2175 * Reassemble received and sent traffic separately.
2176 * We don't reassemble traffic with an unknown direction
2182 * OR in an extra bit to distinguish from traffic
2183 * in the other direction.
2185 frag_key |= 0x10000;
2187 fd_head = fragment_add_seq_next(tvb, localoffset,
2190 x25_reassembled_table,
2191 payload_len, m_bit_set);
2192 pinfo->fragmented = m_bit_set;
2195 if (fd_head->next) {
2196 proto_item *frag_tree_item;
2198 /* This is the last packet */
2199 next_tvb = tvb_new_real_data(fd_head->data,
2202 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
2203 add_new_data_source(pinfo, next_tvb, "Reassembled X.25");
2204 show_fragment_seq_tree(fd_head,
2207 pinfo, next_tvb, &frag_tree_item);
2211 if (m_bit_set && next_tvb == NULL) {
2213 * This isn't the last packet, so just
2214 * show it as X.25 user data.
2216 proto_tree_add_text(x25_tree, tvb, localoffset, -1,
2217 "User data (%u byte%s)", payload_len,
2218 plurality(payload_len, "", "s"));
2226 * Non-data packets (RR, RNR, REJ).
2228 switch (PACKET_TYPE_FC(pkt_type))
2231 if(check_col(pinfo->cinfo, COL_INFO)) {
2233 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2234 vc, (pkt_type >> 5) & 0x07);
2236 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2237 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2240 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2243 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2244 localoffset, 1, pkt_type);
2245 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2246 localoffset, 1, X25_RR);
2249 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2250 localoffset, 1, X25_RR);
2251 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2252 localoffset+1, 1, FALSE);
2258 if(check_col(pinfo->cinfo, COL_INFO)) {
2260 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2261 vc, (pkt_type >> 5) & 0x07);
2263 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2264 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2267 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2270 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2271 localoffset, 1, pkt_type);
2272 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2273 localoffset, 1, X25_RNR);
2276 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2277 localoffset, 1, X25_RNR);
2278 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2279 localoffset+1, 1, FALSE);
2285 if(check_col(pinfo->cinfo, COL_INFO)) {
2287 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2288 vc, (pkt_type >> 5) & 0x07);
2290 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2291 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2294 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2297 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2298 localoffset, 1, pkt_type);
2299 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2300 localoffset, 1, X25_REJ);
2303 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2304 localoffset, 1, X25_REJ);
2305 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2306 localoffset+1, 1, FALSE);
2310 localoffset += (modulo == 8) ? 1 : 2;
2313 if (localoffset >= tvb_reported_length(tvb))
2315 if (pinfo->fragmented)
2319 next_tvb = tvb_new_subset(tvb, localoffset, -1, -1);
2321 saved_private_data = pinfo->private_data;
2322 pinfo->private_data = &q_bit_set;
2324 /* See if there's already a dissector for this circuit. */
2325 if (try_circuit_dissector(CT_X25, vc, pinfo->fd->num, next_tvb, pinfo,
2327 pinfo->private_data = saved_private_data;
2328 return; /* found it and dissected it */
2331 /* Did the user suggest QLLC/SNA? */
2332 if (payload_is_qllc_sna) {
2333 /* Yes - dissect it as QLLC/SNA. */
2334 if (!pinfo->fd->flags.visited)
2335 x25_hash_add_proto_start(vc, pinfo->fd->num, qllc_handle);
2336 call_dissector(qllc_handle, next_tvb, pinfo, tree);
2337 pinfo->private_data = saved_private_data;
2341 /* If the Call Req. has not been captured, let's look at the first
2342 byte of the payload to see if this looks like IP or CLNP. */
2343 switch (tvb_get_guint8(tvb, localoffset)) {
2346 /* Looks like an IP header */
2347 if (!pinfo->fd->flags.visited)
2348 x25_hash_add_proto_start(vc, pinfo->fd->num, ip_handle);
2349 call_dissector(ip_handle, next_tvb, pinfo, tree);
2350 pinfo->private_data = saved_private_data;
2353 case NLPID_ISO8473_CLNP:
2354 if (!pinfo->fd->flags.visited)
2355 x25_hash_add_proto_start(vc, pinfo->fd->num, clnp_handle);
2356 call_dissector(clnp_handle, next_tvb, pinfo, tree);
2357 pinfo->private_data = saved_private_data;
2361 /* Try the heuristic dissectors. */
2362 if (dissector_try_heuristic(x25_heur_subdissector_list, next_tvb, pinfo,
2364 pinfo->private_data = saved_private_data;
2368 /* All else failed; dissect it as raw data */
2369 call_dissector(data_handle, next_tvb, pinfo, tree);
2370 pinfo->private_data = saved_private_data;
2374 * X.25 dissector for use when "pinfo->pseudo_header" points to a
2375 * "struct x25_phdr".
2378 dissect_x25_dir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2380 dissect_x25_common(tvb, pinfo, tree,
2381 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? X25_FROM_DCE :
2383 pinfo->pseudo_header->x25.flags & FROM_DCE);
2387 * X.25 dissector for use when "pinfo->pseudo_header" doesn't point to a
2388 * "struct x25_phdr".
2391 dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2396 * We don't know if this packet is DTE->DCE or DCE->DCE.
2397 * However, we can, at least, distinguish between the two
2398 * sides of the conversation, based on the addresses and
2401 direction = CMP_ADDRESS(&pinfo->src, &pinfo->dst);
2403 direction = (pinfo->srcport > pinfo->destport)*2 - 1;
2404 dissect_x25_common(tvb, pinfo, tree, X25_UNKNOWN, direction > 0);
2408 x25_reassemble_init(void)
2410 fragment_table_init(&x25_segment_table);
2411 reassembled_table_init(&x25_reassembled_table);
2415 proto_register_x25(void)
2417 static hf_register_info hf[] = {
2419 { "GFI", "x.25.gfi", FT_UINT16, BASE_DEC, NULL, 0xF000,
2420 "General format identifier", HFILL }},
2422 { "A Bit", "x.25.a", FT_BOOLEAN, 16, NULL, X25_ABIT,
2423 "Address Bit", HFILL }},
2425 { "Q Bit", "x.25.q", FT_BOOLEAN, 16, NULL, X25_QBIT,
2426 "Qualifier Bit", HFILL }},
2428 { "D Bit", "x.25.d", FT_BOOLEAN, 16, NULL, X25_DBIT,
2429 "Delivery Confirmation Bit", HFILL }},
2431 { "Modulo", "x.25.mod", FT_UINT16, BASE_DEC, VALS(vals_modulo), 0x3000,
2432 "Specifies whether the frame is modulo 8 or 128", HFILL }},
2434 { "Logical Channel", "x.25.lcn", FT_UINT16, BASE_DEC, NULL, 0x0FFF,
2435 "Logical Channel Number", HFILL }},
2437 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x0,
2438 "Packet Type", HFILL }},
2439 { &hf_x25_type_fc_mod8,
2440 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x1F,
2441 "Packet Type", HFILL }},
2442 { &hf_x25_type_data,
2443 { "Packet Type", "x.25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x01,
2444 "Packet Type", HFILL }},
2446 { "P(R)", "x.25.p_r", FT_UINT8, BASE_DEC, NULL, 0xE0,
2447 "Packet Receive Sequence Number", HFILL }},
2448 { &hf_x25_p_r_mod128,
2449 { "P(R)", "x.25.p_r", FT_UINT8, BASE_DEC, NULL, 0xFE,
2450 "Packet Receive Sequence Number", HFILL }},
2451 { &hf_x25_mbit_mod8,
2452 { "M Bit", "x.25.m", FT_BOOLEAN, 8, TFS(&m_bit_tfs), X25_MBIT_MOD8,
2453 "More Bit", HFILL }},
2454 { &hf_x25_mbit_mod128,
2455 { "M Bit", "x.25.m", FT_BOOLEAN, 8, TFS(&m_bit_tfs), X25_MBIT_MOD128,
2456 "More Bit", HFILL }},
2458 { "P(S)", "x.25.p_s", FT_UINT8, BASE_DEC, NULL, 0x0E,
2459 "Packet Send Sequence Number", HFILL }},
2460 { &hf_x25_p_s_mod128,
2461 { "P(S)", "x.25.p_s", FT_UINT8, BASE_DEC, NULL, 0xFE,
2462 "Packet Send Sequence Number", HFILL }},
2463 { &hf_x25_segment_overlap,
2464 { "Fragment overlap", "x25.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2465 "Fragment overlaps with other fragments", HFILL }},
2467 { &hf_x25_segment_overlap_conflict,
2468 { "Conflicting data in fragment overlap", "x25.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2469 "Overlapping fragments contained conflicting data", HFILL }},
2471 { &hf_x25_segment_multiple_tails,
2472 { "Multiple tail fragments found", "x25.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2473 "Several tails were found when defragmenting the packet", HFILL }},
2475 { &hf_x25_segment_too_long_segment,
2476 { "Fragment too long", "x25.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2477 "Fragment contained data past end of packet", HFILL }},
2479 { &hf_x25_segment_error,
2480 { "Defragmentation error", "x25.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2481 "Defragmentation error due to illegal fragments", HFILL }},
2484 { "X.25 Fragment", "x25.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2485 "X25 Fragment", HFILL }},
2488 { "X.25 Fragments", "x25.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
2489 "X.25 Fragments", HFILL }},
2491 static gint *ett[] = {
2495 &ett_x25_fac_unknown,
2497 &ett_x25_fac_reverse,
2498 &ett_x25_fac_throughput,
2500 &ett_x25_fac_called_modif,
2501 &ett_x25_fac_cug_outgoing_acc,
2502 &ett_x25_fac_throughput_min,
2503 &ett_x25_fac_express_data,
2504 &ett_x25_fac_bilateral_cug,
2505 &ett_x25_fac_packet_size,
2506 &ett_x25_fac_window_size,
2507 &ett_x25_fac_rpoa_selection,
2508 &ett_x25_fac_transit_delay,
2509 &ett_x25_fac_call_transfer,
2510 &ett_x25_fac_called_addr_ext,
2511 &ett_x25_fac_ete_transit_delay,
2512 &ett_x25_fac_calling_addr_ext,
2513 &ett_x25_fac_call_deflect,
2514 &ett_x25_fac_priority,
2519 module_t *x25_module;
2521 proto_x25 = proto_register_protocol ("X.25", "X.25", "x.25");
2522 proto_register_field_array (proto_x25, hf, array_length(hf));
2523 proto_register_subtree_array(ett, array_length(ett));
2525 x25_subdissector_table = register_dissector_table("x.25.spi",
2526 "X.25 secondary protocol identifier", FT_UINT8, BASE_HEX);
2527 register_heur_dissector_list("x.25", &x25_heur_subdissector_list);
2529 register_dissector("x.25_dir", dissect_x25_dir, proto_x25);
2530 register_dissector("x.25", dissect_x25, proto_x25);
2533 x25_module = prefs_register_protocol(proto_x25, NULL);
2534 prefs_register_obsolete_preference(x25_module, "non_q_bit_is_sna");
2535 prefs_register_bool_preference(x25_module, "payload_is_qllc_sna",
2536 "Default to QLLC/SNA",
2537 "If CALL REQUEST not seen or didn't specify protocol, dissect as QLLC/SNA",
2538 &payload_is_qllc_sna);
2539 prefs_register_bool_preference(x25_module, "reassemble",
2540 "Reassemble fragmented X.25 packets",
2541 "Reassemble fragmented X.25 packets",
2543 register_init_routine(&x25_reassemble_init);
2547 proto_reg_handoff_x25(void)
2549 dissector_handle_t x25_handle;
2552 * Get handles for various dissectors.
2554 ip_handle = find_dissector("ip");
2555 clnp_handle = find_dissector("clnp");
2556 ositp_handle = find_dissector("ositp");
2557 qllc_handle = find_dissector("qllc");
2558 data_handle = find_dissector("data");
2560 x25_handle = find_dissector("x.25");
2561 dissector_add("llc.dsap", SAP_X25, x25_handle);