2 * Routines for X.25 packet disassembly
3 * Olivier Abad <oabad@noos.fr>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
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.
34 #include <epan/llcsaps.h>
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>
40 #include <epan/nlpid.h>
41 #include <epan/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_CHARGING_INFO 0x04
98 #define X25_FAC_CALLED_MODIF 0x08
99 #define X25_FAC_CUG_OUTGOING_ACC 0x09
100 #define X25_FAC_THROUGHPUT_MIN 0x0A
101 #define X25_FAC_EXPRESS_DATA 0x0B
102 #define X25_FAC_BILATERAL_CUG 0x41
103 #define X25_FAC_PACKET_SIZE 0x42
104 #define X25_FAC_WINDOW_SIZE 0x43
105 #define X25_FAC_RPOA_SELECTION 0x44
106 #define X25_FAC_CUG_EXT 0x47
107 #define X25_FAC_CUG_OUTGOING_ACC_EXT 0x48
108 #define X25_FAC_TRANSIT_DELAY 0x49
109 #define X25_FAC_CALL_DURATION 0xC1
110 #define X25_FAC_SEGMENT_COUNT 0xC2
111 #define X25_FAC_CALL_TRANSFER 0xC3
112 #define X25_FAC_RPOA_SELECTION_EXT 0xC4
113 #define X25_FAC_MONETARY_UNIT 0xC5
114 #define X25_FAC_NUI 0xC6
115 #define X25_FAC_CALLED_ADDR_EXT 0xC9
116 #define X25_FAC_ETE_TRANSIT_DELAY 0xCA
117 #define X25_FAC_CALLING_ADDR_EXT 0xCB
118 #define X25_FAC_CALL_DEFLECT 0xD1
119 #define X25_FAC_PRIORITY 0xD2
121 static int proto_x25 = -1;
122 static int hf_x25_gfi = -1;
123 static int hf_x25_abit = -1;
124 static int hf_x25_qbit = -1;
125 static int hf_x25_dbit = -1;
126 static int hf_x25_mod = -1;
127 static int hf_x25_lcn = -1;
128 static int hf_x25_type = -1;
129 static int hf_x25_type_fc_mod8 = -1;
130 static int hf_x25_type_data = -1;
131 static int hf_x25_p_r_mod8 = -1;
132 static int hf_x25_p_r_mod128 = -1;
133 static int hf_x25_mbit_mod8 = -1;
134 static int hf_x25_mbit_mod128 = -1;
135 static int hf_x25_p_s_mod8 = -1;
136 static int hf_x25_p_s_mod128 = -1;
138 static gint ett_x25 = -1;
139 static gint ett_x25_gfi = -1;
140 static gint ett_x25_fac = -1;
141 static gint ett_x25_fac_unknown = -1;
142 static gint ett_x25_fac_mark = -1;
143 static gint ett_x25_fac_reverse = -1;
144 static gint ett_x25_fac_charging_info = -1;
145 static gint ett_x25_fac_throughput = -1;
146 static gint ett_x25_fac_cug = -1;
147 static gint ett_x25_fac_called_modif = -1;
148 static gint ett_x25_fac_cug_outgoing_acc = -1;
149 static gint ett_x25_fac_throughput_min = -1;
150 static gint ett_x25_fac_express_data = -1;
151 static gint ett_x25_fac_bilateral_cug = -1;
152 static gint ett_x25_fac_packet_size = -1;
153 static gint ett_x25_fac_window_size = -1;
154 static gint ett_x25_fac_rpoa_selection = -1;
155 static gint ett_x25_fac_cug_ext = -1;
156 static gint ett_x25_fac_cug_outgoing_acc_ext = -1;
157 static gint ett_x25_fac_transit_delay = -1;
158 static gint ett_x25_fac_call_duration = -1;
159 static gint ett_x25_fac_segment_count = -1;
160 static gint ett_x25_fac_call_transfer = -1;
161 static gint ett_x25_fac_rpoa_selection_ext = -1;
162 static gint ett_x25_fac_monetary_unit = -1;
163 static gint ett_x25_fac_nui = -1;
164 static gint ett_x25_fac_called_addr_ext = -1;
165 static gint ett_x25_fac_ete_transit_delay = -1;
166 static gint ett_x25_fac_calling_addr_ext = -1;
167 static gint ett_x25_fac_call_deflect = -1;
168 static gint ett_x25_fac_priority = -1;
169 static gint ett_x25_user_data = -1;
171 static gint ett_x25_segment = -1;
172 static gint ett_x25_segments = -1;
173 static gint hf_x25_segments = -1;
174 static gint hf_x25_segment = -1;
175 static gint hf_x25_segment_overlap = -1;
176 static gint hf_x25_segment_overlap_conflict = -1;
177 static gint hf_x25_segment_multiple_tails = -1;
178 static gint hf_x25_segment_too_long_segment = -1;
179 static gint hf_x25_segment_error = -1;
181 static const value_string vals_modulo[] = {
187 static const value_string vals_x25_type[] = {
188 { X25_CALL_REQUEST, "Call" },
189 { X25_CALL_ACCEPTED, "Call Accepted" },
190 { X25_CLEAR_REQUEST, "Clear" },
191 { X25_CLEAR_CONFIRMATION, "Clear Confirmation" },
192 { X25_INTERRUPT, "Interrupt" },
193 { X25_INTERRUPT_CONFIRMATION, "Interrupt Confirmation" },
194 { X25_RESET_REQUEST, "Reset" },
195 { X25_RESET_CONFIRMATION, "Reset Confirmation" },
196 { X25_RESTART_REQUEST, "Restart" },
197 { X25_RESTART_CONFIRMATION, "Restart Confirmation" },
198 { X25_REGISTRATION_REQUEST, "Registration" },
199 { X25_REGISTRATION_CONFIRMATION, "Registration Confirmation" },
200 { X25_DIAGNOSTIC, "Diagnostic" },
204 { X25_DATA, "Data" },
208 static struct true_false_string m_bit_tfs = {
213 static const fragment_items x25_frag_items = {
218 &hf_x25_segment_overlap,
219 &hf_x25_segment_overlap_conflict,
220 &hf_x25_segment_multiple_tails,
221 &hf_x25_segment_too_long_segment,
222 &hf_x25_segment_error,
227 static dissector_handle_t ip_handle;
228 static dissector_handle_t clnp_handle;
229 static dissector_handle_t ositp_handle;
230 static dissector_handle_t qllc_handle;
231 static dissector_handle_t data_handle;
234 static gboolean payload_is_qllc_sna = FALSE;
235 static gboolean call_request_nodata_is_cotp = FALSE;
236 static gboolean payload_check_data = FALSE;
237 static gboolean reassemble_x25 = TRUE;
239 /* Reassembly of X.25 */
241 static GHashTable *x25_segment_table = NULL;
242 static GHashTable *x25_reassembled_table = NULL;
244 static dissector_table_t x25_subdissector_table;
245 static heur_dissector_list_t x25_heur_subdissector_list;
248 x25_hash_add_proto_start(guint16 vc, guint32 frame, dissector_handle_t dissect)
253 * Is there already a circuit with this VC number?
255 circuit = find_circuit(CT_X25, vc, frame);
256 if (circuit != NULL) {
258 * Yes - close it, as we're creating a new one.
260 close_circuit(circuit, frame - 1);
264 * Set up a new circuit.
266 circuit = circuit_new(CT_X25, vc, frame);
271 circuit_set_dissector(circuit, dissect);
275 x25_hash_add_proto_end(guint16 vc, guint32 frame)
280 * Try to find the circuit.
282 circuit = find_circuit(CT_X25, vc, frame);
285 * If we succeeded, close it.
288 close_circuit(circuit, frame);
291 static const char *clear_code(unsigned char code)
295 if (code == 0x00 || (code & 0x80) == 0x80)
296 return "DTE Originated";
298 return "Number Busy";
300 return "Invalid Facility Requested";
302 return "Network Congestion";
304 return "Out Of Order";
306 return "Access Barred";
308 return "Not Obtainable";
310 return "Remote Procedure Error";
312 return "Local Procedure Error";
314 return "RPOA Out Of Order";
316 return "Reverse Charging Acceptance Not Subscribed";
318 return "Incompatible Destination";
320 return "Fast Select Acceptance Not Subscribed";
322 return "Destination Absent";
325 g_snprintf(buffer, 32, "Unknown %02X", code);
330 static const char *clear_diag(unsigned char code)
335 return "No additional information";
337 return "Invalid P(S)";
339 return "Invalid P(R)";
341 return "Packet type invalid";
343 return "Packet type invalid for state r1";
345 return "Packet type invalid for state r2";
347 return "Packet type invalid for state r3";
349 return "Packet type invalid for state p1";
351 return "Packet type invalid for state p2";
353 return "Packet type invalid for state p3";
355 return "Packet type invalid for state p4";
357 return "Packet type invalid for state p5";
359 return "Packet type invalid for state p6";
361 return "Packet type invalid for state p7";
363 return "Packet type invalid for state d1";
365 return "Packet type invalid for state d2";
367 return "Packet type invalid for state d3";
369 return "Packet not allowed";
371 return "Unidentifiable packet";
373 return "Call on one-way logical channel";
375 return "Invalid packet type on a PVC";
377 return "Packet on unassigned LC";
379 return "Reject not subscribed to";
381 return "Packet too short";
383 return "Packet too long";
385 return "Invalid general format identifier";
387 return "Restart/registration packet with nonzero bits";
389 return "Packet type not compatible with facility";
391 return "Unauthorised interrupt confirmation";
393 return "Unauthorised interrupt";
395 return "Unauthorised reject";
397 return "Time expired";
399 return "Time expired for incoming call";
401 return "Time expired for clear indication";
403 return "Time expired for reset indication";
405 return "Time expired for restart indication";
407 return "Time expired for call deflection";
409 return "Call set-up/clearing or registration pb.";
411 return "Facility/registration code not allowed";
413 return "Facility parameter not allowed";
415 return "Invalid called DTE address";
417 return "Invalid calling DTE address";
419 return "Invalid facility/registration length";
421 return "Incoming call barred";
423 return "No logical channel available";
425 return "Call collision";
427 return "Duplicate facility requested";
429 return "Non zero address length";
431 return "Non zero facility length";
433 return "Facility not provided when expected";
435 return "Invalid CCITT-specified DTE facility";
437 return "Max. nb of call redir/defl. exceeded";
439 return "Miscellaneous";
441 return "Improper cause code from DTE";
443 return "Not aligned octet";
445 return "Inconsistent Q bit setting";
447 return "NUI problem";
449 return "International problem";
451 return "Remote network problem";
453 return "International protocol problem";
455 return "International link out of order";
457 return "International link busy";
459 return "Transit network facility problem";
461 return "Remote network facility problem";
463 return "International routing problem";
465 return "Temporary routing problem";
467 return "Unknown called DNIC";
469 return "Maintenance action";
471 return "Timer expired or retransmission count surpassed";
473 return "Timer expired or retransmission count surpassed for INTERRUPT";
475 return "Timer expired or retransmission count surpassed for DATA "
476 "packet transmission";
478 return "Timer expired or retransmission count surpassed for REJECT";
480 return "DTE-specific signals";
482 return "DTE operational";
484 return "DTE not operational";
486 return "DTE resource constraint";
488 return "Fast select not subscribed";
490 return "Invalid partially full DATA packet";
492 return "D-bit procedure not supported";
494 return "Registration/Cancellation confirmed";
496 return "OSI network service problem";
498 return "Disconnection (transient condition)";
500 return "Disconnection (permanent condition)";
502 return "Connection rejection - reason unspecified (transient "
505 return "Connection rejection - reason unspecified (permanent "
508 return "Connection rejection - quality of service not available "
509 "transient condition)";
511 return "Connection rejection - quality of service not available "
512 "permanent condition)";
514 return "Connection rejection - NSAP unreachable (transient condition)";
516 return "Connection rejection - NSAP unreachable (permanent condition)";
518 return "reset - reason unspecified";
520 return "reset - congestion";
522 return "Connection rejection - NSAP address unknown (permanent "
525 return "Higher layer initiated";
527 return "Disconnection - normal";
529 return "Disconnection - abnormal";
531 return "Disconnection - incompatible information in user data";
533 return "Connection rejection - reason unspecified (transient "
536 return "Connection rejection - reason unspecified (permanent "
539 return "Connection rejection - quality of service not available "
540 "(transient condition)";
542 return "Connection rejection - quality of service not available "
543 "(permanent condition)";
545 return "Connection rejection - incompatible information in user data";
547 return "Connection rejection - unrecognizable protocol identifier "
550 return "Reset - user resynchronization";
553 g_snprintf(buffer, 32, "Unknown %d", code);
558 static const char *reset_code(unsigned char code)
562 if (code == 0x00 || (code & 0x80) == 0x80)
563 return "DTE Originated";
565 return "Out of order";
567 return "Remote Procedure Error";
569 return "Local Procedure Error";
571 return "Network Congestion";
573 return "Remote DTE operational";
575 return "Network operational";
577 return "Incompatible Destination";
579 return "Network out of order";
582 g_snprintf(buffer, 32, "Unknown %02X", code);
587 static const char *restart_code(unsigned char code)
591 if (code == 0x00 || (code & 0x80) == 0x80)
592 return "DTE Originated";
594 return "Local Procedure Error";
596 return "Network Congestion";
598 return "Network Operational";
600 return "Registration/cancellation confirmed";
603 g_snprintf(buffer, 32, "Unknown %02X", code);
608 static const char *registration_code(unsigned char code)
613 return "Invalid facility request";
615 return "Network congestion";
617 return "Local procedure error";
619 return "Registration/cancellation confirmed";
622 g_snprintf(buffer, 32, "Unknown %02X", code);
628 dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb)
630 guint8 fac, byte1, byte2, byte3;
631 guint32 len; /* facilities length */
633 proto_tree *fac_tree = 0;
634 proto_tree *fac_subtree;
636 len = tvb_get_guint8(tvb, *offset);
638 ti = proto_tree_add_text(tree, tvb, *offset, len + 1,
640 fac_tree = proto_item_add_subtree(ti, ett_x25_fac);
641 proto_tree_add_text(fac_tree, tvb, *offset, 1,
642 "Facilities length: %d", len);
647 fac = tvb_get_guint8(tvb, *offset);
648 switch(fac & X25_FAC_CLASS_MASK) {
649 case X25_FAC_CLASS_A:
651 case X25_FAC_COMP_MARK:
653 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
654 "Code : 00 (Marker)");
655 switch (tvb_get_guint8(tvb, *offset + 1)) {
658 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
659 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
660 "Parameter : 00 (Network complementary "
661 "services - calling DTE)");
666 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
667 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
668 "Parameter : FF (Network complementary "
669 "services - called DTE)");
674 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
675 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
676 "Parameter : 0F (DTE complementary "
682 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
683 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
684 "Parameter : %02X (Unknown marker)",
685 tvb_get_guint8(tvb, *offset+1));
690 case X25_FAC_REVERSE:
692 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
693 "(Reverse charging / Fast select)", fac);
694 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_reverse);
695 byte1 = tvb_get_guint8(tvb, *offset + 1);
696 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
697 "Parameter : %02X", byte1);
699 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
700 "11.. .... = Fast select with restriction");
701 else if (byte1 & 0x80)
702 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
703 "10.. .... = Fast select - no restriction");
705 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
706 "00.. .... = Fast select not requested");
707 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1, "%s",
708 decode_boolean_bitfield(byte1, 0x01, 1*8,
709 "Reverse charging requested",
710 "Reverse charging not requested"));
713 case X25_FAC_CHARGING_INFO:
715 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
716 "(Charging information)", fac);
717 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_charging_info);
718 byte1 = tvb_get_guint8(tvb, *offset + 1);
719 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
720 "Parameter : %02X", byte1);
721 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1, "%s",
722 decode_boolean_bitfield(byte1, 0x01, 1*8,
723 "Charging information requested",
724 "Charging information not requested"));
727 case X25_FAC_THROUGHPUT:
732 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
733 "(Throughput class negotiation)", fac);
734 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_throughput);
735 byte1 = tvb_get_guint8(tvb, *offset + 1);
747 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (%d bps)",
748 75*(1<<((byte1 >> 4)-3)));
751 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (48000 bps)");
754 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (64000 bps)");
757 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (Reserved)");
759 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1, "%s",
760 decode_numeric_bitfield(byte1, 0xF0, 1*8, tmpbuf));
761 switch (byte1 & 0x0F)
772 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (%d bps)",
773 75*(1<<((byte1 & 0x0F)-3)));
776 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (48000 bps)");
779 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (64000 bps)");
782 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (Reserved)");
784 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1, "%s",
785 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
790 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
791 "(Closed user group selection)", fac);
792 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_cug);
793 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
794 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
797 case X25_FAC_CALLED_MODIF:
799 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
800 "(Called address modified)", fac);
801 fac_subtree = proto_item_add_subtree(ti,
802 ett_x25_fac_called_modif);
803 proto_tree_add_text(fac_tree, tvb, *offset+1, 1,
804 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
807 case X25_FAC_CUG_OUTGOING_ACC:
809 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
810 "(Closed user group with outgoing access selection)",
812 fac_subtree = proto_item_add_subtree(ti,
813 ett_x25_fac_cug_outgoing_acc);
814 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
815 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
818 case X25_FAC_THROUGHPUT_MIN:
820 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
821 "(Minimum throughput class)", fac);
822 fac_subtree = proto_item_add_subtree(ti,
823 ett_x25_fac_throughput_min);
824 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
825 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
828 case X25_FAC_EXPRESS_DATA:
830 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
831 "(Negotiation of express data)", fac);
832 fac_subtree = proto_item_add_subtree(ti,
833 ett_x25_fac_express_data);
834 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
835 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
840 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
841 "Code : %02X (Unknown class A)", fac);
842 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
843 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
844 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
851 case X25_FAC_CLASS_B:
853 case X25_FAC_BILATERAL_CUG:
855 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
856 "(Bilateral closed user group selection)", fac);
857 fac_subtree = proto_item_add_subtree(ti,
858 ett_x25_fac_bilateral_cug);
859 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
860 "Bilateral CUG: %04X",
861 tvb_get_ntohs(tvb, *offset+1));
864 case X25_FAC_PACKET_SIZE:
870 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
871 "(Packet size)", fac);
872 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_packet_size);
873 byte1 = tvb_get_guint8(tvb, *offset + 1);
877 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (16)");
880 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (32)");
883 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (64)");
886 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (128)");
889 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (256)");
892 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (512)");
895 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (1024)");
898 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (2048)");
901 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (4096)");
904 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (Unknown)");
907 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1, "%s",
908 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
910 byte2 = tvb_get_guint8(tvb, *offset + 2);
914 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (16)");
917 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (32)");
920 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (64)");
923 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (128)");
926 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (256)");
929 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (512)");
932 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (1024)");
935 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (2048)");
938 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (4096)");
941 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (Unknown)");
944 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1, "%s",
945 decode_numeric_bitfield(byte2, 0x0F, 1*8, tmpbuf));
948 case X25_FAC_WINDOW_SIZE:
950 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
951 "(Window size)", fac);
952 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_window_size);
953 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1, "%s",
954 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+1),
955 0x7F, 1*8, "From the called DTE: %u"));
956 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1, "%s",
957 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+2),
958 0x7F, 1*8, "From the calling DTE: %u"));
961 case X25_FAC_RPOA_SELECTION:
963 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
964 "(RPOA selection)", fac);
965 fac_subtree = proto_item_add_subtree(ti,
966 ett_x25_fac_rpoa_selection);
967 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
968 "Data network identification code : %04X",
969 tvb_get_ntohs(tvb, *offset+1));
972 case X25_FAC_CUG_EXT:
974 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
975 "(Extended closed user group selection)", fac);
976 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_cug_ext);
977 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
978 "Closed user group: %04X", tvb_get_ntohs(tvb, *offset+1));
981 case X25_FAC_CUG_OUTGOING_ACC_EXT:
983 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
984 "(Extended closed user group with outgoing access selection)",
986 fac_subtree = proto_item_add_subtree(ti,
987 ett_x25_fac_cug_outgoing_acc_ext);
988 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
989 "Closed user group: %04X", tvb_get_ntohs(tvb, *offset+1));
992 case X25_FAC_TRANSIT_DELAY:
994 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
995 "(Transit delay selection and indication)", fac);
996 fac_subtree = proto_item_add_subtree(ti,
997 ett_x25_fac_transit_delay);
998 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
999 "Transit delay: %d ms",
1000 tvb_get_ntohs(tvb, *offset+1));
1005 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1006 "Code : %02X (Unknown class B)", fac);
1007 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1008 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
1009 "Parameter %04X", tvb_get_ntohs(tvb, *offset+1));
1016 case X25_FAC_CLASS_C:
1018 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1019 "Code : %02X (Unknown class C)", fac);
1020 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1021 proto_tree_add_text(fac_subtree, tvb, *offset+1, 3,
1023 tvb_get_ntoh24(tvb, *offset+1));
1028 case X25_FAC_CLASS_D:
1030 case X25_FAC_CALL_DURATION:
1034 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1035 "(Call duration)", fac);
1036 fac_subtree = proto_item_add_subtree(ti,
1037 ett_x25_fac_call_duration);
1038 byte1 = tvb_get_guint8(tvb, *offset+1);
1039 if ((byte1 < 4) || (byte1 % 4)) {
1040 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1041 "Bogus length : %d", byte1);
1044 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1045 "Length : %u", byte1);
1047 for (i = 0; (i<byte1); i+=4) {
1048 proto_tree_add_text(fac_subtree, tvb, *offset+2+i, 4,
1049 "Call duration : %u Day(s) %02X:%02X:%02X Hour(s)",
1050 tvb_get_guint8(tvb, *offset+2+i),
1051 tvb_get_guint8(tvb, *offset+3+i),
1052 tvb_get_guint8(tvb, *offset+4+i),
1053 tvb_get_guint8(tvb, *offset+5+i));
1057 case X25_FAC_SEGMENT_COUNT:
1060 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1061 "(Segment count)", fac);
1062 fac_subtree = proto_item_add_subtree(ti,
1063 ett_x25_fac_segment_count);
1064 byte1 = tvb_get_guint8(tvb, *offset+1);
1065 if ((byte1 < 8) || (byte1 % 8)) {
1066 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1067 "Bogus length : %d", byte1);
1070 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1071 "Length : %u", byte1);
1073 for (i = 0; (i<byte1); i+=8) {
1074 proto_tree_add_text(fac_subtree, tvb, *offset+2+i, 4,
1075 "Segments sent to DTE : %02X%02X%02X%02X",
1076 tvb_get_guint8(tvb, *offset+2+i),
1077 tvb_get_guint8(tvb, *offset+3+i),
1078 tvb_get_guint8(tvb, *offset+4+i),
1079 tvb_get_guint8(tvb, *offset+5+i));
1080 proto_tree_add_text(fac_subtree, tvb, *offset+6+i, 4,
1081 "Segments received from DTE : %02X%02X%02X%02X",
1082 tvb_get_guint8(tvb, *offset+6+i),
1083 tvb_get_guint8(tvb, *offset+7+i),
1084 tvb_get_guint8(tvb, *offset+8+i),
1085 tvb_get_guint8(tvb, *offset+9+i));
1089 case X25_FAC_CALL_TRANSFER:
1094 tmpbuf=ep_alloc(258);
1095 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1096 "(Call redirection or deflection notification)", fac);
1097 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_call_transfer);
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);
1108 if ((byte2 & 0xC0) == 0xC0) {
1109 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1110 "Reason : call deflection by the originally "
1111 "called DTE address");
1116 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1117 "Reason : originally called DTE busy");
1120 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1121 "Reason : call dist. within a hunt group");
1124 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1125 "Reason : originally called DTE out of order");
1128 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1129 "Reason : systematic call redirection");
1132 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1133 "Reason : unknown");
1137 byte3 = tvb_get_guint8(tvb, *offset+3);
1138 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1139 "Number of semi-octets in DTE address : %u",
1141 for (i = 0; (i<byte3)&&(i<256); i++) {
1143 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1145 /* if > 9, convert to the right hexadecimal letter */
1146 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1148 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1150 /* if > 9, convert to the right hexadecimal letter */
1151 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1155 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1156 "DTE address : %s", tmpbuf);
1159 case X25_FAC_RPOA_SELECTION_EXT:
1163 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1164 "(Extended RPOA selection)", fac);
1165 fac_subtree = proto_item_add_subtree(ti,
1166 ett_x25_fac_rpoa_selection_ext);
1167 byte1 = tvb_get_guint8(tvb, *offset+1);
1168 if ((byte1 < 2) || (byte1 % 2)) {
1169 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1170 "Bogus length : %d", byte1);
1173 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1174 "Length : %u", byte1);
1176 for (i = 0; (i<byte1); i+=2) {
1177 proto_tree_add_text(fac_subtree, tvb, *offset+2+i, 2,
1178 "Data network identification code : %04X",
1179 tvb_get_ntohs(tvb, *offset+2+i));
1183 case X25_FAC_CALLING_ADDR_EXT:
1188 tmpbuf=ep_alloc(258);
1189 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1190 "(Calling address extension)", fac);
1191 fac_subtree = proto_item_add_subtree(ti,
1192 ett_x25_fac_calling_addr_ext);
1193 byte1 = tvb_get_guint8(tvb, *offset+1);
1195 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1196 "Bogus length : %d", byte1);
1199 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1200 "Length : %u", byte1);
1202 byte2 = tvb_get_guint8(tvb, *offset+2) & 0x3F;
1203 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1204 "Number of semi-octets in DTE address : %u", byte2);
1205 for (i = 0; (i<byte2)&&(i<256) ; i++) {
1207 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1209 /* if > 9, convert to the right hexadecimal letter */
1210 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1212 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1214 /* if > 9, convert to the right hexadecimal letter */
1215 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1219 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1220 "DTE address : %s", tmpbuf);
1223 case X25_FAC_MONETARY_UNIT:
1225 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1226 "(Monetary Unit)", fac);
1227 fac_subtree = proto_item_add_subtree(ti,
1228 ett_x25_fac_monetary_unit);
1229 byte1 = tvb_get_guint8(tvb, *offset+1);
1230 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1231 "Length : %u", byte1);
1232 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1237 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1238 "(Network User Identification selection)", fac);
1239 fac_subtree = proto_item_add_subtree(ti,
1241 byte1 = tvb_get_guint8(tvb, *offset+1);
1242 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1243 "Length : %u", byte1);
1244 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "NUI");
1247 case X25_FAC_CALLED_ADDR_EXT:
1252 tmpbuf=ep_alloc(258);
1253 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1254 "(Called address extension)", fac);
1255 fac_subtree = proto_item_add_subtree(ti,
1256 ett_x25_fac_called_addr_ext);
1257 byte1 = tvb_get_guint8(tvb, *offset+1);
1259 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1260 "Bogus length : %d", byte1);
1263 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1264 "Length : %u", byte1);
1266 byte2 = tvb_get_guint8(tvb, *offset+2) & 0x3F;
1267 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1268 "Number of semi-octets in DTE address : %u", byte2);
1269 for (i = 0; (i<byte2)&&(i<256) ; i++) {
1271 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1273 /* if > 9, convert to the right hexadecimal letter */
1274 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1276 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1278 /* if > 9, convert to the right hexadecimal letter */
1279 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1283 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1284 "DTE address : %s", tmpbuf);
1287 case X25_FAC_ETE_TRANSIT_DELAY:
1289 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1290 "(End to end transit delay)", fac);
1291 fac_subtree = proto_item_add_subtree(ti,
1292 ett_x25_fac_ete_transit_delay);
1293 byte1 = tvb_get_guint8(tvb, *offset+1);
1294 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1295 "Length : %u", byte1);
1296 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1299 case X25_FAC_CALL_DEFLECT:
1304 tmpbuf=ep_alloc(258);
1305 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1306 "(Call deflection selection)", fac);
1307 fac_subtree = proto_item_add_subtree(ti,
1308 ett_x25_fac_call_deflect);
1309 byte1 = tvb_get_guint8(tvb, *offset+1);
1311 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1312 "Bogus length : %d", byte1);
1315 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1316 "Length : %u", byte1);
1318 byte2 = tvb_get_guint8(tvb, *offset+2);
1319 if ((byte2 & 0xC0) == 0xC0)
1320 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1321 "Reason : call DTE originated");
1323 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1324 "Reason : unknown");
1325 byte3 = tvb_get_guint8(tvb, *offset+3);
1326 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1327 "Number of semi-octets in the alternative DTE address : %u",
1329 for (i = 0; (i<byte3)&&(i<256) ; i++) {
1331 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1333 /* if > 9, convert to the right hexadecimal letter */
1334 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1336 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1338 /* if > 9, convert to the right hexadecimal letter */
1339 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1343 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1344 "Alternative DTE address : %s", tmpbuf);
1347 case X25_FAC_PRIORITY:
1349 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1350 "Code : %02X (Priority)", fac);
1351 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_priority);
1352 byte1 = tvb_get_guint8(tvb, *offset+1);
1353 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1354 "Length : %u", byte1);
1355 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1360 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1361 "Code : %02X (Unknown class D)", fac);
1362 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1363 byte1 = tvb_get_guint8(tvb, *offset+1);
1364 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1365 "Length : %u", byte1);
1366 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1369 byte1 = tvb_get_guint8(tvb, *offset+1);
1370 (*offset) += byte1+2;
1378 x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1379 packet_info *pinfo, gboolean is_registration)
1383 char *addr1, *addr2;
1384 char *first, *second;
1391 byte = tvb_get_guint8(tvb, *offset);
1392 len1 = (byte >> 0) & 0x0F;
1393 len2 = (byte >> 4) & 0x0F;
1396 proto_tree_add_text(tree, tvb, *offset, 1, "%s",
1397 decode_numeric_bitfield(byte, 0xF0, 1*8,
1399 "DTE address length : %u" :
1400 "Calling address length : %u"));
1401 proto_tree_add_text(tree, tvb, *offset, 1, "%s",
1402 decode_numeric_bitfield(byte, 0x0F, 1*8,
1404 "DCE address length : %u" :
1405 "Called address length : %u"));
1409 localoffset = *offset;
1410 byte = tvb_get_guint8(tvb, localoffset);
1414 for (i = 0; i < (len1 + len2); i++) {
1417 *first++ = ((byte >> 0) & 0x0F) + '0';
1419 byte = tvb_get_guint8(tvb, localoffset);
1421 *first++ = ((byte >> 4) & 0x0F) + '0';
1425 *second++ = ((byte >> 0) & 0x0F) + '0';
1427 byte = tvb_get_guint8(tvb, localoffset);
1429 *second++ = ((byte >> 4) & 0x0F) + '0';
1438 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1439 col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1);
1441 proto_tree_add_text(tree, tvb, *offset,
1444 "DCE address : %s" :
1445 "Called address : %s",
1449 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1450 col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2);
1452 proto_tree_add_text(tree, tvb, *offset + len1/2,
1453 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1455 "DTE address : %s" :
1456 "Calling address : %s",
1459 (*offset) += ((len1 + len2 + 1) / 2);
1463 x25_toa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1468 char *addr1, *addr2;
1469 char *first, *second;
1473 addr1=ep_alloc(256);
1474 addr2=ep_alloc(256);
1476 len1 = tvb_get_guint8(tvb, *offset);
1478 proto_tree_add_text(tree, tvb, *offset, 1,
1479 "Called address length : %u",
1484 len2 = tvb_get_guint8(tvb, *offset);
1486 proto_tree_add_text(tree, tvb, *offset, 1,
1487 "Calling address length : %u",
1492 localoffset = *offset;
1493 byte = tvb_get_guint8(tvb, localoffset);
1496 * XXX - the first two half-octets of the address are the TOA and
1497 * NPI; process them as such and, if the TOA says an address is
1498 * an alternative address, process it correctly (i.e., not as a
1499 * sequence of half-octets containing digit values).
1503 for (i = 0; i < (len1 + len2); i++) {
1506 *first++ = ((byte >> 0) & 0x0F) + '0';
1508 byte = tvb_get_guint8(tvb, localoffset);
1510 *first++ = ((byte >> 4) & 0x0F) + '0';
1514 *second++ = ((byte >> 0) & 0x0F) + '0';
1516 byte = tvb_get_guint8(tvb, localoffset);
1518 *second++ = ((byte >> 4) & 0x0F) + '0';
1527 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1528 col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1);
1530 proto_tree_add_text(tree, tvb, *offset,
1532 "Called address : %s",
1536 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1537 col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2);
1539 proto_tree_add_text(tree, tvb, *offset + len1/2,
1540 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1541 "Calling address : %s",
1544 (*offset) += ((len1 + len2 + 1) / 2);
1548 get_x25_pkt_len(tvbuff_t *tvb)
1550 guint length, called_len, calling_len, dte_len, dce_len;
1551 guint8 byte2, bytex;
1553 byte2 = tvb_get_guint8(tvb, 2);
1556 case X25_CALL_REQUEST:
1557 bytex = tvb_get_guint8(tvb, 3);
1558 called_len = (bytex >> 0) & 0x0F;
1559 calling_len = (bytex >> 4) & 0x0F;
1560 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1561 if (length < tvb_reported_length(tvb))
1562 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1564 return MIN(tvb_reported_length(tvb),length);
1566 case X25_CALL_ACCEPTED:
1567 /* The calling/called address length byte (following the packet type)
1568 * is not mandatory, so we must check the packet length before trying
1570 if (tvb_reported_length(tvb) == 3)
1572 bytex = tvb_get_guint8(tvb, 3);
1573 called_len = (bytex >> 0) & 0x0F;
1574 calling_len = (bytex >> 4) & 0x0F;
1575 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1576 if (length < tvb_reported_length(tvb))
1577 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1579 return MIN(tvb_reported_length(tvb),length);
1581 case X25_CLEAR_REQUEST:
1582 case X25_RESET_REQUEST:
1583 case X25_RESTART_REQUEST:
1584 return MIN(tvb_reported_length(tvb),5);
1586 case X25_DIAGNOSTIC:
1587 return MIN(tvb_reported_length(tvb),4);
1589 case X25_CLEAR_CONFIRMATION:
1591 case X25_INTERRUPT_CONFIRMATION:
1592 case X25_RESET_CONFIRMATION:
1593 case X25_RESTART_CONFIRMATION:
1594 return MIN(tvb_reported_length(tvb),3);
1596 case X25_REGISTRATION_REQUEST:
1597 bytex = tvb_get_guint8(tvb, 3);
1598 dce_len = (bytex >> 0) & 0x0F;
1599 dte_len = (bytex >> 4) & 0x0F;
1600 length = 4 + (dte_len + dce_len + 1) / 2; /* addr */
1601 if (length < tvb_reported_length(tvb))
1602 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1604 return MIN(tvb_reported_length(tvb),length);
1606 case X25_REGISTRATION_CONFIRMATION:
1607 bytex = tvb_get_guint8(tvb, 5);
1608 dce_len = (bytex >> 0) & 0x0F;
1609 dte_len = (bytex >> 4) & 0x0F;
1610 length = 6 + (dte_len + dce_len + 1) / 2; /* addr */
1611 if (length < tvb_reported_length(tvb))
1612 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1614 return MIN(tvb_reported_length(tvb),length);
1617 if (PACKET_IS_DATA(byte2))
1618 return MIN(tvb_reported_length(tvb),3);
1620 switch (PACKET_TYPE_FC(byte2))
1623 return MIN(tvb_reported_length(tvb),3);
1626 return MIN(tvb_reported_length(tvb),3);
1629 return MIN(tvb_reported_length(tvb),3);
1635 static const value_string prt_id_vals[] = {
1636 {PRT_ID_ISO_8073, "ISO 8073 COTP"},
1637 {PRT_ID_ISO_8602, "ISO 8602 CLTP"},
1638 {PRT_ID_ISO_10736_ISO_8073, "ISO 10736 in conjunction with ISO 8073 COTP"},
1639 {PRT_ID_ISO_10736_ISO_8602, "ISO 10736 in conjunction with ISO 8602 CLTP"},
1643 static const value_string sharing_strategy_vals[] = {
1644 {0x00, "No sharing"},
1649 dissect_x25_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1650 x25_dir_t dir, gboolean side)
1652 proto_tree *x25_tree=0, *gfi_tree=0, *userdata_tree=0;
1654 guint localoffset=0;
1658 dissector_handle_t dissect = NULL;
1659 gboolean toa; /* TOA/NPI address format */
1662 const char *short_name = NULL, *long_name = NULL;
1663 tvbuff_t *next_tvb = NULL;
1664 gboolean q_bit_set = FALSE;
1668 void *saved_private_data;
1669 fragment_data *fd_head;
1675 col_set_str(pinfo->cinfo, COL_PROTOCOL, "X.25");
1677 bytes0_1 = tvb_get_ntohs(tvb, 0);
1679 modulo = ((bytes0_1 & 0x2000) ? 128 : 8);
1680 vc = (int)(bytes0_1 & 0x0FFF);
1682 pinfo->ctype = CT_X25;
1683 pinfo->circuit_id = vc;
1685 if (bytes0_1 & X25_ABIT) toa = TRUE;
1688 x25_pkt_len = get_x25_pkt_len(tvb);
1689 if (x25_pkt_len < 3) /* packet too short */
1691 col_set_str(pinfo->cinfo, COL_INFO, "Invalid/short X.25 packet");
1693 proto_tree_add_protocol_format(tree, proto_x25, tvb, 0, -1,
1694 "Invalid/short X.25 packet");
1698 pkt_type = tvb_get_guint8(tvb, 2);
1699 if (PACKET_IS_DATA(pkt_type)) {
1700 if (bytes0_1 & X25_QBIT)
1705 ti = proto_tree_add_item(tree, proto_x25, tvb, 0, x25_pkt_len, FALSE);
1706 x25_tree = proto_item_add_subtree(ti, ett_x25);
1707 ti = proto_tree_add_item(x25_tree, hf_x25_gfi, tvb, 0, 2, FALSE);
1708 gfi_tree = proto_item_add_subtree(ti, ett_x25_gfi);
1710 if (PACKET_IS_DATA(pkt_type)) {
1711 proto_tree_add_boolean(gfi_tree, hf_x25_qbit, tvb, 0, 2,
1714 else if (pkt_type == X25_CALL_REQUEST ||
1715 pkt_type == X25_CALL_ACCEPTED ||
1716 pkt_type == X25_CLEAR_REQUEST ||
1717 pkt_type == X25_CLEAR_CONFIRMATION) {
1718 proto_tree_add_boolean(gfi_tree, hf_x25_abit, tvb, 0, 2,
1722 if (pkt_type == X25_CALL_REQUEST || pkt_type == X25_CALL_ACCEPTED ||
1723 PACKET_IS_DATA(pkt_type)) {
1724 proto_tree_add_boolean(gfi_tree, hf_x25_dbit, tvb, 0, 2,
1727 proto_tree_add_uint(gfi_tree, hf_x25_mod, tvb, 0, 2, bytes0_1);
1731 case X25_CALL_REQUEST:
1735 short_name = "Inc. call";
1736 long_name = "Incoming call";
1740 short_name = "Call req.";
1741 long_name = "Call request";
1745 short_name = "Inc. call/Call req.";
1746 long_name = "Incoming call/Call request";
1749 if (check_col(pinfo->cinfo, COL_INFO))
1750 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
1752 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb,
1754 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1755 X25_CALL_REQUEST, "Packet Type: %s", long_name);
1758 if (localoffset < x25_pkt_len) { /* calling/called addresses */
1760 x25_toa(x25_tree, (gint*)&localoffset, tvb, pinfo);
1762 x25_ntoa(x25_tree, (gint*)&localoffset, tvb, pinfo, FALSE);
1765 if (localoffset < x25_pkt_len) /* facilities */
1766 dump_facilities(x25_tree, (gint*)&localoffset, tvb);
1768 if (localoffset < tvb_reported_length(tvb)) /* user data */
1772 ti = proto_tree_add_text(x25_tree, tvb, localoffset, -1,
1774 userdata_tree = proto_item_add_subtree(ti, ett_x25_user_data);
1777 /* X.263/ISO 9577 says that:
1779 When CLNP or ESIS are run over X.25, the SPI
1780 is 0x81 or 0x82, respectively; those are the
1781 NLPIDs for those protocol.
1783 When X.224/ISO 8073 COTP is run over X.25, and
1784 when ISO 11570 explicit identification is being
1785 used, the first octet of the user data field is
1786 a TPDU length field, and the rest is "as defined
1787 in ITU-T Rec. X.225 | ISO/IEC 8073, Annex B,
1788 or ITU-T Rec. X.264 and ISO/IEC 11570".
1790 When X.264/ISO 11570 default identification is
1791 being used, there is no user data field in the
1792 CALL REQUEST packet. This is for X.225/ISO 8073
1795 It also says that SPI values from 0x03 through 0x3f are
1796 reserved and are in use by X.224/ISO 8073 Annex B and
1797 X.264/ISO 11570. The note says that those values are
1798 not NLPIDs, they're "used by the respective higher layer
1799 protocol" and "not used for higher layer protocol
1800 identification". I infer from this and from what
1801 X.264/ISO 11570 says that this means that values in those
1802 range are valid values for the first octet of an
1803 X.224/ISO 8073 packet or for X.264/ISO 11570.
1805 Annex B of X.225/ISO 8073 mentions some additional TPDU
1806 types that can be put in what I presume is the user
1807 data of connect requests. It says that:
1809 The sending transport entity shall:
1811 a) either not transmit any TPDU in the NS-user data
1812 parameter of the N-CONNECT request primitive; or
1814 b) transmit the UN-TPDU (see ITU-T Rec. X.264 and
1815 ISO/IEC 11570) followed by the NCM-TPDU in the
1816 NS-user data parameter of the N-CONNECT request
1819 I don't know if this means that the user data field
1820 will contain a UN TPDU followed by an NCM TPDU or not.
1822 X.264/ISO 11570 says that:
1824 When default identification is being used,
1825 X.225/ISO 8073 COTP is identified. No user data
1826 is sent in the network-layer connection request.
1828 When explicit identification is being used,
1829 the user data is a UN TPDU ("Use of network
1830 connection TPDU"), which specifies the transport
1831 protocol to use over this network connection.
1832 It also says that the length of a UN TPDU shall
1833 not exceed 32 octets, i.e. shall not exceed 0x20;
1834 it says this is "due to the desire not to conflict
1835 with the protocol identifier field carried by X.25
1836 CALL REQUEST/INCOMING CALL packets", and says that
1837 field has values specified in X.244. X.244 has been
1838 superseded by X.263/ISO 9577, so that presumably
1839 means the goal is to allow a UN TPDU's length
1840 field to be distinguished from an NLPID, allowing
1841 you to tell whether X.264/ISO 11570 explicit
1842 identification is being used or an NLPID is
1843 being used as the SPI.
1845 I read this as meaning that, if the ISO mechanisms are
1846 used to identify the protocol being carried over X.25:
1848 if there's no user data in the CALL REQUEST/
1849 INCOMING CALL packet, it's COTP;
1851 if there is user data, then:
1853 if the first octet is less than or equal to
1854 32, it might be a UN TPDU, and that identifies
1855 the transport protocol being used, and
1856 it may be followed by more data, such
1857 as a COTP NCM TPDU if it's COTP;
1859 if the first octet is greater than 32, it's
1860 an NLPID, *not* a TPDU length, and the
1861 stuff following it is *not* a TPDU.
1863 Figure A.2 of X.263/ISO 9577 seems to say that the
1864 first octet of the user data is a TPDU length field,
1865 in the range 0x03 through 0x82, and says they are
1866 for X.225/ISO 8073 Annex B or X.264/ISO 11570.
1868 However, X.264/ISO 11570 seems to imply that the length
1869 field would be that of a UN TPDU, which must be less
1870 than or equal to 0x20, and X.225/ISO 8073 Annex B seems
1871 to indicate that the user data must begin with
1872 an X.264/ISO 11570 UN TPDU, so I'd say that A.2 should
1873 have said "in the range 0x03 through 0x20", instead
1874 (the length value doesn't include the length field,
1875 and the minimum UN TPDU has length, type, PRT-ID,
1876 and SHARE, so that's 3 bytes without the length). */
1877 spi = tvb_get_guint8(tvb, localoffset);
1878 if (spi > 32 || spi < 3) {
1879 /* First octet is > 32, or < 3, so the user data isn't an
1880 X.264/ISO 11570 UN TPDU */
1883 /* First octet is >= 3 and <= 32, so the user data *might*
1884 be an X.264/ISO 11570 UN TPDU. Check whether we have
1885 enough data to see if it is. */
1886 if (tvb_bytes_exist(tvb, localoffset+1, 1)) {
1887 /* We do; check whether the second octet is 1. */
1888 if (tvb_get_guint8(tvb, localoffset+1) == 0x01) {
1889 /* Yes, the second byte is 1, so it looks like
1893 /* No, the second byte is not 1, so it's not a
1898 /* We can't see the second byte of the putative UN
1899 TPDU, so we don't know if that's what it is. */
1903 if (is_x_264 == -1) {
1905 * We don't know what it is; just skip it.
1907 localoffset = tvb_length(tvb);
1908 } else if (is_x_264) {
1909 /* It looks like an X.264 UN TPDU, so show it as such. */
1910 if (userdata_tree) {
1911 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1912 "X.264 length indicator: %u",
1914 proto_tree_add_text(userdata_tree, tvb, localoffset+1, 1,
1915 "X.264 UN TPDU identifier: 0x%02X",
1916 tvb_get_guint8(tvb, localoffset+1));
1918 prt_id = tvb_get_guint8(tvb, localoffset+2);
1919 if (userdata_tree) {
1920 proto_tree_add_text(userdata_tree, tvb, localoffset+2, 1,
1921 "X.264 protocol identifier: %s",
1922 val_to_str(prt_id, prt_id_vals,
1923 "Unknown (0x%02X)"));
1924 proto_tree_add_text(userdata_tree, tvb, localoffset+3, 1,
1925 "X.264 sharing strategy: %s",
1926 val_to_str(tvb_get_guint8(tvb, localoffset+3),
1927 sharing_strategy_vals, "Unknown (0x%02X)"));
1930 /* XXX - dissect the variable part? */
1932 /* The length doesn't include the length octet itself. */
1933 localoffset += spi + 1;
1937 case PRT_ID_ISO_8073:
1939 if (!pinfo->fd->flags.visited)
1940 x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
1941 /* XXX - dissect the rest of the user data as COTP?
1942 That needs support for NCM TPDUs, etc. */
1945 case PRT_ID_ISO_8602:
1947 if (!pinfo->fd->flags.visited)
1948 x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
1951 } else if (is_x_264 == 0) {
1952 /* It doesn't look like a UN TPDU, so compare the first
1953 octet of the CALL REQUEST packet with various X.263/
1954 ISO 9577 NLPIDs, as per Annex A of X.263/ISO 9577. */
1956 if (userdata_tree) {
1957 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1958 "X.263 secondary protocol ID: %s",
1959 val_to_str(spi, nlpid_vals, "Unknown (0x%02x)"));
1962 if (!pinfo->fd->flags.visited) {
1964 * Is there a dissector handle for this SPI?
1965 * If so, assign it to this virtual circuit.
1967 dissect = dissector_get_port_handle(x25_subdissector_table, spi);
1968 if (dissect != NULL)
1969 x25_hash_add_proto_start(vc, pinfo->fd->num, dissect);
1973 * If there's only one octet of user data, it's just
1974 * an NLPID; don't try to dissect it.
1976 if (localoffset + 1 == tvb_reported_length(tvb))
1980 * There's more than one octet of user data, so we'll
1981 * dissect it; for some protocols, the NLPID is considered
1982 * to be part of the PDU, so, for those cases, we don't
1983 * skip past it. For other protocols, we skip the NLPID.
1987 case NLPID_ISO8473_CLNP:
1988 case NLPID_ISO9542_ESIS:
1989 case NLPID_ISO10589_ISIS:
1990 case NLPID_ISO10747_IDRP:
1993 * The NLPID is part of the PDU. Don't skip it.
1994 * But if it's all there is to the PDU, don't
1995 * bother dissecting it.
1999 case NLPID_SPI_X_29:
2001 * The first 4 bytes of the call user data are
2002 * the SPI plus 3 reserved bytes; they are not
2003 * part of the data to be dissected as X.29 data.
2010 * The NLPID isn't part of the PDU - skip it.
2011 * If that means there's nothing to dissect
2017 /* if there's no user data in the CALL REQUEST/
2018 INCOMING CALL packet, it's COTP; */
2020 if (call_request_nodata_is_cotp){
2021 x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
2025 case X25_CALL_ACCEPTED:
2029 short_name = "Call conn.";
2030 long_name = "Call connected";
2034 short_name = "Call acc.";
2035 long_name = "Call accepted";
2039 short_name = "Call conn./Call acc.";
2040 long_name = "Call connected/Call accepted";
2043 if(check_col(pinfo->cinfo, COL_INFO))
2044 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
2046 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
2047 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
2048 X25_CALL_ACCEPTED, "Packet Type: %s", long_name);
2051 if (localoffset < x25_pkt_len) { /* calling/called addresses */
2053 x25_toa(x25_tree, (gint*)&localoffset, tvb, pinfo);
2055 x25_ntoa(x25_tree, (gint*)&localoffset, tvb, pinfo, FALSE);
2058 if (localoffset < x25_pkt_len) /* facilities */
2059 dump_facilities(x25_tree, (gint*)&localoffset, tvb);
2061 case X25_CLEAR_REQUEST:
2065 short_name = "Clear ind.";
2066 long_name = "Clear indication";
2070 short_name = "Clear req.";
2071 long_name = "Clear request";
2075 short_name = "Clear ind./Clear req.";
2076 long_name = "Clear indication/Clear request";
2079 if(check_col(pinfo->cinfo, COL_INFO)) {
2080 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - %s", short_name,
2081 vc, clear_code(tvb_get_guint8(tvb, 3)),
2082 clear_diag(tvb_get_guint8(tvb, 4)));
2084 x25_hash_add_proto_end(vc, pinfo->fd->num);
2086 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
2087 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb,
2088 localoffset+2, 1, X25_CLEAR_REQUEST, "Packet Type: %s",
2090 proto_tree_add_text(x25_tree, tvb, 3, 1,
2091 "Cause : %s", clear_code(tvb_get_guint8(tvb, 3)));
2092 proto_tree_add_text(x25_tree, tvb, 4, 1,
2093 "Diagnostic : %s", clear_diag(tvb_get_guint8(tvb, 4)));
2095 localoffset = x25_pkt_len;
2097 case X25_CLEAR_CONFIRMATION:
2098 if(check_col(pinfo->cinfo, COL_INFO))
2099 col_add_fstr(pinfo->cinfo, COL_INFO, "Clear Conf. VC:%d", vc);
2101 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
2102 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2103 X25_CLEAR_CONFIRMATION);
2105 localoffset = x25_pkt_len;
2107 if (localoffset < tvb_reported_length(tvb)) { /* extended clear conf format */
2109 x25_toa(x25_tree, (gint*)&localoffset, tvb, pinfo);
2111 x25_ntoa(x25_tree,(gint*)&localoffset, tvb, pinfo, FALSE);
2114 if (localoffset < tvb_reported_length(tvb)) /* facilities */
2115 dump_facilities(x25_tree, (gint*)&localoffset, tvb);
2117 case X25_DIAGNOSTIC:
2118 if(check_col(pinfo->cinfo, COL_INFO)) {
2119 col_add_fstr(pinfo->cinfo, COL_INFO, "Diag. %d",
2120 (int)tvb_get_guint8(tvb, 3));
2123 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2125 proto_tree_add_text(x25_tree, tvb, 3, 1,
2126 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 3));
2128 localoffset = x25_pkt_len;
2131 if(check_col(pinfo->cinfo, COL_INFO))
2132 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt VC:%d", vc);
2134 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
2135 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2138 localoffset = x25_pkt_len;
2140 case X25_INTERRUPT_CONFIRMATION:
2141 if(check_col(pinfo->cinfo, COL_INFO))
2142 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt Conf. VC:%d", vc);
2144 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
2145 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2146 X25_INTERRUPT_CONFIRMATION);
2148 localoffset = x25_pkt_len;
2150 case X25_RESET_REQUEST:
2154 short_name = "Reset ind.";
2155 long_name = "Reset indication";
2159 short_name = "Reset req.";
2160 long_name = "Reset request";
2164 short_name = "Reset ind./Reset req.";
2165 long_name = "Reset indication/Reset request";
2168 if(check_col(pinfo->cinfo, COL_INFO)) {
2169 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - Diag.:%d",
2170 short_name, vc, reset_code(tvb_get_guint8(tvb, 3)),
2171 (int)tvb_get_guint8(tvb, 4));
2173 x25_hash_add_proto_end(vc, pinfo->fd->num);
2175 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
2176 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
2177 X25_RESET_REQUEST, "Packet Type: %s", long_name);
2178 proto_tree_add_text(x25_tree, tvb, 3, 1,
2179 "Cause : %s", reset_code(tvb_get_guint8(tvb, 3)));
2180 proto_tree_add_text(x25_tree, tvb, 4, 1,
2181 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
2183 localoffset = x25_pkt_len;
2185 case X25_RESET_CONFIRMATION:
2186 if(check_col(pinfo->cinfo, COL_INFO))
2187 col_add_fstr(pinfo->cinfo, COL_INFO, "Reset conf. VC:%d", vc);
2189 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
2190 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2191 X25_RESET_CONFIRMATION);
2193 localoffset = x25_pkt_len;
2195 case X25_RESTART_REQUEST:
2199 short_name = "Restart ind.";
2200 long_name = "Restart indication";
2204 short_name = "Restart req.";
2205 long_name = "Restart request";
2209 short_name = "Restart ind./Restart req.";
2210 long_name = "Restart indication/Restart request";
2213 if(check_col(pinfo->cinfo, COL_INFO)) {
2214 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s - Diag.:%d",
2216 restart_code(tvb_get_guint8(tvb, 3)),
2217 (int)tvb_get_guint8(tvb, 4));
2220 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
2221 X25_RESTART_REQUEST, "Packet Type: %s", long_name);
2222 proto_tree_add_text(x25_tree, tvb, 3, 1,
2223 "Cause : %s", restart_code(tvb_get_guint8(tvb, 3)));
2224 proto_tree_add_text(x25_tree, tvb, 4, 1,
2225 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
2227 localoffset = x25_pkt_len;
2229 case X25_RESTART_CONFIRMATION:
2230 col_set_str(pinfo->cinfo, COL_INFO, "Restart conf.");
2232 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2233 X25_RESTART_CONFIRMATION);
2234 localoffset = x25_pkt_len;
2236 case X25_REGISTRATION_REQUEST:
2237 col_set_str(pinfo->cinfo, COL_INFO, "Registration req.");
2239 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2240 X25_REGISTRATION_REQUEST);
2242 if (localoffset < x25_pkt_len)
2243 x25_ntoa(x25_tree, (gint*)&localoffset, tvb, pinfo, TRUE);
2246 if (localoffset < x25_pkt_len)
2247 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
2248 "Registration length: %d",
2249 tvb_get_guint8(tvb, localoffset) & 0x7F);
2250 if (localoffset+1 < x25_pkt_len)
2251 proto_tree_add_text(x25_tree, tvb, localoffset+1,
2252 tvb_get_guint8(tvb, localoffset) & 0x7F,
2255 localoffset = tvb_reported_length(tvb);
2257 case X25_REGISTRATION_CONFIRMATION:
2258 col_set_str(pinfo->cinfo, COL_INFO, "Registration conf.");
2260 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2261 X25_REGISTRATION_CONFIRMATION);
2262 proto_tree_add_text(x25_tree, tvb, 3, 1,
2263 "Cause: %s", registration_code(tvb_get_guint8(tvb, 3)));
2264 proto_tree_add_text(x25_tree, tvb, 4, 1,
2265 "Diagnostic: %s", registration_code(tvb_get_guint8(tvb, 4)));
2268 if (localoffset < x25_pkt_len)
2269 x25_ntoa(x25_tree, (gint*)&localoffset, tvb, pinfo, TRUE);
2272 if (localoffset < x25_pkt_len)
2273 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
2274 "Registration length: %d",
2275 tvb_get_guint8(tvb, localoffset) & 0x7F);
2276 if (localoffset+1 < x25_pkt_len)
2277 proto_tree_add_text(x25_tree, tvb, localoffset+1,
2278 tvb_get_guint8(tvb, localoffset) & 0x7F,
2281 localoffset = tvb_reported_length(tvb);
2285 if (PACKET_IS_DATA(pkt_type))
2287 if(check_col(pinfo->cinfo, COL_INFO)) {
2289 col_add_fstr(pinfo->cinfo, COL_INFO,
2290 "Data VC:%d P(S):%d P(R):%d %s", vc,
2291 (pkt_type >> 1) & 0x07,
2292 (pkt_type >> 5) & 0x07,
2293 (pkt_type & X25_MBIT_MOD8) ? " M" : "");
2295 col_add_fstr(pinfo->cinfo, COL_INFO,
2296 "Data VC:%d P(S):%d P(R):%d %s", vc,
2297 tvb_get_guint8(tvb, localoffset+1) >> 1,
2299 (tvb_get_guint8(tvb, localoffset+1) & X25_MBIT_MOD128) ? " M" : "");
2302 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2305 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2306 localoffset, 1, pkt_type);
2307 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod8, tvb,
2308 localoffset, 1, pkt_type);
2309 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod8, tvb,
2310 localoffset, 1, pkt_type);
2311 proto_tree_add_uint(x25_tree, hf_x25_type_data, tvb,
2312 localoffset, 1, pkt_type);
2315 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod128, tvb,
2316 localoffset, 1, pkt_type);
2317 proto_tree_add_uint(x25_tree, hf_x25_type_data, tvb,
2318 localoffset, 1, pkt_type);
2319 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod128, tvb,
2321 tvb_get_guint8(tvb, localoffset+1));
2322 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod128, tvb,
2324 tvb_get_guint8(tvb, localoffset+1));
2328 m_bit_set = pkt_type & X25_MBIT_MOD8;
2331 m_bit_set = tvb_get_guint8(tvb, localoffset+1) & X25_MBIT_MOD128;
2334 payload_len = tvb_reported_length_remaining(tvb, localoffset);
2335 if (reassemble_x25) {
2337 * Reassemble received and sent traffic separately.
2338 * We don't reassemble traffic with an unknown direction
2344 * OR in an extra bit to distinguish from traffic
2345 * in the other direction.
2347 frag_key |= 0x10000;
2349 fd_head = fragment_add_seq_next(tvb, localoffset,
2352 x25_reassembled_table,
2353 payload_len, m_bit_set);
2354 pinfo->fragmented = m_bit_set;
2356 /* Fragment handling is not adapted to handle several x25
2357 * packets in the same frame. This is common with XOT and
2358 * shorter packet sizes.
2359 * Therefore, fragment_add_seq_next seem to always return fd_head
2360 * A fix to use m_bit_set to only show fragments for last pkt
2362 if (!m_bit_set && fd_head) {
2363 if (fd_head->next) {
2364 proto_item *frag_tree_item;
2366 /* This is the last packet */
2367 next_tvb = tvb_new_child_real_data(tvb, fd_head->data,
2370 add_new_data_source(pinfo, next_tvb, "Reassembled X.25");
2372 show_fragment_seq_tree(fd_head,
2375 pinfo, next_tvb, &frag_tree_item);
2380 if (m_bit_set && next_tvb == NULL) {
2382 * This isn't the last packet, so just
2383 * show it as X.25 user data.
2385 proto_tree_add_text(x25_tree, tvb, localoffset, -1,
2386 "User data (%u byte%s)", payload_len,
2387 plurality(payload_len, "", "s"));
2395 * Non-data packets (RR, RNR, REJ).
2397 switch (PACKET_TYPE_FC(pkt_type))
2400 if(check_col(pinfo->cinfo, COL_INFO)) {
2402 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2403 vc, (pkt_type >> 5) & 0x07);
2405 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2406 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2409 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2412 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2413 localoffset, 1, pkt_type);
2414 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2415 localoffset, 1, X25_RR);
2418 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2419 localoffset, 1, X25_RR);
2420 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2421 localoffset+1, 1, FALSE);
2427 if(check_col(pinfo->cinfo, COL_INFO)) {
2429 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2430 vc, (pkt_type >> 5) & 0x07);
2432 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2433 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2436 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2439 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2440 localoffset, 1, pkt_type);
2441 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2442 localoffset, 1, X25_RNR);
2445 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2446 localoffset, 1, X25_RNR);
2447 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2448 localoffset+1, 1, FALSE);
2454 if(check_col(pinfo->cinfo, COL_INFO)) {
2456 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2457 vc, (pkt_type >> 5) & 0x07);
2459 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2460 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2463 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2466 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2467 localoffset, 1, pkt_type);
2468 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2469 localoffset, 1, X25_REJ);
2472 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2473 localoffset, 1, X25_REJ);
2474 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2475 localoffset+1, 1, FALSE);
2479 localoffset += (modulo == 8) ? 1 : 2;
2482 if (localoffset >= tvb_reported_length(tvb))
2484 if (pinfo->fragmented)
2488 next_tvb = tvb_new_subset_remaining(tvb, localoffset);
2490 saved_private_data = pinfo->private_data;
2491 pinfo->private_data = &q_bit_set;
2493 /* See if there's already a dissector for this circuit. */
2494 if (try_circuit_dissector(CT_X25, vc, pinfo->fd->num, next_tvb, pinfo,
2496 pinfo->private_data = saved_private_data;
2497 return; /* found it and dissected it */
2500 /* Did the user suggest QLLC/SNA? */
2501 if (payload_is_qllc_sna) {
2502 /* Yes - dissect it as QLLC/SNA. */
2503 if (!pinfo->fd->flags.visited)
2504 x25_hash_add_proto_start(vc, pinfo->fd->num, qllc_handle);
2505 call_dissector(qllc_handle, next_tvb, pinfo, tree);
2506 pinfo->private_data = saved_private_data;
2510 if (payload_check_data){
2511 /* If the Call Req. has not been captured, let's look at the first
2512 two bytes of the payload to see if this looks like COTP. */
2513 if (tvb_get_guint8(tvb, localoffset) == tvb_length(next_tvb)-1) {
2514 /* First byte contains the length of the remaining buffer */
2515 if ((tvb_get_guint8(tvb, localoffset+1) & 0x0F) == 0) {
2516 /* Second byte contains a valid COTP TPDU */
2517 if (!pinfo->fd->flags.visited)
2518 x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
2519 call_dissector(ositp_handle, next_tvb, pinfo, tree);
2520 pinfo->private_data = saved_private_data;
2525 /* Then let's look at the first byte of the payload to see if this
2526 looks like IP or CLNP. */
2527 switch (tvb_get_guint8(tvb, localoffset)) {
2530 /* Looks like an IP header */
2531 if (!pinfo->fd->flags.visited)
2532 x25_hash_add_proto_start(vc, pinfo->fd->num, ip_handle);
2533 call_dissector(ip_handle, next_tvb, pinfo, tree);
2534 pinfo->private_data = saved_private_data;
2537 case NLPID_ISO8473_CLNP:
2538 if (!pinfo->fd->flags.visited)
2539 x25_hash_add_proto_start(vc, pinfo->fd->num, clnp_handle);
2540 call_dissector(clnp_handle, next_tvb, pinfo, tree);
2541 pinfo->private_data = saved_private_data;
2546 /* Try the heuristic dissectors. */
2547 if (dissector_try_heuristic(x25_heur_subdissector_list, next_tvb, pinfo,
2549 pinfo->private_data = saved_private_data;
2553 /* All else failed; dissect it as raw data */
2554 call_dissector(data_handle, next_tvb, pinfo, tree);
2555 pinfo->private_data = saved_private_data;
2559 * X.25 dissector for use when "pinfo->pseudo_header" points to a
2560 * "struct x25_phdr".
2563 dissect_x25_dir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2565 dissect_x25_common(tvb, pinfo, tree,
2566 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? X25_FROM_DCE :
2568 pinfo->pseudo_header->x25.flags & FROM_DCE);
2572 * X.25 dissector for use when "pinfo->pseudo_header" doesn't point to a
2573 * "struct x25_phdr".
2576 dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2581 * We don't know if this packet is DTE->DCE or DCE->DCE.
2582 * However, we can, at least, distinguish between the two
2583 * sides of the conversation, based on the addresses and
2586 direction = CMP_ADDRESS(&pinfo->src, &pinfo->dst);
2588 direction = (pinfo->srcport > pinfo->destport)*2 - 1;
2589 dissect_x25_common(tvb, pinfo, tree, X25_UNKNOWN, direction > 0);
2593 x25_reassemble_init(void)
2595 fragment_table_init(&x25_segment_table);
2596 reassembled_table_init(&x25_reassembled_table);
2600 proto_register_x25(void)
2602 static hf_register_info hf[] = {
2604 { "GFI", "x25.gfi", FT_UINT16, BASE_DEC, NULL, 0xF000,
2605 "General format identifier", HFILL }},
2607 { "A Bit", "x25.a", FT_BOOLEAN, 16, NULL, X25_ABIT,
2608 "Address Bit", HFILL }},
2610 { "Q Bit", "x25.q", FT_BOOLEAN, 16, NULL, X25_QBIT,
2611 "Qualifier Bit", HFILL }},
2613 { "D Bit", "x25.d", FT_BOOLEAN, 16, NULL, X25_DBIT,
2614 "Delivery Confirmation Bit", HFILL }},
2616 { "Modulo", "x25.mod", FT_UINT16, BASE_DEC, VALS(vals_modulo), 0x3000,
2617 "Specifies whether the frame is modulo 8 or 128", HFILL }},
2619 { "Logical Channel", "x25.lcn", FT_UINT16, BASE_DEC, NULL, 0x0FFF,
2620 "Logical Channel Number", HFILL }},
2622 { "Packet Type", "x25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x0,
2624 { &hf_x25_type_fc_mod8,
2625 { "Packet Type", "x25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x1F,
2627 { &hf_x25_type_data,
2628 { "Packet Type", "x25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x01,
2631 { "P(R)", "x25.p_r", FT_UINT8, BASE_DEC, NULL, 0xE0,
2632 "Packet Receive Sequence Number", HFILL }},
2633 { &hf_x25_p_r_mod128,
2634 { "P(R)", "x25.p_r", FT_UINT8, BASE_DEC, NULL, 0xFE,
2635 "Packet Receive Sequence Number", HFILL }},
2636 { &hf_x25_mbit_mod8,
2637 { "M Bit", "x25.m", FT_BOOLEAN, 8, TFS(&m_bit_tfs), X25_MBIT_MOD8,
2638 "More Bit", HFILL }},
2639 { &hf_x25_mbit_mod128,
2640 { "M Bit", "x25.m", FT_BOOLEAN, 8, TFS(&m_bit_tfs), X25_MBIT_MOD128,
2641 "More Bit", HFILL }},
2643 { "P(S)", "x25.p_s", FT_UINT8, BASE_DEC, NULL, 0x0E,
2644 "Packet Send Sequence Number", HFILL }},
2645 { &hf_x25_p_s_mod128,
2646 { "P(S)", "x25.p_s", FT_UINT8, BASE_DEC, NULL, 0xFE,
2647 "Packet Send Sequence Number", HFILL }},
2648 { &hf_x25_segment_overlap,
2649 { "Fragment overlap", "x25.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2650 "Fragment overlaps with other fragments", HFILL }},
2652 { &hf_x25_segment_overlap_conflict,
2653 { "Conflicting data in fragment overlap", "x25.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2654 "Overlapping fragments contained conflicting data", HFILL }},
2656 { &hf_x25_segment_multiple_tails,
2657 { "Multiple tail fragments found", "x25.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2658 "Several tails were found when defragmenting the packet", HFILL }},
2660 { &hf_x25_segment_too_long_segment,
2661 { "Fragment too long", "x25.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2662 "Fragment contained data past end of packet", HFILL }},
2664 { &hf_x25_segment_error,
2665 { "Defragmentation error", "x25.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2666 "Defragmentation error due to illegal fragments", HFILL }},
2669 { "X.25 Fragment", "x25.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2670 "X25 Fragment", HFILL }},
2673 { "X.25 Fragments", "x25.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
2676 static gint *ett[] = {
2680 &ett_x25_fac_unknown,
2682 &ett_x25_fac_reverse,
2683 &ett_x25_fac_charging_info,
2684 &ett_x25_fac_throughput,
2686 &ett_x25_fac_called_modif,
2687 &ett_x25_fac_cug_outgoing_acc,
2688 &ett_x25_fac_throughput_min,
2689 &ett_x25_fac_express_data,
2690 &ett_x25_fac_bilateral_cug,
2691 &ett_x25_fac_packet_size,
2692 &ett_x25_fac_window_size,
2693 &ett_x25_fac_rpoa_selection,
2694 &ett_x25_fac_cug_ext,
2695 &ett_x25_fac_cug_outgoing_acc_ext,
2696 &ett_x25_fac_transit_delay,
2697 &ett_x25_fac_call_duration,
2698 &ett_x25_fac_segment_count,
2699 &ett_x25_fac_call_transfer,
2700 &ett_x25_fac_rpoa_selection_ext,
2701 &ett_x25_fac_monetary_unit,
2703 &ett_x25_fac_called_addr_ext,
2704 &ett_x25_fac_ete_transit_delay,
2705 &ett_x25_fac_calling_addr_ext,
2706 &ett_x25_fac_call_deflect,
2707 &ett_x25_fac_priority,
2712 module_t *x25_module;
2714 proto_x25 = proto_register_protocol ("X.25", "X.25", "x25");
2715 proto_register_field_array (proto_x25, hf, array_length(hf));
2716 proto_register_subtree_array(ett, array_length(ett));
2718 x25_subdissector_table = register_dissector_table("x.25.spi",
2719 "X.25 secondary protocol identifier", FT_UINT8, BASE_HEX);
2720 register_heur_dissector_list("x.25", &x25_heur_subdissector_list);
2722 register_dissector("x.25_dir", dissect_x25_dir, proto_x25);
2723 register_dissector("x.25", dissect_x25, proto_x25);
2726 x25_module = prefs_register_protocol(proto_x25, NULL);
2727 prefs_register_obsolete_preference(x25_module, "non_q_bit_is_sna");
2728 prefs_register_bool_preference(x25_module, "payload_is_qllc_sna",
2729 "Default to QLLC/SNA",
2730 "If CALL REQUEST not seen or didn't specify protocol, dissect as QLLC/SNA",
2731 &payload_is_qllc_sna);
2732 prefs_register_bool_preference(x25_module, "call_request_nodata_is_cotp",
2733 "Assume COTP for Call Request without data",
2734 "If CALL REQUEST has no data, assume the protocol handled is COTP",
2735 &call_request_nodata_is_cotp);
2736 prefs_register_bool_preference(x25_module, "payload_check_data",
2737 "Check data for COTP/IP/CLNP",
2738 "If CALL REQUEST not seen or didn't specify protocol, check user data before checking heuristic dissectors",
2739 &payload_check_data);
2740 prefs_register_bool_preference(x25_module, "reassemble",
2741 "Reassemble fragmented X.25 packets",
2742 "Reassemble fragmented X.25 packets",
2744 register_init_routine(&x25_reassemble_init);
2748 proto_reg_handoff_x25(void)
2750 dissector_handle_t x25_handle;
2753 * Get handles for various dissectors.
2755 ip_handle = find_dissector("ip");
2756 clnp_handle = find_dissector("clnp");
2757 ositp_handle = find_dissector("ositp");
2758 qllc_handle = find_dissector("qllc");
2759 data_handle = find_dissector("data");
2761 x25_handle = find_dissector("x.25");
2762 dissector_add("llc.dsap", SAP_X25, x25_handle);