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 ros -c ./ros.cnf -s ./packet-ros-template -D . -O ../.. ros.asn Remote-Operations-Information-Objects.asn */
7 * Routines for ROS 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/asn1.h>
22 #include <epan/expert.h>
23 #include <wsutil/array.h>
25 #include "packet-ber.h"
26 #include "packet-pres.h"
27 #include "packet-ros.h"
29 #define PNAME "X.880 OSI Remote Operations Service"
33 void proto_register_ros(void);
34 void proto_reg_handoff_ros(void);
36 /* Initialize the protocol and registered fields */
39 static proto_tree
*top_tree
;
40 static uint32_t opcode
;
41 static uint32_t invokeid
;
43 static dissector_handle_t ros_handle
;
45 typedef struct ros_conv_info_t
{
46 wmem_map_t
*unmatched
; /* unmatched operations */
47 wmem_map_t
*matched
; /* matched operations */
50 typedef struct ros_call_response
{
56 } ros_call_response_t
;
58 static int hf_ros_response_in
;
59 static int hf_ros_response_to
;
60 static int hf_ros_time
;
63 static int hf_ros_invoke
; /* Invoke */
64 static int hf_ros_returnResult
; /* ReturnResult */
65 static int hf_ros_returnError
; /* ReturnError */
66 static int hf_ros_reject
; /* T_reject */
67 static int hf_ros_bind_invoke
; /* T_bind_invoke */
68 static int hf_ros_bind_result
; /* T_bind_result */
69 static int hf_ros_bind_error
; /* T_bind_error */
70 static int hf_ros_unbind_invoke
; /* T_unbind_invoke */
71 static int hf_ros_unbind_result
; /* T_unbind_result */
72 static int hf_ros_unbind_error
; /* T_unbind_error */
73 static int hf_ros_invokeId
; /* InvokeId */
74 static int hf_ros_linkedId
; /* INTEGER */
75 static int hf_ros_opcode
; /* OperationCode */
76 static int hf_ros_argument
; /* T_argument */
77 static int hf_ros_result
; /* T_result */
78 static int hf_ros_operationResult
; /* OperationResult */
79 static int hf_ros_errcode
; /* ErrorCode */
80 static int hf_ros_parameter
; /* T_parameter */
81 static int hf_ros_problem
; /* T_problem */
82 static int hf_ros_general
; /* GeneralProblem */
83 static int hf_ros_invokeProblem
; /* InvokeProblem */
84 static int hf_ros_rejectResult
; /* ReturnResultProblem */
85 static int hf_ros_rejectError
; /* ReturnErrorProblem */
86 static int hf_ros_present
; /* T_present */
87 static int hf_ros_absent
; /* NULL */
88 static int hf_ros_local
; /* INTEGER */
89 static int hf_ros_global
; /* OBJECT_IDENTIFIER */
91 /* Initialize the subtree pointers */
93 static int ett_ros_unknown
;
94 static int ett_ros_invoke_argument
;
95 static int ett_ros_return_result
;
96 static int ett_ros_bind_invoke
;
97 static int ett_ros_bind_result
;
98 static int ett_ros_bind_error
;
99 static int ett_ros_unbind_invoke
;
100 static int ett_ros_unbind_result
;
101 static int ett_ros_unbind_error
;
102 static int ett_ros_ROS
;
103 static int ett_ros_Invoke
;
104 static int ett_ros_ReturnResult
;
105 static int ett_ros_T_result
;
106 static int ett_ros_ReturnError
;
107 static int ett_ros_Reject
;
108 static int ett_ros_T_problem
;
109 static int ett_ros_InvokeId
;
110 static int ett_ros_Code
;
112 static expert_field ei_ros_dissector_oid_not_implemented
;
113 static expert_field ei_ros_unknown_ros_pdu
;
115 static dissector_table_t ros_oid_dissector_table
;
117 static wmem_map_t
*protocol_table
;
120 register_ros_oid_dissector_handle(const char *oid
, dissector_handle_t dissector
, int proto _U_
, const char *name
, bool uses_rtse
)
122 dissector_add_string("ros.oid", oid
, dissector
);
125 /* if we are not using RTSE, then we must register ROS with BER (ACSE) */
126 register_ber_oid_dissector_handle(oid
, ros_handle
, proto
, name
);
130 register_ros_protocol_info(const char *oid
, const ros_info_t
*rinfo
, int proto _U_
, const char *name
, bool uses_rtse
)
132 wmem_map_insert(protocol_table
, (void *)oid
, (void *)rinfo
);
135 /* if we are not using RTSE, then we must register ROS with BER (ACSE) */
136 register_ber_oid_dissector_handle(oid
, ros_handle
, proto
, name
);
139 static dissector_t
ros_lookup_opr_dissector(int32_t opcode_lcl
, const ros_opr_t
*operations
, bool argument
)
141 /* we don't know what order asn2wrs/module definition is, so ... */
143 for(;operations
->arg_pdu
!= (dissector_t
)(-1); operations
++)
144 if(operations
->opcode
== opcode_lcl
)
145 return argument
? operations
->arg_pdu
: operations
->res_pdu
;
151 static dissector_t
ros_lookup_err_dissector(int32_t errcode
, const ros_err_t
*errors
)
153 /* we don't know what order asn2wrs/module definition is, so ... */
155 for(;errors
->err_pdu
!= (dissector_t
) (-1); errors
++) {
156 if(errors
->errcode
== errcode
)
157 return errors
->err_pdu
;
165 ros_try_string(const char *oid
, tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, struct SESSION_DATA_STRUCTURE
* session
)
168 int32_t opcode_lcl
= 0;
169 const char *opname
= NULL
;
170 const char *suffix
= NULL
;
171 dissector_t opdissector
= NULL
;
172 const value_string
*lookup
;
173 proto_item
*item
=NULL
;
174 proto_tree
*ros_tree
=NULL
;
176 if((session
!= NULL
) && (oid
!= NULL
) && ((rinfo
= (ros_info_t
*)wmem_map_lookup(protocol_table
, oid
)) != NULL
)) {
179 item
= proto_tree_add_item(tree
, *(rinfo
->proto
), tvb
, 0, -1, ENC_NA
);
180 ros_tree
= proto_item_add_subtree(item
, *(rinfo
->ett_proto
));
183 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, rinfo
->name
);
185 /* if this is a bind operation */
186 if((session
->ros_op
& ROS_OP_TYPE_MASK
) == ROS_OP_BIND
) {
187 /* use the in-built operation codes */
188 if((session
->ros_op
& ROS_OP_PDU_MASK
) == ROS_OP_ERROR
)
189 opcode_lcl
= err_ros_bind
;
191 opcode_lcl
= op_ros_bind
;
193 /* otherwise just take the opcode */
194 opcode_lcl
= session
->ros_op
& ROS_OP_OPCODE_MASK
;
196 /* default lookup in the operations */
197 lookup
= rinfo
->opr_code_strings
;
199 switch(session
->ros_op
& ROS_OP_PDU_MASK
) {
200 case ROS_OP_ARGUMENT
:
201 opdissector
= ros_lookup_opr_dissector(opcode_lcl
, rinfo
->opr_code_dissectors
, true);
202 suffix
= "_argument";
205 opdissector
= ros_lookup_opr_dissector(opcode_lcl
, rinfo
->opr_code_dissectors
, false);
209 opdissector
= ros_lookup_err_dissector(opcode_lcl
, rinfo
->err_code_dissectors
);
210 lookup
= rinfo
->err_code_strings
;
218 opname
= val_to_str(opcode_lcl
, lookup
, "Unknown opcode (%d)");
220 col_set_str(pinfo
->cinfo
, COL_INFO
, opname
);
222 col_append_str(pinfo
->cinfo
, COL_INFO
, suffix
);
224 return (*opdissector
)(tvb
, pinfo
, ros_tree
, NULL
);
232 call_ros_oid_callback(const char *oid
, tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, struct SESSION_DATA_STRUCTURE
* session
)
237 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
239 if(((len
= ros_try_string(oid
, next_tvb
, pinfo
, tree
, session
)) == 0) &&
240 ((len
= dissector_try_string_with_data(ros_oid_dissector_table
, oid
, next_tvb
, pinfo
, tree
, true, session
)) == 0)) {
242 proto_tree
*next_tree
;
244 next_tree
= proto_tree_add_subtree_format(tree
, next_tvb
, 0, -1, ett_ros_unknown
, &item
,
245 "ROS: Dissector for OID:%s not implemented. Contact Wireshark developers if you want this supported", oid
);
247 expert_add_info_format(pinfo
, item
, &ei_ros_dissector_oid_not_implemented
,
248 "ROS: Dissector for OID %s not implemented", oid
);
249 len
= dissect_unknown_ber(pinfo
, next_tvb
, offset
, next_tree
);
259 ros_info_hash_matched(const void *k
)
261 const ros_call_response_t
*key
= (const ros_call_response_t
*)k
;
263 return key
->invokeId
;
267 ros_info_equal_matched(const void *k1
, const void *k2
)
269 const ros_call_response_t
*key1
= (const ros_call_response_t
*)k1
;
270 const ros_call_response_t
*key2
= (const ros_call_response_t
*)k2
;
272 if( key1
->req_frame
&& key2
->req_frame
&& (key1
->req_frame
!=key2
->req_frame
) ){
275 /* a response may span multiple frames
276 if( key1->rep_frame && key2->rep_frame && (key1->rep_frame!=key2->rep_frame) ){
281 return key1
->invokeId
==key2
->invokeId
;
285 ros_info_hash_unmatched(const void *k
)
287 const ros_call_response_t
*key
= (const ros_call_response_t
*)k
;
289 return key
->invokeId
;
293 ros_info_equal_unmatched(const void *k1
, const void *k2
)
295 const ros_call_response_t
*key1
= (const ros_call_response_t
*)k1
;
296 const ros_call_response_t
*key2
= (const ros_call_response_t
*)k2
;
298 return key1
->invokeId
==key2
->invokeId
;
301 static ros_call_response_t
*
302 ros_match_call_response(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned invokeId
, bool isInvoke
)
304 ros_call_response_t rcr
, *rcrp
=NULL
;
305 ros_conv_info_t
*ros_info
;
306 conversation_t
*conversation
;
308 /* first see if we have already matched this */
309 conversation
= find_conversation_pinfo(pinfo
, 0);
310 if (conversation
== NULL
)
313 ros_info
= (ros_conv_info_t
*)conversation_get_proto_data(conversation
, proto_ros
);
314 if (ros_info
== NULL
)
317 rcr
.invokeId
=invokeId
;
318 rcr
.is_request
= isInvoke
;
321 rcr
.req_frame
=pinfo
->num
;
325 rcr
.rep_frame
=pinfo
->num
;
328 rcrp
=(ros_call_response_t
*)wmem_map_lookup(ros_info
->matched
, &rcr
);
331 /* we have found a match */
332 rcrp
->is_request
=rcr
.is_request
;
336 /* we haven't found a match - try and match it up */
339 /* this is a request - add it to the unmatched list */
341 /* check that we don't already have one of those in the
342 unmatched list and if so remove it */
344 rcr
.invokeId
=invokeId
;
346 rcrp
=(ros_call_response_t
*)wmem_map_lookup(ros_info
->unmatched
, &rcr
);
349 wmem_map_remove(ros_info
->unmatched
, rcrp
);
352 /* if we can't reuse the old one, grab a new chunk */
354 rcrp
=wmem_new(wmem_file_scope(), ros_call_response_t
);
356 rcrp
->invokeId
=invokeId
;
357 rcrp
->req_frame
=pinfo
->num
;
358 rcrp
->req_time
=pinfo
->abs_ts
;
360 rcrp
->is_request
=true;
361 wmem_map_insert(ros_info
->unmatched
, rcrp
, rcrp
);
366 /* this is a result - it should be in our unmatched list */
368 rcr
.invokeId
=invokeId
;
369 rcrp
=(ros_call_response_t
*)wmem_map_lookup(ros_info
->unmatched
, &rcr
);
373 if(!rcrp
->rep_frame
){
374 wmem_map_remove(ros_info
->unmatched
, rcrp
);
375 rcrp
->rep_frame
=pinfo
->num
;
376 rcrp
->is_request
=false;
377 wmem_map_insert(ros_info
->matched
, rcrp
, rcrp
);
383 if(rcrp
){ /* we have found a match */
384 proto_item
*item
= NULL
;
386 if(rcrp
->is_request
){
387 item
=proto_tree_add_uint(tree
, hf_ros_response_in
, tvb
, 0, 0, rcrp
->rep_frame
);
388 proto_item_set_generated (item
);
391 item
=proto_tree_add_uint(tree
, hf_ros_response_to
, tvb
, 0, 0, rcrp
->req_frame
);
392 proto_item_set_generated (item
);
393 nstime_delta(&ns
, &pinfo
->abs_ts
, &rcrp
->req_time
);
394 item
=proto_tree_add_time(tree
, hf_ros_time
, tvb
, 0, 0, &ns
);
395 proto_item_set_generated (item
);
405 dissect_ros_T_present(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
406 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
415 dissect_ros_NULL(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
416 offset
= dissect_ber_null(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
);
422 const value_string ros_InvokeId_vals
[] = {
428 static const ber_choice_t InvokeId_choice
[] = {
429 { 0, &hf_ros_present
, BER_CLASS_UNI
, BER_UNI_TAG_INTEGER
, BER_FLAGS_NOOWNTAG
, dissect_ros_T_present
},
430 { 1, &hf_ros_absent
, BER_CLASS_UNI
, BER_UNI_TAG_NULL
, BER_FLAGS_NOOWNTAG
, dissect_ros_NULL
},
431 { 0, NULL
, 0, 0, 0, NULL
}
435 dissect_ros_InvokeId(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
436 offset
= dissect_ber_choice(actx
, tree
, tvb
, offset
,
437 InvokeId_choice
, hf_index
, ett_ros_InvokeId
,
446 dissect_ros_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_
) {
447 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
456 dissect_ros_OperationCode(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
457 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
466 dissect_ros_T_argument(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
469 struct SESSION_DATA_STRUCTURE
* session
= (struct SESSION_DATA_STRUCTURE
*)actx
->private_data
;
471 /* not sure what the length should be - -1 for now */
472 subtree
= proto_tree_add_subtree(tree
, tvb
, offset
, -1, ett_ros_invoke_argument
, NULL
, "invoke argument");
474 ros_match_call_response(tvb
, actx
->pinfo
, subtree
, invokeid
, true);
476 if(session
&& session
->pres_ctx_id
&& (oid
= find_oid_by_pres_ctx_id(actx
->pinfo
, session
->pres_ctx_id
))) {
477 /* this should be ROS! */
478 session
->ros_op
= (ROS_OP_INVOKE
| ROS_OP_ARGUMENT
);
479 /* now add the opcode */
480 session
->ros_op
|= opcode
;
481 offset
= call_ros_oid_callback(oid
, tvb
, offset
, actx
->pinfo
, top_tree
, session
);
489 static const ber_sequence_t Invoke_sequence
[] = {
490 { &hf_ros_invokeId
, BER_CLASS_ANY
/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG
|BER_FLAGS_NOTCHKTAG
, dissect_ros_InvokeId
},
491 { &hf_ros_linkedId
, BER_CLASS_CON
, 0, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_ros_INTEGER
},
492 { &hf_ros_opcode
, BER_CLASS_UNI
, BER_UNI_TAG_INTEGER
, BER_FLAGS_NOOWNTAG
, dissect_ros_OperationCode
},
493 { &hf_ros_argument
, BER_CLASS_ANY
, 0, BER_FLAGS_OPTIONAL
|BER_FLAGS_NOOWNTAG
, dissect_ros_T_argument
},
494 { NULL
, 0, 0, 0, NULL
}
498 dissect_ros_Invoke(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
499 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
500 Invoke_sequence
, hf_index
, ett_ros_Invoke
);
508 dissect_ros_OperationResult(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
511 struct SESSION_DATA_STRUCTURE
* session
= (struct SESSION_DATA_STRUCTURE
*)actx
->private_data
;
513 /* not sure what the length should be - -1 for now */
514 subtree
= proto_tree_add_subtree(tree
, tvb
, offset
,-1, ett_ros_return_result
, NULL
, "return result");
516 ros_match_call_response(tvb
, actx
->pinfo
, subtree
, invokeid
, false);
518 if(session
&& session
->pres_ctx_id
&& (oid
= find_oid_by_pres_ctx_id(actx
->pinfo
, session
->pres_ctx_id
))) {
519 /* this should be ROS! */
520 session
->ros_op
= (ROS_OP_INVOKE
| ROS_OP_RESULT
);
521 /* now add the opcode */
522 session
->ros_op
|= opcode
;
523 offset
= call_ros_oid_callback(oid
, tvb
, offset
, actx
->pinfo
, top_tree
, session
);
531 static const ber_sequence_t T_result_sequence
[] = {
532 { &hf_ros_opcode
, BER_CLASS_UNI
, BER_UNI_TAG_INTEGER
, BER_FLAGS_NOOWNTAG
, dissect_ros_OperationCode
},
533 { &hf_ros_operationResult
, BER_CLASS_ANY
, 0, BER_FLAGS_NOOWNTAG
, dissect_ros_OperationResult
},
534 { NULL
, 0, 0, 0, NULL
}
538 dissect_ros_T_result(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
539 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
540 T_result_sequence
, hf_index
, ett_ros_T_result
);
546 static const ber_sequence_t ReturnResult_sequence
[] = {
547 { &hf_ros_invokeId
, BER_CLASS_ANY
/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG
|BER_FLAGS_NOTCHKTAG
, dissect_ros_InvokeId
},
548 { &hf_ros_result
, BER_CLASS_UNI
, BER_UNI_TAG_SEQUENCE
, BER_FLAGS_OPTIONAL
|BER_FLAGS_NOOWNTAG
, dissect_ros_T_result
},
549 { NULL
, 0, 0, 0, NULL
}
553 dissect_ros_ReturnResult(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
554 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
555 ReturnResult_sequence
, hf_index
, ett_ros_ReturnResult
);
563 dissect_ros_ErrorCode(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
564 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
573 dissect_ros_T_parameter(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
576 struct SESSION_DATA_STRUCTURE
* session
= (struct SESSION_DATA_STRUCTURE
*)actx
->private_data
;
578 /* not sure what the length should be - -1 for now */
579 subtree
= proto_tree_add_subtree(tree
, tvb
, offset
,-1, ett_ros_return_result
, NULL
, "return result");
581 ros_match_call_response(tvb
, actx
->pinfo
, subtree
, invokeid
, false);
583 if(session
&& session
->pres_ctx_id
&& (oid
= find_oid_by_pres_ctx_id(actx
->pinfo
, session
->pres_ctx_id
))) {
584 /* this should be ROS! */
585 session
->ros_op
= (ROS_OP_INVOKE
| ROS_OP_ERROR
);
586 /* now add the opcode (really the error code) */
587 session
->ros_op
|= opcode
;
588 offset
= call_ros_oid_callback(oid
, tvb
, offset
, actx
->pinfo
, top_tree
, session
);
596 static const ber_sequence_t ReturnError_sequence
[] = {
597 { &hf_ros_invokeId
, BER_CLASS_ANY
/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG
|BER_FLAGS_NOTCHKTAG
, dissect_ros_InvokeId
},
598 { &hf_ros_errcode
, BER_CLASS_UNI
, BER_UNI_TAG_INTEGER
, BER_FLAGS_NOOWNTAG
, dissect_ros_ErrorCode
},
599 { &hf_ros_parameter
, BER_CLASS_ANY
, 0, BER_FLAGS_OPTIONAL
|BER_FLAGS_NOOWNTAG
, dissect_ros_T_parameter
},
600 { NULL
, 0, 0, 0, NULL
}
604 dissect_ros_ReturnError(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
605 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
606 ReturnError_sequence
, hf_index
, ett_ros_ReturnError
);
612 static const value_string ros_GeneralProblem_vals
[] = {
613 { 0, "unrecognizedPDU" },
614 { 1, "mistypedPDU" },
615 { 2, "badlyStructuredPDU" },
621 dissect_ros_GeneralProblem(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
624 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
628 col_append_fstr(actx
->pinfo
->cinfo
, COL_INFO
, " %s", val_to_str(problem
, ros_GeneralProblem_vals
, "GeneralProblem(%d)"));
635 static const value_string ros_InvokeProblem_vals
[] = {
636 { 0, "duplicateInvocation" },
637 { 1, "unrecognizedOperation" },
638 { 2, "mistypedArgument" },
639 { 3, "resourceLimitation" },
640 { 4, "releaseInProgress" },
641 { 5, "unrecognizedLinkedId" },
642 { 6, "linkedResponseUnexpected" },
643 { 7, "unexpectedLinkedOperation" },
649 dissect_ros_InvokeProblem(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
652 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
656 col_append_fstr(actx
->pinfo
->cinfo
, COL_INFO
, " %s", val_to_str(problem
, ros_InvokeProblem_vals
, "InvokeProblem(%d)"));
663 static const value_string ros_ReturnResultProblem_vals
[] = {
664 { 0, "unrecognizedInvocation" },
665 { 1, "resultResponseUnexpected" },
666 { 2, "mistypedResult" },
672 dissect_ros_ReturnResultProblem(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
675 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
679 col_append_fstr(actx
->pinfo
->cinfo
, COL_INFO
, " %s", val_to_str(problem
, ros_ReturnResultProblem_vals
, "ReturnResultProblem(%d)"));
686 static const value_string ros_ReturnErrorProblem_vals
[] = {
687 { 0, "unrecognizedInvocation" },
688 { 1, "errorResponseUnexpected" },
689 { 2, "unrecognizedError" },
690 { 3, "unexpectedError" },
691 { 4, "mistypedParameter" },
697 dissect_ros_ReturnErrorProblem(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
700 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
704 col_append_fstr(actx
->pinfo
->cinfo
, COL_INFO
, " %s", val_to_str(problem
, ros_ReturnErrorProblem_vals
, "ReturnErrorProblem(%d)"));
711 static const value_string ros_T_problem_vals
[] = {
714 { 2, "returnResult" },
715 { 3, "returnError" },
719 static const ber_choice_t T_problem_choice
[] = {
720 { 0, &hf_ros_general
, BER_CLASS_CON
, 0, BER_FLAGS_IMPLTAG
, dissect_ros_GeneralProblem
},
721 { 1, &hf_ros_invokeProblem
, BER_CLASS_CON
, 1, BER_FLAGS_IMPLTAG
, dissect_ros_InvokeProblem
},
722 { 2, &hf_ros_rejectResult
, BER_CLASS_CON
, 2, BER_FLAGS_IMPLTAG
, dissect_ros_ReturnResultProblem
},
723 { 3, &hf_ros_rejectError
, BER_CLASS_CON
, 3, BER_FLAGS_IMPLTAG
, dissect_ros_ReturnErrorProblem
},
724 { 0, NULL
, 0, 0, 0, NULL
}
728 dissect_ros_T_problem(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
729 offset
= dissect_ber_choice(actx
, tree
, tvb
, offset
,
730 T_problem_choice
, hf_index
, ett_ros_T_problem
,
737 static const ber_sequence_t Reject_sequence
[] = {
738 { &hf_ros_invokeId
, BER_CLASS_ANY
/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG
|BER_FLAGS_NOTCHKTAG
, dissect_ros_InvokeId
},
739 { &hf_ros_problem
, BER_CLASS_ANY
/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG
|BER_FLAGS_NOTCHKTAG
, dissect_ros_T_problem
},
740 { NULL
, 0, 0, 0, NULL
}
744 dissect_ros_Reject(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
745 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
746 Reject_sequence
, hf_index
, ett_ros_Reject
);
754 dissect_ros_T_reject(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
755 col_set_str(actx
->pinfo
->cinfo
, COL_INFO
, "Reject");
756 offset
= dissect_ros_Reject(implicit_tag
, tvb
, offset
, actx
, tree
, hf_index
);
766 dissect_ros_T_bind_invoke(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
768 struct SESSION_DATA_STRUCTURE
* session
= (struct SESSION_DATA_STRUCTURE
*)actx
->private_data
;
770 /* not sure what the length should be - -1 for now */
771 proto_tree_add_subtree(tree
, tvb
, offset
,-1, ett_ros_bind_result
, NULL
, "bind-invoke");
773 if(session
&& session
->pres_ctx_id
&& (oid
= find_oid_by_pres_ctx_id(actx
->pinfo
, session
->pres_ctx_id
))) {
774 /* this should be ROS! */
775 session
->ros_op
= (ROS_OP_BIND
| ROS_OP_ARGUMENT
);
776 offset
= call_ros_oid_callback(oid
, tvb
, offset
, actx
->pinfo
, top_tree
, session
);
786 dissect_ros_T_bind_result(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
788 struct SESSION_DATA_STRUCTURE
* session
= (struct SESSION_DATA_STRUCTURE
*)actx
->private_data
;
790 /* not sure what the length should be - -1 for now */
791 proto_tree_add_subtree(tree
, tvb
, offset
,-1, ett_ros_bind_result
, NULL
, "bind-result");
793 if(session
&& session
->pres_ctx_id
&& (oid
= find_oid_by_pres_ctx_id(actx
->pinfo
, session
->pres_ctx_id
))) {
794 /* this should be ROS! */
795 session
->ros_op
= (ROS_OP_BIND
| ROS_OP_RESULT
);
796 offset
= call_ros_oid_callback(oid
, tvb
, offset
, actx
->pinfo
, top_tree
, session
);
806 dissect_ros_T_bind_error(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
808 struct SESSION_DATA_STRUCTURE
* session
= (struct SESSION_DATA_STRUCTURE
*)actx
->private_data
;
810 /* not sure what the length should be - -1 for now */
811 proto_tree_add_subtree(tree
, tvb
, offset
,-1, ett_ros_bind_error
, NULL
, "bind-error");
813 if(session
&& session
->pres_ctx_id
&& (oid
= find_oid_by_pres_ctx_id(actx
->pinfo
, session
->pres_ctx_id
))) {
814 /* this should be ROS! */
815 session
->ros_op
= (ROS_OP_BIND
| ROS_OP_ERROR
);
816 offset
= call_ros_oid_callback(oid
, tvb
, offset
, actx
->pinfo
, top_tree
, session
);
827 dissect_ros_T_unbind_invoke(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
829 struct SESSION_DATA_STRUCTURE
* session
= (struct SESSION_DATA_STRUCTURE
*)actx
->private_data
;
831 /* not sure what the length should be - -1 for now */
832 proto_tree_add_subtree(tree
, tvb
, offset
,-1, ett_ros_unbind_invoke
, NULL
, "unbind-invoke");
834 if(session
&& session
->pres_ctx_id
&& (oid
= find_oid_by_pres_ctx_id(actx
->pinfo
, session
->pres_ctx_id
))) {
835 /* this should be ROS! */
836 session
->ros_op
= (ROS_OP_UNBIND
| ROS_OP_ARGUMENT
);
837 offset
= call_ros_oid_callback(oid
, tvb
, offset
, actx
->pinfo
, top_tree
, session
);
848 dissect_ros_T_unbind_result(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
850 struct SESSION_DATA_STRUCTURE
* session
= (struct SESSION_DATA_STRUCTURE
*)actx
->private_data
;
852 /* not sure what the length should be - -1 for now */
853 proto_tree_add_subtree(tree
, tvb
, offset
,-1, ett_ros_unbind_result
, NULL
, "unbind-result");
855 if(session
&& session
->pres_ctx_id
&& (oid
= find_oid_by_pres_ctx_id(actx
->pinfo
, session
->pres_ctx_id
))) {
856 /* this should be ROS! */
857 session
->ros_op
= (ROS_OP_UNBIND
| ROS_OP_RESULT
);
858 offset
= call_ros_oid_callback(oid
, tvb
, offset
, actx
->pinfo
, top_tree
, session
);
868 dissect_ros_T_unbind_error(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
870 struct SESSION_DATA_STRUCTURE
* session
= (struct SESSION_DATA_STRUCTURE
*)actx
->private_data
;
872 /* not sure what the length should be - -1 for now */
873 proto_tree_add_subtree(tree
, tvb
, offset
,-1, ett_ros_unbind_error
, NULL
, "unbind-error");
875 if(session
&& session
->pres_ctx_id
&& (oid
= find_oid_by_pres_ctx_id(actx
->pinfo
, session
->pres_ctx_id
))) {
876 /* this should be ROS! */
877 session
->ros_op
= (ROS_OP_UNBIND
| ROS_OP_ERROR
);
878 offset
= call_ros_oid_callback(oid
, tvb
, offset
, actx
->pinfo
, top_tree
, session
);
886 const value_string ros_ROS_vals
[] = {
888 { 2, "returnResult" },
889 { 3, "returnError" },
891 { 16, "bind-invoke" },
892 { 17, "bind-result" },
893 { 18, "bind-error" },
894 { 19, "unbind-invoke" },
895 { 20, "unbind-result" },
896 { 21, "unbind-error" },
900 static const ber_choice_t ROS_choice
[] = {
901 { 1, &hf_ros_invoke
, BER_CLASS_CON
, 1, BER_FLAGS_IMPLTAG
, dissect_ros_Invoke
},
902 { 2, &hf_ros_returnResult
, BER_CLASS_CON
, 2, BER_FLAGS_IMPLTAG
, dissect_ros_ReturnResult
},
903 { 3, &hf_ros_returnError
, BER_CLASS_CON
, 3, BER_FLAGS_IMPLTAG
, dissect_ros_ReturnError
},
904 { 4, &hf_ros_reject
, BER_CLASS_CON
, 4, BER_FLAGS_IMPLTAG
, dissect_ros_T_reject
},
905 { 16, &hf_ros_bind_invoke
, BER_CLASS_CON
, 16, BER_FLAGS_IMPLTAG
, dissect_ros_T_bind_invoke
},
906 { 17, &hf_ros_bind_result
, BER_CLASS_CON
, 17, BER_FLAGS_IMPLTAG
, dissect_ros_T_bind_result
},
907 { 18, &hf_ros_bind_error
, BER_CLASS_CON
, 18, BER_FLAGS_IMPLTAG
, dissect_ros_T_bind_error
},
908 { 19, &hf_ros_unbind_invoke
, BER_CLASS_CON
, 19, BER_FLAGS_IMPLTAG
, dissect_ros_T_unbind_invoke
},
909 { 20, &hf_ros_unbind_result
, BER_CLASS_CON
, 20, BER_FLAGS_IMPLTAG
, dissect_ros_T_unbind_result
},
910 { 21, &hf_ros_unbind_error
, BER_CLASS_CON
, 21, BER_FLAGS_IMPLTAG
, dissect_ros_T_unbind_error
},
911 { 0, NULL
, 0, 0, 0, NULL
}
915 dissect_ros_ROS(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
916 offset
= dissect_ber_choice(actx
, tree
, tvb
, offset
,
917 ROS_choice
, hf_index
, ett_ros_ROS
,
926 dissect_ros_OBJECT_IDENTIFIER(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
927 offset
= dissect_ber_object_identifier(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
, NULL
);
933 const value_string ros_Code_vals
[] = {
939 static const ber_choice_t Code_choice
[] = {
940 { 0, &hf_ros_local
, BER_CLASS_UNI
, BER_UNI_TAG_INTEGER
, BER_FLAGS_NOOWNTAG
, dissect_ros_INTEGER
},
941 { 1, &hf_ros_global
, BER_CLASS_UNI
, BER_UNI_TAG_OID
, BER_FLAGS_NOOWNTAG
, dissect_ros_OBJECT_IDENTIFIER
},
942 { 0, NULL
, 0, 0, 0, NULL
}
946 dissect_ros_Code(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
947 offset
= dissect_ber_choice(actx
, tree
, tvb
, offset
,
948 Code_choice
, hf_index
, ett_ros_Code
,
956 * Dissect ROS PDUs inside a PPDU.
959 dissect_ros(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, void* data
)
965 proto_tree
*next_tree
=NULL
;
966 conversation_t
*conversation
;
967 ros_conv_info_t
*ros_info
= NULL
;
969 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, true, pinfo
);
971 /* do we have application context from the acse dissector? */
974 asn1_ctx
.private_data
= data
;
976 /* save parent_tree so subdissectors can create new top nodes */
977 top_tree
=parent_tree
;
979 conversation
= find_or_create_conversation(pinfo
);
982 * Do we already have our info
984 ros_info
= (ros_conv_info_t
*)conversation_get_proto_data(conversation
, proto_ros
);
985 if (ros_info
== NULL
) {
987 /* No. Attach that information to the conversation. */
989 ros_info
= (ros_conv_info_t
*)wmem_new0(wmem_file_scope(), ros_conv_info_t
);
990 ros_info
->matched
=wmem_map_new(wmem_file_scope(), ros_info_hash_matched
, ros_info_equal_matched
);
991 ros_info
->unmatched
=wmem_map_new(wmem_file_scope(), ros_info_hash_unmatched
, ros_info_equal_unmatched
);
993 conversation_add_proto_data(conversation
, proto_ros
, ros_info
);
996 item
= proto_tree_add_item(parent_tree
, proto_ros
, tvb
, 0, -1, ENC_NA
);
997 tree
= proto_item_add_subtree(item
, ett_ros
);
999 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ROS");
1000 col_clear(pinfo
->cinfo
, COL_INFO
);
1002 while (tvb_reported_length_remaining(tvb
, offset
) > 0){
1004 offset
=dissect_ros_ROS(false, tvb
, offset
, &asn1_ctx
, tree
, -1);
1005 if(offset
== old_offset
){
1006 next_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, -1, ett_ros_unknown
, &item
, "Unknown ROS PDU");
1008 expert_add_info(pinfo
, item
, &ei_ros_unknown_ros_pdu
);
1009 dissect_unknown_ber(pinfo
, tvb
, offset
, next_tree
);
1014 return tvb_captured_length(tvb
);
1017 /*--- proto_register_ros -------------------------------------------*/
1018 void proto_register_ros(void) {
1020 /* List of fields */
1021 static hf_register_info hf
[] =
1023 { &hf_ros_response_in
,
1024 { "Response In", "ros.response_in",
1025 FT_FRAMENUM
, BASE_NONE
, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE
), 0x0,
1026 "The response to this remote operation invocation is in this frame", HFILL
}},
1027 { &hf_ros_response_to
,
1028 { "Response To", "ros.response_to",
1029 FT_FRAMENUM
, BASE_NONE
, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST
), 0x0,
1030 "This is a response to the remote operation invocation in this frame", HFILL
}},
1032 { "Time", "ros.time",
1033 FT_RELATIVE_TIME
, BASE_NONE
, NULL
, 0x0,
1034 "The time between the Invoke and the Response", HFILL
}},
1037 { "invoke", "ros.invoke_element",
1038 FT_NONE
, BASE_NONE
, NULL
, 0,
1040 { &hf_ros_returnResult
,
1041 { "returnResult", "ros.returnResult_element",
1042 FT_NONE
, BASE_NONE
, NULL
, 0,
1044 { &hf_ros_returnError
,
1045 { "returnError", "ros.returnError_element",
1046 FT_NONE
, BASE_NONE
, NULL
, 0,
1049 { "reject", "ros.reject_element",
1050 FT_NONE
, BASE_NONE
, NULL
, 0,
1052 { &hf_ros_bind_invoke
,
1053 { "bind-invoke", "ros.bind_invoke_element",
1054 FT_NONE
, BASE_NONE
, NULL
, 0,
1056 { &hf_ros_bind_result
,
1057 { "bind-result", "ros.bind_result_element",
1058 FT_NONE
, BASE_NONE
, NULL
, 0,
1060 { &hf_ros_bind_error
,
1061 { "bind-error", "ros.bind_error_element",
1062 FT_NONE
, BASE_NONE
, NULL
, 0,
1064 { &hf_ros_unbind_invoke
,
1065 { "unbind-invoke", "ros.unbind_invoke_element",
1066 FT_NONE
, BASE_NONE
, NULL
, 0,
1068 { &hf_ros_unbind_result
,
1069 { "unbind-result", "ros.unbind_result_element",
1070 FT_NONE
, BASE_NONE
, NULL
, 0,
1072 { &hf_ros_unbind_error
,
1073 { "unbind-error", "ros.unbind_error_element",
1074 FT_NONE
, BASE_NONE
, NULL
, 0,
1077 { "invokeId", "ros.invokeId",
1078 FT_UINT32
, BASE_DEC
, VALS(ros_InvokeId_vals
), 0,
1081 { "linkedId", "ros.linkedId",
1082 FT_INT32
, BASE_DEC
, NULL
, 0,
1083 "INTEGER", HFILL
}},
1085 { "opcode", "ros.opcode",
1086 FT_INT32
, BASE_DEC
, NULL
, 0,
1087 "OperationCode", HFILL
}},
1089 { "argument", "ros.argument_element",
1090 FT_NONE
, BASE_NONE
, NULL
, 0,
1093 { "result", "ros.result_element",
1094 FT_NONE
, BASE_NONE
, NULL
, 0,
1096 { &hf_ros_operationResult
,
1097 { "result", "ros.result_element",
1098 FT_NONE
, BASE_NONE
, NULL
, 0,
1099 "OperationResult", HFILL
}},
1101 { "errcode", "ros.errcode",
1102 FT_INT32
, BASE_DEC
, NULL
, 0,
1103 "ErrorCode", HFILL
}},
1104 { &hf_ros_parameter
,
1105 { "parameter", "ros.parameter_element",
1106 FT_NONE
, BASE_NONE
, NULL
, 0,
1109 { "problem", "ros.problem",
1110 FT_UINT32
, BASE_DEC
, VALS(ros_T_problem_vals
), 0,
1113 { "general", "ros.general",
1114 FT_INT32
, BASE_DEC
, VALS(ros_GeneralProblem_vals
), 0,
1115 "GeneralProblem", HFILL
}},
1116 { &hf_ros_invokeProblem
,
1117 { "invoke", "ros.invoke",
1118 FT_INT32
, BASE_DEC
, VALS(ros_InvokeProblem_vals
), 0,
1119 "InvokeProblem", HFILL
}},
1120 { &hf_ros_rejectResult
,
1121 { "returnResult", "ros.returnResult",
1122 FT_INT32
, BASE_DEC
, VALS(ros_ReturnResultProblem_vals
), 0,
1123 "ReturnResultProblem", HFILL
}},
1124 { &hf_ros_rejectError
,
1125 { "returnError", "ros.returnError",
1126 FT_INT32
, BASE_DEC
, VALS(ros_ReturnErrorProblem_vals
), 0,
1127 "ReturnErrorProblem", HFILL
}},
1129 { "present", "ros.present",
1130 FT_INT32
, BASE_DEC
, NULL
, 0,
1133 { "absent", "ros.absent_element",
1134 FT_NONE
, BASE_NONE
, NULL
, 0,
1137 { "local", "ros.local",
1138 FT_INT32
, BASE_DEC
, NULL
, 0,
1139 "INTEGER", HFILL
}},
1141 { "global", "ros.global",
1142 FT_OID
, BASE_NONE
, NULL
, 0,
1143 "OBJECT_IDENTIFIER", HFILL
}},
1146 /* List of subtrees */
1147 static int *ett
[] = {
1150 &ett_ros_invoke_argument
,
1151 &ett_ros_return_result
,
1152 &ett_ros_bind_invoke
,
1153 &ett_ros_bind_result
,
1154 &ett_ros_bind_error
,
1155 &ett_ros_unbind_invoke
,
1156 &ett_ros_unbind_result
,
1157 &ett_ros_unbind_error
,
1161 &ett_ros_ReturnResult
,
1163 &ett_ros_ReturnError
,
1170 static ei_register_info ei
[] = {
1171 { &ei_ros_dissector_oid_not_implemented
, { "ros.dissector_oid_not_implemented", PI_UNDECODED
, PI_WARN
, "ROS: Dissector for OID not implemented", EXPFILL
}},
1172 { &ei_ros_unknown_ros_pdu
, { "ros.unknown_ros_pdu", PI_UNDECODED
, PI_WARN
, "Unknown ROS PDU", EXPFILL
}},
1175 expert_module_t
* expert_ros
;
1177 /* Register protocol */
1178 proto_ros
= proto_register_protocol(PNAME
, PSNAME
, PFNAME
);
1179 ros_handle
= register_dissector("ros", dissect_ros
, proto_ros
);
1180 /* Register fields and subtrees */
1181 proto_register_field_array(proto_ros
, hf
, array_length(hf
));
1182 proto_register_subtree_array(ett
, array_length(ett
));
1183 expert_ros
= expert_register_protocol(proto_ros
);
1184 expert_register_field_array(expert_ros
, ei
, array_length(ei
));
1186 ros_oid_dissector_table
= register_dissector_table("ros.oid", "ROS OID Dissectors", proto_ros
, FT_STRING
, STRING_CASE_SENSITIVE
);
1187 protocol_table
= wmem_map_new(wmem_epan_scope(), wmem_str_hash
, g_str_equal
);
1191 /*--- proto_reg_handoff_ros --- */
1192 void proto_reg_handoff_ros(void) {