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.
33 #include <epan/llcsaps.h>
34 #include <epan/packet.h>
35 #include <epan/circuit.h>
36 #include <epan/reassemble.h>
37 #include <epan/prefs.h>
38 #include <epan/emem.h>
39 #include <epan/nlpid.h>
40 #include <epan/x264_prt_id.h>
43 * Direction of packet.
46 X25_FROM_DCE, /* DCE->DTE */
47 X25_FROM_DTE, /* DTE->DCE */
48 X25_UNKNOWN /* direction unknown */
52 * 0 for data packets, 1 for non-data packets.
54 #define X25_NONDATA_BIT 0x01
56 #define X25_CALL_REQUEST 0x0B
57 #define X25_CALL_ACCEPTED 0x0F
58 #define X25_CLEAR_REQUEST 0x13
59 #define X25_CLEAR_CONFIRMATION 0x17
60 #define X25_INTERRUPT 0x23
61 #define X25_INTERRUPT_CONFIRMATION 0x27
62 #define X25_RESET_REQUEST 0x1B
63 #define X25_RESET_CONFIRMATION 0x1F
64 #define X25_RESTART_REQUEST 0xFB
65 #define X25_RESTART_CONFIRMATION 0xFF
66 #define X25_REGISTRATION_REQUEST 0xF3
67 #define X25_REGISTRATION_CONFIRMATION 0xF7
68 #define X25_DIAGNOSTIC 0xF1
74 #define PACKET_IS_DATA(type) (!(type & X25_NONDATA_BIT))
75 #define PACKET_TYPE_FC(type) (type & 0x1F)
77 #define X25_MBIT_MOD8 0x10
78 #define X25_MBIT_MOD128 0x01
80 #define X25_ABIT 0x8000
82 #define X25_QBIT 0x8000
83 #define X25_DBIT 0x4000
85 #define X25_FAC_CLASS_MASK 0xC0
87 #define X25_FAC_CLASS_A 0x00
88 #define X25_FAC_CLASS_B 0x40
89 #define X25_FAC_CLASS_C 0x80
90 #define X25_FAC_CLASS_D 0xC0
92 #define X25_FAC_COMP_MARK 0x00
93 #define X25_FAC_REVERSE 0x01
94 #define X25_FAC_THROUGHPUT 0x02
95 #define X25_FAC_CUG 0x03
96 #define X25_FAC_CHARGING_INFO 0x04
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_CUG_EXT 0x47
106 #define X25_FAC_CUG_OUTGOING_ACC_EXT 0x48
107 #define X25_FAC_TRANSIT_DELAY 0x49
108 #define X25_FAC_CALL_DURATION 0xC1
109 #define X25_FAC_SEGMENT_COUNT 0xC2
110 #define X25_FAC_CALL_TRANSFER 0xC3
111 #define X25_FAC_RPOA_SELECTION_EXT 0xC4
112 #define X25_FAC_MONETARY_UNIT 0xC5
113 #define X25_FAC_NUI 0xC6
114 #define X25_FAC_CALLED_ADDR_EXT 0xC9
115 #define X25_FAC_ETE_TRANSIT_DELAY 0xCA
116 #define X25_FAC_CALLING_ADDR_EXT 0xCB
117 #define X25_FAC_CALL_DEFLECT 0xD1
118 #define X25_FAC_PRIORITY 0xD2
120 static int proto_x25 = -1;
121 static int hf_x25_gfi = -1;
122 static int hf_x25_abit = -1;
123 static int hf_x25_qbit = -1;
124 static int hf_x25_dbit = -1;
125 static int hf_x25_mod = -1;
126 static int hf_x25_lcn = -1;
127 static int hf_x25_type = -1;
128 static int hf_x25_type_fc_mod8 = -1;
129 static int hf_x25_type_data = -1;
130 static int hf_x25_p_r_mod8 = -1;
131 static int hf_x25_p_r_mod128 = -1;
132 static int hf_x25_mbit_mod8 = -1;
133 static int hf_x25_mbit_mod128 = -1;
134 static int hf_x25_p_s_mod8 = -1;
135 static int hf_x25_p_s_mod128 = -1;
137 static gint ett_x25 = -1;
138 static gint ett_x25_gfi = -1;
139 static gint ett_x25_fac = -1;
140 static gint ett_x25_fac_unknown = -1;
141 static gint ett_x25_fac_mark = -1;
142 static gint ett_x25_fac_reverse = -1;
143 static gint ett_x25_fac_charging_info = -1;
144 static gint ett_x25_fac_throughput = -1;
145 static gint ett_x25_fac_cug = -1;
146 static gint ett_x25_fac_called_modif = -1;
147 static gint ett_x25_fac_cug_outgoing_acc = -1;
148 static gint ett_x25_fac_throughput_min = -1;
149 static gint ett_x25_fac_express_data = -1;
150 static gint ett_x25_fac_bilateral_cug = -1;
151 static gint ett_x25_fac_packet_size = -1;
152 static gint ett_x25_fac_window_size = -1;
153 static gint ett_x25_fac_rpoa_selection = -1;
154 static gint ett_x25_fac_cug_ext = -1;
155 static gint ett_x25_fac_cug_outgoing_acc_ext = -1;
156 static gint ett_x25_fac_transit_delay = -1;
157 static gint ett_x25_fac_call_duration = -1;
158 static gint ett_x25_fac_segment_count = -1;
159 static gint ett_x25_fac_call_transfer = -1;
160 static gint ett_x25_fac_rpoa_selection_ext = -1;
161 static gint ett_x25_fac_monetary_unit = -1;
162 static gint ett_x25_fac_nui = -1;
163 static gint ett_x25_fac_called_addr_ext = -1;
164 static gint ett_x25_fac_ete_transit_delay = -1;
165 static gint ett_x25_fac_calling_addr_ext = -1;
166 static gint ett_x25_fac_call_deflect = -1;
167 static gint ett_x25_fac_priority = -1;
168 static gint ett_x25_user_data = -1;
170 static gint ett_x25_segment = -1;
171 static gint ett_x25_segments = -1;
172 static gint hf_x25_segments = -1;
173 static gint hf_x25_segment = -1;
174 static gint hf_x25_segment_overlap = -1;
175 static gint hf_x25_segment_overlap_conflict = -1;
176 static gint hf_x25_segment_multiple_tails = -1;
177 static gint hf_x25_segment_too_long_segment = -1;
178 static gint hf_x25_segment_error = -1;
179 static gint hf_x25_segment_count = -1;
180 static gint hf_x25_reassembled_length = -1;
182 static const value_string vals_modulo[] = {
188 static const value_string vals_x25_type[] = {
189 { X25_CALL_REQUEST, "Call" },
190 { X25_CALL_ACCEPTED, "Call Accepted" },
191 { X25_CLEAR_REQUEST, "Clear" },
192 { X25_CLEAR_CONFIRMATION, "Clear Confirmation" },
193 { X25_INTERRUPT, "Interrupt" },
194 { X25_INTERRUPT_CONFIRMATION, "Interrupt Confirmation" },
195 { X25_RESET_REQUEST, "Reset" },
196 { X25_RESET_CONFIRMATION, "Reset Confirmation" },
197 { X25_RESTART_REQUEST, "Restart" },
198 { X25_RESTART_CONFIRMATION, "Restart Confirmation" },
199 { X25_REGISTRATION_REQUEST, "Registration" },
200 { X25_REGISTRATION_CONFIRMATION, "Registration Confirmation" },
201 { X25_DIAGNOSTIC, "Diagnostic" },
205 { X25_DATA, "Data" },
209 static struct true_false_string m_bit_tfs = {
214 static const fragment_items x25_frag_items = {
219 &hf_x25_segment_overlap,
220 &hf_x25_segment_overlap_conflict,
221 &hf_x25_segment_multiple_tails,
222 &hf_x25_segment_too_long_segment,
223 &hf_x25_segment_error,
224 &hf_x25_segment_count,
226 &hf_x25_reassembled_length,
230 static dissector_handle_t ip_handle;
231 static dissector_handle_t clnp_handle;
232 static dissector_handle_t ositp_handle;
233 static dissector_handle_t qllc_handle;
234 static dissector_handle_t data_handle;
237 static gboolean payload_is_qllc_sna = FALSE;
238 static gboolean call_request_nodata_is_cotp = FALSE;
239 static gboolean payload_check_data = FALSE;
240 static gboolean reassemble_x25 = TRUE;
242 /* Reassembly of X.25 */
244 static GHashTable *x25_segment_table = NULL;
245 static GHashTable *x25_reassembled_table = NULL;
247 static dissector_table_t x25_subdissector_table;
248 static heur_dissector_list_t x25_heur_subdissector_list;
251 x25_hash_add_proto_start(guint16 vc, guint32 frame, dissector_handle_t dissect)
256 * Is there already a circuit with this VC number?
258 circuit = find_circuit(CT_X25, vc, frame);
259 if (circuit != NULL) {
261 * Yes - close it, as we're creating a new one.
263 close_circuit(circuit, frame - 1);
267 * Set up a new circuit.
269 circuit = circuit_new(CT_X25, vc, frame);
274 circuit_set_dissector(circuit, dissect);
278 x25_hash_add_proto_end(guint16 vc, guint32 frame)
283 * Try to find the circuit.
285 circuit = find_circuit(CT_X25, vc, frame);
288 * If we succeeded, close it.
291 close_circuit(circuit, frame);
294 static const char *clear_code(unsigned char code)
296 if (code == 0x00 || (code & 0x80) == 0x80)
297 return "DTE Originated";
299 return "Number Busy";
301 return "Invalid Facility Requested";
303 return "Network Congestion";
305 return "Out Of Order";
307 return "Access Barred";
309 return "Not Obtainable";
311 return "Remote Procedure Error";
313 return "Local Procedure Error";
315 return "RPOA Out Of Order";
317 return "Reverse Charging Acceptance Not Subscribed";
319 return "Incompatible Destination";
321 return "Fast Select Acceptance Not Subscribed";
323 return "Destination Absent";
325 return ep_strdup_printf("Unknown %02X", code);
328 static const char *clear_diag(unsigned char code)
331 return "No additional information";
333 return "Invalid P(S)";
335 return "Invalid P(R)";
337 return "Packet type invalid";
339 return "Packet type invalid for state r1";
341 return "Packet type invalid for state r2";
343 return "Packet type invalid for state r3";
345 return "Packet type invalid for state p1";
347 return "Packet type invalid for state p2";
349 return "Packet type invalid for state p3";
351 return "Packet type invalid for state p4";
353 return "Packet type invalid for state p5";
355 return "Packet type invalid for state p6";
357 return "Packet type invalid for state p7";
359 return "Packet type invalid for state d1";
361 return "Packet type invalid for state d2";
363 return "Packet type invalid for state d3";
365 return "Packet not allowed";
367 return "Unidentifiable packet";
369 return "Call on one-way logical channel";
371 return "Invalid packet type on a PVC";
373 return "Packet on unassigned LC";
375 return "Reject not subscribed to";
377 return "Packet too short";
379 return "Packet too long";
381 return "Invalid general format identifier";
383 return "Restart/registration packet with nonzero bits";
385 return "Packet type not compatible with facility";
387 return "Unauthorised interrupt confirmation";
389 return "Unauthorised interrupt";
391 return "Unauthorised reject";
393 return "Time expired";
395 return "Time expired for incoming call";
397 return "Time expired for clear indication";
399 return "Time expired for reset indication";
401 return "Time expired for restart indication";
403 return "Time expired for call deflection";
405 return "Call set-up/clearing or registration pb.";
407 return "Facility/registration code not allowed";
409 return "Facility parameter not allowed";
411 return "Invalid called DTE address";
413 return "Invalid calling DTE address";
415 return "Invalid facility/registration length";
417 return "Incoming call barred";
419 return "No logical channel available";
421 return "Call collision";
423 return "Duplicate facility requested";
425 return "Non zero address length";
427 return "Non zero facility length";
429 return "Facility not provided when expected";
431 return "Invalid CCITT-specified DTE facility";
433 return "Max. nb of call redir/defl. exceeded";
435 return "Miscellaneous";
437 return "Improper cause code from DTE";
439 return "Not aligned octet";
441 return "Inconsistent Q bit setting";
443 return "NUI problem";
445 return "International problem";
447 return "Remote network problem";
449 return "International protocol problem";
451 return "International link out of order";
453 return "International link busy";
455 return "Transit network facility problem";
457 return "Remote network facility problem";
459 return "International routing problem";
461 return "Temporary routing problem";
463 return "Unknown called DNIC";
465 return "Maintenance action";
467 return "Timer expired or retransmission count surpassed";
469 return "Timer expired or retransmission count surpassed for INTERRUPT";
471 return "Timer expired or retransmission count surpassed for DATA "
472 "packet transmission";
474 return "Timer expired or retransmission count surpassed for REJECT";
476 return "DTE-specific signals";
478 return "DTE operational";
480 return "DTE not operational";
482 return "DTE resource constraint";
484 return "Fast select not subscribed";
486 return "Invalid partially full DATA packet";
488 return "D-bit procedure not supported";
490 return "Registration/Cancellation confirmed";
492 return "OSI network service problem";
494 return "Disconnection (transient condition)";
496 return "Disconnection (permanent condition)";
498 return "Connection rejection - reason unspecified (transient "
501 return "Connection rejection - reason unspecified (permanent "
504 return "Connection rejection - quality of service not available "
505 "transient condition)";
507 return "Connection rejection - quality of service not available "
508 "permanent condition)";
510 return "Connection rejection - NSAP unreachable (transient condition)";
512 return "Connection rejection - NSAP unreachable (permanent condition)";
514 return "reset - reason unspecified";
516 return "reset - congestion";
518 return "Connection rejection - NSAP address unknown (permanent "
521 return "Higher layer initiated";
523 return "Disconnection - normal";
525 return "Disconnection - abnormal";
527 return "Disconnection - incompatible information in user data";
529 return "Connection rejection - reason unspecified (transient "
532 return "Connection rejection - reason unspecified (permanent "
535 return "Connection rejection - quality of service not available "
536 "(transient condition)";
538 return "Connection rejection - quality of service not available "
539 "(permanent condition)";
541 return "Connection rejection - incompatible information in user data";
543 return "Connection rejection - unrecognizable protocol identifier "
546 return "Reset - user resynchronization";
548 return ep_strdup_printf("Unknown %d", code);
551 static const char *reset_code(unsigned char code)
553 if (code == 0x00 || (code & 0x80) == 0x80)
554 return "DTE Originated";
556 return "Out of order";
558 return "Remote Procedure Error";
560 return "Local Procedure Error";
562 return "Network Congestion";
564 return "Remote DTE operational";
566 return "Network operational";
568 return "Incompatible Destination";
570 return "Network out of order";
572 return ep_strdup_printf("Unknown %02X", code);
575 static const char *restart_code(unsigned char code)
577 if (code == 0x00 || (code & 0x80) == 0x80)
578 return "DTE Originated";
580 return "Local Procedure Error";
582 return "Network Congestion";
584 return "Network Operational";
586 return "Registration/cancellation confirmed";
588 return ep_strdup_printf("Unknown %02X", code);
591 static const char *registration_code(unsigned char code)
594 return "Invalid facility request";
596 return "Network congestion";
598 return "Local procedure error";
600 return "Registration/cancellation confirmed";
602 return ep_strdup_printf("Unknown %02X", code);
606 dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb)
608 guint8 fac, byte1, byte2, byte3;
609 guint32 len; /* facilities length */
611 proto_tree *fac_tree = 0;
612 proto_tree *fac_subtree;
614 len = tvb_get_guint8(tvb, *offset);
616 ti = proto_tree_add_text(tree, tvb, *offset, len + 1,
618 fac_tree = proto_item_add_subtree(ti, ett_x25_fac);
619 proto_tree_add_text(fac_tree, tvb, *offset, 1,
620 "Facilities length: %d", len);
625 fac = tvb_get_guint8(tvb, *offset);
626 switch(fac & X25_FAC_CLASS_MASK) {
627 case X25_FAC_CLASS_A:
629 case X25_FAC_COMP_MARK:
631 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
632 "Code : 00 (Marker)");
633 switch (tvb_get_guint8(tvb, *offset + 1)) {
636 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
637 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
638 "Parameter : 00 (Network complementary "
639 "services - calling DTE)");
644 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
645 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
646 "Parameter : FF (Network complementary "
647 "services - called DTE)");
652 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
653 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
654 "Parameter : 0F (DTE complementary "
660 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
661 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
662 "Parameter : %02X (Unknown marker)",
663 tvb_get_guint8(tvb, *offset+1));
668 case X25_FAC_REVERSE:
670 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
671 "(Reverse charging / Fast select)", fac);
672 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_reverse);
673 byte1 = tvb_get_guint8(tvb, *offset + 1);
674 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
675 "Parameter : %02X", byte1);
677 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
678 "11.. .... = Fast select with restriction");
679 else if (byte1 & 0x80)
680 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
681 "10.. .... = Fast select - no restriction");
683 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
684 "00.. .... = Fast select not requested");
685 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1, "%s",
686 decode_boolean_bitfield(byte1, 0x01, 1*8,
687 "Reverse charging requested",
688 "Reverse charging not requested"));
691 case X25_FAC_CHARGING_INFO:
693 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
694 "(Charging information)", fac);
695 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_charging_info);
696 byte1 = tvb_get_guint8(tvb, *offset + 1);
697 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
698 "Parameter : %02X", byte1);
699 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1, "%s",
700 decode_boolean_bitfield(byte1, 0x01, 1*8,
701 "Charging information requested",
702 "Charging information not requested"));
705 case X25_FAC_THROUGHPUT:
710 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
711 "(Throughput class negotiation)", fac);
712 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_throughput);
713 byte1 = tvb_get_guint8(tvb, *offset + 1);
725 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (%d bps)",
726 75*(1<<((byte1 >> 4)-3)));
729 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (48000 bps)");
732 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (64000 bps)");
735 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (Reserved)");
737 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1, "%s",
738 decode_numeric_bitfield(byte1, 0xF0, 1*8, tmpbuf));
739 switch (byte1 & 0x0F)
750 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (%d bps)",
751 75*(1<<((byte1 & 0x0F)-3)));
754 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (48000 bps)");
757 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (64000 bps)");
760 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (Reserved)");
762 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1, "%s",
763 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
768 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
769 "(Closed user group selection)", fac);
770 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_cug);
771 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
772 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
775 case X25_FAC_CALLED_MODIF:
777 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
778 "(Called address modified)", fac);
779 fac_subtree = proto_item_add_subtree(ti,
780 ett_x25_fac_called_modif);
781 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
782 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
785 case X25_FAC_CUG_OUTGOING_ACC:
787 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
788 "(Closed user group with outgoing access selection)",
790 fac_subtree = proto_item_add_subtree(ti,
791 ett_x25_fac_cug_outgoing_acc);
792 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
793 "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
796 case X25_FAC_THROUGHPUT_MIN:
798 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
799 "(Minimum throughput class)", fac);
800 fac_subtree = proto_item_add_subtree(ti,
801 ett_x25_fac_throughput_min);
802 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
803 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
806 case X25_FAC_EXPRESS_DATA:
808 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
809 "(Negotiation of express data)", fac);
810 fac_subtree = proto_item_add_subtree(ti,
811 ett_x25_fac_express_data);
812 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
813 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
818 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
819 "Code : %02X (Unknown class A)", fac);
820 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
821 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
822 "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
829 case X25_FAC_CLASS_B:
831 case X25_FAC_BILATERAL_CUG:
833 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
834 "(Bilateral closed user group selection)", fac);
835 fac_subtree = proto_item_add_subtree(ti,
836 ett_x25_fac_bilateral_cug);
837 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
838 "Bilateral CUG: %04X",
839 tvb_get_ntohs(tvb, *offset+1));
842 case X25_FAC_PACKET_SIZE:
848 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
849 "(Packet size)", fac);
850 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_packet_size);
851 byte1 = tvb_get_guint8(tvb, *offset + 1);
855 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (16)");
858 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (32)");
861 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (64)");
864 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (128)");
867 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (256)");
870 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (512)");
873 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (1024)");
876 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (2048)");
879 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (4096)");
882 g_snprintf(tmpbuf, 80, "From the called DTE : %%u (Unknown)");
885 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1, "%s",
886 decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
888 byte2 = tvb_get_guint8(tvb, *offset + 2);
892 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (16)");
895 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (32)");
898 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (64)");
901 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (128)");
904 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (256)");
907 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (512)");
910 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (1024)");
913 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (2048)");
916 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (4096)");
919 g_snprintf(tmpbuf, 80, "From the calling DTE : %%u (Unknown)");
922 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1, "%s",
923 decode_numeric_bitfield(byte2, 0x0F, 1*8, tmpbuf));
926 case X25_FAC_WINDOW_SIZE:
928 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
929 "(Window size)", fac);
930 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_window_size);
931 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1, "%s",
932 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+1),
933 0x7F, 1*8, "From the called DTE: %u"));
934 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1, "%s",
935 decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+2),
936 0x7F, 1*8, "From the calling DTE: %u"));
939 case X25_FAC_RPOA_SELECTION:
941 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
942 "(RPOA selection)", fac);
943 fac_subtree = proto_item_add_subtree(ti,
944 ett_x25_fac_rpoa_selection);
945 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
946 "Data network identification code : %04X",
947 tvb_get_ntohs(tvb, *offset+1));
950 case X25_FAC_CUG_EXT:
952 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
953 "(Extended closed user group selection)", fac);
954 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_cug_ext);
955 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
956 "Closed user group: %04X", tvb_get_ntohs(tvb, *offset+1));
959 case X25_FAC_CUG_OUTGOING_ACC_EXT:
961 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
962 "(Extended closed user group with outgoing access selection)",
964 fac_subtree = proto_item_add_subtree(ti,
965 ett_x25_fac_cug_outgoing_acc_ext);
966 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
967 "Closed user group: %04X", tvb_get_ntohs(tvb, *offset+1));
970 case X25_FAC_TRANSIT_DELAY:
972 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
973 "(Transit delay selection and indication)", fac);
974 fac_subtree = proto_item_add_subtree(ti,
975 ett_x25_fac_transit_delay);
976 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
977 "Transit delay: %d ms",
978 tvb_get_ntohs(tvb, *offset+1));
983 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
984 "Code : %02X (Unknown class B)", fac);
985 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
986 proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
987 "Parameter %04X", tvb_get_ntohs(tvb, *offset+1));
994 case X25_FAC_CLASS_C:
996 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
997 "Code : %02X (Unknown class C)", fac);
998 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
999 proto_tree_add_text(fac_subtree, tvb, *offset+1, 3,
1001 tvb_get_ntoh24(tvb, *offset+1));
1006 case X25_FAC_CLASS_D:
1008 case X25_FAC_CALL_DURATION:
1012 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1013 "(Call duration)", fac);
1014 fac_subtree = proto_item_add_subtree(ti,
1015 ett_x25_fac_call_duration);
1016 byte1 = tvb_get_guint8(tvb, *offset+1);
1017 if ((byte1 < 4) || (byte1 % 4)) {
1018 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1019 "Bogus length : %d", byte1);
1022 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1023 "Length : %u", byte1);
1025 for (i = 0; (i<byte1); i+=4) {
1026 proto_tree_add_text(fac_subtree, tvb, *offset+2+i, 4,
1027 "Call duration : %u Day(s) %02X:%02X:%02X Hour(s)",
1028 tvb_get_guint8(tvb, *offset+2+i),
1029 tvb_get_guint8(tvb, *offset+3+i),
1030 tvb_get_guint8(tvb, *offset+4+i),
1031 tvb_get_guint8(tvb, *offset+5+i));
1035 case X25_FAC_SEGMENT_COUNT:
1038 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1039 "(Segment count)", fac);
1040 fac_subtree = proto_item_add_subtree(ti,
1041 ett_x25_fac_segment_count);
1042 byte1 = tvb_get_guint8(tvb, *offset+1);
1043 if ((byte1 < 8) || (byte1 % 8)) {
1044 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1045 "Bogus length : %d", byte1);
1048 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1049 "Length : %u", byte1);
1051 for (i = 0; (i<byte1); i+=8) {
1052 proto_tree_add_text(fac_subtree, tvb, *offset+2+i, 4,
1053 "Segments sent to DTE : %02X%02X%02X%02X",
1054 tvb_get_guint8(tvb, *offset+2+i),
1055 tvb_get_guint8(tvb, *offset+3+i),
1056 tvb_get_guint8(tvb, *offset+4+i),
1057 tvb_get_guint8(tvb, *offset+5+i));
1058 proto_tree_add_text(fac_subtree, tvb, *offset+6+i, 4,
1059 "Segments received from DTE : %02X%02X%02X%02X",
1060 tvb_get_guint8(tvb, *offset+6+i),
1061 tvb_get_guint8(tvb, *offset+7+i),
1062 tvb_get_guint8(tvb, *offset+8+i),
1063 tvb_get_guint8(tvb, *offset+9+i));
1067 case X25_FAC_CALL_TRANSFER:
1072 tmpbuf=ep_alloc(258);
1073 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1074 "(Call redirection or deflection notification)", fac);
1075 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_call_transfer);
1076 byte1 = tvb_get_guint8(tvb, *offset+1);
1078 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1079 "Bogus length : %d", byte1);
1082 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1083 "Length : %u", byte1);
1085 byte2 = tvb_get_guint8(tvb, *offset+2);
1086 if ((byte2 & 0xC0) == 0xC0) {
1087 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1088 "Reason : call deflection by the originally "
1089 "called DTE address");
1094 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1095 "Reason : originally called DTE busy");
1098 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1099 "Reason : call dist. within a hunt group");
1102 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1103 "Reason : originally called DTE out of order");
1106 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1107 "Reason : systematic call redirection");
1110 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1111 "Reason : unknown");
1115 byte3 = tvb_get_guint8(tvb, *offset+3);
1116 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1117 "Number of semi-octets in DTE address : %u",
1119 for (i = 0; (i<byte3)&&(i<256); i++) {
1121 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1123 /* if > 9, convert to the right hexadecimal letter */
1124 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1126 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1128 /* if > 9, convert to the right hexadecimal letter */
1129 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1133 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1134 "DTE address : %s", tmpbuf);
1137 case X25_FAC_RPOA_SELECTION_EXT:
1141 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1142 "(Extended RPOA selection)", fac);
1143 fac_subtree = proto_item_add_subtree(ti,
1144 ett_x25_fac_rpoa_selection_ext);
1145 byte1 = tvb_get_guint8(tvb, *offset+1);
1146 if ((byte1 < 2) || (byte1 % 2)) {
1147 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1148 "Bogus length : %d", byte1);
1151 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1152 "Length : %u", byte1);
1154 for (i = 0; (i<byte1); i+=2) {
1155 proto_tree_add_text(fac_subtree, tvb, *offset+2+i, 2,
1156 "Data network identification code : %04X",
1157 tvb_get_ntohs(tvb, *offset+2+i));
1161 case X25_FAC_CALLING_ADDR_EXT:
1166 tmpbuf=ep_alloc(258);
1167 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1168 "(Calling address extension)", fac);
1169 fac_subtree = proto_item_add_subtree(ti,
1170 ett_x25_fac_calling_addr_ext);
1171 byte1 = tvb_get_guint8(tvb, *offset+1);
1173 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1174 "Bogus length : %d", byte1);
1177 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1178 "Length : %u", byte1);
1180 byte2 = tvb_get_guint8(tvb, *offset+2) & 0x3F;
1181 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1182 "Number of semi-octets in DTE address : %u", byte2);
1183 for (i = 0; (i<byte2)&&(i<256) ; i++) {
1185 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1187 /* if > 9, convert to the right hexadecimal letter */
1188 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1190 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1192 /* if > 9, convert to the right hexadecimal letter */
1193 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1197 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1198 "DTE address : %s", tmpbuf);
1201 case X25_FAC_MONETARY_UNIT:
1203 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1204 "(Monetary Unit)", fac);
1205 fac_subtree = proto_item_add_subtree(ti,
1206 ett_x25_fac_monetary_unit);
1207 byte1 = tvb_get_guint8(tvb, *offset+1);
1208 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1209 "Length : %u", byte1);
1210 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1215 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1216 "(Network User Identification selection)", fac);
1217 fac_subtree = proto_item_add_subtree(ti,
1219 byte1 = tvb_get_guint8(tvb, *offset+1);
1220 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1221 "Length : %u", byte1);
1222 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "NUI");
1225 case X25_FAC_CALLED_ADDR_EXT:
1230 tmpbuf=ep_alloc(258);
1231 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1232 "(Called address extension)", fac);
1233 fac_subtree = proto_item_add_subtree(ti,
1234 ett_x25_fac_called_addr_ext);
1235 byte1 = tvb_get_guint8(tvb, *offset+1);
1237 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1238 "Bogus length : %d", byte1);
1241 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1242 "Length : %u", byte1);
1244 byte2 = tvb_get_guint8(tvb, *offset+2) & 0x3F;
1245 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1246 "Number of semi-octets in DTE address : %u", byte2);
1247 for (i = 0; (i<byte2)&&(i<256) ; i++) {
1249 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
1251 /* if > 9, convert to the right hexadecimal letter */
1252 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1254 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
1256 /* if > 9, convert to the right hexadecimal letter */
1257 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1261 proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
1262 "DTE address : %s", tmpbuf);
1265 case X25_FAC_ETE_TRANSIT_DELAY:
1267 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1268 "(End to end transit delay)", fac);
1269 fac_subtree = proto_item_add_subtree(ti,
1270 ett_x25_fac_ete_transit_delay);
1271 byte1 = tvb_get_guint8(tvb, *offset+1);
1272 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1273 "Length : %u", byte1);
1274 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1277 case X25_FAC_CALL_DEFLECT:
1282 tmpbuf=ep_alloc(258);
1283 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
1284 "(Call deflection selection)", fac);
1285 fac_subtree = proto_item_add_subtree(ti,
1286 ett_x25_fac_call_deflect);
1287 byte1 = tvb_get_guint8(tvb, *offset+1);
1289 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1290 "Bogus length : %d", byte1);
1293 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1294 "Length : %u", byte1);
1296 byte2 = tvb_get_guint8(tvb, *offset+2);
1297 if ((byte2 & 0xC0) == 0xC0)
1298 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1299 "Reason : call DTE originated");
1301 proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
1302 "Reason : unknown");
1303 byte3 = tvb_get_guint8(tvb, *offset+3);
1304 proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
1305 "Number of semi-octets in the alternative DTE address : %u",
1307 for (i = 0; (i<byte3)&&(i<256) ; i++) {
1309 tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
1311 /* if > 9, convert to the right hexadecimal letter */
1312 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1314 tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
1316 /* if > 9, convert to the right hexadecimal letter */
1317 if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
1321 proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
1322 "Alternative DTE address : %s", tmpbuf);
1325 case X25_FAC_PRIORITY:
1327 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1328 "Code : %02X (Priority)", fac);
1329 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_priority);
1330 byte1 = tvb_get_guint8(tvb, *offset+1);
1331 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1332 "Length : %u", byte1);
1333 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1338 ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
1339 "Code : %02X (Unknown class D)", fac);
1340 fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
1341 byte1 = tvb_get_guint8(tvb, *offset+1);
1342 proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
1343 "Length : %u", byte1);
1344 proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
1347 byte1 = tvb_get_guint8(tvb, *offset+1);
1348 (*offset) += byte1+2;
1356 x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1357 packet_info *pinfo, gboolean is_registration)
1361 char *addr1, *addr2;
1362 char *first, *second;
1369 byte = tvb_get_guint8(tvb, *offset);
1370 len1 = (byte >> 0) & 0x0F;
1371 len2 = (byte >> 4) & 0x0F;
1374 proto_tree_add_text(tree, tvb, *offset, 1, "%s",
1375 decode_numeric_bitfield(byte, 0xF0, 1*8,
1377 "DTE address length : %u" :
1378 "Calling address length : %u"));
1379 proto_tree_add_text(tree, tvb, *offset, 1, "%s",
1380 decode_numeric_bitfield(byte, 0x0F, 1*8,
1382 "DCE address length : %u" :
1383 "Called address length : %u"));
1387 localoffset = *offset;
1388 byte = tvb_get_guint8(tvb, localoffset);
1392 for (i = 0; i < (len1 + len2); i++) {
1395 *first++ = ((byte >> 0) & 0x0F) + '0';
1397 byte = tvb_get_guint8(tvb, localoffset);
1399 *first++ = ((byte >> 4) & 0x0F) + '0';
1403 *second++ = ((byte >> 0) & 0x0F) + '0';
1405 byte = tvb_get_guint8(tvb, localoffset);
1407 *second++ = ((byte >> 4) & 0x0F) + '0';
1416 col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1);
1418 proto_tree_add_text(tree, tvb, *offset,
1421 "DCE address : %s" :
1422 "Called address : %s",
1426 col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2);
1428 proto_tree_add_text(tree, tvb, *offset + len1/2,
1429 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1431 "DTE address : %s" :
1432 "Calling address : %s",
1435 (*offset) += ((len1 + len2 + 1) / 2);
1439 x25_toa(proto_tree *tree, int *offset, tvbuff_t *tvb,
1444 char *addr1, *addr2;
1445 char *first, *second;
1449 addr1=ep_alloc(256);
1450 addr2=ep_alloc(256);
1452 len1 = tvb_get_guint8(tvb, *offset);
1454 proto_tree_add_text(tree, tvb, *offset, 1,
1455 "Called address length : %u",
1460 len2 = tvb_get_guint8(tvb, *offset);
1462 proto_tree_add_text(tree, tvb, *offset, 1,
1463 "Calling address length : %u",
1468 localoffset = *offset;
1469 byte = tvb_get_guint8(tvb, localoffset);
1472 * XXX - the first two half-octets of the address are the TOA and
1473 * NPI; process them as such and, if the TOA says an address is
1474 * an alternative address, process it correctly (i.e., not as a
1475 * sequence of half-octets containing digit values).
1479 for (i = 0; i < (len1 + len2); i++) {
1482 *first++ = ((byte >> 0) & 0x0F) + '0';
1484 byte = tvb_get_guint8(tvb, localoffset);
1486 *first++ = ((byte >> 4) & 0x0F) + '0';
1490 *second++ = ((byte >> 0) & 0x0F) + '0';
1492 byte = tvb_get_guint8(tvb, localoffset);
1494 *second++ = ((byte >> 4) & 0x0F) + '0';
1503 col_add_str(pinfo->cinfo, COL_RES_DL_DST, addr1);
1505 proto_tree_add_text(tree, tvb, *offset,
1507 "Called address : %s",
1511 col_add_str(pinfo->cinfo, COL_RES_DL_SRC, addr2);
1513 proto_tree_add_text(tree, tvb, *offset + len1/2,
1514 (len2+1)/2+(len1%2+(len2+1)%2)/2,
1515 "Calling address : %s",
1518 (*offset) += ((len1 + len2 + 1) / 2);
1522 get_x25_pkt_len(tvbuff_t *tvb)
1524 guint length, called_len, calling_len, dte_len, dce_len;
1525 guint8 byte2, bytex;
1527 byte2 = tvb_get_guint8(tvb, 2);
1530 case X25_CALL_REQUEST:
1531 bytex = tvb_get_guint8(tvb, 3);
1532 called_len = (bytex >> 0) & 0x0F;
1533 calling_len = (bytex >> 4) & 0x0F;
1534 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1535 if (length < tvb_reported_length(tvb))
1536 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1538 return MIN(tvb_reported_length(tvb),length);
1540 case X25_CALL_ACCEPTED:
1541 /* The calling/called address length byte (following the packet type)
1542 * is not mandatory, so we must check the packet length before trying
1544 if (tvb_reported_length(tvb) == 3)
1546 bytex = tvb_get_guint8(tvb, 3);
1547 called_len = (bytex >> 0) & 0x0F;
1548 calling_len = (bytex >> 4) & 0x0F;
1549 length = 4 + (called_len + calling_len + 1) / 2; /* addr */
1550 if (length < tvb_reported_length(tvb))
1551 length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
1553 return MIN(tvb_reported_length(tvb),length);
1555 case X25_CLEAR_REQUEST:
1556 case X25_RESET_REQUEST:
1557 case X25_RESTART_REQUEST:
1558 return MIN(tvb_reported_length(tvb),5);
1560 case X25_DIAGNOSTIC:
1561 return MIN(tvb_reported_length(tvb),4);
1563 case X25_CLEAR_CONFIRMATION:
1565 case X25_INTERRUPT_CONFIRMATION:
1566 case X25_RESET_CONFIRMATION:
1567 case X25_RESTART_CONFIRMATION:
1568 return MIN(tvb_reported_length(tvb),3);
1570 case X25_REGISTRATION_REQUEST:
1571 bytex = tvb_get_guint8(tvb, 3);
1572 dce_len = (bytex >> 0) & 0x0F;
1573 dte_len = (bytex >> 4) & 0x0F;
1574 length = 4 + (dte_len + dce_len + 1) / 2; /* addr */
1575 if (length < tvb_reported_length(tvb))
1576 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1578 return MIN(tvb_reported_length(tvb),length);
1580 case X25_REGISTRATION_CONFIRMATION:
1581 bytex = tvb_get_guint8(tvb, 5);
1582 dce_len = (bytex >> 0) & 0x0F;
1583 dte_len = (bytex >> 4) & 0x0F;
1584 length = 6 + (dte_len + dce_len + 1) / 2; /* addr */
1585 if (length < tvb_reported_length(tvb))
1586 length += (1 + tvb_get_guint8(tvb, length)); /* registration */
1588 return MIN(tvb_reported_length(tvb),length);
1591 if (PACKET_IS_DATA(byte2))
1592 return MIN(tvb_reported_length(tvb),3);
1594 switch (PACKET_TYPE_FC(byte2))
1597 return MIN(tvb_reported_length(tvb),3);
1600 return MIN(tvb_reported_length(tvb),3);
1603 return MIN(tvb_reported_length(tvb),3);
1609 static const value_string prt_id_vals[] = {
1610 {PRT_ID_ISO_8073, "ISO 8073 COTP"},
1611 {PRT_ID_ISO_8602, "ISO 8602 CLTP"},
1612 {PRT_ID_ISO_10736_ISO_8073, "ISO 10736 in conjunction with ISO 8073 COTP"},
1613 {PRT_ID_ISO_10736_ISO_8602, "ISO 10736 in conjunction with ISO 8602 CLTP"},
1617 static const value_string sharing_strategy_vals[] = {
1618 {0x00, "No sharing"},
1623 dissect_x25_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1624 x25_dir_t dir, gboolean side)
1626 proto_tree *x25_tree=0, *gfi_tree=0, *userdata_tree=0;
1628 guint localoffset=0;
1632 dissector_handle_t dissect = NULL;
1633 gboolean toa; /* TOA/NPI address format */
1636 const char *short_name = NULL, *long_name = NULL;
1637 tvbuff_t *next_tvb = NULL;
1638 gboolean q_bit_set = FALSE;
1642 void *saved_private_data;
1643 fragment_data *fd_head;
1649 col_set_str(pinfo->cinfo, COL_PROTOCOL, "X.25");
1651 bytes0_1 = tvb_get_ntohs(tvb, 0);
1653 modulo = ((bytes0_1 & 0x2000) ? 128 : 8);
1654 vc = (int)(bytes0_1 & 0x0FFF);
1656 pinfo->ctype = CT_X25;
1657 pinfo->circuit_id = vc;
1659 if (bytes0_1 & X25_ABIT) toa = TRUE;
1662 x25_pkt_len = get_x25_pkt_len(tvb);
1663 if (x25_pkt_len < 3) /* packet too short */
1665 col_set_str(pinfo->cinfo, COL_INFO, "Invalid/short X.25 packet");
1667 proto_tree_add_protocol_format(tree, proto_x25, tvb, 0, -1,
1668 "Invalid/short X.25 packet");
1672 pkt_type = tvb_get_guint8(tvb, 2);
1673 if (PACKET_IS_DATA(pkt_type)) {
1674 if (bytes0_1 & X25_QBIT)
1679 ti = proto_tree_add_item(tree, proto_x25, tvb, 0, x25_pkt_len, ENC_NA);
1680 x25_tree = proto_item_add_subtree(ti, ett_x25);
1681 ti = proto_tree_add_item(x25_tree, hf_x25_gfi, tvb, 0, 2, ENC_BIG_ENDIAN);
1682 gfi_tree = proto_item_add_subtree(ti, ett_x25_gfi);
1684 if (PACKET_IS_DATA(pkt_type)) {
1685 proto_tree_add_boolean(gfi_tree, hf_x25_qbit, tvb, 0, 2,
1688 else if (pkt_type == X25_CALL_REQUEST ||
1689 pkt_type == X25_CALL_ACCEPTED ||
1690 pkt_type == X25_CLEAR_REQUEST ||
1691 pkt_type == X25_CLEAR_CONFIRMATION) {
1692 proto_tree_add_boolean(gfi_tree, hf_x25_abit, tvb, 0, 2,
1696 if (pkt_type == X25_CALL_REQUEST || pkt_type == X25_CALL_ACCEPTED ||
1697 PACKET_IS_DATA(pkt_type)) {
1698 proto_tree_add_boolean(gfi_tree, hf_x25_dbit, tvb, 0, 2,
1701 proto_tree_add_uint(gfi_tree, hf_x25_mod, tvb, 0, 2, bytes0_1);
1705 case X25_CALL_REQUEST:
1709 short_name = "Inc. call";
1710 long_name = "Incoming call";
1714 short_name = "Call req.";
1715 long_name = "Call request";
1719 short_name = "Inc. call/Call req.";
1720 long_name = "Incoming call/Call request";
1723 if (check_col(pinfo->cinfo, COL_INFO))
1724 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
1726 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb,
1728 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
1729 X25_CALL_REQUEST, "Packet Type: %s", long_name);
1732 if (localoffset < x25_pkt_len) { /* calling/called addresses */
1734 x25_toa(x25_tree, (gint*)&localoffset, tvb, pinfo);
1736 x25_ntoa(x25_tree, (gint*)&localoffset, tvb, pinfo, FALSE);
1739 if (localoffset < x25_pkt_len) /* facilities */
1740 dump_facilities(x25_tree, (gint*)&localoffset, tvb);
1742 if (localoffset < tvb_reported_length(tvb)) /* user data */
1746 ti = proto_tree_add_text(x25_tree, tvb, localoffset, -1,
1748 userdata_tree = proto_item_add_subtree(ti, ett_x25_user_data);
1751 /* X.263/ISO 9577 says that:
1753 When CLNP or ESIS are run over X.25, the SPI
1754 is 0x81 or 0x82, respectively; those are the
1755 NLPIDs for those protocol.
1757 When X.224/ISO 8073 COTP is run over X.25, and
1758 when ISO 11570 explicit identification is being
1759 used, the first octet of the user data field is
1760 a TPDU length field, and the rest is "as defined
1761 in ITU-T Rec. X.225 | ISO/IEC 8073, Annex B,
1762 or ITU-T Rec. X.264 and ISO/IEC 11570".
1764 When X.264/ISO 11570 default identification is
1765 being used, there is no user data field in the
1766 CALL REQUEST packet. This is for X.225/ISO 8073
1769 It also says that SPI values from 0x03 through 0x3f are
1770 reserved and are in use by X.224/ISO 8073 Annex B and
1771 X.264/ISO 11570. The note says that those values are
1772 not NLPIDs, they're "used by the respective higher layer
1773 protocol" and "not used for higher layer protocol
1774 identification". I infer from this and from what
1775 X.264/ISO 11570 says that this means that values in those
1776 range are valid values for the first octet of an
1777 X.224/ISO 8073 packet or for X.264/ISO 11570.
1779 Annex B of X.225/ISO 8073 mentions some additional TPDU
1780 types that can be put in what I presume is the user
1781 data of connect requests. It says that:
1783 The sending transport entity shall:
1785 a) either not transmit any TPDU in the NS-user data
1786 parameter of the N-CONNECT request primitive; or
1788 b) transmit the UN-TPDU (see ITU-T Rec. X.264 and
1789 ISO/IEC 11570) followed by the NCM-TPDU in the
1790 NS-user data parameter of the N-CONNECT request
1793 I don't know if this means that the user data field
1794 will contain a UN TPDU followed by an NCM TPDU or not.
1796 X.264/ISO 11570 says that:
1798 When default identification is being used,
1799 X.225/ISO 8073 COTP is identified. No user data
1800 is sent in the network-layer connection request.
1802 When explicit identification is being used,
1803 the user data is a UN TPDU ("Use of network
1804 connection TPDU"), which specifies the transport
1805 protocol to use over this network connection.
1806 It also says that the length of a UN TPDU shall
1807 not exceed 32 octets, i.e. shall not exceed 0x20;
1808 it says this is "due to the desire not to conflict
1809 with the protocol identifier field carried by X.25
1810 CALL REQUEST/INCOMING CALL packets", and says that
1811 field has values specified in X.244. X.244 has been
1812 superseded by X.263/ISO 9577, so that presumably
1813 means the goal is to allow a UN TPDU's length
1814 field to be distinguished from an NLPID, allowing
1815 you to tell whether X.264/ISO 11570 explicit
1816 identification is being used or an NLPID is
1817 being used as the SPI.
1819 I read this as meaning that, if the ISO mechanisms are
1820 used to identify the protocol being carried over X.25:
1822 if there's no user data in the CALL REQUEST/
1823 INCOMING CALL packet, it's COTP;
1825 if there is user data, then:
1827 if the first octet is less than or equal to
1828 32, it might be a UN TPDU, and that identifies
1829 the transport protocol being used, and
1830 it may be followed by more data, such
1831 as a COTP NCM TPDU if it's COTP;
1833 if the first octet is greater than 32, it's
1834 an NLPID, *not* a TPDU length, and the
1835 stuff following it is *not* a TPDU.
1837 Figure A.2 of X.263/ISO 9577 seems to say that the
1838 first octet of the user data is a TPDU length field,
1839 in the range 0x03 through 0x82, and says they are
1840 for X.225/ISO 8073 Annex B or X.264/ISO 11570.
1842 However, X.264/ISO 11570 seems to imply that the length
1843 field would be that of a UN TPDU, which must be less
1844 than or equal to 0x20, and X.225/ISO 8073 Annex B seems
1845 to indicate that the user data must begin with
1846 an X.264/ISO 11570 UN TPDU, so I'd say that A.2 should
1847 have said "in the range 0x03 through 0x20", instead
1848 (the length value doesn't include the length field,
1849 and the minimum UN TPDU has length, type, PRT-ID,
1850 and SHARE, so that's 3 bytes without the length). */
1851 spi = tvb_get_guint8(tvb, localoffset);
1852 if (spi > 32 || spi < 3) {
1853 /* First octet is > 32, or < 3, so the user data isn't an
1854 X.264/ISO 11570 UN TPDU */
1857 /* First octet is >= 3 and <= 32, so the user data *might*
1858 be an X.264/ISO 11570 UN TPDU. Check whether we have
1859 enough data to see if it is. */
1860 if (tvb_bytes_exist(tvb, localoffset+1, 1)) {
1861 /* We do; check whether the second octet is 1. */
1862 if (tvb_get_guint8(tvb, localoffset+1) == 0x01) {
1863 /* Yes, the second byte is 1, so it looks like
1867 /* No, the second byte is not 1, so it's not a
1872 /* We can't see the second byte of the putative UN
1873 TPDU, so we don't know if that's what it is. */
1877 if (is_x_264 == -1) {
1879 * We don't know what it is; just skip it.
1881 localoffset = tvb_length(tvb);
1882 } else if (is_x_264) {
1883 /* It looks like an X.264 UN TPDU, so show it as such. */
1884 if (userdata_tree) {
1885 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1886 "X.264 length indicator: %u",
1888 proto_tree_add_text(userdata_tree, tvb, localoffset+1, 1,
1889 "X.264 UN TPDU identifier: 0x%02X",
1890 tvb_get_guint8(tvb, localoffset+1));
1892 prt_id = tvb_get_guint8(tvb, localoffset+2);
1893 if (userdata_tree) {
1894 proto_tree_add_text(userdata_tree, tvb, localoffset+2, 1,
1895 "X.264 protocol identifier: %s",
1896 val_to_str(prt_id, prt_id_vals,
1897 "Unknown (0x%02X)"));
1898 proto_tree_add_text(userdata_tree, tvb, localoffset+3, 1,
1899 "X.264 sharing strategy: %s",
1900 val_to_str(tvb_get_guint8(tvb, localoffset+3),
1901 sharing_strategy_vals, "Unknown (0x%02X)"));
1904 /* XXX - dissect the variable part? */
1906 /* The length doesn't include the length octet itself. */
1907 localoffset += spi + 1;
1911 case PRT_ID_ISO_8073:
1913 if (!pinfo->fd->flags.visited)
1914 x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
1915 /* XXX - dissect the rest of the user data as COTP?
1916 That needs support for NCM TPDUs, etc. */
1919 case PRT_ID_ISO_8602:
1921 if (!pinfo->fd->flags.visited)
1922 x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
1925 } else if (is_x_264 == 0) {
1926 /* It doesn't look like a UN TPDU, so compare the first
1927 octet of the CALL REQUEST packet with various X.263/
1928 ISO 9577 NLPIDs, as per Annex A of X.263/ISO 9577. */
1930 if (userdata_tree) {
1931 proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
1932 "X.263 secondary protocol ID: %s",
1933 val_to_str(spi, nlpid_vals, "Unknown (0x%02x)"));
1936 if (!pinfo->fd->flags.visited) {
1938 * Is there a dissector handle for this SPI?
1939 * If so, assign it to this virtual circuit.
1941 dissect = dissector_get_uint_handle(x25_subdissector_table, spi);
1942 if (dissect != NULL)
1943 x25_hash_add_proto_start(vc, pinfo->fd->num, dissect);
1947 * If there's only one octet of user data, it's just
1948 * an NLPID; don't try to dissect it.
1950 if (localoffset + 1 == tvb_reported_length(tvb))
1954 * There's more than one octet of user data, so we'll
1955 * dissect it; for some protocols, the NLPID is considered
1956 * to be part of the PDU, so, for those cases, we don't
1957 * skip past it. For other protocols, we skip the NLPID.
1961 case NLPID_ISO8473_CLNP:
1962 case NLPID_ISO9542_ESIS:
1963 case NLPID_ISO10589_ISIS:
1964 case NLPID_ISO10747_IDRP:
1967 * The NLPID is part of the PDU. Don't skip it.
1968 * But if it's all there is to the PDU, don't
1969 * bother dissecting it.
1973 case NLPID_SPI_X_29:
1975 * The first 4 bytes of the call user data are
1976 * the SPI plus 3 reserved bytes; they are not
1977 * part of the data to be dissected as X.29 data.
1984 * The NLPID isn't part of the PDU - skip it.
1985 * If that means there's nothing to dissect
1991 /* if there's no user data in the CALL REQUEST/
1992 INCOMING CALL packet, it's COTP; */
1994 if (call_request_nodata_is_cotp){
1995 x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
1999 case X25_CALL_ACCEPTED:
2003 short_name = "Call conn.";
2004 long_name = "Call connected";
2008 short_name = "Call acc.";
2009 long_name = "Call accepted";
2013 short_name = "Call conn./Call acc.";
2014 long_name = "Call connected/Call accepted";
2017 if(check_col(pinfo->cinfo, COL_INFO))
2018 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d", short_name, vc);
2020 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
2021 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
2022 X25_CALL_ACCEPTED, "Packet Type: %s", long_name);
2025 if (localoffset < x25_pkt_len) { /* calling/called addresses */
2027 x25_toa(x25_tree, (gint*)&localoffset, tvb, pinfo);
2029 x25_ntoa(x25_tree, (gint*)&localoffset, tvb, pinfo, FALSE);
2032 if (localoffset < x25_pkt_len) /* facilities */
2033 dump_facilities(x25_tree, (gint*)&localoffset, tvb);
2035 case X25_CLEAR_REQUEST:
2039 short_name = "Clear ind.";
2040 long_name = "Clear indication";
2044 short_name = "Clear req.";
2045 long_name = "Clear request";
2049 short_name = "Clear ind./Clear req.";
2050 long_name = "Clear indication/Clear request";
2053 if(check_col(pinfo->cinfo, COL_INFO)) {
2054 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - %s", short_name,
2055 vc, clear_code(tvb_get_guint8(tvb, 3)),
2056 clear_diag(tvb_get_guint8(tvb, 4)));
2058 x25_hash_add_proto_end(vc, pinfo->fd->num);
2060 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
2061 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb,
2062 localoffset+2, 1, X25_CLEAR_REQUEST, "Packet Type: %s",
2064 proto_tree_add_text(x25_tree, tvb, 3, 1,
2065 "Cause : %s", clear_code(tvb_get_guint8(tvb, 3)));
2066 proto_tree_add_text(x25_tree, tvb, 4, 1,
2067 "Diagnostic : %s", clear_diag(tvb_get_guint8(tvb, 4)));
2069 localoffset = x25_pkt_len;
2071 case X25_CLEAR_CONFIRMATION:
2072 if(check_col(pinfo->cinfo, COL_INFO))
2073 col_add_fstr(pinfo->cinfo, COL_INFO, "Clear Conf. VC:%d", vc);
2075 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
2076 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2077 X25_CLEAR_CONFIRMATION);
2079 localoffset = x25_pkt_len;
2081 if (localoffset < tvb_reported_length(tvb)) { /* extended clear conf format */
2083 x25_toa(x25_tree, (gint*)&localoffset, tvb, pinfo);
2085 x25_ntoa(x25_tree,(gint*)&localoffset, tvb, pinfo, FALSE);
2088 if (localoffset < tvb_reported_length(tvb)) /* facilities */
2089 dump_facilities(x25_tree, (gint*)&localoffset, tvb);
2091 case X25_DIAGNOSTIC:
2092 if(check_col(pinfo->cinfo, COL_INFO)) {
2093 col_add_fstr(pinfo->cinfo, COL_INFO, "Diag. %d",
2094 (int)tvb_get_guint8(tvb, 3));
2097 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2099 proto_tree_add_text(x25_tree, tvb, 3, 1,
2100 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 3));
2102 localoffset = x25_pkt_len;
2105 if(check_col(pinfo->cinfo, COL_INFO))
2106 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt VC:%d", vc);
2108 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
2109 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2112 localoffset = x25_pkt_len;
2114 case X25_INTERRUPT_CONFIRMATION:
2115 if(check_col(pinfo->cinfo, COL_INFO))
2116 col_add_fstr(pinfo->cinfo, COL_INFO, "Interrupt Conf. VC:%d", vc);
2118 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
2119 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2120 X25_INTERRUPT_CONFIRMATION);
2122 localoffset = x25_pkt_len;
2124 case X25_RESET_REQUEST:
2128 short_name = "Reset ind.";
2129 long_name = "Reset indication";
2133 short_name = "Reset req.";
2134 long_name = "Reset request";
2138 short_name = "Reset ind./Reset req.";
2139 long_name = "Reset indication/Reset request";
2142 if(check_col(pinfo->cinfo, COL_INFO)) {
2143 col_add_fstr(pinfo->cinfo, COL_INFO, "%s VC:%d %s - Diag.:%d",
2144 short_name, vc, reset_code(tvb_get_guint8(tvb, 3)),
2145 (int)tvb_get_guint8(tvb, 4));
2147 x25_hash_add_proto_end(vc, pinfo->fd->num);
2149 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
2150 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
2151 X25_RESET_REQUEST, "Packet Type: %s", long_name);
2152 proto_tree_add_text(x25_tree, tvb, 3, 1,
2153 "Cause : %s", reset_code(tvb_get_guint8(tvb, 3)));
2154 proto_tree_add_text(x25_tree, tvb, 4, 1,
2155 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
2157 localoffset = x25_pkt_len;
2159 case X25_RESET_CONFIRMATION:
2160 if(check_col(pinfo->cinfo, COL_INFO))
2161 col_add_fstr(pinfo->cinfo, COL_INFO, "Reset conf. VC:%d", vc);
2163 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, 0, 2, bytes0_1);
2164 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2165 X25_RESET_CONFIRMATION);
2167 localoffset = x25_pkt_len;
2169 case X25_RESTART_REQUEST:
2173 short_name = "Restart ind.";
2174 long_name = "Restart indication";
2178 short_name = "Restart req.";
2179 long_name = "Restart request";
2183 short_name = "Restart ind./Restart req.";
2184 long_name = "Restart indication/Restart request";
2187 if(check_col(pinfo->cinfo, COL_INFO)) {
2188 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s - Diag.:%d",
2190 restart_code(tvb_get_guint8(tvb, 3)),
2191 (int)tvb_get_guint8(tvb, 4));
2194 proto_tree_add_uint_format(x25_tree, hf_x25_type, tvb, 2, 1,
2195 X25_RESTART_REQUEST, "Packet Type: %s", long_name);
2196 proto_tree_add_text(x25_tree, tvb, 3, 1,
2197 "Cause : %s", restart_code(tvb_get_guint8(tvb, 3)));
2198 proto_tree_add_text(x25_tree, tvb, 4, 1,
2199 "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
2201 localoffset = x25_pkt_len;
2203 case X25_RESTART_CONFIRMATION:
2204 col_set_str(pinfo->cinfo, COL_INFO, "Restart conf.");
2206 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2207 X25_RESTART_CONFIRMATION);
2208 localoffset = x25_pkt_len;
2210 case X25_REGISTRATION_REQUEST:
2211 col_set_str(pinfo->cinfo, COL_INFO, "Registration req.");
2213 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2214 X25_REGISTRATION_REQUEST);
2216 if (localoffset < x25_pkt_len)
2217 x25_ntoa(x25_tree, (gint*)&localoffset, tvb, pinfo, TRUE);
2220 if (localoffset < x25_pkt_len)
2221 proto_tree_add_text(x25_tree, tvb, localoffset, 1,
2222 "Registration length: %d",
2223 tvb_get_guint8(tvb, localoffset) & 0x7F);
2224 if (localoffset+1 < x25_pkt_len)
2225 proto_tree_add_text(x25_tree, tvb, localoffset+1,
2226 tvb_get_guint8(tvb, localoffset) & 0x7F,
2229 localoffset = tvb_reported_length(tvb);
2231 case X25_REGISTRATION_CONFIRMATION:
2232 col_set_str(pinfo->cinfo, COL_INFO, "Registration conf.");
2234 proto_tree_add_uint(x25_tree, hf_x25_type, tvb, 2, 1,
2235 X25_REGISTRATION_CONFIRMATION);
2236 proto_tree_add_text(x25_tree, tvb, 3, 1,
2237 "Cause: %s", registration_code(tvb_get_guint8(tvb, 3)));
2238 proto_tree_add_text(x25_tree, tvb, 4, 1,
2239 "Diagnostic: %s", registration_code(tvb_get_guint8(tvb, 4)));
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);
2259 if (PACKET_IS_DATA(pkt_type))
2261 if(check_col(pinfo->cinfo, COL_INFO)) {
2263 col_add_fstr(pinfo->cinfo, COL_INFO,
2264 "Data VC:%d P(S):%d P(R):%d %s", vc,
2265 (pkt_type >> 1) & 0x07,
2266 (pkt_type >> 5) & 0x07,
2267 (pkt_type & X25_MBIT_MOD8) ? " M" : "");
2269 col_add_fstr(pinfo->cinfo, COL_INFO,
2270 "Data VC:%d P(S):%d P(R):%d %s", vc,
2271 tvb_get_guint8(tvb, localoffset+1) >> 1,
2273 (tvb_get_guint8(tvb, localoffset+1) & X25_MBIT_MOD128) ? " M" : "");
2276 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2279 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2280 localoffset, 1, pkt_type);
2281 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod8, tvb,
2282 localoffset, 1, pkt_type);
2283 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod8, tvb,
2284 localoffset, 1, pkt_type);
2285 proto_tree_add_uint(x25_tree, hf_x25_type_data, tvb,
2286 localoffset, 1, pkt_type);
2289 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod128, tvb,
2290 localoffset, 1, pkt_type);
2291 proto_tree_add_uint(x25_tree, hf_x25_type_data, tvb,
2292 localoffset, 1, pkt_type);
2293 proto_tree_add_uint(x25_tree, hf_x25_p_s_mod128, tvb,
2295 tvb_get_guint8(tvb, localoffset+1));
2296 proto_tree_add_boolean(x25_tree, hf_x25_mbit_mod128, tvb,
2298 tvb_get_guint8(tvb, localoffset+1));
2302 m_bit_set = pkt_type & X25_MBIT_MOD8;
2305 m_bit_set = tvb_get_guint8(tvb, localoffset+1) & X25_MBIT_MOD128;
2308 payload_len = tvb_reported_length_remaining(tvb, localoffset);
2309 if (reassemble_x25) {
2311 * Reassemble received and sent traffic separately.
2312 * We don't reassemble traffic with an unknown direction
2318 * OR in an extra bit to distinguish from traffic
2319 * in the other direction.
2321 frag_key |= 0x10000;
2323 fd_head = fragment_add_seq_next(tvb, localoffset,
2326 x25_reassembled_table,
2327 payload_len, m_bit_set);
2328 pinfo->fragmented = m_bit_set;
2330 /* Fragment handling is not adapted to handle several x25
2331 * packets in the same frame. This is common with XOT and
2332 * shorter packet sizes.
2333 * Therefore, fragment_add_seq_next seem to always return fd_head
2334 * A fix to use m_bit_set to only show fragments for last pkt
2336 if (!m_bit_set && fd_head) {
2337 if (fd_head->next) {
2338 proto_item *frag_tree_item;
2340 /* This is the last packet */
2341 next_tvb = tvb_new_child_real_data(tvb, fd_head->data,
2344 add_new_data_source(pinfo, next_tvb, "Reassembled X.25");
2346 show_fragment_seq_tree(fd_head,
2349 pinfo, next_tvb, &frag_tree_item);
2354 if (m_bit_set && next_tvb == NULL) {
2356 * This isn't the last packet, so just
2357 * show it as X.25 user data.
2359 proto_tree_add_text(x25_tree, tvb, localoffset, -1,
2360 "User data (%u byte%s)", payload_len,
2361 plurality(payload_len, "", "s"));
2369 * Non-data packets (RR, RNR, REJ).
2371 switch (PACKET_TYPE_FC(pkt_type))
2374 if(check_col(pinfo->cinfo, COL_INFO)) {
2376 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2377 vc, (pkt_type >> 5) & 0x07);
2379 col_add_fstr(pinfo->cinfo, COL_INFO, "RR VC:%d P(R):%d",
2380 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2383 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2386 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2387 localoffset, 1, pkt_type);
2388 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2389 localoffset, 1, X25_RR);
2392 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2393 localoffset, 1, X25_RR);
2394 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2395 localoffset+1, 1, ENC_BIG_ENDIAN);
2401 if(check_col(pinfo->cinfo, COL_INFO)) {
2403 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2404 vc, (pkt_type >> 5) & 0x07);
2406 col_add_fstr(pinfo->cinfo, COL_INFO, "RNR VC:%d P(R):%d",
2407 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2410 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2413 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2414 localoffset, 1, pkt_type);
2415 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2416 localoffset, 1, X25_RNR);
2419 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2420 localoffset, 1, X25_RNR);
2421 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2422 localoffset+1, 1, ENC_BIG_ENDIAN);
2428 if(check_col(pinfo->cinfo, COL_INFO)) {
2430 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2431 vc, (pkt_type >> 5) & 0x07);
2433 col_add_fstr(pinfo->cinfo, COL_INFO, "REJ VC:%d P(R):%d",
2434 vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
2437 proto_tree_add_uint(x25_tree, hf_x25_lcn, tvb, localoffset-2,
2440 proto_tree_add_uint(x25_tree, hf_x25_p_r_mod8, tvb,
2441 localoffset, 1, pkt_type);
2442 proto_tree_add_uint(x25_tree, hf_x25_type_fc_mod8, tvb,
2443 localoffset, 1, X25_REJ);
2446 proto_tree_add_uint(x25_tree, hf_x25_type, tvb,
2447 localoffset, 1, X25_REJ);
2448 proto_tree_add_item(x25_tree, hf_x25_p_r_mod128, tvb,
2449 localoffset+1, 1, ENC_BIG_ENDIAN);
2453 localoffset += (modulo == 8) ? 1 : 2;
2456 if (localoffset >= tvb_reported_length(tvb))
2458 if (pinfo->fragmented)
2462 next_tvb = tvb_new_subset_remaining(tvb, localoffset);
2464 saved_private_data = pinfo->private_data;
2465 pinfo->private_data = &q_bit_set;
2467 /* See if there's already a dissector for this circuit. */
2468 if (try_circuit_dissector(CT_X25, vc, pinfo->fd->num, next_tvb, pinfo,
2470 pinfo->private_data = saved_private_data;
2471 return; /* found it and dissected it */
2474 /* Did the user suggest QLLC/SNA? */
2475 if (payload_is_qllc_sna) {
2476 /* Yes - dissect it as QLLC/SNA. */
2477 if (!pinfo->fd->flags.visited)
2478 x25_hash_add_proto_start(vc, pinfo->fd->num, qllc_handle);
2479 call_dissector(qllc_handle, next_tvb, pinfo, tree);
2480 pinfo->private_data = saved_private_data;
2484 if (payload_check_data){
2485 /* If the Call Req. has not been captured, let's look at the first
2486 two bytes of the payload to see if this looks like COTP. */
2487 if (tvb_get_guint8(tvb, localoffset) == tvb_length(next_tvb)-1) {
2488 /* First byte contains the length of the remaining buffer */
2489 if ((tvb_get_guint8(tvb, localoffset+1) & 0x0F) == 0) {
2490 /* Second byte contains a valid COTP TPDU */
2491 if (!pinfo->fd->flags.visited)
2492 x25_hash_add_proto_start(vc, pinfo->fd->num, ositp_handle);
2493 call_dissector(ositp_handle, next_tvb, pinfo, tree);
2494 pinfo->private_data = saved_private_data;
2499 /* Then let's look at the first byte of the payload to see if this
2500 looks like IP or CLNP. */
2501 switch (tvb_get_guint8(tvb, localoffset)) {
2504 /* Looks like an IP header */
2505 if (!pinfo->fd->flags.visited)
2506 x25_hash_add_proto_start(vc, pinfo->fd->num, ip_handle);
2507 call_dissector(ip_handle, next_tvb, pinfo, tree);
2508 pinfo->private_data = saved_private_data;
2511 case NLPID_ISO8473_CLNP:
2512 if (!pinfo->fd->flags.visited)
2513 x25_hash_add_proto_start(vc, pinfo->fd->num, clnp_handle);
2514 call_dissector(clnp_handle, next_tvb, pinfo, tree);
2515 pinfo->private_data = saved_private_data;
2520 /* Try the heuristic dissectors. */
2521 if (dissector_try_heuristic(x25_heur_subdissector_list, next_tvb, pinfo,
2523 pinfo->private_data = saved_private_data;
2527 /* All else failed; dissect it as raw data */
2528 call_dissector(data_handle, next_tvb, pinfo, tree);
2529 pinfo->private_data = saved_private_data;
2533 * X.25 dissector for use when "pinfo->pseudo_header" points to a
2534 * "struct x25_phdr".
2537 dissect_x25_dir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2539 dissect_x25_common(tvb, pinfo, tree,
2540 (pinfo->pseudo_header->x25.flags & FROM_DCE) ? X25_FROM_DCE :
2542 pinfo->pseudo_header->x25.flags & FROM_DCE);
2546 * X.25 dissector for use when "pinfo->pseudo_header" doesn't point to a
2547 * "struct x25_phdr".
2550 dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2555 * We don't know if this packet is DTE->DCE or DCE->DCE.
2556 * However, we can, at least, distinguish between the two
2557 * sides of the conversation, based on the addresses and
2560 direction = CMP_ADDRESS(&pinfo->src, &pinfo->dst);
2562 direction = (pinfo->srcport > pinfo->destport)*2 - 1;
2563 dissect_x25_common(tvb, pinfo, tree, X25_UNKNOWN, direction > 0);
2567 x25_reassemble_init(void)
2569 fragment_table_init(&x25_segment_table);
2570 reassembled_table_init(&x25_reassembled_table);
2574 proto_register_x25(void)
2576 static hf_register_info hf[] = {
2578 { "GFI", "x25.gfi", FT_UINT16, BASE_DEC, NULL, 0xF000,
2579 "General format identifier", HFILL }},
2581 { "A Bit", "x25.a", FT_BOOLEAN, 16, NULL, X25_ABIT,
2582 "Address Bit", HFILL }},
2584 { "Q Bit", "x25.q", FT_BOOLEAN, 16, NULL, X25_QBIT,
2585 "Qualifier Bit", HFILL }},
2587 { "D Bit", "x25.d", FT_BOOLEAN, 16, NULL, X25_DBIT,
2588 "Delivery Confirmation Bit", HFILL }},
2590 { "Modulo", "x25.mod", FT_UINT16, BASE_DEC, VALS(vals_modulo), 0x3000,
2591 "Specifies whether the frame is modulo 8 or 128", HFILL }},
2593 { "Logical Channel", "x25.lcn", FT_UINT16, BASE_DEC, NULL, 0x0FFF,
2594 "Logical Channel Number", HFILL }},
2596 { "Packet Type", "x25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x0,
2598 { &hf_x25_type_fc_mod8,
2599 { "Packet Type", "x25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x1F,
2601 { &hf_x25_type_data,
2602 { "Packet Type", "x25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x01,
2605 { "P(R)", "x25.p_r", FT_UINT8, BASE_DEC, NULL, 0xE0,
2606 "Packet Receive Sequence Number", HFILL }},
2607 { &hf_x25_p_r_mod128,
2608 { "P(R)", "x25.p_r", FT_UINT8, BASE_DEC, NULL, 0xFE,
2609 "Packet Receive Sequence Number", HFILL }},
2610 { &hf_x25_mbit_mod8,
2611 { "M Bit", "x25.m", FT_BOOLEAN, 8, TFS(&m_bit_tfs), X25_MBIT_MOD8,
2612 "More Bit", HFILL }},
2613 { &hf_x25_mbit_mod128,
2614 { "M Bit", "x25.m", FT_BOOLEAN, 8, TFS(&m_bit_tfs), X25_MBIT_MOD128,
2615 "More Bit", HFILL }},
2617 { "P(S)", "x25.p_s", FT_UINT8, BASE_DEC, NULL, 0x0E,
2618 "Packet Send Sequence Number", HFILL }},
2619 { &hf_x25_p_s_mod128,
2620 { "P(S)", "x25.p_s", FT_UINT8, BASE_DEC, NULL, 0xFE,
2621 "Packet Send Sequence Number", HFILL }},
2622 { &hf_x25_segment_overlap,
2623 { "Fragment overlap", "x25.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2624 "Fragment overlaps with other fragments", HFILL }},
2626 { &hf_x25_segment_overlap_conflict,
2627 { "Conflicting data in fragment overlap", "x25.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2628 "Overlapping fragments contained conflicting data", HFILL }},
2630 { &hf_x25_segment_multiple_tails,
2631 { "Multiple tail fragments found", "x25.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2632 "Several tails were found when defragmenting the packet", HFILL }},
2634 { &hf_x25_segment_too_long_segment,
2635 { "Fragment too long", "x25.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2636 "Fragment contained data past end of packet", HFILL }},
2638 { &hf_x25_segment_error,
2639 { "Defragmentation error", "x25.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2640 "Defragmentation error due to illegal fragments", HFILL }},
2642 { &hf_x25_segment_count,
2643 { "Fragment count", "x25.fragment.count", FT_UINT32, BASE_DEC, NULL, 0x0,
2646 { &hf_x25_reassembled_length,
2647 { "Reassembled X.25 length", "x25.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x0,
2648 "The total length of the reassembled payload", HFILL }},
2651 { "X.25 Fragment", "x25.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2652 "X25 Fragment", HFILL }},
2655 { "X.25 Fragments", "x25.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
2658 static gint *ett[] = {
2662 &ett_x25_fac_unknown,
2664 &ett_x25_fac_reverse,
2665 &ett_x25_fac_charging_info,
2666 &ett_x25_fac_throughput,
2668 &ett_x25_fac_called_modif,
2669 &ett_x25_fac_cug_outgoing_acc,
2670 &ett_x25_fac_throughput_min,
2671 &ett_x25_fac_express_data,
2672 &ett_x25_fac_bilateral_cug,
2673 &ett_x25_fac_packet_size,
2674 &ett_x25_fac_window_size,
2675 &ett_x25_fac_rpoa_selection,
2676 &ett_x25_fac_cug_ext,
2677 &ett_x25_fac_cug_outgoing_acc_ext,
2678 &ett_x25_fac_transit_delay,
2679 &ett_x25_fac_call_duration,
2680 &ett_x25_fac_segment_count,
2681 &ett_x25_fac_call_transfer,
2682 &ett_x25_fac_rpoa_selection_ext,
2683 &ett_x25_fac_monetary_unit,
2685 &ett_x25_fac_called_addr_ext,
2686 &ett_x25_fac_ete_transit_delay,
2687 &ett_x25_fac_calling_addr_ext,
2688 &ett_x25_fac_call_deflect,
2689 &ett_x25_fac_priority,
2694 module_t *x25_module;
2696 proto_x25 = proto_register_protocol ("X.25", "X.25", "x25");
2697 proto_register_field_array (proto_x25, hf, array_length(hf));
2698 proto_register_subtree_array(ett, array_length(ett));
2700 x25_subdissector_table = register_dissector_table("x.25.spi",
2701 "X.25 secondary protocol identifier", FT_UINT8, BASE_HEX);
2702 register_heur_dissector_list("x.25", &x25_heur_subdissector_list);
2704 register_dissector("x.25_dir", dissect_x25_dir, proto_x25);
2705 register_dissector("x.25", dissect_x25, proto_x25);
2708 x25_module = prefs_register_protocol(proto_x25, NULL);
2709 prefs_register_obsolete_preference(x25_module, "non_q_bit_is_sna");
2710 prefs_register_bool_preference(x25_module, "payload_is_qllc_sna",
2711 "Default to QLLC/SNA",
2712 "If CALL REQUEST not seen or didn't specify protocol, dissect as QLLC/SNA",
2713 &payload_is_qllc_sna);
2714 prefs_register_bool_preference(x25_module, "call_request_nodata_is_cotp",
2715 "Assume COTP for Call Request without data",
2716 "If CALL REQUEST has no data, assume the protocol handled is COTP",
2717 &call_request_nodata_is_cotp);
2718 prefs_register_bool_preference(x25_module, "payload_check_data",
2719 "Check data for COTP/IP/CLNP",
2720 "If CALL REQUEST not seen or didn't specify protocol, check user data before checking heuristic dissectors",
2721 &payload_check_data);
2722 prefs_register_bool_preference(x25_module, "reassemble",
2723 "Reassemble fragmented X.25 packets",
2724 "Reassemble fragmented X.25 packets",
2726 register_init_routine(&x25_reassemble_init);
2730 proto_reg_handoff_x25(void)
2732 dissector_handle_t x25_handle;
2735 * Get handles for various dissectors.
2737 ip_handle = find_dissector("ip");
2738 clnp_handle = find_dissector("clnp");
2739 ositp_handle = find_dissector("ositp");
2740 qllc_handle = find_dissector("qllc");
2741 data_handle = find_dissector("data");
2743 x25_handle = find_dissector("x.25");
2744 dissector_add_uint("llc.dsap", SAP_X25, x25_handle);