2 * Routines for ISO/OSI transport protocol (connection-oriented
3 * and connectionless) packet disassembly
6 * Laurent Deniel <laurent.deniel@free.fr>
7 * Ralf Schneider <Ralf.Schneider@t-online.de>
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include <epan/prefs.h>
34 #include <epan/packet.h>
35 #include <epan/reassemble.h>
36 #include <epan/conversation.h>
37 #include <epan/wmem/wmem.h>
38 #include "packet-frame.h"
39 #include "packet-osi.h"
40 #include "packet-osi-options.h"
41 #include "packet-isis.h"
42 #include "packet-esis.h"
43 #include <epan/nlpid.h>
44 #include <epan/ipproto.h>
45 #include <epan/expert.h>
46 #include <epan/strutil.h>
48 /* protocols and fields */
50 static int proto_clnp
;
52 static int proto_cotp
= -1;
53 static gint ett_cotp
= -1;
54 static gint ett_cotp_segments
= -1;
55 static gint ett_cotp_segment
= -1;
57 static int hf_cotp_li
= -1;
58 static int hf_cotp_type
= -1;
59 static int hf_cotp_srcref
= -1;
60 static int hf_cotp_destref
= -1;
61 static int hf_cotp_class
= -1;
62 static int hf_cotp_opts_extended_formats
= -1;
63 static int hf_cotp_opts_no_explicit_flow_control
= -1;
64 static int hf_cotp_tpdu_number
= -1;
65 static int hf_cotp_tpdu_number_extended
= -1;
66 static int hf_cotp_next_tpdu_number
= -1;
67 static int hf_cotp_next_tpdu_number_extended
= -1;
68 static int hf_cotp_eot
= -1;
69 static int hf_cotp_eot_extended
= -1;
71 static int hf_cotp_segments
= -1;
72 static int hf_cotp_segment
= -1;
73 static int hf_cotp_segment_overlap
= -1;
74 static int hf_cotp_segment_overlap_conflict
= -1;
75 static int hf_cotp_segment_multiple_tails
= -1;
76 static int hf_cotp_segment_too_long_segment
= -1;
77 static int hf_cotp_segment_error
= -1;
78 static int hf_cotp_segment_count
= -1;
79 static int hf_cotp_reassembled_in
= -1;
80 static int hf_cotp_reassembled_length
= -1;
82 static expert_field ei_cotp_disconnect_confirm
= EI_INIT
;
83 static expert_field ei_cotp_multiple_tpdus
= EI_INIT
;
84 static expert_field ei_cotp_reject
= EI_INIT
;
85 static expert_field ei_cotp_connection
= EI_INIT
;
86 static expert_field ei_cotp_disconnect_request
= EI_INIT
;
88 static int proto_cltp
= -1;
89 static gint ett_cltp
= -1;
91 static int hf_cltp_li
= -1;
92 static int hf_cltp_type
= -1;
94 static const fragment_items cotp_frag_items
= {
99 &hf_cotp_segment_overlap
,
100 &hf_cotp_segment_overlap_conflict
,
101 &hf_cotp_segment_multiple_tails
,
102 &hf_cotp_segment_too_long_segment
,
103 &hf_cotp_segment_error
,
104 &hf_cotp_segment_count
,
105 &hf_cotp_reassembled_in
,
106 &hf_cotp_reassembled_length
,
107 /* Reassembled data field */
112 static dissector_handle_t data_handle
;
115 * ISO8073 OSI COTP definition
116 * See http://standards.iso.org/ittf/PubliclyAvailableStandards/index.html
117 * (or RFC905 for historic, and now-outdated information)
120 /* don't use specific TPDU types to avoid alignment problems & copy overhead */
122 /* TPDU definition */
124 #define ED_TPDU 0x1 /* COTP */
125 #define EA_TPDU 0x2 /* COTP */
126 #define UD_TPDU 0x4 /* CLTP */
127 #define RJ_TPDU 0x5 /* COTP */
128 #define AK_TPDU 0x6 /* COTP */
129 #define ER_TPDU 0x7 /* COTP */
130 #define DR_TPDU 0x8 /* COTP */
131 #define DC_TPDU 0xC /* COTP */
132 #define CC_TPDU 0xD /* COTP */
133 #define CR_TPDU 0xE /* COTP */
134 #define DT_TPDU 0xF /* COTP */
136 static const value_string cotp_tpdu_type_abbrev_vals
[] = {
137 { ED_TPDU
, "ED Expedited Data" },
138 { EA_TPDU
, "EA Expedited Data Acknowledgement" },
139 { RJ_TPDU
, "RJ Reject" },
140 { AK_TPDU
, "AK Data Acknowledgement" },
141 { ER_TPDU
, "ER TPDU Error" },
142 { DR_TPDU
, "DR Disconnect Request" },
143 { DC_TPDU
, "DC Disconnect Confirm" },
144 { CC_TPDU
, "CC Connect Confirm" },
145 { CR_TPDU
, "CR Connect Request" },
146 { DT_TPDU
, "DT Data" },
150 static const value_string cltp_tpdu_type_abbrev_vals
[] = {
156 static const value_string class_option_vals
[] = {
173 #define P_TPDU_NR_0_1 2
174 #define P_TPDU_NR_234 4
175 #define P_VAR_PART_NDT 5
176 #define P_VAR_PART_EDT 8
177 #define P_VAR_PART_DC 6
178 #define P_CDT_IN_AK 8
179 #define P_CDT_IN_RJ 8
180 #define P_REJECT_ER 4
181 #define P_REASON_IN_DR 6
182 #define P_CLASS_OPTION 6
185 * TPDU length indicator values.
186 * Checksum parameter is 4 octets - 1 octet of parameter code, 1 octet
187 * of parameter length, 2 octets of checksum.
190 #define LI_NORMAL_DT_CLASS_01 2
191 #define LI_NORMAL_DT_WITHOUT_CHECKSUM 4
192 #define LI_NORMAL_DT_WITH_CHECKSUM (LI_NORMAL_DT_WITHOUT_CHECKSUM+4)
193 #define LI_EXTENDED_DT_WITHOUT_CHECKSUM 7
194 #define LI_EXTENDED_DT_WITH_CHECKSUM (LI_EXTENDED_DT_WITHOUT_CHECKSUM+4)
195 #define LI_NORMAL_EA_WITHOUT_CHECKSUM 4
196 #define LI_NORMAL_EA_WITH_CHECKSUM (LI_NORMAL_EA_WITHOUT_CHECKSUM+4)
197 #define LI_EXTENDED_EA_WITHOUT_CHECKSUM 7
198 #define LI_EXTENDED_EA_WITH_CHECKSUM (LI_EXTENDED_EA_WITHOUT_CHECKSUM+4)
199 #define LI_NORMAL_RJ 4
200 #define LI_EXTENDED_RJ 9
206 /* XXX - can we always decide this based on whether the length
207 indicator is odd or not? What if the variable part has an odd
209 #define is_LI_NORMAL_AK(p) ((p & 0x01) == 0)
212 * Modified TPDU length indicator values due to ATN 4-octet extended
214 * Checksum parameter is 6 octets - 1 octet of parameter code, 1 octet
215 * of parameter length, 4 octets of checksum. That adds 2 octets to
216 * the lengths with a 2-octet checksum.
218 #define LI_ATN_NORMAL_DT_WITH_CHECKSUM (LI_NORMAL_DT_WITH_CHECKSUM+2)
219 #define LI_ATN_EXTENDED_DT_WITH_CHECKSUM (LI_EXTENDED_DT_WITH_CHECKSUM+2)
220 #define LI_ATN_NORMAL_EA_WITH_CHECKSUM (LI_NORMAL_EA_WITH_CHECKSUM+2)
221 #define LI_ATN_EXTENDED_EA_WITH_CHECKSUM (LI_EXTENDED_EA_WITH_CHECKSUM+2)
222 #define LI_ATN_NORMAL_RJ (LI_NORMAL_RJ+2)
223 #define LI_ATN_EXTENDED_RJ (LI_EXTENDED_RJ+2)
224 #define LI_ATN_MAX_DC (LI_MAX_DC+2)
225 #define LI_ATN_MAX_AK (LI_MAX_AK+2+1) /* +1 for padding? */
226 #define LI_ATN_MAX_EA (LI_MAX_EA+2)
227 #define LI_ATN_MAX_ER (LI_MAX_ER+2)
231 #define VP_ACK_TIME 0x85
232 #define VP_RES_ERROR 0x86
233 #define VP_PRIORITY 0x87
234 #define VP_TRANSIT_DEL 0x88
235 #define VP_THROUGHPUT 0x89
236 #define VP_SEQ_NR 0x8A /* in AK */
237 #define VP_REASSIGNMENT 0x8B
238 #define VP_FLOW_CNTL 0x8C /* in AK */
239 #define VP_TPDU_SIZE 0xC0
240 #define VP_SRC_TSAP 0xC1 /* in CR/CC */
241 #define VP_DST_TSAP 0xC2
242 #define VP_CHECKSUM 0xC3
243 #define VP_VERSION_NR 0xC4
244 #define VP_PROTECTION 0xC5
245 #define VP_OPT_SEL 0xC6
246 #define VP_PROTO_CLASS 0xC7
247 #define VP_CLEARING_INFO 0xE0 /* in DR */
248 #define VP_PREF_MAX_TPDU_SIZE 0xF0
249 #define VP_INACTIVITY_TIMER 0xF2
252 /* Parameter codes with bits 7 and 8 are explicitly not */
253 /* assigned by ISO/IEC 8073, nor is their use precluded. */
254 /* Parameter codes for ATN defined in ICAO doc 9507 Ed3 SV 5 section 5.5.2.4.3.1 */
255 #define VP_ATN_EC_32 0x08 /* 4 octet ATN Extended Transport Checksum parameter */
256 #define VP_ATN_EC_16 0x09 /* 2 octet ATN Extended Transport Checksum parameter */
259 static const value_string tp_vpart_type_vals
[] = {
260 { VP_ATN_EC_16
, "ATN extended checksum - 16 bit" },
261 { VP_ATN_EC_32
, "ATN extended checksum - 32 bit" },
262 { VP_ACK_TIME
, "ack time" },
263 { VP_RES_ERROR
, "res error" },
264 { VP_PRIORITY
, "priority" },
265 { VP_TRANSIT_DEL
, "transit delay" },
266 { VP_THROUGHPUT
, "throughput" },
267 { VP_SEQ_NR
, "seq number" },
268 { VP_REASSIGNMENT
, "reassignment" },
269 { VP_FLOW_CNTL
, "flow control" },
270 { VP_TPDU_SIZE
, "tpdu-size" },
271 { VP_SRC_TSAP
, "src-tsap" },
272 { VP_DST_TSAP
, "dst-tsap" },
273 { VP_CHECKSUM
, "checksum" },
274 { VP_VERSION_NR
, "version" },
275 { VP_PROTECTION
, "protection" },
276 { VP_OPT_SEL
, "options" },
277 { VP_PROTO_CLASS
, "proto class" },
278 { VP_CLEARING_INFO
, "additional connection clearing info" },
279 { VP_PREF_MAX_TPDU_SIZE
, "preferred max TPDU size" },
280 { VP_INACTIVITY_TIMER
, "inactivity timer" },
284 static int hf_cotp_vp_src_tsap
= -1;
285 static int hf_cotp_vp_dst_tsap
= -1;
286 static int hf_cotp_vp_src_tsap_bytes
= -1;
287 static int hf_cotp_vp_dst_tsap_bytes
= -1;
289 /* global variables */
291 /* List of dissectors to call for COTP packets put atop the Inactive
293 static heur_dissector_list_t cotp_is_heur_subdissector_list
;
294 /* List of dissectors to call for COTP packets put atop CLNP */
295 static heur_dissector_list_t cotp_heur_subdissector_list
;
296 /* List of dissectors to call for CLTP packets put atop CLNP */
297 static heur_dissector_list_t cltp_heur_subdissector_list
;
300 * Reassembly of COTP.
302 static reassembly_table cotp_reassembly_table
;
303 static guint16 cotp_dst_ref
= 0;
304 static gboolean cotp_frame_reset
= FALSE
;
305 static gboolean cotp_last_fragment
= FALSE
;
307 #define TSAP_DISPLAY_AUTO 0
308 #define TSAP_DISPLAY_STRING 1
309 #define TSAP_DISPLAY_BYTES 2
312 static gboolean cotp_reassemble
= TRUE
;
313 static gint32 tsap_display
= TSAP_DISPLAY_AUTO
;
314 static gboolean cotp_decode_atn
= FALSE
;
316 static const enum_val_t tsap_display_options
[] = {
317 {"auto", "As strings if printable", TSAP_DISPLAY_AUTO
},
318 {"string", "As strings", TSAP_DISPLAY_STRING
},
319 {"bytes", "As bytes", TSAP_DISPLAY_BYTES
},
323 /* function definitions */
325 #define MAX_TSAP_LEN 32
327 static void cotp_frame_end(void)
329 if (!cotp_last_fragment
) {
330 /* Last COTP in frame is not fragmented.
331 * No need for incrementing the dst_ref, so we decrement it here.
335 cotp_frame_reset
= TRUE
;
338 static gboolean
is_all_printable(const guchar
*stringtocheck
, int length
)
340 gboolean allprintable
;
344 for (i
=0;i
<length
;i
++) {
345 if (!(isascii(stringtocheck
[i
]) && isprint(stringtocheck
[i
]))) {
351 } /* is_all_printable */
354 static gchar
*print_tsap(const guchar
*tsap
, int length
)
358 gboolean allprintable
;
359 gint idx
= 0, returned_length
;
361 cur
=(gchar
*)wmem_alloc(wmem_packet_scope(), MAX_TSAP_LEN
* 2 + 3);
363 if (length
<= 0 || length
> MAX_TSAP_LEN
)
364 g_snprintf(cur
, MAX_TSAP_LEN
* 2 + 3, "<unsupported TSAP length>");
366 allprintable
= is_all_printable(tsap
,length
);
368 returned_length
= g_snprintf(cur
, MAX_TSAP_LEN
* 2 + 3, "0x");
369 idx
+= MIN(returned_length
, MAX_TSAP_LEN
* 2 + 3 - 1);
371 while (length
!= 0) {
373 returned_length
= g_snprintf(&cur
[idx
], MAX_TSAP_LEN
* 2 + 3 - idx
,
375 idx
+= MIN(returned_length
, MAX_TSAP_LEN
* 2 + 3 - idx
- 1);
377 returned_length
= g_snprintf(&cur
[idx
], MAX_TSAP_LEN
* 2 + 3 - idx
,
379 idx
+= MIN(returned_length
, MAX_TSAP_LEN
* 2 + 3 - idx
- 1);
388 static gboolean
ositp_decode_var_part(tvbuff_t
*tvb
, int offset
, int vp_length
,
389 int class_option
, int tpdu_len
,
390 packet_info
*pinfo
, proto_tree
*tree
)
394 guint16 s
, s1
,s2
,s3
,s4
;
395 guint32 t1
, t2
, t3
, t4
;
396 guint32 offset_iso8073_checksum
= 0;
400 cksum_status_t cksum_status
;
401 gboolean checksum_ok
= FALSE
;
402 guint32 pref_max_tpdu_size
;
403 proto_item
*hidden_item
;
405 while (vp_length
!= 0) {
406 code
= tvb_get_guint8(tvb
, offset
);
407 proto_tree_add_text(tree
, tvb
, offset
, 1,
408 "Parameter code: 0x%02x (%s)", code
,
409 val_to_str_const(code
, tp_vpart_type_vals
, "Unknown"));
415 length
= tvb_get_guint8(tvb
, offset
);
416 proto_tree_add_text(tree
, tvb
, offset
, 1, "Parameter length: %u", length
);
422 case VP_ATN_EC_16
: /* ATN */
423 if (cotp_decode_atn
) {
424 /* if an alternate OSI checksum is present in the currently unprocessed
425 * VP section to the checksum algorithm has to know.
426 * this may be the case for backward compatible CR TPDU */
427 if (!offset_iso8073_checksum
) {
428 /* search following parameters in VP part for ISO checksum */
429 for (i
= offset
+ length
; i
< vp_length
;) {
430 tmp_code
= tvb_get_guint8(tvb
, i
++);
431 tmp_len
= tvb_get_guint8(tvb
, i
++);
432 if (tmp_code
== VP_CHECKSUM
) {
433 offset_iso8073_checksum
= i
; /* save ISO 8073 checksum offset for ATN extended checksum calculation */
439 checksum_ok
= check_atn_ec_16(tvb
, tpdu_len
, offset
,
440 offset_iso8073_checksum
,
441 pinfo
->dst
.len
, (guint8
*)pinfo
->dst
.data
,
442 pinfo
->src
.len
, (guint8
*)pinfo
->src
.data
);
443 proto_tree_add_text(tree
, tvb
, offset
, length
,
444 "ATN extended checksum : 0x%04x (%s)",
445 tvb_get_ntohs(tvb
, offset
),
446 checksum_ok
? "correct" : "incorrect");
448 proto_tree_add_text(tree
, tvb
, offset
, length
,
449 "Parameter value: <not shown>");
455 case VP_ATN_EC_32
: /* ATN */
456 if (cotp_decode_atn
) {
457 /* if an alternate OSI checksum is present in the currently unprocessed
458 * VP section the checksum algorithm has to know.
459 * this may be the case for backward compatible CR TPDU */
460 if (!offset_iso8073_checksum
) {
461 /* search following parameters in VP part for ISO checksum */
462 for (i
= offset
+ length
; i
< vp_length
;) {
463 tmp_code
= tvb_get_guint8(tvb
, i
++);
464 tmp_len
= tvb_get_guint8(tvb
, i
++);
465 if (tmp_code
== VP_CHECKSUM
) {
466 offset_iso8073_checksum
= i
; /* save ISO 8073 checksum offset for ATN extended checksum calculation */
472 checksum_ok
= check_atn_ec_32(tvb
, tpdu_len
, offset
,
473 offset_iso8073_checksum
,
474 pinfo
->dst
.len
, (guint8
*)pinfo
->dst
.data
,
475 pinfo
->src
.len
, (guint8
*)pinfo
->src
.data
);
476 proto_tree_add_text(tree
, tvb
, offset
, length
,
477 "ATN extended checksum : 0x%08x (%s)",
478 tvb_get_ntohl(tvb
, offset
),
479 checksum_ok
? "correct" : "incorrect");
481 proto_tree_add_text(tree
, tvb
, offset
, length
,
482 "Parameter value: <not shown>");
489 s
= tvb_get_ntohs(tvb
, offset
);
490 proto_tree_add_text(tree
, tvb
, offset
, length
, "Ack time (ms): %u", s
);
496 proto_tree_add_text(tree
, tvb
, offset
, 1,
497 "Residual error rate, target value: 10^%u",
498 tvb_get_guint8(tvb
, offset
));
502 proto_tree_add_text(tree
, tvb
, offset
, 1,
503 "Residual error rate, minimum acceptable: 10^%u",
504 tvb_get_guint8(tvb
, offset
));
508 proto_tree_add_text(tree
, tvb
, offset
, 1,
509 "Residual error rate, TSDU size of interest: %u",
510 1 << tvb_get_guint8(tvb
, offset
));
516 s
= tvb_get_ntohs(tvb
, offset
);
517 proto_tree_add_text(tree
, tvb
, offset
, length
, "Priority: %u", s
);
523 s1
= tvb_get_ntohs(tvb
, offset
);
524 proto_tree_add_text(tree
, tvb
, offset
, 2,
525 "Transit delay, target value, calling-called: %u ms",
530 s2
= tvb_get_ntohs(tvb
, offset
);
531 proto_tree_add_text(tree
, tvb
, offset
, 2,
532 "Transit delay, maximum acceptable, calling-called: %u ms",
537 s3
= tvb_get_ntohs(tvb
, offset
);
538 proto_tree_add_text(tree
, tvb
, offset
, 2,
539 "Transit delay, target value, called-calling: %u ms",
544 s4
= tvb_get_ntohs(tvb
, offset
);
545 proto_tree_add_text(tree
, tvb
, offset
, 2,
546 "Transit delay, maximum acceptable, called-calling: %u ms",
553 t1
= tvb_get_ntoh24(tvb
, offset
);
554 proto_tree_add_text(tree
, tvb
, offset
, 3,
555 "Maximum throughput, target value, calling-called: %u o/s",
561 t2
= tvb_get_ntoh24(tvb
, offset
);
562 proto_tree_add_text(tree
, tvb
, offset
, 3,
563 "Maximum throughput, minimum acceptable, calling-called: %u o/s",
569 t3
= tvb_get_ntoh24(tvb
, offset
);
570 proto_tree_add_text(tree
, tvb
, offset
, 3,
571 "Maximum throughput, target value, called-calling: %u o/s",
577 t4
= tvb_get_ntoh24(tvb
, offset
);
578 proto_tree_add_text(tree
, tvb
, offset
, 3,
579 "Maximum throughput, minimum acceptable, called-calling: %u o/s",
585 if (length
!= 0) { /* XXX - should be 0 or 12 */
586 t1
= tvb_get_ntoh24(tvb
, offset
);
587 proto_tree_add_text(tree
, tvb
, offset
, 3,
588 "Average throughput, target value, calling-called: %u o/s",
593 t2
= tvb_get_ntoh24(tvb
, offset
);
594 proto_tree_add_text(tree
, tvb
, offset
, 3,
595 "Average throughput, minimum acceptable, calling-called: %u o/s",
600 t3
= tvb_get_ntoh24(tvb
, offset
);
601 proto_tree_add_text(tree
, tvb
, offset
, 3,
602 "Average throughput, target value, called-calling: %u o/s",
607 t4
= tvb_get_ntoh24(tvb
, offset
);
608 proto_tree_add_text(tree
, tvb
, offset
, 3,
609 "Average throughput, minimum acceptable, called-calling: %u o/s",
617 proto_tree_add_text(tree
, tvb
, offset
, 2, "Sequence number: 0x%04x",
618 tvb_get_ntohs(tvb
, offset
));
623 case VP_REASSIGNMENT
:
624 proto_tree_add_text(tree
, tvb
, offset
, 2, "Reassignment time: %u secs",
625 tvb_get_ntohs(tvb
, offset
));
631 proto_tree_add_text(tree
, tvb
, offset
, 4, "Lower window edge: 0x%08x",
632 tvb_get_ntohl(tvb
, offset
));
636 proto_tree_add_text(tree
, tvb
, offset
, 2, "Sequence number: 0x%04x",
637 tvb_get_ntohs(tvb
, offset
));
641 proto_tree_add_text(tree
, tvb
, offset
, 2, "Credit: 0x%04x",
642 tvb_get_ntohs(tvb
, offset
));
649 c1
= tvb_get_guint8(tvb
, offset
) & 0x0F;
650 proto_tree_add_text(tree
, tvb
, offset
, length
, "TPDU size: %u", 1 << c1
);
656 /* if our preference is set to STRING or the TSAP is not printable,
657 * add as bytes and hidden as string; otherwise vice-versa */
658 if (tsap_display
==TSAP_DISPLAY_STRING
||
659 (tsap_display
==TSAP_DISPLAY_AUTO
&&
660 is_all_printable(tvb_get_ptr(tvb
, offset
,length
),length
))) {
661 proto_tree_add_string(tree
, hf_cotp_vp_src_tsap
, tvb
, offset
, length
,
662 print_tsap(tvb_get_ptr(tvb
, offset
, length
),
664 hidden_item
= proto_tree_add_item(tree
, hf_cotp_vp_src_tsap_bytes
, tvb
,
665 offset
, length
, ENC_NA
);
666 PROTO_ITEM_SET_HIDDEN(hidden_item
);
668 hidden_item
= proto_tree_add_string(tree
, hf_cotp_vp_src_tsap
, tvb
,
670 print_tsap(tvb_get_ptr(tvb
, offset
,
673 PROTO_ITEM_SET_HIDDEN(hidden_item
);
674 proto_tree_add_item(tree
, hf_cotp_vp_src_tsap_bytes
, tvb
, offset
,
682 /* if our preference is set to STRING or the TSAP is not printable,
683 * add as bytes and hidden as string; otherwise vice-versa */
684 if (tsap_display
==TSAP_DISPLAY_STRING
||
685 (tsap_display
==TSAP_DISPLAY_AUTO
&&
686 is_all_printable(tvb_get_ptr(tvb
,offset
,length
),length
))) {
687 proto_tree_add_string(tree
, hf_cotp_vp_dst_tsap
, tvb
, offset
, length
,
688 print_tsap(tvb_get_ptr(tvb
, offset
, length
),
690 hidden_item
= proto_tree_add_item(tree
, hf_cotp_vp_dst_tsap_bytes
, tvb
,
691 offset
, length
, ENC_NA
);
692 PROTO_ITEM_SET_HIDDEN(hidden_item
);
694 hidden_item
= proto_tree_add_string(tree
, hf_cotp_vp_dst_tsap
, tvb
,
696 print_tsap(tvb_get_ptr(tvb
, offset
,
699 PROTO_ITEM_SET_HIDDEN(hidden_item
);
700 proto_tree_add_item(tree
, hf_cotp_vp_dst_tsap_bytes
, tvb
, offset
,
708 offset_iso8073_checksum
= offset
; /* save ISO 8073 checksum offset for ATN extended checksum calculation */
709 cksum_status
= calc_checksum(tvb
, 0, tpdu_len
,
710 tvb_get_ntohs(tvb
, offset
));
711 switch (cksum_status
) {
715 * No checksum present, or not enough of the packet present to
718 proto_tree_add_text(tree
, tvb
, offset
, length
,
719 "Checksum: 0x%04x", tvb_get_ntohs(tvb
, offset
));
724 * Checksum is correct.
726 proto_tree_add_text(tree
, tvb
, offset
, length
,
727 "Checksum: 0x%04x (correct)",
728 tvb_get_ntohs(tvb
, offset
));
733 * Checksum is not correct.
735 proto_tree_add_text(tree
, tvb
, offset
, length
,
736 "Checksum: 0x%04x (incorrect)",
737 tvb_get_ntohs(tvb
, offset
));
745 c1
= tvb_get_guint8(tvb
, offset
);
746 proto_tree_add_text(tree
, tvb
, offset
, length
, "Version: %u", c1
);
752 c1
= tvb_get_guint8(tvb
, offset
) & 0x0F;
753 switch (class_option
) {
757 proto_tree_add_text(tree
, tvb
, offset
, 1,
758 "Use of network expedited data");
760 proto_tree_add_text(tree
, tvb
, offset
, 1,
761 "Non use of network expedited data");
763 proto_tree_add_text(tree
, tvb
, offset
, 1,
764 "Use of Receipt confirmation");
766 proto_tree_add_text(tree
, tvb
, offset
, 1,
767 "Use of explicit AK variant");
772 proto_tree_add_text(tree
, tvb
, offset
, 1,
773 "Non-use 16 bit checksum in class 4");
775 proto_tree_add_text(tree
, tvb
, offset
, 1, "Use 16 bit checksum ");
780 proto_tree_add_text(tree
, tvb
, offset
, 1,
781 "Use of transport expedited data transfer");
783 proto_tree_add_text(tree
, tvb
, offset
, 1,
784 "Non-use of transport expedited data transfer");
789 case VP_PREF_MAX_TPDU_SIZE
:
793 pref_max_tpdu_size
= tvb_get_guint8(tvb
, offset
);
797 pref_max_tpdu_size
= tvb_get_ntohs(tvb
, offset
);
801 pref_max_tpdu_size
= tvb_get_ntoh24(tvb
, offset
);
805 pref_max_tpdu_size
= tvb_get_ntohl(tvb
, offset
);
809 proto_tree_add_text(tree
, tvb
, offset
, length
,
810 "Preferred maximum TPDU size: bogus length %u (not 1, 2, 3, or 4)",
814 proto_tree_add_text(tree
, tvb
, offset
, length
,
815 "Preferred maximum TPDU size: %u",
816 pref_max_tpdu_size
*128);
821 case VP_INACTIVITY_TIMER
:
822 proto_tree_add_text(tree
, tvb
, offset
, length
, "Inactivity timer: %u ms",
823 tvb_get_ntohl(tvb
, offset
));
828 case VP_PROTECTION
: /* user-defined */
829 case VP_PROTO_CLASS
: /* todo */
830 case VP_CLEARING_INFO
: /* user-defined */
831 default: /* unknown, no decoding */
832 proto_tree_add_text(tree
, tvb
, offset
, length
,
833 "Parameter value: <not shown>");
843 static int ositp_decode_DR(tvbuff_t
*tvb
, int offset
, guint8 li
, guint8 tpdu
,
844 packet_info
*pinfo
, proto_tree
*tree
)
846 proto_tree
*cotp_tree
= NULL
;
847 proto_item
*ti
= NULL
;
848 guint16 dst_ref
, src_ref
;
853 /* ATN TPDU's tend to be larger than normal OSI,
854 * so nothing to do with respect to LI checks */
858 /* DR TPDUs can have user data, so they run to the end of the containing PDU */
859 tpdu_len
= tvb_reported_length_remaining(tvb
, offset
);
861 dst_ref
= tvb_get_ntohs(tvb
, offset
+ P_DST_REF
);
863 src_ref
= tvb_get_ntohs(tvb
, offset
+ P_SRC_REF
);
865 reason
= tvb_get_guint8(tvb
, offset
+ P_REASON_IN_DR
);
867 pinfo
->clnp_dstref
= dst_ref
;
868 pinfo
->clnp_srcref
= src_ref
;
870 /* the settings of the TCP srcport and destport are currently disables,
871 * for the following reasons:
872 * a) only used for ISO conversation handling (which currently doesn't work)
873 * b) will prevent "ISO on TCP" (RFC1006) packets from using
874 * "follow TCP stream" correctly
876 * A future conversation handling might be able to handle different kinds of
877 * conversations (TCP, ISO, TCP on TCP, ...), but in that case this has to be
880 /*pinfo->srcport = src_ref;*/
881 /*pinfo->destport = dst_ref;*/
883 case (128+0): str
= "Normal Disconnect"; break;
884 case (128+1): str
= "Remote transport entity congestion"; break;
885 case (128+2): str
= "Connection negotiation failed"; break;
886 case (128+3): str
= "Duplicate source reference"; break;
887 case (128+4): str
= "Mismatched references"; break;
888 case (128+5): str
= "Protocol error"; break;
889 case (128+7): str
= "Reference overflow"; break;
890 case (128+8): str
= "Connection request refused"; break;
891 case (128+10):str
= "Header or parameter length invalid"; break;
892 case (0): str
= "Reason not specified"; break;
893 case (1): str
= "Congestion at TSAP"; break;
894 case (2): str
= "Session entity not attached to TSAP"; break;
895 case (3): str
= "Address unknown"; break;
899 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
900 "DR TPDU src-ref: 0x%04x dst-ref: 0x%04x", src_ref
, dst_ref
);
903 ti
= proto_tree_add_item(tree
, proto_cotp
, tvb
, offset
, li
+ 1, ENC_NA
);
904 cotp_tree
= proto_item_add_subtree(ti
, ett_cotp
);
905 proto_tree_add_uint(cotp_tree
, hf_cotp_li
, tvb
, offset
, 1,li
);
906 proto_tree_add_uint(cotp_tree
, hf_cotp_type
, tvb
, offset
+ 1, 1, tpdu
);
907 proto_tree_add_uint(cotp_tree
, hf_cotp_destref
, tvb
, offset
+ 2, 2,
909 proto_tree_add_uint(cotp_tree
, hf_cotp_srcref
, tvb
, offset
+ 4, 2,
911 proto_tree_add_text(cotp_tree
, tvb
, offset
+ 6, 1, "Cause: %s", str
);
917 ositp_decode_var_part(tvb
, offset
, li
, 4, tpdu_len
, pinfo
, cotp_tree
);
920 expert_add_info_format(pinfo
, ti
, &ei_cotp_disconnect_request
, "Disconnect Request(DR): 0x%x -> 0x%x", src_ref
, dst_ref
);
923 call_dissector(data_handle
, tvb_new_subset_remaining(tvb
, offset
), pinfo
,
925 offset
+= tvb_length_remaining(tvb
, offset
);
926 /* we dissected all of the containing PDU */
930 } /* ositp_decode_DR */
932 static int ositp_decode_DT(tvbuff_t
*tvb
, int offset
, guint8 li
, guint8 tpdu
,
933 packet_info
*pinfo
, proto_tree
*tree
,
934 gboolean uses_inactive_subset
,
935 gboolean
*subdissector_found
)
937 proto_tree
*cotp_tree
= NULL
;
939 gboolean is_extended
;
940 gboolean is_class_234
;
942 guint32
*prev_dst_ref
;
944 gboolean fragment
= FALSE
;
945 guint32 fragment_length
= 0;
947 fragment_head
*fd_head
;
948 conversation_t
*conv
;
951 /* DT TPDUs have user data, so they run to the end of the containing PDU */
952 tpdu_len
= tvb_reported_length_remaining(tvb
, offset
);
954 /* The fixed part is 2 octets long, not including the length indicator,
955 for classes 0 and 1; it is at least 4 octets long, not including
956 the length indicator, for classes 2, 3, and 4. */
957 is_class_234
= (li
> LI_NORMAL_DT_CLASS_01
);
959 /* note: in the ATN the user is up to chose between 3 different checksums:
960 * standard OSI, 2 or 4 octet extended checksum.
961 * The differences for DT are that the TPDU headers may be enlarged by 2
962 * octets and that checksum related option codes and option lengths are
963 * different. To not mess up the original OSI dissector LI checking was
964 * implemented separately. */
965 if (!cotp_decode_atn
) { /* non ATN, plain OSI*/
966 /* VP_CHECKSUM is the only parameter allowed in the variable part.
967 * (This means we may misdissect this if the packet is bad and
968 * contains other parameters.).
970 * XXX - not true; ISO/IEC 8073:1997 (E) says that "if the use of
971 * non-blocking expedited data transfer service is negotiated (class
972 * 4 only), the variable part shall contain the ED-TPDU-NR for the
973 * first DT-TPDU created from a T-DATA request subsequent to the
974 * T-EXPEDITED DATA request". */
977 case LI_NORMAL_DT_WITH_CHECKSUM
:
978 if (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_NDT
) != VP_CHECKSUM
)
982 case LI_NORMAL_DT_WITHOUT_CHECKSUM
:
983 tpdu_nr
= tvb_get_guint8(tvb
, offset
+ P_TPDU_NR_234
);
985 tpdu_nr
= tpdu_nr
& 0x7F;
989 dst_ref
= tvb_get_ntohs(tvb
, offset
+ P_DST_REF
);
992 case LI_EXTENDED_DT_WITH_CHECKSUM
:
993 if (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_EDT
) != VP_CHECKSUM
)
997 case LI_EXTENDED_DT_WITHOUT_CHECKSUM
:
998 tpdu_nr
= tvb_get_ntohl(tvb
, offset
+ P_TPDU_NR_234
);
999 if (tpdu_nr
& 0x80000000)
1000 tpdu_nr
= tpdu_nr
& 0x7FFFFFFF;
1004 dst_ref
= tvb_get_ntohs(tvb
, offset
+ P_DST_REF
);
1007 case LI_NORMAL_DT_CLASS_01
:
1008 tpdu_nr
= tvb_get_guint8(tvb
, offset
+ P_TPDU_NR_0_1
);
1010 tpdu_nr
= tpdu_nr
& 0x7F;
1013 is_extended
= FALSE
;
1014 prev_dst_ref
= (guint32
*)p_get_proto_data (pinfo
->fd
, proto_clnp
, 0);
1015 if (!prev_dst_ref
) {
1016 /* First COTP in frame - save previous dst_ref as offset */
1017 prev_dst_ref
= wmem_new(wmem_file_scope(), guint32
);
1018 *prev_dst_ref
= cotp_dst_ref
;
1019 p_add_proto_data (pinfo
->fd
, proto_clnp
, 0, prev_dst_ref
);
1020 } else if (cotp_frame_reset
) {
1021 cotp_dst_ref
= *prev_dst_ref
;
1023 cotp_frame_reset
= FALSE
;
1024 cotp_last_fragment
= fragment
;
1025 dst_ref
= cotp_dst_ref
;
1026 conv
= find_conversation(pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
1027 pinfo
->ptype
, pinfo
->srcport
, pinfo
->destport
,
1030 /* Found a conversation, also use index for the generated dst_ref */
1031 dst_ref
+= (conv
->index
<< 16);
1035 register_frame_end_routine(pinfo
, cotp_frame_end
);
1039 default : /* bad TPDU */
1043 /* check ATN class4 TPDU's here */
1045 /* check packet length indicators of DaTa(DT) TPDU
1046 * note: use of checksum depends on the selected RER
1047 * (high:non-use medium:16-bit OSI/16-bit ext.ATN low:32-bit ext. ATN)
1049 * note: sole use of TP4 class in the ATN
1050 * note: normal/extended TPDU numbering is negociable */
1053 /* normal DT with 2 octets of OSI or of ATN Extended Checksum */
1054 case LI_NORMAL_DT_WITH_CHECKSUM
:
1055 if (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_NDT
) != VP_CHECKSUM
&&
1056 tvb_get_guint8(tvb
, offset
+ P_VAR_PART_NDT
) != VP_ATN_EC_16
)
1060 case LI_NORMAL_DT_WITHOUT_CHECKSUM
:
1061 tpdu_nr
= tvb_get_guint8(tvb
, offset
+ P_TPDU_NR_234
);
1063 tpdu_nr
= tpdu_nr
& 0x7F;
1066 is_extended
= FALSE
;
1067 dst_ref
= tvb_get_ntohs(tvb
, offset
+ P_DST_REF
);
1070 /* extended DT with 2 octets of OSI or of ATN Extended Checksum */
1071 case LI_EXTENDED_DT_WITH_CHECKSUM
:
1072 if (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_EDT
) != VP_CHECKSUM
&&
1073 tvb_get_guint8(tvb
, offset
+ P_VAR_PART_EDT
) != VP_ATN_EC_16
)
1077 case LI_EXTENDED_DT_WITHOUT_CHECKSUM
:
1078 tpdu_nr
= tvb_get_ntohl(tvb
, offset
+ P_TPDU_NR_234
);
1079 if (tpdu_nr
& 0x80000000)
1080 tpdu_nr
= tpdu_nr
& 0x7FFFFFFF;
1084 dst_ref
= tvb_get_ntohs(tvb
, offset
+ P_DST_REF
);
1087 /* normal DT with ATN Extended Checksum (4 octets)*/
1088 case LI_ATN_NORMAL_DT_WITH_CHECKSUM
:
1089 if (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_NDT
) != VP_ATN_EC_32
)
1092 tpdu_nr
= tvb_get_guint8(tvb
, offset
+ P_TPDU_NR_234
);
1095 tpdu_nr
= tpdu_nr
& 0x7F;
1098 is_extended
= FALSE
;
1099 dst_ref
= tvb_get_ntohs(tvb
, offset
+ P_DST_REF
);
1102 /* extended DT with 4 octets ATN Extended Checksum */
1103 case LI_ATN_EXTENDED_DT_WITH_CHECKSUM
:
1104 if (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_EDT
) != VP_ATN_EC_32
)
1107 tpdu_nr
= tvb_get_ntohl(tvb
, offset
+ P_TPDU_NR_234
);
1108 if (tpdu_nr
& 0x80000000)
1109 tpdu_nr
= tpdu_nr
& 0x7FFFFFFF;
1113 dst_ref
= tvb_get_ntohs(tvb
, offset
+ P_DST_REF
);
1116 default : /* bad TPDU */
1119 } /* cotp_decode_atn */
1121 pinfo
->clnp_dstref
= dst_ref
;
1123 pinfo
->fragmented
= fragment
;
1125 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "DT TPDU (%u) dst-ref: 0x%04x",
1128 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "DT TPDU (%u)", tpdu_nr
);
1132 ti
= proto_tree_add_item(tree
, proto_cotp
, tvb
, offset
, li
+ 1, ENC_NA
);
1133 cotp_tree
= proto_item_add_subtree(ti
, ett_cotp
);
1134 proto_tree_add_uint(cotp_tree
, hf_cotp_li
, tvb
, offset
, 1,li
);
1139 proto_tree_add_uint(cotp_tree
, hf_cotp_type
, tvb
, offset
, 1, tpdu
);
1146 proto_tree_add_uint(cotp_tree
, hf_cotp_destref
, tvb
, offset
, 2, dst_ref
);
1150 ti
= proto_tree_add_uint (cotp_tree
, hf_cotp_destref
, tvb
, offset
, 0,
1152 PROTO_ITEM_SET_GENERATED (ti
);
1157 proto_tree_add_uint(cotp_tree
, hf_cotp_tpdu_number_extended
, tvb
, offset
,
1159 proto_tree_add_item(cotp_tree
, hf_cotp_eot_extended
, tvb
, offset
, 4,
1166 proto_tree_add_uint(cotp_tree
, hf_cotp_tpdu_number
, tvb
, offset
, 1,
1168 proto_tree_add_item(cotp_tree
, hf_cotp_eot
, tvb
, offset
, 1,
1176 ositp_decode_var_part(tvb
, offset
, li
, 4, tpdu_len
, pinfo
, cotp_tree
);
1179 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1180 fragment_length
= tvb_length(next_tvb
);
1182 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " [COTP fragment, %u byte%s]",
1183 fragment_length
, plurality(fragment_length
, "", "s"));
1185 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " EOT");
1188 if (cotp_reassemble
) {
1190 * XXX - these sequence numbers are connection sequence number,
1191 * not segment sequence numbers - the first segment of a
1192 * segmented packet doesn't have a specific sequence number (e.g., 0
1193 * or 1), it has whatever the appropriate sequence number is for
1194 * it in the connection.
1196 * For now, we assume segments arrive in order, and just supply
1197 * the negation of the EOT flag as the "more flags" argument.
1198 * We should probably handle out-of-order packets separately,
1199 * so that we can deliver them in order even when *not*
1202 * Note also that TP0 has no sequence number, and relies on
1203 * the protocol atop which it runs to guarantee in-order delivery.
1205 fd_head
= fragment_add_seq_next(&cotp_reassembly_table
, next_tvb
, 0, pinfo
,
1206 dst_ref
, NULL
, fragment_length
, fragment
);
1207 if (fd_head
&& fd_head
->next
) {
1208 /* don't use -1 if fragment length is zero (throws Exception) */
1209 proto_tree_add_text(cotp_tree
, tvb
, offset
, (fragment_length
) ? -1 : 0,
1210 "COTP segment data (%u byte%s)", fragment_length
,
1211 plurality(fragment_length
, "", "s"));
1214 /* This is the last packet */
1215 next_tvb
= process_reassembled_data (next_tvb
, offset
, pinfo
,
1216 "Reassembled COTP", fd_head
,
1217 &cotp_frag_items
, NULL
, tree
);
1218 } else if (pinfo
->fd
->num
!= fd_head
->reassembled_in
) {
1219 /* Add a "Reassembled in" link if not reassembled in this frame */
1220 proto_tree_add_uint(cotp_tree
, *(cotp_frag_items
.hf_reassembled_in
),
1221 next_tvb
, 0, 0, fd_head
->reassembled_in
);
1223 pinfo
->fragmented
= fragment
;
1227 if (uses_inactive_subset
) {
1228 if (dissector_try_heuristic(cotp_is_heur_subdissector_list
, next_tvb
,
1229 pinfo
, tree
, NULL
)) {
1230 *subdissector_found
= TRUE
;
1232 /* Fill in other Dissectors using inactive subset here */
1233 call_dissector(data_handle
,next_tvb
, pinfo
, tree
);
1237 * We dissect payload if one of the following is TRUE:
1239 * - Reassembly option for COTP in preferences is unchecked
1240 * - Reassembly option is checked and this packet is the last fragment
1242 if ((!cotp_reassemble
) || ((cotp_reassemble
) && (!fragment
))) {
1243 if (dissector_try_heuristic(cotp_heur_subdissector_list
, next_tvb
, pinfo
,
1245 *subdissector_found
= TRUE
;
1247 call_dissector(data_handle
,next_tvb
, pinfo
, tree
);
1252 offset
+= tvb_length_remaining(tvb
, offset
);
1253 /* we dissected all of the containing PDU */
1257 } /* ositp_decode_DT */
1259 static int ositp_decode_ED(tvbuff_t
*tvb
, int offset
, guint8 li
, guint8 tpdu
,
1260 packet_info
*pinfo
, proto_tree
*tree
)
1262 proto_tree
*cotp_tree
= NULL
;
1264 gboolean is_extended
;
1270 /* ED TPDUs have user data, so they run to the end of the containing PDU */
1271 tpdu_len
= tvb_reported_length_remaining(tvb
, offset
);
1273 /* note: in the ATN the user is up to chose between 3 different checksums:
1274 * standard OSI, 2 or 4 octet extended checksum.
1275 * The differences for ED (as for DT) are that the TPDU headers may be
1276 * enlarged by 2 octets and that checksum related option codes and option
1277 * lengths are different. To not mess up the original OSI dissector LI
1278 * checking was implemented separately.
1280 * note: this could not be tested, because no sample was avail for expedited
1282 if (!cotp_decode_atn
) { /* non ATN, plain OSI*/
1283 /* ED TPDUs are never fragmented */
1285 /* VP_CHECKSUM is the only parameter allowed in the variable part.
1286 (This means we may misdissect this if the packet is bad and
1287 contains other parameters.) */
1290 case LI_NORMAL_DT_WITH_CHECKSUM
:
1291 if (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_NDT
) != VP_CHECKSUM
)
1295 case LI_NORMAL_DT_WITHOUT_CHECKSUM
:
1296 tpdu_nr
= tvb_get_guint8(tvb
, offset
+ P_TPDU_NR_234
);
1298 tpdu_nr
= tpdu_nr
& 0x7F;
1301 is_extended
= FALSE
;
1304 case LI_EXTENDED_DT_WITH_CHECKSUM
:
1305 if (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_EDT
) != VP_CHECKSUM
)
1309 case LI_EXTENDED_DT_WITHOUT_CHECKSUM
:
1310 tpdu_nr
= tvb_get_ntohl(tvb
, offset
+ P_TPDU_NR_234
);
1311 if (tpdu_nr
& 0x80000000)
1312 tpdu_nr
= tpdu_nr
& 0x7FFFFFFF;
1318 default : /* bad TPDU */
1322 /* check packet length indicators of ATN Expedited Data (ED) TPDU
1323 * note: use of checksum depends on the selected RER
1324 * (high:non-use medium:16-bit OSI/16-bit ext.ATN low:32-bit ext. ATN)
1326 * note: sole use of TP4 class in the ATN
1327 * note: normal/extended TPDU numbering is negociable */
1330 case LI_NORMAL_DT_WITHOUT_CHECKSUM
:
1331 tpdu_nr
= tvb_get_guint8(tvb
, offset
+ P_TPDU_NR_234
);
1333 tpdu_nr
= tpdu_nr
& 0x7F;
1336 is_extended
= FALSE
;
1339 case LI_NORMAL_DT_WITH_CHECKSUM
:
1340 if ((tvb_get_guint8(tvb
, offset
+ P_VAR_PART_NDT
) != VP_CHECKSUM
) &&
1341 (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_NDT
) != VP_ATN_EC_16
))
1344 tpdu_nr
= tvb_get_guint8(tvb
, offset
+ P_TPDU_NR_234
);
1346 tpdu_nr
= tpdu_nr
& 0x7F;
1349 is_extended
= FALSE
;
1352 case LI_ATN_NORMAL_DT_WITH_CHECKSUM
:
1353 if (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_NDT
) != VP_ATN_EC_32
)
1356 tpdu_nr
= tvb_get_guint8(tvb
, offset
+ P_TPDU_NR_234
);
1358 tpdu_nr
= tpdu_nr
& 0x7F;
1361 is_extended
= FALSE
;
1364 case LI_EXTENDED_DT_WITHOUT_CHECKSUM
:
1365 tpdu_nr
= tvb_get_ntohl(tvb
, offset
+ P_TPDU_NR_234
);
1366 if (tpdu_nr
& 0x80000000)
1367 tpdu_nr
= tpdu_nr
& 0x7FFFFFFF;
1373 case LI_EXTENDED_DT_WITH_CHECKSUM
:
1374 if ((tvb_get_guint8(tvb
, offset
+ P_VAR_PART_EDT
) != VP_CHECKSUM
) &&
1375 (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_EDT
) != VP_ATN_EC_16
))
1378 tpdu_nr
= tvb_get_ntohl(tvb
, offset
+ P_TPDU_NR_234
);
1379 if (tpdu_nr
& 0x80000000)
1380 tpdu_nr
= tpdu_nr
& 0x7FFFFFFF;
1386 case LI_ATN_EXTENDED_DT_WITH_CHECKSUM
:
1387 if (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_EDT
) != VP_ATN_EC_32
)
1390 tpdu_nr
= tvb_get_ntohl(tvb
, offset
+ P_TPDU_NR_234
);
1391 if (tpdu_nr
& 0x80000000)
1392 tpdu_nr
= tpdu_nr
& 0x7FFFFFFF;
1398 default : /* bad TPDU */
1401 } /* cotp_decode_atn */
1403 dst_ref
= tvb_get_ntohs(tvb
, offset
+ P_DST_REF
);
1404 pinfo
->clnp_dstref
= dst_ref
;
1406 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "ED TPDU (%u) dst-ref: 0x%04x",
1410 ti
= proto_tree_add_item(tree
, proto_cotp
, tvb
, offset
, li
+ 1, ENC_NA
);
1411 cotp_tree
= proto_item_add_subtree(ti
, ett_cotp
);
1412 proto_tree_add_uint(cotp_tree
, hf_cotp_li
, tvb
, offset
, 1,li
);
1417 proto_tree_add_uint(cotp_tree
, hf_cotp_type
, tvb
, offset
, 1, tpdu
);
1423 proto_tree_add_uint(cotp_tree
, hf_cotp_destref
, tvb
, offset
, 2, dst_ref
);
1429 proto_tree_add_uint(cotp_tree
, hf_cotp_tpdu_number_extended
, tvb
, offset
,
1436 proto_tree_add_uint(cotp_tree
, hf_cotp_tpdu_number
, tvb
, offset
, 1,
1444 ositp_decode_var_part(tvb
, offset
, li
, 4, tpdu_len
, pinfo
, cotp_tree
);
1448 * XXX - hand this to subdissectors but tell them that this is
1451 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1452 call_dissector(data_handle
,next_tvb
, pinfo
, tree
);
1454 offset
+= tvb_length_remaining(tvb
, offset
);
1455 /* we dissected all of the containing PDU */
1459 } /* ositp_decode_ED */
1461 static int ositp_decode_RJ(tvbuff_t
*tvb
, int offset
, guint8 li
, guint8 tpdu
,
1462 guint8 cdt
, packet_info
*pinfo
, proto_tree
*tree
)
1464 proto_tree
*cotp_tree
;
1466 proto_item
*item
= NULL
;
1471 /* note: in the ATN the user is up to chose between 3 different checksums:
1472 * standard OSI, 2 or 4 octet extended checksum.
1473 * The difference for RJ is that the TPDU header may be enlarged by 2 octets
1474 * for checksum parameters are not going to be checked here */
1475 if (!cotp_decode_atn
) { /* non ATN, plain OSI */
1478 tpdu_nr
= tvb_get_guint8(tvb
, offset
+ P_TPDU_NR_234
);
1480 case LI_EXTENDED_RJ
:
1481 tpdu_nr
= tvb_get_ntohl(tvb
, offset
+ P_TPDU_NR_234
);
1482 credit
= tvb_get_ntohs(tvb
, offset
+ P_CDT_IN_RJ
);
1489 /* normal with 2 octets of OSI or ATN checksum */
1491 /* with 4 octets of ATN checksum */
1492 case LI_ATN_NORMAL_RJ
:
1493 tpdu_nr
= tvb_get_guint8(tvb
, offset
+ P_TPDU_NR_234
);
1495 /* extended with 2 octets of OSI or ATN checksum */
1496 case LI_EXTENDED_RJ
:
1497 /* with 4 octets of ATN checksum */
1498 case LI_ATN_EXTENDED_RJ
:
1499 tpdu_nr
= tvb_get_ntohl(tvb
, offset
+ P_TPDU_NR_234
);
1500 credit
= tvb_get_ntohs(tvb
, offset
+ P_CDT_IN_RJ
);
1507 dst_ref
= tvb_get_ntohs(tvb
, offset
+ P_DST_REF
);
1508 pinfo
->clnp_dstref
= dst_ref
;
1510 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "RJ TPDU (%u) dst-ref: 0x%04x",
1514 ti
= proto_tree_add_item(tree
, proto_cotp
, tvb
, offset
, li
+ 1, ENC_NA
);
1515 cotp_tree
= proto_item_add_subtree(ti
, ett_cotp
);
1516 proto_tree_add_uint(cotp_tree
, hf_cotp_li
, tvb
, offset
, 1,li
);
1517 item
= proto_tree_add_uint(cotp_tree
, hf_cotp_type
, tvb
, offset
+ 1, 1,
1519 if (li
== LI_NORMAL_RJ
)
1520 proto_tree_add_text(cotp_tree
, tvb
, offset
+ 1, 1, "Credit: %u", cdt
);
1521 proto_tree_add_uint(cotp_tree
, hf_cotp_destref
, tvb
, offset
+ 2, 2,
1523 if (li
== LI_NORMAL_RJ
)
1524 proto_tree_add_uint(cotp_tree
, hf_cotp_next_tpdu_number
, tvb
, offset
+ 4,
1527 proto_tree_add_uint(cotp_tree
, hf_cotp_next_tpdu_number_extended
, tvb
,
1528 offset
+ 4, 4, tpdu_nr
);
1529 proto_tree_add_text(cotp_tree
, tvb
, offset
+ 8, 2, "Credit: 0x%02x",
1536 expert_add_info_format(pinfo
, item
, &ei_cotp_reject
, "Reject(RJ): -> 0x%x", dst_ref
);
1540 } /* ositp_decode_RJ */
1542 static int ositp_decode_CC(tvbuff_t
*tvb
, int offset
, guint8 li
, guint8 tpdu
,
1543 packet_info
*pinfo
, proto_tree
*tree
,
1544 gboolean uses_inactive_subset
,
1545 gboolean
*subdissector_found
)
1547 /* note: in the ATN the user is up to chose between 3 different checksums:
1548 * standard OSI, 2 or 4 octet extended checksum.
1549 * Nothing has to be done here, for all ATN specifics are handled in VP. */
1551 /* CC & CR decoding in the same function */
1553 proto_tree
*cotp_tree
= NULL
;
1555 proto_item
*item
= NULL
;
1556 guint16 dst_ref
, src_ref
;
1557 guint8 class_option
;
1561 src_ref
= tvb_get_ntohs(tvb
, offset
+ P_SRC_REF
);
1563 class_option
= tvb_get_guint8(tvb
, offset
+ P_CLASS_OPTION
);
1564 if (((class_option
& 0xF0) >> 4) > 4) /* class 0..4 allowed */
1567 /* CR and CC TPDUs can have user data, so they run to the end of the
1569 tpdu_len
= tvb_reported_length_remaining(tvb
, offset
);
1571 dst_ref
= tvb_get_ntohs(tvb
, offset
+ P_DST_REF
);
1572 pinfo
->clnp_srcref
= src_ref
;
1573 pinfo
->clnp_dstref
= dst_ref
;
1575 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
1576 "%s TPDU src-ref: 0x%04x dst-ref: 0x%04x",
1577 (tpdu
== CR_TPDU
) ? "CR" : "CC", src_ref
, dst_ref
);
1580 ti
= proto_tree_add_item(tree
, proto_cotp
, tvb
, offset
, li
+ 1, ENC_NA
);
1581 cotp_tree
= proto_item_add_subtree(ti
, ett_cotp
);
1582 proto_tree_add_uint(cotp_tree
, hf_cotp_li
, tvb
, offset
, 1,li
);
1587 item
= proto_tree_add_uint(cotp_tree
, hf_cotp_type
, tvb
, offset
, 1, tpdu
);
1593 proto_tree_add_uint(cotp_tree
, hf_cotp_destref
, tvb
, offset
, 2, dst_ref
);
1598 proto_tree_add_uint(cotp_tree
, hf_cotp_srcref
, tvb
, offset
, 2, src_ref
);
1602 /* expert info, but only if not encapsulated in TCP/SMB */
1603 /* XXX - the best way to detect seems to be if we have a port set */
1604 if (pinfo
->destport
== 0) {
1605 expert_add_info_format(pinfo
, item
, &ei_cotp_connection
, "Connection %s: 0x%x -> 0x%x", tpdu
== CR_TPDU
? "Request(CR)" : "Confirm(CC)", src_ref
, dst_ref
);
1609 proto_tree_add_uint(cotp_tree
, hf_cotp_class
, tvb
, offset
, 1, class_option
);
1610 proto_tree_add_boolean(cotp_tree
, hf_cotp_opts_extended_formats
, tvb
,
1611 offset
, 1, class_option
);
1612 proto_tree_add_boolean(cotp_tree
, hf_cotp_opts_no_explicit_flow_control
,
1613 tvb
, offset
, 1, class_option
);
1619 /* Microsoft runs their Remote Desktop Protocol atop ISO COTP
1620 atop TPKT, and does some weird stuff in the CR packet:
1622 http://msdn.microsoft.com/en-us/library/cc240470
1624 where they might stuff a string that begins with "Cookie: ",
1625 possibly followed by an RDP Negotiation Request, into the
1626 variable part of the CR packet. (See also
1628 http://download.microsoft.com/download/5/B/C/5BC37A4E-6304-45AB-8C2D-AE712526E7F7/TS_Session_Directory.pdf
1630 a/k/a "[MSFT-SDLBTS]", as linked to, under the name "Session
1631 Directory and Load Balancing Using Terminal Server", on
1633 http://msdn.microsoft.com/en-us/library/E4BD6494-06AD-4aed-9823-445E921C9624
1635 which indicates that the routingToken is a string of the form
1636 "Cookie: msts=...".)
1638 They also may stuff an RDP Negotiation Response into the CC
1641 XXX - have TPKT know that a given session is an RDP session,
1642 and let us know, so we know whether to check for this stuff. */
1643 ositp_decode_var_part(tvb
, offset
, li
, class_option
, tpdu_len
, pinfo
,
1649 * XXX - tell the subdissector that this is user data in a CC or
1650 * CR packet rather than a DT packet?
1652 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1653 if (!uses_inactive_subset
){
1654 if (dissector_try_heuristic(cotp_heur_subdissector_list
, next_tvb
, pinfo
,
1656 *subdissector_found
= TRUE
;
1658 call_dissector(data_handle
,next_tvb
, pinfo
, tree
);
1662 call_dissector(data_handle
, next_tvb
, pinfo
, tree
);
1663 offset
+= tvb_length_remaining(tvb
, offset
);
1664 /* we dissected all of the containing PDU */
1668 } /* ositp_decode_CC */
1670 static int ositp_decode_DC(tvbuff_t
*tvb
, int offset
, guint8 li
, guint8 tpdu
,
1671 packet_info
*pinfo
, proto_tree
*tree
)
1673 proto_tree
*cotp_tree
= NULL
;
1675 proto_item
*item
= NULL
;
1676 guint16 dst_ref
, src_ref
;
1679 /* ATN may use checksums different from OSI */
1680 /* which may result in different TPDU header length. */
1681 if (!cotp_decode_atn
) {
1685 if (li
> LI_ATN_MAX_DC
)
1689 /* DC TPDUs have no user data, so the length indicator determines the
1693 dst_ref
= tvb_get_ntohs(tvb
, offset
+ P_DST_REF
);
1694 src_ref
= tvb_get_ntohs(tvb
, offset
+ P_SRC_REF
);
1695 pinfo
->clnp_dstref
= dst_ref
;
1696 pinfo
->clnp_dstref
= src_ref
;
1698 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
1699 "DC TPDU src-ref: 0x%04x dst-ref: 0x%04x", src_ref
, dst_ref
);
1702 ti
= proto_tree_add_item(tree
, proto_cotp
, tvb
, offset
, li
+ 1, ENC_NA
);
1703 cotp_tree
= proto_item_add_subtree(ti
, ett_cotp
);
1704 proto_tree_add_uint(cotp_tree
, hf_cotp_li
, tvb
, offset
, 1,li
);
1709 item
= proto_tree_add_uint(cotp_tree
, hf_cotp_type
, tvb
, offset
, 1, tpdu
);
1715 proto_tree_add_uint(cotp_tree
, hf_cotp_destref
, tvb
, offset
, 2, dst_ref
);
1720 proto_tree_add_uint(cotp_tree
, hf_cotp_srcref
, tvb
, offset
, 2, src_ref
);
1725 ositp_decode_var_part(tvb
, offset
, li
, 4, tpdu_len
, pinfo
, cotp_tree
);
1728 expert_add_info_format(pinfo
, item
, &ei_cotp_disconnect_confirm
, "Disconnect Confirm(DC): 0x%x -> 0x%x", src_ref
, dst_ref
);
1732 } /* ositp_decode_DC */
1734 static int ositp_decode_AK(tvbuff_t
*tvb
, int offset
, guint8 li
, guint8 tpdu
,
1735 guint8 cdt
, packet_info
*pinfo
, proto_tree
*tree
)
1737 proto_tree
*cotp_tree
= NULL
;
1744 if (!cotp_decode_atn
) {
1748 if (li
> LI_ATN_MAX_AK
)
1752 /* AK TPDUs have no user data, so the length indicator determines the
1756 /* is_LI_NORMAL_AK() works for normal ATN AK's, */
1757 /* for the TPDU header size may be enlarged by 2 octets */
1758 if (is_LI_NORMAL_AK(li
)) {
1760 dst_ref
= tvb_get_ntohs(tvb
, offset
+ P_DST_REF
);
1761 tpdu_nr
= tvb_get_guint8(tvb
, offset
+ P_TPDU_NR_234
);
1762 pinfo
->clnp_dstref
= dst_ref
;
1764 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "AK TPDU (%u) dst-ref: 0x%04x",
1768 ti
= proto_tree_add_item(tree
, proto_cotp
, tvb
, offset
, li
+ 1, ENC_NA
);
1769 cotp_tree
= proto_item_add_subtree(ti
, ett_cotp
);
1770 proto_tree_add_uint(cotp_tree
, hf_cotp_li
, tvb
, offset
, 1,li
);
1775 proto_tree_add_uint(cotp_tree
, hf_cotp_type
, tvb
, offset
, 1, tpdu
);
1776 proto_tree_add_text(cotp_tree
, tvb
, offset
, 1, "Credit: %u", cdt
);
1782 proto_tree_add_uint(cotp_tree
, hf_cotp_destref
, tvb
, offset
, 2, dst_ref
);
1787 proto_tree_add_uint(cotp_tree
, hf_cotp_next_tpdu_number
, tvb
, offset
, 1,
1794 ositp_decode_var_part(tvb
, offset
, li
, 4, tpdu_len
, pinfo
, cotp_tree
);
1797 } else { /* extended format */
1799 dst_ref
= tvb_get_ntohs(tvb
, offset
+ P_DST_REF
);
1800 tpdu_nr
= tvb_get_ntohl(tvb
, offset
+ P_TPDU_NR_234
);
1801 cdt_in_ak
= tvb_get_ntohs(tvb
, offset
+ P_CDT_IN_AK
);
1802 pinfo
->clnp_dstref
= dst_ref
;
1804 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
1805 "AK TPDU (%u) dst-ref: 0x%04x Credit: %u",
1806 tpdu_nr
, dst_ref
, cdt_in_ak
);
1809 ti
= proto_tree_add_item(tree
, proto_cotp
, tvb
, offset
, li
+ 1, ENC_NA
);
1810 cotp_tree
= proto_item_add_subtree(ti
, ett_cotp
);
1811 proto_tree_add_uint(cotp_tree
, hf_cotp_li
, tvb
, offset
, 1,li
);
1816 proto_tree_add_uint(cotp_tree
, hf_cotp_type
, tvb
, offset
, 1, tpdu
);
1822 proto_tree_add_uint(cotp_tree
, hf_cotp_destref
, tvb
, offset
, 2, dst_ref
);
1827 proto_tree_add_uint(cotp_tree
, hf_cotp_next_tpdu_number_extended
, tvb
,
1828 offset
, 4, tpdu_nr
);
1834 proto_tree_add_text(cotp_tree
, tvb
, offset
, 2, "Credit: 0x%04x",
1841 ositp_decode_var_part(tvb
, offset
, li
, 4, tpdu_len
, pinfo
, cotp_tree
);
1844 } /* is_LI_NORMAL_AK */
1848 } /* ositp_decode_AK */
1850 static int ositp_decode_EA(tvbuff_t
*tvb
, int offset
, guint8 li
, guint8 tpdu
,
1851 packet_info
*pinfo
, proto_tree
*tree
)
1853 proto_tree
*cotp_tree
= NULL
;
1855 gboolean is_extended
;
1860 /* Due to different checksums in the ATN the TPDU header sizes
1861 * as well as the checksum parameters may be different than plain OSI EA
1862 * because these are heavily checked for EA these checks had to be
1864 * note: this could not be tested, because no sample was avail for expedited
1866 if (!cotp_decode_atn
) {
1870 /* VP_CHECKSUM is the only parameter allowed in the variable part.
1871 (This means we may misdissect this if the packet is bad and
1872 contains other parameters.) */
1875 case LI_NORMAL_EA_WITH_CHECKSUM
:
1876 if (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_NDT
) != VP_CHECKSUM
||
1877 tvb_get_guint8(tvb
, offset
+ P_VAR_PART_NDT
+ 1) != 2)
1881 case LI_NORMAL_EA_WITHOUT_CHECKSUM
:
1882 tpdu_nr
= tvb_get_guint8(tvb
, offset
+ P_TPDU_NR_234
);
1883 is_extended
= FALSE
;
1886 case LI_EXTENDED_EA_WITH_CHECKSUM
:
1887 if (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_EDT
) != VP_CHECKSUM
||
1888 tvb_get_guint8(tvb
, offset
+ P_VAR_PART_EDT
+ 1) != 2)
1892 case LI_EXTENDED_EA_WITHOUT_CHECKSUM
:
1893 tpdu_nr
= tvb_get_ntohl(tvb
, offset
+ P_TPDU_NR_234
);
1897 default : /* bad TPDU */
1900 } else { /* cotp_decode_atn */
1901 /* check for ATN length: TPDU may be 2 octets longer due to checksum */
1902 if (li
> LI_ATN_MAX_EA
)
1907 /* extended TPDU numbering EA with no checksum */
1908 case LI_NORMAL_EA_WITHOUT_CHECKSUM
:
1909 tpdu_nr
= tvb_get_guint8(tvb
, offset
+ P_TPDU_NR_234
);
1910 is_extended
= FALSE
;
1913 /* normal TPDU numbering EA with 2 octets of OSI or ATN extended
1915 case LI_NORMAL_EA_WITH_CHECKSUM
:
1916 /* check checksum parameter (in VP) parameter code octet */
1917 if ((tvb_get_guint8(tvb
, offset
+ P_VAR_PART_NDT
) != VP_CHECKSUM
) &&
1918 (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_NDT
) != VP_ATN_EC_16
))
1921 /* check checksum parameter (in VP) length octet */
1922 if (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_NDT
+ 1) != 2)
1925 tpdu_nr
= tvb_get_guint8(tvb
, offset
+ P_TPDU_NR_234
);
1926 is_extended
= FALSE
;
1929 /* normal TPDU numbering EA with 4 octets of ATN extended checksum */
1930 case LI_ATN_NORMAL_EA_WITH_CHECKSUM
:
1931 /* check checksum parameter (in VP) parameter code octet */
1932 if (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_NDT
) != VP_ATN_EC_32
)
1935 /* check checksum parameter (in VP) length octet */
1936 if (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_NDT
+ 1) != 4)
1939 tpdu_nr
= tvb_get_guint8(tvb
, offset
+ P_TPDU_NR_234
);
1940 is_extended
= FALSE
;
1943 /* extended TPDU numbering EA with no checksum */
1944 case LI_EXTENDED_EA_WITHOUT_CHECKSUM
:
1945 tpdu_nr
= tvb_get_ntohl(tvb
, offset
+ P_TPDU_NR_234
);
1949 /* extended TPDU numbering EA with 2 octets of OSI or ATN extended
1951 case LI_EXTENDED_EA_WITH_CHECKSUM
:
1952 /* check checksum parameter (in VP) parameter code octet */
1953 if ((tvb_get_guint8(tvb
, offset
+ P_VAR_PART_EDT
) != VP_CHECKSUM
) &&
1954 (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_EDT
) != VP_ATN_EC_16
))
1957 /* check checksum parameter (in VP) length octet */
1958 if (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_EDT
+ 1) != 2)
1961 tpdu_nr
= tvb_get_ntohl(tvb
, offset
+ P_TPDU_NR_234
);
1965 /* extended EA with 4 octets ATN extended checksum */
1966 case LI_ATN_EXTENDED_EA_WITH_CHECKSUM
:
1967 /* check checksum parameter (in VP) parameter code octet */
1968 if (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_EDT
) != VP_ATN_EC_32
)
1971 /* check checksum parameter (in VP) length octet */
1972 if (tvb_get_guint8(tvb
, offset
+ P_VAR_PART_EDT
+ 1) != 2)
1975 tpdu_nr
= tvb_get_ntohl(tvb
, offset
+ P_TPDU_NR_234
);
1979 default : /* bad TPDU */
1984 /* ER TPDUs have no user data, so the length indicator determines the
1988 dst_ref
= tvb_get_ntohs(tvb
, offset
+ P_DST_REF
);
1989 pinfo
->clnp_dstref
= dst_ref
;
1991 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "EA TPDU (%u) dst-ref: 0x%04x",
1995 ti
= proto_tree_add_item(tree
, proto_cotp
, tvb
, offset
, li
+ 1, ENC_NA
);
1996 cotp_tree
= proto_item_add_subtree(ti
, ett_cotp
);
1997 proto_tree_add_uint(cotp_tree
, hf_cotp_li
, tvb
, offset
, 1,li
);
2002 proto_tree_add_uint(cotp_tree
, hf_cotp_type
, tvb
, offset
, 1, tpdu
);
2008 proto_tree_add_uint(cotp_tree
, hf_cotp_destref
, tvb
, offset
, 2, dst_ref
);
2014 proto_tree_add_uint(cotp_tree
, hf_cotp_next_tpdu_number_extended
, tvb
,
2015 offset
, 4, tpdu_nr
);
2021 proto_tree_add_uint(cotp_tree
, hf_cotp_next_tpdu_number
, tvb
, offset
, 1,
2029 ositp_decode_var_part(tvb
, offset
, li
, 4, tpdu_len
, pinfo
, cotp_tree
);
2034 } /* ositp_decode_EA */
2036 static int ositp_decode_ER(tvbuff_t
*tvb
, int offset
, guint8 li
, guint8 tpdu
,
2037 packet_info
*pinfo
, proto_tree
*tree
)
2039 proto_tree
*cotp_tree
= NULL
;
2045 /* ATN: except for modified LI checking nothing to be done here */
2046 if (!cotp_decode_atn
) {
2050 if (li
> LI_ATN_MAX_ER
)
2054 /* ER TPDUs have no user data, so the length indicator determines the
2058 switch(tvb_get_guint8(tvb
, offset
+ P_REJECT_ER
)) {
2060 str
= "Reason not specified";
2063 str
= "Invalid parameter code";
2066 str
= "Invalid TPDU type";
2069 str
= "Invalid parameter value";
2075 dst_ref
= tvb_get_ntohs(tvb
, offset
+ P_DST_REF
);
2076 pinfo
->clnp_dstref
= dst_ref
;
2078 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "ER TPDU dst-ref: 0x%04x", dst_ref
);
2081 ti
= proto_tree_add_item(tree
, proto_cotp
, tvb
, offset
, li
+ 1, ENC_NA
);
2082 cotp_tree
= proto_item_add_subtree(ti
, ett_cotp
);
2083 proto_tree_add_uint(cotp_tree
, hf_cotp_li
, tvb
, offset
, 1,li
);
2084 proto_tree_add_uint(cotp_tree
, hf_cotp_type
, tvb
, offset
+ 1, 1, tpdu
);
2085 proto_tree_add_uint(cotp_tree
, hf_cotp_destref
, tvb
, offset
+ 2, 2,
2087 proto_tree_add_text(cotp_tree
, tvb
, offset
+ 4, 1, "Reject cause: %s",
2094 ositp_decode_var_part(tvb
, offset
, li
, 4, tpdu_len
, pinfo
, cotp_tree
);
2099 } /* ositp_decode_ER */
2101 static int ositp_decode_UD(tvbuff_t
*tvb
, int offset
, guint8 li
, guint8 tpdu
,
2102 packet_info
*pinfo
, proto_tree
*tree
,
2103 gboolean
*subdissector_found
)
2106 proto_tree
*cltp_tree
= NULL
;
2110 /* UD TPDUs have user data, so they run to the end of the containing PDU */
2111 tpdu_len
= tvb_reported_length_remaining(tvb
, offset
);
2113 col_append_str(pinfo
->cinfo
, COL_INFO
, "UD TPDU");
2116 ti
= proto_tree_add_item(tree
, proto_cltp
, tvb
, offset
, li
+ 1, ENC_NA
);
2117 cltp_tree
= proto_item_add_subtree(ti
, ett_cltp
);
2118 proto_tree_add_uint(cltp_tree
, hf_cltp_li
, tvb
, offset
, 1,li
);
2123 proto_tree_add_uint(cltp_tree
, hf_cltp_type
, tvb
, offset
, 1, tpdu
);
2129 ositp_decode_var_part(tvb
, offset
, li
, 0, tpdu_len
, pinfo
, cltp_tree
);
2132 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
2134 if (dissector_try_heuristic(cltp_heur_subdissector_list
, next_tvb
,
2135 pinfo
, tree
, NULL
)) {
2136 *subdissector_found
= TRUE
;
2138 call_dissector(data_handle
,next_tvb
, pinfo
, tree
);
2142 /*call_dissector(data_handle,next_tvb, pinfo, tree); */
2144 offset
+= tvb_length_remaining(tvb
, offset
);
2145 /* we dissected all of the containing PDU */
2149 } /* ositp_decode_UD */
2151 /* Returns the offset past the last valid COTP or CLTP PDU if we found
2152 at least one valid COTP or CLTP PDU, 0 otherwise.
2154 There doesn't seem to be any way in which the OSI network layer protocol
2155 distinguishes between COTP and CLTP, but the first two octets of both
2156 protocols' headers mean the same thing - length and PDU type - and the
2157 only valid CLTP PDU type is not a valid COTP PDU type, so we'll handle
2158 both of them here. */
2159 static gint
dissect_ositp_internal(tvbuff_t
*tvb
, packet_info
*pinfo
,
2161 gboolean uses_inactive_subset
)
2164 guint8 li
, tpdu
, cdt
;
2165 gboolean first_tpdu
= TRUE
;
2167 gboolean found_ositp
= FALSE
;
2168 gboolean is_cltp
= FALSE
;
2169 gboolean subdissector_found
= FALSE
;
2171 if (!proto_is_protocol_enabled(find_protocol_by_id(proto_cotp
)))
2172 return FALSE
; /* COTP has been disabled */
2173 /* XXX - what about CLTP? */
2175 pinfo
->current_proto
= "COTP";
2177 /* Initialize the COL_INFO field; each of the TPDUs will have its
2178 information appended. */
2179 col_set_str(pinfo
->cinfo
, COL_INFO
, "");
2181 while (tvb_offset_exists(tvb
, offset
)) {
2183 col_append_str(pinfo
->cinfo
, COL_INFO
, ", ");
2184 expert_add_info(pinfo
, NULL
, &ei_cotp_multiple_tpdus
);
2185 /* adjust tvb and offset to the start of the current PDU */
2186 tvb
= tvb_new_subset_remaining(tvb
, offset
);
2189 if ((li
= tvb_get_guint8(tvb
, offset
+ P_LI
)) == 0) {
2190 col_append_str(pinfo
->cinfo
, COL_INFO
, "Length indicator is zero");
2192 call_dissector(data_handle
, tvb_new_subset_remaining(tvb
, offset
),
2197 tpdu
= (tvb_get_guint8(tvb
, offset
+ P_TPDU
) >> 4) & 0x0F;
2198 if (tpdu
== UD_TPDU
)
2199 pinfo
->current_proto
= "CLTP"; /* connectionless transport */
2200 cdt
= tvb_get_guint8(tvb
, offset
+ P_CDT
) & 0x0F;
2205 new_offset
= ositp_decode_CC(tvb
, offset
, li
, tpdu
, pinfo
, tree
,
2206 uses_inactive_subset
, &subdissector_found
);
2209 new_offset
= ositp_decode_DR(tvb
, offset
, li
, tpdu
, pinfo
, tree
);
2212 new_offset
= ositp_decode_DT(tvb
, offset
, li
, tpdu
, pinfo
, tree
,
2213 uses_inactive_subset
, &subdissector_found
);
2216 new_offset
= ositp_decode_ED(tvb
, offset
, li
, tpdu
, pinfo
, tree
);
2219 new_offset
= ositp_decode_RJ(tvb
, offset
, li
, tpdu
, cdt
, pinfo
, tree
);
2222 new_offset
= ositp_decode_DC(tvb
, offset
, li
, tpdu
, pinfo
, tree
);
2225 new_offset
= ositp_decode_AK(tvb
, offset
, li
, tpdu
, cdt
, pinfo
, tree
);
2228 new_offset
= ositp_decode_EA(tvb
, offset
, li
, tpdu
, pinfo
, tree
);
2231 new_offset
= ositp_decode_ER(tvb
, offset
, li
, tpdu
, pinfo
, tree
);
2234 new_offset
= ositp_decode_UD(tvb
, offset
, li
, tpdu
, pinfo
, tree
,
2235 &subdissector_found
);
2240 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "Unknown TPDU type (0x%x)",
2242 new_offset
= -1; /* bad PDU type */
2246 if (new_offset
== -1) { /* incorrect TPDU */
2248 call_dissector(data_handle
, tvb_new_subset_remaining(tvb
, offset
),
2254 /* Well, we found at least one valid COTP or CLTP PDU, so I guess this
2255 is either COTP or CLTP. */
2256 if (!subdissector_found
)
2257 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, is_cltp
? "CLTP" : "COTP");
2261 offset
= new_offset
;
2264 return found_ositp
? offset
: 0;
2265 } /* dissect_ositp_internal */
2267 static gint
dissect_ositp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
2270 return dissect_ositp_internal(tvb
, pinfo
, tree
, FALSE
);
2273 static gint
dissect_ositp_inactive(tvbuff_t
*tvb
, packet_info
*pinfo
,
2274 proto_tree
*tree
, void *data _U_
)
2276 return dissect_ositp_internal(tvb
, pinfo
, tree
, TRUE
);
2280 cotp_reassemble_init(void)
2283 * XXX - this is a connection-oriented transport-layer protocol,
2284 * so we should probably use more than just network-layer
2285 * endpoint addresses to match segments together, but the functions
2286 * in addresses_ports_reassembly_table_functions do matching based
2287 * on port numbers, so they won't let us ensure that segments from
2288 * different connections don't get assembled together.
2290 reassembly_table_init(&cotp_reassembly_table
,
2291 &addresses_reassembly_table_functions
);
2295 void proto_register_cotp(void)
2297 static hf_register_info hf
[] = {
2299 { "Length", "cotp.li", FT_UINT8
, BASE_DEC
,
2300 NULL
, 0x0, "Length Indicator, length of this header", HFILL
}},
2302 { "PDU Type", "cotp.type", FT_UINT8
, BASE_HEX
,
2303 VALS(cotp_tpdu_type_abbrev_vals
), 0x0,
2304 "PDU Type - upper nibble of byte", HFILL
}},
2306 { "Source reference", "cotp.srcref", FT_UINT16
, BASE_HEX
,
2307 NULL
, 0x0, "Source address reference", HFILL
}},
2309 { "Destination reference", "cotp.destref", FT_UINT16
, BASE_HEX
,
2310 NULL
, 0x0, "Destination address reference", HFILL
}},
2312 { "Class", "cotp.class", FT_UINT8
, BASE_DEC
, NULL
,
2313 0xF0, "Transport protocol class", HFILL
}},
2314 { &hf_cotp_opts_extended_formats
,
2315 { "Extended formats", "cotp.opts.extended_formats", FT_BOOLEAN
, 8,
2316 NULL
, 0x02, "Use of extended formats in classes 2, 3, and 4", HFILL
}},
2317 { &hf_cotp_opts_no_explicit_flow_control
,
2318 { "No explicit flow control", "cotp.opts.no_explicit_flow_control",
2319 FT_BOOLEAN
, 8, NULL
, 0x01, "No explicit flow control in class 2",
2321 { &hf_cotp_tpdu_number
,
2322 { "TPDU number", "cotp.tpdu-number", FT_UINT8
, BASE_HEX
,
2323 NULL
, 0x7f, NULL
, HFILL
}},
2324 { &hf_cotp_tpdu_number_extended
,
2325 { "TPDU number", "cotp.tpdu-number", FT_UINT32
, BASE_HEX
,
2326 NULL
, 0x0 /* XXX - 0x7fff? */, NULL
, HFILL
}},
2327 { &hf_cotp_next_tpdu_number
,
2328 { "Your TPDU number", "cotp.next-tpdu-number", FT_UINT8
, BASE_HEX
,
2329 NULL
, 0x0, NULL
, HFILL
}},
2330 { &hf_cotp_next_tpdu_number_extended
,
2331 { "Your TPDU number", "cotp.next-tpdu-number", FT_UINT32
, BASE_HEX
,
2332 NULL
, 0x0, NULL
, HFILL
}},
2334 { "Last data unit", "cotp.eot", FT_BOOLEAN
, 8,
2335 TFS(&tfs_yes_no
), 0x80,
2336 "Is current TPDU the last data unit of a complete DT TPDU sequence "
2337 "(End of TSDU)?", HFILL
}},
2338 { &hf_cotp_eot_extended
,
2339 { "Last data unit", "cotp.eot", FT_BOOLEAN
, 32,
2340 TFS(&tfs_yes_no
), 0x80000000,
2341 "Is current TPDU the last data unit of a complete DT TPDU sequence "
2342 "(End of TSDU)?", HFILL
}},
2343 { &hf_cotp_segment_overlap
,
2344 { "Segment overlap", "cotp.segment.overlap", FT_BOOLEAN
, BASE_NONE
,
2345 NULL
, 0x0, "Segment overlaps with other segments", HFILL
}},
2346 { &hf_cotp_segment_overlap_conflict
,
2347 { "Conflicting data in segment overlap", "cotp.segment.overlap.conflict",
2348 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
2349 "Overlapping segments contained conflicting data", HFILL
}},
2350 { &hf_cotp_segment_multiple_tails
,
2351 { "Multiple tail segments found", "cotp.segment.multipletails",
2352 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
2353 "Several tails were found when reassembling the packet", HFILL
}},
2354 { &hf_cotp_segment_too_long_segment
,
2355 { "Segment too long", "cotp.segment.toolongsegment",
2356 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
2357 "Segment contained data past end of packet", HFILL
}},
2358 { &hf_cotp_segment_error
,
2359 { "Reassembly error", "cotp.segment.error", FT_FRAMENUM
, BASE_NONE
,
2360 NULL
, 0x0, "Reassembly error due to illegal segments", HFILL
}},
2361 { &hf_cotp_segment_count
,
2362 { "Segment count", "cotp.segment.count", FT_UINT32
, BASE_DEC
,
2363 NULL
, 0x0, NULL
, HFILL
}},
2365 { "COTP Segment", "cotp.segment", FT_FRAMENUM
, BASE_NONE
,
2366 NULL
, 0x0, NULL
, HFILL
}},
2367 { &hf_cotp_segments
,
2368 { "COTP Segments", "cotp.segments", FT_NONE
, BASE_NONE
,
2369 NULL
, 0x0, NULL
, HFILL
}},
2370 { &hf_cotp_reassembled_in
,
2371 { "Reassembled COTP in frame", "cotp.reassembled_in",
2372 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
2373 "This COTP packet is reassembled in this frame", HFILL
}},
2374 { &hf_cotp_reassembled_length
,
2375 { "Reassembled COTP length", "cotp.reassembled.length",
2376 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2377 "The total length of the reassembled payload", HFILL
}},
2378 /* ISO DP 8073 i13.3.4(a) Source and destination TSAPs are defined as
2379 identifiers of unspecified type and length.
2380 Some implementations of COTP use printable strings, others use raw bytes.
2381 We always add both representations to the tree; one will always be hidden
2382 depending on the tsap display preference */
2383 { &hf_cotp_vp_src_tsap
,
2384 { "Source TSAP", "cotp.src-tsap", FT_STRING
, BASE_NONE
,
2385 NULL
, 0x0, "Calling TSAP", HFILL
}},
2386 { &hf_cotp_vp_src_tsap_bytes
,
2387 { "Source TSAP", "cotp.src-tsap-bytes", FT_BYTES
, BASE_NONE
,
2388 NULL
, 0x0, "Calling TSAP (bytes representation)", HFILL
}},
2389 { &hf_cotp_vp_dst_tsap
,
2390 { "Destination TSAP", "cotp.dst-tsap", FT_STRING
, BASE_NONE
,
2391 NULL
, 0x0, "Called TSAP", HFILL
}},
2392 { &hf_cotp_vp_dst_tsap_bytes
,
2393 { "Destination TSAP", "cotp.dst-tsap-bytes", FT_BYTES
, BASE_NONE
,
2394 NULL
, 0x0, "Called TSAP (bytes representation)", HFILL
}}
2396 static gint
*ett
[] = {
2401 static ei_register_info ei
[] = {
2402 { &ei_cotp_disconnect_request
, { "cotp.disconnect_request", PI_SEQUENCE
, PI_CHAT
, "Disconnect Request(DR): 0x%x -> 0x%x", EXPFILL
}},
2403 { &ei_cotp_reject
, { "cotp.reject", PI_SEQUENCE
, PI_NOTE
, "Reject(RJ): -> 0x%x", EXPFILL
}},
2404 { &ei_cotp_connection
, { "cotp.connection", PI_SEQUENCE
, PI_CHAT
, "Connection %s: 0x%x -> 0x%x", EXPFILL
}},
2405 { &ei_cotp_disconnect_confirm
, { "cotp.disconnect_confirm", PI_SEQUENCE
, PI_CHAT
, "Disconnect Confirm(DC): 0x%x -> 0x%x", EXPFILL
}},
2406 { &ei_cotp_multiple_tpdus
, { "cotp.multiple_tpdus", PI_SEQUENCE
, PI_NOTE
, "Multiple TPDUs in one packet", EXPFILL
}},
2409 module_t
*cotp_module
;
2410 expert_module_t
* expert_cotp
;
2412 proto_cotp
= proto_register_protocol(PROTO_STRING_COTP
, "COTP", "cotp");
2413 proto_register_field_array(proto_cotp
, hf
, array_length(hf
));
2414 proto_register_subtree_array(ett
, array_length(ett
));
2415 expert_cotp
= expert_register_protocol(proto_cotp
);
2416 expert_register_field_array(expert_cotp
, ei
, array_length(ei
));
2417 cotp_module
= prefs_register_protocol(proto_cotp
, NULL
);
2419 prefs_register_bool_preference(cotp_module
, "reassemble",
2420 "Reassemble segmented COTP datagrams",
2421 "Whether segmented COTP datagrams should be "
2422 "reassembled. To use this option, you must "
2423 "also enable \"Allow subdissectors to "
2424 "reassemble TCP streams\" in the TCP "
2425 "protocol settings.",
2428 prefs_register_enum_preference(cotp_module
, "tsap_display",
2429 "Display TSAPs as strings or bytes",
2430 "How TSAPs should be displayed",
2431 &tsap_display
, tsap_display_options
, FALSE
);
2433 prefs_register_bool_preference(cotp_module
, "decode_atn", "Decode ATN TPDUs",
2434 "Whether to decode OSI TPDUs with ATN "
2435 "(Aereonautical Telecommunications Network) "
2436 "extensions. To use this option, you must "
2437 "also enable \"Always try to decode NSDU as "
2438 "transport PDUs\" in the CLNP protocol "
2439 "settings.", &cotp_decode_atn
);
2441 /* subdissector code in inactive subset */
2442 register_heur_dissector_list("cotp_is", &cotp_is_heur_subdissector_list
);
2444 /* other COTP/ISO 8473 subdissectors */
2445 register_heur_dissector_list("cotp", &cotp_heur_subdissector_list
);
2447 /* XXX - what about CLTP and proto_cltp? */
2448 new_register_dissector("ositp", dissect_ositp
, proto_cotp
);
2449 new_register_dissector("ositp_inactive", dissect_ositp_inactive
, proto_cotp
);
2451 register_init_routine(cotp_reassemble_init
);
2454 void proto_register_cltp(void)
2456 static hf_register_info hf
[] = {
2458 { "Length", "cltp.li", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2459 "Length Indicator, length of this header", HFILL
}},
2461 { "PDU Type", "cltp.type", FT_UINT8
, BASE_HEX
,
2462 VALS(cltp_tpdu_type_abbrev_vals
), 0x0, NULL
, HFILL
}}
2464 static gint
*ett
[] = {
2468 proto_cltp
= proto_register_protocol(PROTO_STRING_CLTP
, "CLTP", "cltp");
2469 proto_register_field_array(proto_cltp
, hf
, array_length(hf
));
2470 proto_register_subtree_array(ett
, array_length(ett
));
2472 register_heur_dissector_list("cltp", &cltp_heur_subdissector_list
);
2476 proto_reg_handoff_cotp(void)
2478 dissector_handle_t ositp_handle
;
2480 ositp_handle
= find_dissector("ositp");
2481 dissector_add_uint("ip.proto", IP_PROTO_TP
, ositp_handle
);
2483 data_handle
= find_dissector("data");
2485 proto_clnp
= proto_get_id_by_filter_name("clnp");
2489 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2494 * indent-tabs-mode: nil
2497 * vi: set shiftwidth=2 tabstop=2 expandtab:
2498 * :indentSize=2:tabSize=2:noTabs=true: