1 /* Do not modify this file. Changes will be overwritten. */
2 /* Generated automatically by the ASN.1 to Wireshark dissector compiler */
4 /* asn2wrs.py -b -q -L -p rtse -c ./rtse.cnf -s ./packet-rtse-template -D . -O ../.. rtse.asn */
6 /* packet-rtse-template.c
7 * Routines for RTSE packet dissection
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * SPDX-License-Identifier: GPL-2.0-or-later
19 #include <epan/packet.h>
20 #include <epan/conversation.h>
21 #include <epan/prefs.h>
22 #include <epan/reassemble.h>
23 #include <epan/asn1.h>
24 #include <epan/expert.h>
26 #include <wsutil/array.h>
27 #include <wsutil/str_util.h>
29 #include "packet-ber.h"
30 #include "packet-pres.h"
31 #include "packet-acse.h"
32 #include "packet-ros.h"
33 #include "packet-rtse.h"
35 #define PNAME "X.228 OSI Reliable Transfer Service"
39 void proto_register_rtse(void);
40 void proto_reg_handoff_rtse(void);
42 /* Initialize the protocol and registered fields */
43 static int proto_rtse
;
45 static bool open_request
=false;
46 static uint32_t app_proto
=0;
48 static proto_tree
*top_tree
;
51 static bool rtse_reassemble
= true;
53 static int hf_rtse_rtorq_apdu
; /* RTORQapdu */
54 static int hf_rtse_rtoac_apdu
; /* RTOACapdu */
55 static int hf_rtse_rtorj_apdu
; /* RTORJapdu */
56 static int hf_rtse_rttp_apdu
; /* RTTPapdu */
57 static int hf_rtse_rttr_apdu
; /* RTTRapdu */
58 static int hf_rtse_rtab_apdu
; /* RTABapdu */
59 static int hf_rtse_checkpointSize
; /* INTEGER */
60 static int hf_rtse_windowSize
; /* INTEGER */
61 static int hf_rtse_dialogueMode
; /* T_dialogueMode */
62 static int hf_rtse_connectionDataRQ
; /* ConnectionData */
63 static int hf_rtse_applicationProtocol
; /* T_applicationProtocol */
64 static int hf_rtse_connectionDataAC
; /* ConnectionData */
65 static int hf_rtse_refuseReason
; /* RefuseReason */
66 static int hf_rtse_userDataRJ
; /* T_userDataRJ */
67 static int hf_rtse_abortReason
; /* AbortReason */
68 static int hf_rtse_reflectedParameter
; /* BIT_STRING */
69 static int hf_rtse_userdataAB
; /* T_userdataAB */
70 static int hf_rtse_open
; /* T_open */
71 static int hf_rtse_recover
; /* SessionConnectionIdentifier */
72 static int hf_rtse_callingSSuserReference
; /* CallingSSuserReference */
73 static int hf_rtse_commonReference
; /* CommonReference */
74 static int hf_rtse_additionalReferenceInformation
; /* AdditionalReferenceInformation */
75 static int hf_rtse_t61String
; /* T_t61String */
76 static int hf_rtse_octetString
; /* T_octetString */
78 /* Initialize the subtree pointers */
80 static int ett_rtse_RTSE_apdus
;
81 static int ett_rtse_RTORQapdu
;
82 static int ett_rtse_RTOACapdu
;
83 static int ett_rtse_RTORJapdu
;
84 static int ett_rtse_RTABapdu
;
85 static int ett_rtse_ConnectionData
;
86 static int ett_rtse_SessionConnectionIdentifier
;
87 static int ett_rtse_CallingSSuserReference
;
89 static expert_field ei_rtse_dissector_oid_not_implemented
;
90 static expert_field ei_rtse_unknown_rtse_pdu
;
91 static expert_field ei_rtse_abstract_syntax
;
93 static dissector_table_t rtse_oid_dissector_table
;
94 static dissector_handle_t rtse_handle
;
95 static int ett_rtse_unknown
;
97 static reassembly_table rtse_reassembly_table
;
99 static int hf_rtse_segment_data
;
100 static int hf_rtse_fragments
;
101 static int hf_rtse_fragment
;
102 static int hf_rtse_fragment_overlap
;
103 static int hf_rtse_fragment_overlap_conflicts
;
104 static int hf_rtse_fragment_multiple_tails
;
105 static int hf_rtse_fragment_too_long_fragment
;
106 static int hf_rtse_fragment_error
;
107 static int hf_rtse_fragment_count
;
108 static int hf_rtse_reassembled_in
;
109 static int hf_rtse_reassembled_length
;
111 static int ett_rtse_fragment
;
112 static int ett_rtse_fragments
;
114 static const fragment_items rtse_frag_items
= {
115 /* Fragment subtrees */
118 /* Fragment fields */
121 &hf_rtse_fragment_overlap
,
122 &hf_rtse_fragment_overlap_conflicts
,
123 &hf_rtse_fragment_multiple_tails
,
124 &hf_rtse_fragment_too_long_fragment
,
125 &hf_rtse_fragment_error
,
126 &hf_rtse_fragment_count
,
127 /* Reassembled in field */
128 &hf_rtse_reassembled_in
,
129 /* Reassembled length field */
130 &hf_rtse_reassembled_length
,
131 /* Reassembled data field */
138 register_rtse_oid_dissector_handle(const char *oid
, dissector_handle_t dissector
, int proto
, const char *name
, bool uses_ros
)
140 /* XXX: Note that this fcn is called from proto_reg_handoff in *other* dissectors ... */
142 static dissector_handle_t ros_handle
= NULL
;
144 if (ros_handle
== NULL
)
145 ros_handle
= find_dissector("ros");
147 /* register RTSE with the BER (ACSE) */
148 register_ber_oid_dissector_handle(oid
, rtse_handle
, proto
, name
);
151 /* make sure we call ROS ... */
152 dissector_add_string("rtse.oid", oid
, ros_handle
);
154 /* and then tell ROS how to dissect the AS*/
155 if (dissector
!= NULL
)
156 register_ros_oid_dissector_handle(oid
, dissector
, proto
, name
, true);
159 /* otherwise we just remember how to dissect the AS */
160 dissector_add_string("rtse.oid", oid
, dissector
);
165 call_rtse_oid_callback(const char *oid
, tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
170 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
172 if ((len
= dissector_try_string_with_data(rtse_oid_dissector_table
, oid
, next_tvb
, pinfo
, tree
, true, data
)) == 0) {
174 proto_tree
*next_tree
;
176 next_tree
= proto_tree_add_subtree_format(tree
, next_tvb
, 0, -1, ett_rtse_unknown
, &item
,
177 "RTSE: Dissector for OID:%s not implemented. Contact Wireshark developers if you want this supported", oid
);
179 expert_add_info_format(pinfo
, item
, &ei_rtse_dissector_oid_not_implemented
,
180 "RTSE: Dissector for OID %s not implemented", oid
);
181 len
= dissect_unknown_ber(pinfo
, next_tvb
, offset
, next_tree
);
190 call_rtse_external_type_callback(bool implicit_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index _U_
)
192 const char *oid
= NULL
;
194 if (actx
->external
.indirect_ref_present
) {
196 oid
= (const char *)find_oid_by_pres_ctx_id(actx
->pinfo
, actx
->external
.indirect_reference
);
199 proto_tree_add_expert_format(tree
, actx
->pinfo
, &ei_rtse_abstract_syntax
, tvb
, offset
, tvb_captured_length_remaining(tvb
, offset
),
200 "Unable to determine abstract syntax for indirect reference: %d.", actx
->external
.indirect_reference
);
201 } else if (actx
->external
.direct_ref_present
) {
202 oid
= actx
->external
.direct_reference
;
206 offset
= call_rtse_oid_callback(oid
, tvb
, offset
, actx
->pinfo
, top_tree
? top_tree
: tree
, actx
->private_data
);
214 dissect_rtse_INTEGER(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
215 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
222 static const value_string rtse_T_dialogueMode_vals
[] = {
230 dissect_rtse_T_dialogueMode(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
231 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
240 dissect_rtse_T_open(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
242 struct SESSION_DATA_STRUCTURE
* session
= (struct SESSION_DATA_STRUCTURE
*)actx
->private_data
;
243 const char *oid
= NULL
;
246 case 1: /* mts-transfer-protocol-1984 */
247 oid
= "applicationProtocol.1";
249 case 12: /* mts-transfer-protocol */
250 oid
= "applicationProtocol.12";
253 if(session
&& session
->pres_ctx_id
)
254 oid
= find_oid_by_pres_ctx_id(actx
->pinfo
, session
->pres_ctx_id
);
258 if(!oid
) /* XXX: problem here is we haven't decoded the applicationProtocol yet - so we make assumptions! */
259 oid
= "applicationProtocol.12";
263 offset
= call_rtse_oid_callback(oid
, tvb
, offset
, actx
->pinfo
, top_tree
? top_tree
: tree
, session
);
266 /* else XXX: need to flag we can't find the presentation context */
275 dissect_rtse_T_t61String(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
276 tvbuff_t
*string
= NULL
;
277 offset
= dissect_ber_restricted_string(implicit_tag
, BER_UNI_TAG_TeletexString
,
278 actx
, tree
, tvb
, offset
, hf_index
,
281 if(open_request
&& string
)
282 col_append_fstr(actx
->pinfo
->cinfo
, COL_INFO
, " %s", tvb_get_string_enc(actx
->pinfo
->pool
, string
, 0,
283 tvb_reported_length(string
), ENC_T61
));
292 dissect_rtse_T_octetString(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
293 tvbuff_t
*string
= NULL
;
294 offset
= dissect_ber_octet_string(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
297 if(open_request
&& string
)
298 col_append_fstr(actx
->pinfo
->cinfo
, COL_INFO
, " %s", tvb_format_text(actx
->pinfo
->pool
, string
, 0, tvb_reported_length(string
)));
305 static const value_string rtse_CallingSSuserReference_vals
[] = {
307 { 1, "octetString" },
311 static const ber_choice_t CallingSSuserReference_choice
[] = {
312 { 0, &hf_rtse_t61String
, BER_CLASS_UNI
, BER_UNI_TAG_TeletexString
, BER_FLAGS_NOOWNTAG
, dissect_rtse_T_t61String
},
313 { 1, &hf_rtse_octetString
, BER_CLASS_UNI
, BER_UNI_TAG_OCTETSTRING
, BER_FLAGS_NOOWNTAG
, dissect_rtse_T_octetString
},
314 { 0, NULL
, 0, 0, 0, NULL
}
318 dissect_rtse_CallingSSuserReference(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
319 offset
= dissect_ber_choice(actx
, tree
, tvb
, offset
,
320 CallingSSuserReference_choice
, hf_index
, ett_rtse_CallingSSuserReference
,
329 dissect_rtse_CommonReference(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
330 tvbuff_t
*string
= NULL
;
331 offset
= dissect_ber_UTCTime(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
, NULL
, NULL
);
333 if(open_request
&& string
)
334 col_append_fstr(actx
->pinfo
->cinfo
, COL_INFO
, " %s", tvb_format_text(actx
->pinfo
->pool
, string
, 0, tvb_reported_length(string
)));
343 dissect_rtse_AdditionalReferenceInformation(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
344 offset
= dissect_ber_restricted_string(implicit_tag
, BER_UNI_TAG_TeletexString
,
345 actx
, tree
, tvb
, offset
, hf_index
,
352 static const ber_sequence_t SessionConnectionIdentifier_sequence
[] = {
353 { &hf_rtse_callingSSuserReference
, BER_CLASS_ANY
/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG
|BER_FLAGS_NOTCHKTAG
, dissect_rtse_CallingSSuserReference
},
354 { &hf_rtse_commonReference
, BER_CLASS_UNI
, BER_UNI_TAG_UTCTime
, BER_FLAGS_NOOWNTAG
, dissect_rtse_CommonReference
},
355 { &hf_rtse_additionalReferenceInformation
, BER_CLASS_CON
, 0, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_rtse_AdditionalReferenceInformation
},
356 { NULL
, 0, 0, 0, NULL
}
360 dissect_rtse_SessionConnectionIdentifier(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
362 col_append_str(actx
->pinfo
->cinfo
, COL_INFO
, "Recover");
364 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
365 SessionConnectionIdentifier_sequence
, hf_index
, ett_rtse_SessionConnectionIdentifier
);
373 static const value_string rtse_ConnectionData_vals
[] = {
379 static const ber_choice_t ConnectionData_choice
[] = {
380 { 0, &hf_rtse_open
, BER_CLASS_CON
, 0, 0, dissect_rtse_T_open
},
381 { 1, &hf_rtse_recover
, BER_CLASS_CON
, 1, BER_FLAGS_IMPLTAG
, dissect_rtse_SessionConnectionIdentifier
},
382 { 0, NULL
, 0, 0, 0, NULL
}
386 dissect_rtse_ConnectionData(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
387 offset
= dissect_ber_choice(actx
, tree
, tvb
, offset
,
388 ConnectionData_choice
, hf_index
, ett_rtse_ConnectionData
,
395 static const value_string rtse_T_applicationProtocol_vals
[] = {
396 { 12, "mts-transfer-protocol" },
397 { 1, "mts-transfer-protocol-1984" },
403 dissect_rtse_T_applicationProtocol(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
405 offset
= dissect_ber_integer(true, actx
, tree
, tvb
, offset
, hf_index
, &app_proto
);
412 static const ber_sequence_t RTORQapdu_set
[] = {
413 { &hf_rtse_checkpointSize
, BER_CLASS_CON
, 0, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_rtse_INTEGER
},
414 { &hf_rtse_windowSize
, BER_CLASS_CON
, 1, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_rtse_INTEGER
},
415 { &hf_rtse_dialogueMode
, BER_CLASS_CON
, 2, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_rtse_T_dialogueMode
},
416 { &hf_rtse_connectionDataRQ
, BER_CLASS_CON
, 3, BER_FLAGS_NOTCHKTAG
, dissect_rtse_ConnectionData
},
417 { &hf_rtse_applicationProtocol
, BER_CLASS_CON
, 4, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_rtse_T_applicationProtocol
},
418 { NULL
, 0, 0, 0, NULL
}
422 dissect_rtse_RTORQapdu(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
423 struct SESSION_DATA_STRUCTURE
* session
= (struct SESSION_DATA_STRUCTURE
*)actx
->private_data
;
426 session
->ros_op
= (ROS_OP_BIND
| ROS_OP_ARGUMENT
);
428 offset
= dissect_ber_set(implicit_tag
, actx
, tree
, tvb
, offset
,
429 RTORQapdu_set
, hf_index
, ett_rtse_RTORQapdu
);
438 static const ber_sequence_t RTOACapdu_set
[] = {
439 { &hf_rtse_checkpointSize
, BER_CLASS_CON
, 0, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_rtse_INTEGER
},
440 { &hf_rtse_windowSize
, BER_CLASS_CON
, 1, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_rtse_INTEGER
},
441 { &hf_rtse_connectionDataAC
, BER_CLASS_CON
, 2, BER_FLAGS_NOTCHKTAG
, dissect_rtse_ConnectionData
},
442 { NULL
, 0, 0, 0, NULL
}
446 dissect_rtse_RTOACapdu(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
447 struct SESSION_DATA_STRUCTURE
* session
= (struct SESSION_DATA_STRUCTURE
*)actx
->private_data
;
450 session
->ros_op
= (ROS_OP_BIND
| ROS_OP_RESULT
);
452 offset
= dissect_ber_set(implicit_tag
, actx
, tree
, tvb
, offset
,
453 RTOACapdu_set
, hf_index
, ett_rtse_RTOACapdu
);
461 static const value_string rtse_RefuseReason_vals
[] = {
463 { 1, "cannotRecover" },
464 { 2, "validationFailure" },
465 { 3, "unacceptableDialogueMode" },
471 dissect_rtse_RefuseReason(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
474 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
479 col_append_fstr(actx
->pinfo
->cinfo
, COL_INFO
, " (%s)", val_to_str(reason
, rtse_RefuseReason_vals
, "reason(%d)"));
488 dissect_rtse_T_userDataRJ(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
489 struct SESSION_DATA_STRUCTURE
* session
= (struct SESSION_DATA_STRUCTURE
*)actx
->private_data
;
490 const char *oid
= NULL
;
493 case 1: /* mts-transfer-protocol-1984 */
494 oid
= "applicationProtocol.1";
496 case 12: /* mts-transfer-protocol */
497 oid
= "applicationProtocol.12";
500 if(session
&& session
->pres_ctx_id
)
501 oid
= find_oid_by_pres_ctx_id(actx
->pinfo
, session
->pres_ctx_id
);
505 if(!oid
) /* XXX: problem here is we haven't decoded the applicationProtocol yet - so we make assumptions! */
506 oid
= "applicationProtocol.12";
510 session
->ros_op
= (ROS_OP_BIND
| ROS_OP_ERROR
);
512 offset
= call_rtse_oid_callback(oid
, tvb
, offset
, actx
->pinfo
, top_tree
? top_tree
: tree
, session
);
520 static const ber_sequence_t RTORJapdu_set
[] = {
521 { &hf_rtse_refuseReason
, BER_CLASS_CON
, 0, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_rtse_RefuseReason
},
522 { &hf_rtse_userDataRJ
, BER_CLASS_CON
, 1, BER_FLAGS_OPTIONAL
, dissect_rtse_T_userDataRJ
},
523 { NULL
, 0, 0, 0, NULL
}
527 dissect_rtse_RTORJapdu(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
528 col_append_str(actx
->pinfo
->cinfo
, COL_INFO
, "Refuse");
530 offset
= dissect_ber_set(implicit_tag
, actx
, tree
, tvb
, offset
,
531 RTORJapdu_set
, hf_index
, ett_rtse_RTORJapdu
);
541 dissect_rtse_RTTPapdu(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
544 col_append_str(actx
->pinfo
->cinfo
, COL_INFO
, "Turn-Please");
546 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
551 col_append_fstr(actx
->pinfo
->cinfo
, COL_INFO
, " (%d)", priority
);
560 dissect_rtse_RTTRapdu(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
561 tvbuff_t
*next_tvb
= NULL
;
562 struct SESSION_DATA_STRUCTURE
* session
= (struct SESSION_DATA_STRUCTURE
*)actx
->private_data
;
564 offset
= dissect_ber_octet_string(false, actx
, tree
, tvb
, offset
, hf_index
, &next_tvb
);
568 /* XXX: we should check is this is an EXTERNAL first */
570 /* ROS won't do this for us */
572 session
->ros_op
= (ROS_OP_INVOKE
| ROS_OP_ARGUMENT
);
574 offset
= dissect_ber_external_type(false, tree
, next_tvb
, 0, actx
, -1, call_rtse_external_type_callback
);
583 static const value_string rtse_AbortReason_vals
[] = {
584 { 0, "localSystemProblem" },
585 { 1, "invalidParameter" },
586 { 2, "unrecognizedActivity" },
587 { 3, "temporaryProblem" },
588 { 4, "protocolError" },
589 { 5, "permanentProblem" },
591 { 7, "transferCompleted" },
597 dissect_rtse_AbortReason(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
600 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
605 col_append_fstr(actx
->pinfo
->cinfo
, COL_INFO
, " (%s)", val_to_str(reason
, rtse_AbortReason_vals
, "reason(%d)"));
614 dissect_rtse_BIT_STRING(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
615 offset
= dissect_ber_bitstring(implicit_tag
, actx
, tree
, tvb
, offset
,
616 NULL
, 0, hf_index
, -1,
625 dissect_rtse_T_userdataAB(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
626 /*XXX not implemented yet */
633 static const ber_sequence_t RTABapdu_set
[] = {
634 { &hf_rtse_abortReason
, BER_CLASS_CON
, 0, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_rtse_AbortReason
},
635 { &hf_rtse_reflectedParameter
, BER_CLASS_CON
, 1, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_rtse_BIT_STRING
},
636 { &hf_rtse_userdataAB
, BER_CLASS_CON
, 2, BER_FLAGS_OPTIONAL
, dissect_rtse_T_userdataAB
},
637 { NULL
, 0, 0, 0, NULL
}
641 dissect_rtse_RTABapdu(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
642 col_append_str(actx
->pinfo
->cinfo
, COL_INFO
, "Abort");
644 offset
= dissect_ber_set(implicit_tag
, actx
, tree
, tvb
, offset
,
645 RTABapdu_set
, hf_index
, ett_rtse_RTABapdu
);
653 static const ber_choice_t RTSE_apdus_choice
[] = {
654 { 0, &hf_rtse_rtorq_apdu
, BER_CLASS_CON
, 16, BER_FLAGS_IMPLTAG
, dissect_rtse_RTORQapdu
},
655 { 1, &hf_rtse_rtoac_apdu
, BER_CLASS_CON
, 17, BER_FLAGS_IMPLTAG
, dissect_rtse_RTOACapdu
},
656 { 2, &hf_rtse_rtorj_apdu
, BER_CLASS_CON
, 18, BER_FLAGS_IMPLTAG
, dissect_rtse_RTORJapdu
},
657 { 3, &hf_rtse_rttp_apdu
, BER_CLASS_UNI
, BER_UNI_TAG_INTEGER
, BER_FLAGS_NOOWNTAG
, dissect_rtse_RTTPapdu
},
658 { 4, &hf_rtse_rttr_apdu
, BER_CLASS_UNI
, BER_UNI_TAG_OCTETSTRING
, BER_FLAGS_NOOWNTAG
, dissect_rtse_RTTRapdu
},
659 { 5, &hf_rtse_rtab_apdu
, BER_CLASS_CON
, 22, BER_FLAGS_IMPLTAG
, dissect_rtse_RTABapdu
},
660 { 0, NULL
, 0, 0, 0, NULL
}
664 dissect_rtse_RTSE_apdus(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
665 offset
= dissect_ber_choice(actx
, tree
, tvb
, offset
,
666 RTSE_apdus_choice
, hf_index
, ett_rtse_RTSE_apdus
,
674 * Dissect RTSE PDUs inside a PPDU.
677 dissect_rtse(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, void* data
)
683 proto_tree
*next_tree
=NULL
;
684 tvbuff_t
*next_tvb
= NULL
;
685 tvbuff_t
*data_tvb
= NULL
;
686 fragment_head
*frag_msg
= NULL
;
687 uint32_t fragment_length
;
688 uint32_t rtse_id
= 0;
689 bool data_handled
= false;
690 struct SESSION_DATA_STRUCTURE
* session
;
691 conversation_t
*conversation
= NULL
;
693 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, true, pinfo
);
695 /* do we have application context from the acse dissector? */
698 session
= (struct SESSION_DATA_STRUCTURE
*)data
;
700 /* save parent_tree so subdissectors can create new top nodes */
701 top_tree
=parent_tree
;
703 asn1_ctx
.private_data
= session
;
705 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "RTSE");
706 col_clear(pinfo
->cinfo
, COL_INFO
);
708 if (rtse_reassemble
&&
709 ((session
->spdu_type
== SES_DATA_TRANSFER
) ||
710 (session
->spdu_type
== SES_MAJOR_SYNC_POINT
)))
712 /* Use conversation index as fragment id */
713 conversation
= find_conversation_pinfo(pinfo
, 0);
714 if (conversation
!= NULL
) {
715 rtse_id
= conversation
->conv_index
;
717 session
->rtse_reassemble
= true;
719 if (rtse_reassemble
&& session
->spdu_type
== SES_MAJOR_SYNC_POINT
) {
720 frag_msg
= fragment_end_seq_next (&rtse_reassembly_table
,
721 pinfo
, rtse_id
, NULL
);
722 next_tvb
= process_reassembled_data (tvb
, offset
, pinfo
, "Reassembled RTSE",
723 frag_msg
, &rtse_frag_items
, NULL
, parent_tree
);
726 item
= proto_tree_add_item(parent_tree
, proto_rtse
, next_tvb
? next_tvb
: tvb
, 0, -1, ENC_NA
);
727 tree
= proto_item_add_subtree(item
, ett_rtse
);
729 if (rtse_reassemble
&& session
->spdu_type
== SES_DATA_TRANSFER
) {
730 /* strip off the OCTET STRING encoding - including any CONSTRUCTED OCTET STRING */
731 dissect_ber_octet_string(false, &asn1_ctx
, tree
, tvb
, offset
, hf_rtse_segment_data
, &data_tvb
);
734 fragment_length
= tvb_captured_length_remaining (data_tvb
, 0);
735 proto_item_append_text(asn1_ctx
.created_item
, " (%u byte%s)", fragment_length
,
736 plurality(fragment_length
, "", "s"));
737 frag_msg
= fragment_add_seq_next (&rtse_reassembly_table
,
740 fragment_length
, true);
741 if (frag_msg
&& pinfo
->num
!= frag_msg
->reassembled_in
) {
742 /* Add a "Reassembled in" link if not reassembled in this frame */
743 proto_tree_add_uint (tree
, *(rtse_frag_items
.hf_reassembled_in
),
744 data_tvb
, 0, 0, frag_msg
->reassembled_in
);
746 pinfo
->fragmented
= true;
749 fragment_length
= tvb_captured_length_remaining (tvb
, offset
);
752 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "[RTSE fragment, %u byte%s]",
753 fragment_length
, plurality(fragment_length
, "", "s"));
754 } else if (rtse_reassemble
&& session
->spdu_type
== SES_MAJOR_SYNC_POINT
) {
756 /* ROS won't do this for us */
757 session
->ros_op
= (ROS_OP_INVOKE
| ROS_OP_ARGUMENT
);
758 /*offset=*/dissect_ber_external_type(false, tree
, next_tvb
, 0, &asn1_ctx
, -1, call_rtse_external_type_callback
);
760 /* Return other than 0 to indicate that we handled this packet */
763 offset
= tvb_captured_length (tvb
);
765 pinfo
->fragmented
= false;
770 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
772 offset
=dissect_rtse_RTSE_apdus(true, tvb
, offset
, &asn1_ctx
, tree
, -1);
773 if (offset
== old_offset
) {
774 next_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, -1,
775 ett_rtse_unknown
, &item
, "Unknown RTSE PDU");
776 expert_add_info (pinfo
, item
, &ei_rtse_unknown_rtse_pdu
);
777 dissect_unknown_ber(pinfo
, tvb
, offset
, next_tree
);
784 return tvb_captured_length(tvb
);
787 /*--- proto_register_rtse -------------------------------------------*/
788 void proto_register_rtse(void) {
791 static hf_register_info hf
[] =
793 /* Fragment entries */
794 { &hf_rtse_segment_data
,
795 { "RTSE segment data", "rtse.segment", FT_NONE
, BASE_NONE
,
796 NULL
, 0x00, NULL
, HFILL
} },
797 { &hf_rtse_fragments
,
798 { "RTSE fragments", "rtse.fragments", FT_NONE
, BASE_NONE
,
799 NULL
, 0x00, NULL
, HFILL
} },
801 { "RTSE fragment", "rtse.fragment", FT_FRAMENUM
, BASE_NONE
,
802 NULL
, 0x00, NULL
, HFILL
} },
803 { &hf_rtse_fragment_overlap
,
804 { "RTSE fragment overlap", "rtse.fragment.overlap", FT_BOOLEAN
,
805 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
806 { &hf_rtse_fragment_overlap_conflicts
,
807 { "RTSE fragment overlapping with conflicting data",
808 "rtse.fragment.overlap.conflicts", FT_BOOLEAN
, BASE_NONE
,
809 NULL
, 0x0, NULL
, HFILL
} },
810 { &hf_rtse_fragment_multiple_tails
,
811 { "RTSE has multiple tail fragments",
812 "rtse.fragment.multiple_tails", FT_BOOLEAN
, BASE_NONE
,
813 NULL
, 0x0, NULL
, HFILL
} },
814 { &hf_rtse_fragment_too_long_fragment
,
815 { "RTSE fragment too long", "rtse.fragment.too_long_fragment",
816 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
817 { &hf_rtse_fragment_error
,
818 { "RTSE defragmentation error", "rtse.fragment.error", FT_FRAMENUM
,
819 BASE_NONE
, NULL
, 0x00, NULL
, HFILL
} },
820 { &hf_rtse_fragment_count
,
821 { "RTSE fragment count", "rtse.fragment.count", FT_UINT32
, BASE_DEC
,
822 NULL
, 0x00, NULL
, HFILL
} },
823 { &hf_rtse_reassembled_in
,
824 { "Reassembled RTSE in frame", "rtse.reassembled.in", FT_FRAMENUM
, BASE_NONE
,
825 NULL
, 0x00, "This RTSE packet is reassembled in this frame", HFILL
} },
826 { &hf_rtse_reassembled_length
,
827 { "Reassembled RTSE length", "rtse.reassembled.length", FT_UINT32
, BASE_DEC
,
828 NULL
, 0x00, "The total length of the reassembled payload", HFILL
} },
830 { &hf_rtse_rtorq_apdu
,
831 { "rtorq-apdu", "rtse.rtorq_apdu_element",
832 FT_NONE
, BASE_NONE
, NULL
, 0,
833 "RTORQapdu", HFILL
}},
834 { &hf_rtse_rtoac_apdu
,
835 { "rtoac-apdu", "rtse.rtoac_apdu_element",
836 FT_NONE
, BASE_NONE
, NULL
, 0,
837 "RTOACapdu", HFILL
}},
838 { &hf_rtse_rtorj_apdu
,
839 { "rtorj-apdu", "rtse.rtorj_apdu_element",
840 FT_NONE
, BASE_NONE
, NULL
, 0,
841 "RTORJapdu", HFILL
}},
842 { &hf_rtse_rttp_apdu
,
843 { "rttp-apdu", "rtse.rttp_apdu",
844 FT_INT32
, BASE_DEC
, NULL
, 0,
845 "RTTPapdu", HFILL
}},
846 { &hf_rtse_rttr_apdu
,
847 { "rttr-apdu", "rtse.rttr_apdu",
848 FT_BYTES
, BASE_NONE
, NULL
, 0,
849 "RTTRapdu", HFILL
}},
850 { &hf_rtse_rtab_apdu
,
851 { "rtab-apdu", "rtse.rtab_apdu_element",
852 FT_NONE
, BASE_NONE
, NULL
, 0,
853 "RTABapdu", HFILL
}},
854 { &hf_rtse_checkpointSize
,
855 { "checkpointSize", "rtse.checkpointSize",
856 FT_INT32
, BASE_DEC
, NULL
, 0,
858 { &hf_rtse_windowSize
,
859 { "windowSize", "rtse.windowSize",
860 FT_INT32
, BASE_DEC
, NULL
, 0,
862 { &hf_rtse_dialogueMode
,
863 { "dialogueMode", "rtse.dialogueMode",
864 FT_INT32
, BASE_DEC
, VALS(rtse_T_dialogueMode_vals
), 0,
866 { &hf_rtse_connectionDataRQ
,
867 { "connectionDataRQ", "rtse.connectionDataRQ",
868 FT_UINT32
, BASE_DEC
, VALS(rtse_ConnectionData_vals
), 0,
869 "ConnectionData", HFILL
}},
870 { &hf_rtse_applicationProtocol
,
871 { "applicationProtocol", "rtse.applicationProtocol",
872 FT_INT32
, BASE_DEC
, VALS(rtse_T_applicationProtocol_vals
), 0,
874 { &hf_rtse_connectionDataAC
,
875 { "connectionDataAC", "rtse.connectionDataAC",
876 FT_UINT32
, BASE_DEC
, VALS(rtse_ConnectionData_vals
), 0,
877 "ConnectionData", HFILL
}},
878 { &hf_rtse_refuseReason
,
879 { "refuseReason", "rtse.refuseReason",
880 FT_INT32
, BASE_DEC
, VALS(rtse_RefuseReason_vals
), 0,
882 { &hf_rtse_userDataRJ
,
883 { "userDataRJ", "rtse.userDataRJ_element",
884 FT_NONE
, BASE_NONE
, NULL
, 0,
886 { &hf_rtse_abortReason
,
887 { "abortReason", "rtse.abortReason",
888 FT_INT32
, BASE_DEC
, VALS(rtse_AbortReason_vals
), 0,
890 { &hf_rtse_reflectedParameter
,
891 { "reflectedParameter", "rtse.reflectedParameter",
892 FT_BYTES
, BASE_NONE
, NULL
, 0,
893 "BIT_STRING", HFILL
}},
894 { &hf_rtse_userdataAB
,
895 { "userdataAB", "rtse.userdataAB_element",
896 FT_NONE
, BASE_NONE
, NULL
, 0,
899 { "open", "rtse.open_element",
900 FT_NONE
, BASE_NONE
, NULL
, 0,
903 { "recover", "rtse.recover_element",
904 FT_NONE
, BASE_NONE
, NULL
, 0,
905 "SessionConnectionIdentifier", HFILL
}},
906 { &hf_rtse_callingSSuserReference
,
907 { "callingSSuserReference", "rtse.callingSSuserReference",
908 FT_UINT32
, BASE_DEC
, VALS(rtse_CallingSSuserReference_vals
), 0,
910 { &hf_rtse_commonReference
,
911 { "commonReference", "rtse.commonReference",
912 FT_STRING
, BASE_NONE
, NULL
, 0,
914 { &hf_rtse_additionalReferenceInformation
,
915 { "additionalReferenceInformation", "rtse.additionalReferenceInformation",
916 FT_STRING
, BASE_NONE
, NULL
, 0,
918 { &hf_rtse_t61String
,
919 { "t61String", "rtse.t61String",
920 FT_STRING
, BASE_NONE
, NULL
, 0,
922 { &hf_rtse_octetString
,
923 { "octetString", "rtse.octetString",
924 FT_BYTES
, BASE_NONE
, NULL
, 0,
928 /* List of subtrees */
929 static int *ett
[] = {
934 &ett_rtse_RTSE_apdus
,
939 &ett_rtse_ConnectionData
,
940 &ett_rtse_SessionConnectionIdentifier
,
941 &ett_rtse_CallingSSuserReference
,
944 static ei_register_info ei
[] = {
945 { &ei_rtse_dissector_oid_not_implemented
, { "rtse.dissector_oid_not_implemented", PI_UNDECODED
, PI_WARN
, "RTSE: Dissector for OID not implemented", EXPFILL
}},
946 { &ei_rtse_unknown_rtse_pdu
, { "rtse.unknown_rtse_pdu", PI_UNDECODED
, PI_WARN
, "Unknown RTSE PDU", EXPFILL
}},
947 { &ei_rtse_abstract_syntax
, { "rtse.bad_abstract_syntax", PI_PROTOCOL
, PI_WARN
, "Unable to determine abstract syntax for indirect reference", EXPFILL
}},
950 expert_module_t
* expert_rtse
;
951 module_t
*rtse_module
;
953 /* Register protocol */
954 proto_rtse
= proto_register_protocol(PNAME
, PSNAME
, PFNAME
);
955 rtse_handle
= register_dissector("rtse", dissect_rtse
, proto_rtse
);
956 /* Register fields and subtrees */
957 proto_register_field_array(proto_rtse
, hf
, array_length(hf
));
958 proto_register_subtree_array(ett
, array_length(ett
));
959 expert_rtse
= expert_register_protocol(proto_rtse
);
960 expert_register_field_array(expert_rtse
, ei
, array_length(ei
));
962 reassembly_table_register (&rtse_reassembly_table
,
963 &addresses_reassembly_table_functions
);
965 rtse_module
= prefs_register_protocol_subtree("OSI", proto_rtse
, NULL
);
967 prefs_register_bool_preference(rtse_module
, "reassemble",
968 "Reassemble segmented RTSE datagrams",
969 "Whether segmented RTSE datagrams should be reassembled."
970 " To use this option, you must also enable"
971 " \"Allow subdissectors to reassemble TCP streams\""
972 " in the TCP protocol settings.", &rtse_reassemble
);
974 rtse_oid_dissector_table
= register_dissector_table("rtse.oid", "RTSE OID Dissectors", proto_rtse
, FT_STRING
, STRING_CASE_SENSITIVE
);
978 /*--- proto_reg_handoff_rtse --- */
979 void proto_reg_handoff_rtse(void) {
985 * Editor modelines - https://www.wireshark.org/tools/modelines.html
990 * indent-tabs-mode: nil
993 * vi: set shiftwidth=4 tabstop=8 expandtab:
994 * :indentSize=4:tabSize=8:noTabs=true: