Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-ros.c
Line
Count
Source
1
/* Do not modify this file. Changes will be overwritten.                      */
2
/* Generated automatically by the ASN.1 to Wireshark dissector compiler       */
3
/* packet-ros.c                                                               */
4
/* asn2wrs.py -b -q -L -p ros -c ./ros.cnf -s ./packet-ros-template -D . -O ../.. ros.asn Remote-Operations-Information-Objects.asn */
5
6
/* packet-ros_asn1.c
7
 * Routines for ROS packet dissection
8
 * Graeme Lunt 2005
9
 *
10
 * Wireshark - Network traffic analyzer
11
 * By Gerald Combs <gerald@wireshark.org>
12
 * Copyright 1998 Gerald Combs
13
 *
14
 * SPDX-License-Identifier: GPL-2.0-or-later
15
 */
16
17
#include "config.h"
18
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>
24
25
#include "packet-ber.h"
26
#include "packet-pres.h"
27
#include "packet-ros.h"
28
29
void proto_register_ros(void);
30
void proto_reg_handoff_ros(void);
31
32
/* Initialize the protocol and registered fields */
33
static int proto_ros;
34
35
static proto_tree *top_tree;
36
static uint32_t opcode;
37
static uint32_t invokeid;
38
39
static  dissector_handle_t ros_handle;
40
41
typedef struct ros_conv_info_t {
42
  wmem_map_t *unmatched; /* unmatched operations */
43
  wmem_map_t *matched;   /* matched operations */
44
} ros_conv_info_t;
45
46
typedef struct ros_call_response {
47
  bool is_request;
48
  uint32_t req_frame;
49
  nstime_t req_time;
50
  uint32_t rep_frame;
51
  unsigned invokeId;
52
} ros_call_response_t;
53
54
static int hf_ros_response_in;
55
static int hf_ros_response_to;
56
static int hf_ros_time;
57
58
59
static int hf_ros_invoke;                         /* Invoke */
60
static int hf_ros_returnResult;                   /* ReturnResult */
61
static int hf_ros_returnError;                    /* ReturnError */
62
static int hf_ros_reject;                         /* T_reject */
63
static int hf_ros_bind_invoke;                    /* T_bind_invoke */
64
static int hf_ros_bind_result;                    /* T_bind_result */
65
static int hf_ros_bind_error;                     /* T_bind_error */
66
static int hf_ros_unbind_invoke;                  /* T_unbind_invoke */
67
static int hf_ros_unbind_result;                  /* T_unbind_result */
68
static int hf_ros_unbind_error;                   /* T_unbind_error */
69
static int hf_ros_invokeId;                       /* InvokeId */
70
static int hf_ros_linkedId;                       /* INTEGER */
71
static int hf_ros_opcode;                         /* OperationCode */
72
static int hf_ros_argument;                       /* T_argument */
73
static int hf_ros_result;                         /* T_result */
74
static int hf_ros_operationResult;                /* OperationResult */
75
static int hf_ros_errcode;                        /* ErrorCode */
76
static int hf_ros_parameter;                      /* T_parameter */
77
static int hf_ros_problem;                        /* T_problem */
78
static int hf_ros_general;                        /* GeneralProblem */
79
static int hf_ros_invokeProblem;                  /* InvokeProblem */
80
static int hf_ros_rejectResult;                   /* ReturnResultProblem */
81
static int hf_ros_rejectError;                    /* ReturnErrorProblem */
82
static int hf_ros_present;                        /* T_present */
83
static int hf_ros_absent;                         /* NULL */
84
static int hf_ros_local;                          /* INTEGER */
85
static int hf_ros_global;                         /* OBJECT_IDENTIFIER */
86
87
/* Initialize the subtree pointers */
88
static int ett_ros;
89
static int ett_ros_unknown;
90
static int ett_ros_invoke_argument;
91
static int ett_ros_return_result;
92
static int ett_ros_bind_invoke;
93
static int ett_ros_bind_result;
94
static int ett_ros_bind_error;
95
static int ett_ros_unbind_invoke;
96
static int ett_ros_unbind_result;
97
static int ett_ros_unbind_error;
98
static int ett_ros_ROS;
99
static int ett_ros_Invoke;
100
static int ett_ros_ReturnResult;
101
static int ett_ros_T_result;
102
static int ett_ros_ReturnError;
103
static int ett_ros_Reject;
104
static int ett_ros_T_problem;
105
static int ett_ros_InvokeId;
106
static int ett_ros_Code;
107
108
static expert_field ei_ros_dissector_oid_not_implemented;
109
static expert_field ei_ros_unknown_ros_pdu;
110
111
static dissector_table_t ros_oid_dissector_table;
112
113
static wmem_map_t *protocol_table;
114
115
void
116
register_ros_oid_dissector_handle(const char *oid, dissector_handle_t dissector, int proto _U_, const char *name, bool uses_rtse)
117
60
{
118
60
  dissector_add_string("ros.oid", oid, dissector);
119
120
60
  if(!uses_rtse)
121
    /* if we are not using RTSE, then we must register ROS with BER (ACSE) */
122
45
    register_ber_oid_dissector_handle(oid, ros_handle, proto, name);
123
60
}
124
125
void
126
register_ros_protocol_info(const char *oid, const ros_info_t *rinfo, int proto _U_, const char *name, bool uses_rtse)
127
180
{
128
180
  wmem_map_insert(protocol_table, (void *)oid, (void *)rinfo);
129
130
180
  if(!uses_rtse)
131
    /* if we are not using RTSE, then we must register ROS with BER (ACSE) */
132
165
    register_ber_oid_dissector_handle(oid, ros_handle, proto, name);
133
180
}
134
135
static dissector_t ros_lookup_opr_dissector(int32_t opcode_lcl, const ros_opr_t *operations, bool argument)
136
0
{
137
  /* we don't know what order asn2wrs/module definition is, so ... */
138
0
  if(operations) {
139
0
    for(;operations->arg_pdu != (dissector_t)(-1); operations++)
140
0
      if(operations->opcode == opcode_lcl)
141
0
        return argument ? operations->arg_pdu : operations->res_pdu;
142
143
0
  }
144
0
  return NULL;
145
0
}
146
147
static dissector_t ros_lookup_err_dissector(int32_t errcode, const ros_err_t *errors)
148
0
{
149
  /* we don't know what order asn2wrs/module definition is, so ... */
150
0
  if(errors) {
151
0
    for(;errors->err_pdu != (dissector_t) (-1); errors++) {
152
0
      if(errors->errcode == errcode)
153
0
        return errors->err_pdu;
154
0
    }
155
0
  }
156
0
  return NULL;
157
0
}
158
159
160
static int
161
ros_try_string(const char *oid, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, struct SESSION_DATA_STRUCTURE* session)
162
77
{
163
77
  ros_info_t *rinfo;
164
77
  int32_t    opcode_lcl = 0;
165
77
  const char *opname = NULL;
166
77
  const char *suffix = NULL;
167
77
  dissector_t opdissector = NULL;
168
77
  const value_string *lookup;
169
77
  proto_item *item=NULL;
170
77
  proto_tree *ros_tree=NULL;
171
172
77
  if((session != NULL) && (oid != NULL) && ((rinfo = (ros_info_t*)wmem_map_lookup(protocol_table, oid)) != NULL)) {
173
174
0
    if(tree){
175
0
      item = proto_tree_add_item(tree, *(rinfo->proto), tvb, 0, -1, ENC_NA);
176
0
      ros_tree = proto_item_add_subtree(item, *(rinfo->ett_proto));
177
0
    }
178
179
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, rinfo->name);
180
181
    /* if this is a bind operation */
182
0
    if((session->ros_op & ROS_OP_TYPE_MASK) == ROS_OP_BIND) {
183
      /* use the in-built operation codes */
184
0
      if((session->ros_op & ROS_OP_PDU_MASK) ==  ROS_OP_ERROR)
185
0
        opcode_lcl = err_ros_bind;
186
0
      else
187
0
        opcode_lcl = op_ros_bind;
188
0
    } else
189
      /* otherwise just take the opcode */
190
0
      opcode_lcl = session->ros_op & ROS_OP_OPCODE_MASK;
191
192
    /* default lookup in the operations */
193
0
    lookup = rinfo->opr_code_strings;
194
195
0
    switch(session->ros_op & ROS_OP_PDU_MASK) {
196
0
    case ROS_OP_ARGUMENT:
197
0
      opdissector = ros_lookup_opr_dissector(opcode_lcl, rinfo->opr_code_dissectors, true);
198
0
      suffix = "_argument";
199
0
      break;
200
0
    case ROS_OP_RESULT:
201
0
      opdissector = ros_lookup_opr_dissector(opcode_lcl, rinfo->opr_code_dissectors, false);
202
0
      suffix = "_result";
203
0
      break;
204
0
    case ROS_OP_ERROR:
205
0
      opdissector = ros_lookup_err_dissector(opcode_lcl, rinfo->err_code_dissectors);
206
0
      lookup = rinfo->err_code_strings;
207
0
      break;
208
0
    default:
209
0
      break;
210
0
    }
211
212
0
    if(opdissector) {
213
214
0
      opname = val_to_str(pinfo->pool, opcode_lcl, lookup, "Unknown opcode (%d)");
215
216
0
      col_set_str(pinfo->cinfo, COL_INFO, opname);
217
0
      if(suffix)
218
0
        col_append_str(pinfo->cinfo, COL_INFO, suffix);
219
220
0
      return (*opdissector)(tvb, pinfo, ros_tree, NULL);
221
0
    }
222
0
  }
223
224
77
  return 0;
225
77
}
226
227
int
228
call_ros_oid_callback(const char *oid, tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, struct SESSION_DATA_STRUCTURE* session)
229
77
{
230
77
  tvbuff_t *next_tvb;
231
77
  int len;
232
233
77
  next_tvb = tvb_new_subset_remaining(tvb, offset);
234
235
77
  if(((len = ros_try_string(oid, next_tvb, pinfo, tree, session)) == 0) &&
236
77
     ((len = dissector_try_string_with_data(ros_oid_dissector_table, oid, next_tvb, pinfo, tree, true, session)) == 0)) {
237
77
    proto_item *item;
238
77
    proto_tree *next_tree;
239
240
77
    next_tree = proto_tree_add_subtree_format(tree, next_tvb, 0, -1, ett_ros_unknown, &item,
241
77
        "ROS: Dissector for OID:%s not implemented. Contact Wireshark developers if you want this supported", oid);
242
243
77
    expert_add_info_format(pinfo, item, &ei_ros_dissector_oid_not_implemented,
244
77
               "ROS: Dissector for OID %s not implemented", oid);
245
77
    len = dissect_unknown_ber(pinfo, next_tvb, offset, next_tree);
246
77
  }
247
248
77
  offset += len;
249
250
77
  return offset;
251
77
}
252
253
254
static unsigned
255
ros_info_hash_matched(const void *k)
256
0
{
257
0
  const ros_call_response_t *key = (const ros_call_response_t *)k;
258
259
0
  return key->invokeId;
260
0
}
261
262
static int
263
ros_info_equal_matched(const void *k1, const void *k2)
264
0
{
265
0
  const ros_call_response_t *key1 = (const ros_call_response_t *)k1;
266
0
  const ros_call_response_t *key2 = (const ros_call_response_t *)k2;
267
268
0
  if( key1->req_frame && key2->req_frame && (key1->req_frame!=key2->req_frame) ){
269
0
    return 0;
270
0
  }
271
  /* a response may span multiple frames
272
  if( key1->rep_frame && key2->rep_frame && (key1->rep_frame!=key2->rep_frame) ){
273
    return 0;
274
  }
275
  */
276
277
0
  return key1->invokeId==key2->invokeId;
278
0
}
279
280
static unsigned
281
ros_info_hash_unmatched(const void *k)
282
0
{
283
0
  const ros_call_response_t *key = (const ros_call_response_t *)k;
284
285
0
  return key->invokeId;
286
0
}
287
288
static int
289
ros_info_equal_unmatched(const void *k1, const void *k2)
290
0
{
291
0
  const ros_call_response_t *key1 = (const ros_call_response_t *)k1;
292
0
  const ros_call_response_t *key2 = (const ros_call_response_t *)k2;
293
294
0
  return key1->invokeId==key2->invokeId;
295
0
}
296
297
static ros_call_response_t *
298
ros_match_call_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned invokeId, bool isInvoke)
299
0
{
300
0
  ros_call_response_t rcr, *rcrp=NULL;
301
0
  ros_conv_info_t *ros_info;
302
0
  conversation_t *conversation;
303
304
  /* first see if we have already matched this */
305
0
  conversation = find_conversation_pinfo(pinfo, 0);
306
0
  if (conversation == NULL)
307
0
    return NULL;
308
309
0
  ros_info = (ros_conv_info_t *)conversation_get_proto_data(conversation, proto_ros);
310
0
  if (ros_info == NULL)
311
0
    return NULL;
312
313
0
  rcr.invokeId=invokeId;
314
0
  rcr.is_request = isInvoke;
315
316
0
  if(isInvoke) {
317
0
    rcr.req_frame=pinfo->num;
318
0
    rcr.rep_frame=0;
319
0
  } else {
320
0
    rcr.req_frame=0;
321
0
    rcr.rep_frame=pinfo->num;
322
0
  }
323
324
0
  rcrp=(ros_call_response_t *)wmem_map_lookup(ros_info->matched, &rcr);
325
326
0
  if(rcrp) {
327
    /* we have found a match */
328
0
    rcrp->is_request=rcr.is_request;
329
330
0
  } else {
331
332
    /* we haven't found a match - try and match it up */
333
334
0
    if(isInvoke) {
335
      /* this is a request - add it to the unmatched list */
336
337
      /* check that we don't already have one of those in the
338
   unmatched list and if so remove it */
339
340
0
      rcr.invokeId=invokeId;
341
342
0
      rcrp=(ros_call_response_t *)wmem_map_lookup(ros_info->unmatched, &rcr);
343
344
0
      if(rcrp){
345
0
  wmem_map_remove(ros_info->unmatched, rcrp);
346
0
      }
347
348
      /* if we can't reuse the old one, grab a new chunk */
349
0
      if(!rcrp){
350
0
  rcrp=wmem_new(wmem_file_scope(), ros_call_response_t);
351
0
      }
352
0
      rcrp->invokeId=invokeId;
353
0
      rcrp->req_frame=pinfo->num;
354
0
      rcrp->req_time=pinfo->abs_ts;
355
0
      rcrp->rep_frame=0;
356
0
      rcrp->is_request=true;
357
0
      wmem_map_insert(ros_info->unmatched, rcrp, rcrp);
358
0
      return NULL;
359
360
0
    } else {
361
362
      /* this is a result - it should be in our unmatched list */
363
364
0
      rcr.invokeId=invokeId;
365
0
      rcrp=(ros_call_response_t *)wmem_map_lookup(ros_info->unmatched, &rcr);
366
367
0
      if(rcrp){
368
369
0
  if(!rcrp->rep_frame){
370
0
    wmem_map_remove(ros_info->unmatched, rcrp);
371
0
    rcrp->rep_frame=pinfo->num;
372
0
    rcrp->is_request=false;
373
0
    wmem_map_insert(ros_info->matched, rcrp, rcrp);
374
0
  }
375
0
      }
376
0
    }
377
0
  }
378
379
0
  if(rcrp){ /* we have found a match */
380
0
    proto_item *item = NULL;
381
382
0
    if(rcrp->is_request){
383
0
      item=proto_tree_add_uint(tree, hf_ros_response_in, tvb, 0, 0, rcrp->rep_frame);
384
0
      proto_item_set_generated (item);
385
0
    } else {
386
0
      nstime_t ns;
387
0
      item=proto_tree_add_uint(tree, hf_ros_response_to, tvb, 0, 0, rcrp->req_frame);
388
0
      proto_item_set_generated (item);
389
0
      nstime_delta(&ns, &pinfo->abs_ts, &rcrp->req_time);
390
0
      item=proto_tree_add_time(tree, hf_ros_time, tvb, 0, 0, &ns);
391
0
      proto_item_set_generated (item);
392
0
    }
393
0
  }
394
395
0
  return rcrp;
396
0
}
397
398
399
400
static unsigned
401
0
dissect_ros_T_present(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
402
0
  offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
403
0
                                                &invokeid);
404
405
0
  return offset;
406
0
}
407
408
409
410
static unsigned
411
0
dissect_ros_NULL(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
412
0
  offset = dissect_ber_null(implicit_tag, actx, tree, tvb, offset, hf_index);
413
414
0
  return offset;
415
0
}
416
417
418
const value_string ros_InvokeId_vals[] = {
419
  {   0, "present" },
420
  {   1, "absent" },
421
  { 0, NULL }
422
};
423
424
static const ber_choice_t InvokeId_choice[] = {
425
  {   0, &hf_ros_present         , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_ros_T_present },
426
  {   1, &hf_ros_absent          , BER_CLASS_UNI, BER_UNI_TAG_NULL, BER_FLAGS_NOOWNTAG, dissect_ros_NULL },
427
  { 0, NULL, 0, 0, 0, NULL }
428
};
429
430
unsigned
431
0
dissect_ros_InvokeId(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
432
0
  offset = dissect_ber_choice(actx, tree, tvb, offset,
433
0
                                 InvokeId_choice, hf_index, ett_ros_InvokeId,
434
0
                                 NULL);
435
436
0
  return offset;
437
0
}
438
439
440
441
static unsigned
442
0
dissect_ros_INTEGER(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
443
0
  offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
444
0
                                                NULL);
445
446
0
  return offset;
447
0
}
448
449
450
451
static unsigned
452
0
dissect_ros_OperationCode(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
453
0
  offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
454
0
                                                &opcode);
455
456
0
  return offset;
457
0
}
458
459
460
461
static unsigned
462
0
dissect_ros_T_argument(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
463
0
  char *oid;
464
0
  proto_tree* subtree;
465
0
  struct SESSION_DATA_STRUCTURE* session = (struct SESSION_DATA_STRUCTURE *)actx->private_data;
466
467
  /* not sure what the length should be - -1 for now */
468
0
  subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_ros_invoke_argument, NULL, "invoke argument");
469
470
0
  ros_match_call_response(tvb, actx->pinfo, subtree, invokeid, true);
471
472
0
  if(session && session->pres_ctx_id && (oid = find_oid_by_pres_ctx_id(actx->pinfo, session->pres_ctx_id))) {
473
  /* this should be ROS! */
474
0
  session->ros_op = (ROS_OP_INVOKE | ROS_OP_ARGUMENT);
475
  /* now add the opcode */
476
0
  session->ros_op |= opcode;
477
0
  offset = call_ros_oid_callback(oid, tvb, offset, actx->pinfo, top_tree, session);
478
0
  }
479
480
481
0
  return offset;
482
0
}
483
484
485
static const ber_sequence_t Invoke_sequence[] = {
486
  { &hf_ros_invokeId        , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ros_InvokeId },
487
  { &hf_ros_linkedId        , BER_CLASS_CON, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_ros_INTEGER },
488
  { &hf_ros_opcode          , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_ros_OperationCode },
489
  { &hf_ros_argument        , BER_CLASS_ANY, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ros_T_argument },
490
  { NULL, 0, 0, 0, NULL }
491
};
492
493
static unsigned
494
0
dissect_ros_Invoke(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
495
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
496
0
                                   Invoke_sequence, hf_index, ett_ros_Invoke);
497
498
0
  return offset;
499
0
}
500
501
502
503
static unsigned
504
0
dissect_ros_OperationResult(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
505
0
  char *oid;
506
0
  proto_tree* subtree;
507
0
  struct SESSION_DATA_STRUCTURE* session = (struct SESSION_DATA_STRUCTURE *)actx->private_data;
508
509
  /* not sure what the length should be - -1 for now */
510
0
  subtree = proto_tree_add_subtree(tree, tvb, offset,-1, ett_ros_return_result, NULL, "return result");
511
512
0
  ros_match_call_response(tvb, actx->pinfo, subtree, invokeid, false);
513
514
0
  if(session && session->pres_ctx_id && (oid = find_oid_by_pres_ctx_id(actx->pinfo, session->pres_ctx_id))) {
515
  /* this should be ROS! */
516
0
  session->ros_op = (ROS_OP_INVOKE | ROS_OP_RESULT);
517
  /* now add the opcode */
518
0
  session->ros_op |= opcode;
519
0
  offset = call_ros_oid_callback(oid, tvb, offset, actx->pinfo, top_tree, session);
520
0
  }
521
522
523
0
  return offset;
524
0
}
525
526
527
static const ber_sequence_t T_result_sequence[] = {
528
  { &hf_ros_opcode          , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_ros_OperationCode },
529
  { &hf_ros_operationResult , BER_CLASS_ANY, 0, BER_FLAGS_NOOWNTAG, dissect_ros_OperationResult },
530
  { NULL, 0, 0, 0, NULL }
531
};
532
533
static unsigned
534
0
dissect_ros_T_result(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
535
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
536
0
                                   T_result_sequence, hf_index, ett_ros_T_result);
537
538
0
  return offset;
539
0
}
540
541
542
static const ber_sequence_t ReturnResult_sequence[] = {
543
  { &hf_ros_invokeId        , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ros_InvokeId },
544
  { &hf_ros_result          , BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ros_T_result },
545
  { NULL, 0, 0, 0, NULL }
546
};
547
548
static unsigned
549
0
dissect_ros_ReturnResult(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
550
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
551
0
                                   ReturnResult_sequence, hf_index, ett_ros_ReturnResult);
552
553
0
  return offset;
554
0
}
555
556
557
558
static unsigned
559
0
dissect_ros_ErrorCode(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
560
0
  offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
561
0
                                                &opcode);
562
563
0
  return offset;
564
0
}
565
566
567
568
static unsigned
569
0
dissect_ros_T_parameter(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
570
0
  char *oid;
571
0
  proto_tree* subtree;
572
0
  struct SESSION_DATA_STRUCTURE* session = (struct SESSION_DATA_STRUCTURE *)actx->private_data;
573
574
  /* not sure what the length should be - -1 for now */
575
0
  subtree = proto_tree_add_subtree(tree, tvb, offset,-1, ett_ros_return_result, NULL, "return result");
576
577
0
  ros_match_call_response(tvb, actx->pinfo, subtree, invokeid, false);
578
579
0
  if(session && session->pres_ctx_id && (oid = find_oid_by_pres_ctx_id(actx->pinfo, session->pres_ctx_id))) {
580
  /* this should be ROS! */
581
0
  session->ros_op = (ROS_OP_INVOKE | ROS_OP_ERROR);
582
  /* now add the opcode  (really the error code) */
583
0
  session->ros_op |= opcode;
584
0
  offset = call_ros_oid_callback(oid, tvb, offset, actx->pinfo, top_tree, session);
585
0
  }
586
587
588
0
  return offset;
589
0
}
590
591
592
static const ber_sequence_t ReturnError_sequence[] = {
593
  { &hf_ros_invokeId        , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ros_InvokeId },
594
  { &hf_ros_errcode         , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_ros_ErrorCode },
595
  { &hf_ros_parameter       , BER_CLASS_ANY, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ros_T_parameter },
596
  { NULL, 0, 0, 0, NULL }
597
};
598
599
static unsigned
600
0
dissect_ros_ReturnError(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
601
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
602
0
                                   ReturnError_sequence, hf_index, ett_ros_ReturnError);
603
604
0
  return offset;
605
0
}
606
607
608
static const value_string ros_GeneralProblem_vals[] = {
609
  {   0, "unrecognizedPDU" },
610
  {   1, "mistypedPDU" },
611
  {   2, "badlyStructuredPDU" },
612
  { 0, NULL }
613
};
614
615
616
static unsigned
617
0
dissect_ros_GeneralProblem(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
618
0
  uint32_t problem;
619
620
0
    offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
621
0
                                                &problem);
622
623
624
0
  col_append_fstr(actx->pinfo->cinfo, COL_INFO, " %s", val_to_str(actx->pinfo->pool, problem, ros_GeneralProblem_vals, "GeneralProblem(%d)"));
625
626
627
0
  return offset;
628
0
}
629
630
631
static const value_string ros_InvokeProblem_vals[] = {
632
  {   0, "duplicateInvocation" },
633
  {   1, "unrecognizedOperation" },
634
  {   2, "mistypedArgument" },
635
  {   3, "resourceLimitation" },
636
  {   4, "releaseInProgress" },
637
  {   5, "unrecognizedLinkedId" },
638
  {   6, "linkedResponseUnexpected" },
639
  {   7, "unexpectedLinkedOperation" },
640
  { 0, NULL }
641
};
642
643
644
static unsigned
645
0
dissect_ros_InvokeProblem(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
646
0
  uint32_t problem;
647
648
0
    offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
649
0
                                                &problem);
650
651
652
0
  col_append_fstr(actx->pinfo->cinfo, COL_INFO, " %s", val_to_str(actx->pinfo->pool, problem, ros_InvokeProblem_vals, "InvokeProblem(%d)"));
653
654
655
0
  return offset;
656
0
}
657
658
659
static const value_string ros_ReturnResultProblem_vals[] = {
660
  {   0, "unrecognizedInvocation" },
661
  {   1, "resultResponseUnexpected" },
662
  {   2, "mistypedResult" },
663
  { 0, NULL }
664
};
665
666
667
static unsigned
668
0
dissect_ros_ReturnResultProblem(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
669
0
  uint32_t problem;
670
671
0
    offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
672
0
                                                &problem);
673
674
675
0
  col_append_fstr(actx->pinfo->cinfo, COL_INFO, " %s", val_to_str(actx->pinfo->pool, problem, ros_ReturnResultProblem_vals, "ReturnResultProblem(%d)"));
676
677
678
0
  return offset;
679
0
}
680
681
682
static const value_string ros_ReturnErrorProblem_vals[] = {
683
  {   0, "unrecognizedInvocation" },
684
  {   1, "errorResponseUnexpected" },
685
  {   2, "unrecognizedError" },
686
  {   3, "unexpectedError" },
687
  {   4, "mistypedParameter" },
688
  { 0, NULL }
689
};
690
691
692
static unsigned
693
0
dissect_ros_ReturnErrorProblem(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
694
0
  uint32_t problem;
695
696
0
    offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
697
0
                                                &problem);
698
699
700
0
  col_append_fstr(actx->pinfo->cinfo, COL_INFO, " %s", val_to_str(actx->pinfo->pool, problem, ros_ReturnErrorProblem_vals, "ReturnErrorProblem(%d)"));
701
702
703
0
  return offset;
704
0
}
705
706
707
static const value_string ros_T_problem_vals[] = {
708
  {   0, "general" },
709
  {   1, "invoke" },
710
  {   2, "returnResult" },
711
  {   3, "returnError" },
712
  { 0, NULL }
713
};
714
715
static const ber_choice_t T_problem_choice[] = {
716
  {   0, &hf_ros_general         , BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_ros_GeneralProblem },
717
  {   1, &hf_ros_invokeProblem   , BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_ros_InvokeProblem },
718
  {   2, &hf_ros_rejectResult    , BER_CLASS_CON, 2, BER_FLAGS_IMPLTAG, dissect_ros_ReturnResultProblem },
719
  {   3, &hf_ros_rejectError     , BER_CLASS_CON, 3, BER_FLAGS_IMPLTAG, dissect_ros_ReturnErrorProblem },
720
  { 0, NULL, 0, 0, 0, NULL }
721
};
722
723
static unsigned
724
0
dissect_ros_T_problem(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
725
0
  offset = dissect_ber_choice(actx, tree, tvb, offset,
726
0
                                 T_problem_choice, hf_index, ett_ros_T_problem,
727
0
                                 NULL);
728
729
0
  return offset;
730
0
}
731
732
733
static const ber_sequence_t Reject_sequence[] = {
734
  { &hf_ros_invokeId        , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ros_InvokeId },
735
  { &hf_ros_problem         , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ros_T_problem },
736
  { NULL, 0, 0, 0, NULL }
737
};
738
739
static unsigned
740
0
dissect_ros_Reject(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
741
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
742
0
                                   Reject_sequence, hf_index, ett_ros_Reject);
743
744
0
  return offset;
745
0
}
746
747
748
749
static unsigned
750
0
dissect_ros_T_reject(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
751
0
  col_set_str(actx->pinfo->cinfo, COL_INFO, "Reject");
752
0
    offset = dissect_ros_Reject(implicit_tag, tvb, offset, actx, tree, hf_index);
753
754
755
756
0
  return offset;
757
0
}
758
759
760
761
static unsigned
762
0
dissect_ros_T_bind_invoke(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
763
0
  char *oid;
764
0
  struct SESSION_DATA_STRUCTURE* session = (struct SESSION_DATA_STRUCTURE *)actx->private_data;
765
766
  /* not sure what the length should be - -1 for now */
767
0
  proto_tree_add_subtree(tree, tvb, offset,-1, ett_ros_bind_result, NULL, "bind-invoke");
768
769
0
  if(session && session->pres_ctx_id && (oid = find_oid_by_pres_ctx_id(actx->pinfo, session->pres_ctx_id))) {
770
    /* this should be ROS! */
771
0
    session->ros_op = (ROS_OP_BIND | ROS_OP_ARGUMENT);
772
0
    offset = call_ros_oid_callback(oid, tvb, offset, actx->pinfo, top_tree, session);
773
0
  }
774
775
776
0
  return offset;
777
0
}
778
779
780
781
static unsigned
782
0
dissect_ros_T_bind_result(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
783
0
  char *oid;
784
0
  struct SESSION_DATA_STRUCTURE* session = (struct SESSION_DATA_STRUCTURE *)actx->private_data;
785
786
  /* not sure what the length should be - -1 for now */
787
0
  proto_tree_add_subtree(tree, tvb, offset,-1, ett_ros_bind_result, NULL, "bind-result");
788
789
0
  if(session && session->pres_ctx_id && (oid = find_oid_by_pres_ctx_id(actx->pinfo, session->pres_ctx_id))) {
790
    /* this should be ROS! */
791
0
    session->ros_op = (ROS_OP_BIND | ROS_OP_RESULT);
792
0
    offset = call_ros_oid_callback(oid, tvb, offset, actx->pinfo, top_tree, session);
793
0
  }
794
795
796
0
  return offset;
797
0
}
798
799
800
801
static unsigned
802
0
dissect_ros_T_bind_error(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
803
0
  char *oid;
804
0
  struct SESSION_DATA_STRUCTURE* session = (struct SESSION_DATA_STRUCTURE *)actx->private_data;
805
806
  /* not sure what the length should be - -1 for now */
807
0
  proto_tree_add_subtree(tree, tvb, offset,-1, ett_ros_bind_error, NULL, "bind-error");
808
809
0
  if(session && session->pres_ctx_id && (oid = find_oid_by_pres_ctx_id(actx->pinfo, session->pres_ctx_id))) {
810
    /* this should be ROS! */
811
0
    session->ros_op = (ROS_OP_BIND | ROS_OP_ERROR);
812
0
    offset = call_ros_oid_callback(oid, tvb, offset, actx->pinfo, top_tree, session);
813
0
  }
814
815
816
817
0
  return offset;
818
0
}
819
820
821
822
static unsigned
823
0
dissect_ros_T_unbind_invoke(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
824
0
  char *oid;
825
0
  struct SESSION_DATA_STRUCTURE* session = (struct SESSION_DATA_STRUCTURE *)actx->private_data;
826
827
  /* not sure what the length should be - -1 for now */
828
0
  proto_tree_add_subtree(tree, tvb, offset,-1, ett_ros_unbind_invoke, NULL, "unbind-invoke");
829
830
0
  if(session && session->pres_ctx_id && (oid = find_oid_by_pres_ctx_id(actx->pinfo, session->pres_ctx_id))) {
831
    /* this should be ROS! */
832
0
    session->ros_op = (ROS_OP_UNBIND | ROS_OP_ARGUMENT);
833
0
    offset = call_ros_oid_callback(oid, tvb, offset, actx->pinfo, top_tree, session);
834
0
  }
835
836
837
838
0
  return offset;
839
0
}
840
841
842
843
static unsigned
844
0
dissect_ros_T_unbind_result(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
845
0
  char *oid;
846
0
  struct SESSION_DATA_STRUCTURE* session = (struct SESSION_DATA_STRUCTURE *)actx->private_data;
847
848
  /* not sure what the length should be - -1 for now */
849
0
  proto_tree_add_subtree(tree, tvb, offset,-1, ett_ros_unbind_result, NULL, "unbind-result");
850
851
0
  if(session && session->pres_ctx_id && (oid = find_oid_by_pres_ctx_id(actx->pinfo, session->pres_ctx_id))) {
852
    /* this should be ROS! */
853
0
    session->ros_op = (ROS_OP_UNBIND | ROS_OP_RESULT);
854
0
    offset = call_ros_oid_callback(oid, tvb, offset, actx->pinfo, top_tree, session);
855
0
  }
856
857
858
0
  return offset;
859
0
}
860
861
862
863
static unsigned
864
0
dissect_ros_T_unbind_error(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
865
0
  char *oid;
866
0
  struct SESSION_DATA_STRUCTURE* session = (struct SESSION_DATA_STRUCTURE *)actx->private_data;
867
868
  /* not sure what the length should be - -1 for now */
869
0
  proto_tree_add_subtree(tree, tvb, offset,-1, ett_ros_unbind_error, NULL, "unbind-error");
870
871
0
  if(session && session->pres_ctx_id && (oid = find_oid_by_pres_ctx_id(actx->pinfo, session->pres_ctx_id))) {
872
    /* this should be ROS! */
873
0
    session->ros_op = (ROS_OP_UNBIND | ROS_OP_ERROR);
874
0
    offset = call_ros_oid_callback(oid, tvb, offset, actx->pinfo, top_tree, session);
875
0
  }
876
877
878
0
  return offset;
879
0
}
880
881
882
const value_string ros_ROS_vals[] = {
883
  {   1, "invoke" },
884
  {   2, "returnResult" },
885
  {   3, "returnError" },
886
  {   4, "reject" },
887
  {  16, "bind-invoke" },
888
  {  17, "bind-result" },
889
  {  18, "bind-error" },
890
  {  19, "unbind-invoke" },
891
  {  20, "unbind-result" },
892
  {  21, "unbind-error" },
893
  { 0, NULL }
894
};
895
896
static const ber_choice_t ROS_choice[] = {
897
  {   1, &hf_ros_invoke          , BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_ros_Invoke },
898
  {   2, &hf_ros_returnResult    , BER_CLASS_CON, 2, BER_FLAGS_IMPLTAG, dissect_ros_ReturnResult },
899
  {   3, &hf_ros_returnError     , BER_CLASS_CON, 3, BER_FLAGS_IMPLTAG, dissect_ros_ReturnError },
900
  {   4, &hf_ros_reject          , BER_CLASS_CON, 4, BER_FLAGS_IMPLTAG, dissect_ros_T_reject },
901
  {  16, &hf_ros_bind_invoke     , BER_CLASS_CON, 16, BER_FLAGS_IMPLTAG, dissect_ros_T_bind_invoke },
902
  {  17, &hf_ros_bind_result     , BER_CLASS_CON, 17, BER_FLAGS_IMPLTAG, dissect_ros_T_bind_result },
903
  {  18, &hf_ros_bind_error      , BER_CLASS_CON, 18, BER_FLAGS_IMPLTAG, dissect_ros_T_bind_error },
904
  {  19, &hf_ros_unbind_invoke   , BER_CLASS_CON, 19, BER_FLAGS_IMPLTAG, dissect_ros_T_unbind_invoke },
905
  {  20, &hf_ros_unbind_result   , BER_CLASS_CON, 20, BER_FLAGS_IMPLTAG, dissect_ros_T_unbind_result },
906
  {  21, &hf_ros_unbind_error    , BER_CLASS_CON, 21, BER_FLAGS_IMPLTAG, dissect_ros_T_unbind_error },
907
  { 0, NULL, 0, 0, 0, NULL }
908
};
909
910
unsigned
911
0
dissect_ros_ROS(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
912
0
  offset = dissect_ber_choice(actx, tree, tvb, offset,
913
0
                                 ROS_choice, hf_index, ett_ros_ROS,
914
0
                                 NULL);
915
916
0
  return offset;
917
0
}
918
919
920
921
static unsigned
922
0
dissect_ros_OBJECT_IDENTIFIER(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
923
0
  offset = dissect_ber_object_identifier(implicit_tag, actx, tree, tvb, offset, hf_index, NULL);
924
925
0
  return offset;
926
0
}
927
928
929
const value_string ros_Code_vals[] = {
930
  {   0, "local" },
931
  {   1, "global" },
932
  { 0, NULL }
933
};
934
935
static const ber_choice_t Code_choice[] = {
936
  {   0, &hf_ros_local           , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_ros_INTEGER },
937
  {   1, &hf_ros_global          , BER_CLASS_UNI, BER_UNI_TAG_OID, BER_FLAGS_NOOWNTAG, dissect_ros_OBJECT_IDENTIFIER },
938
  { 0, NULL, 0, 0, 0, NULL }
939
};
940
941
unsigned
942
0
dissect_ros_Code(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
943
0
  offset = dissect_ber_choice(actx, tree, tvb, offset,
944
0
                                 Code_choice, hf_index, ett_ros_Code,
945
0
                                 NULL);
946
947
0
  return offset;
948
0
}
949
950
951
/*
952
* Dissect ROS PDUs inside a PPDU.
953
*/
954
static int
955
dissect_ros(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
956
0
{
957
0
  unsigned offset = 0;
958
0
  unsigned old_offset;
959
0
  proto_item *item;
960
0
  proto_tree *tree;
961
0
  proto_tree *next_tree=NULL;
962
0
  conversation_t *conversation;
963
0
  ros_conv_info_t *ros_info = NULL;
964
0
  asn1_ctx_t asn1_ctx;
965
0
  asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, true, pinfo);
966
967
  /* do we have application context from the acse dissector? */
968
0
  if (data == NULL)
969
0
    return 0;
970
0
  asn1_ctx.private_data = data;
971
972
  /* save parent_tree so subdissectors can create new top nodes */
973
0
  top_tree=parent_tree;
974
975
0
  conversation = find_or_create_conversation(pinfo);
976
977
  /*
978
   * Do we already have our info
979
   */
980
0
  ros_info = (ros_conv_info_t *)conversation_get_proto_data(conversation, proto_ros);
981
0
  if (ros_info == NULL) {
982
983
    /* No.  Attach that information to the conversation. */
984
985
0
    ros_info = (ros_conv_info_t *)wmem_new0(wmem_file_scope(), ros_conv_info_t);
986
0
    ros_info->matched=wmem_map_new(wmem_file_scope(), ros_info_hash_matched, ros_info_equal_matched);
987
0
    ros_info->unmatched=wmem_map_new(wmem_file_scope(), ros_info_hash_unmatched, ros_info_equal_unmatched);
988
989
0
    conversation_add_proto_data(conversation, proto_ros, ros_info);
990
0
  }
991
992
0
  item = proto_tree_add_item(parent_tree, proto_ros, tvb, 0, -1, ENC_NA);
993
0
  tree = proto_item_add_subtree(item, ett_ros);
994
995
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "ROS");
996
0
    col_clear(pinfo->cinfo, COL_INFO);
997
998
0
  while (tvb_reported_length_remaining(tvb, offset) > 0){
999
0
    old_offset=offset;
1000
0
    offset=dissect_ros_ROS(false, tvb, offset, &asn1_ctx , tree, -1);
1001
0
    if(offset == old_offset){
1002
0
      next_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_ros_unknown, &item, "Unknown ROS PDU");
1003
1004
0
      expert_add_info(pinfo, item, &ei_ros_unknown_ros_pdu);
1005
0
      dissect_unknown_ber(pinfo, tvb, offset, next_tree);
1006
0
      break;
1007
0
    }
1008
0
  }
1009
1010
0
  return tvb_captured_length(tvb);
1011
0
}
1012
1013
/*--- proto_register_ros -------------------------------------------*/
1014
15
void proto_register_ros(void) {
1015
1016
  /* List of fields */
1017
15
  static hf_register_info hf[] =
1018
15
  {
1019
15
    { &hf_ros_response_in,
1020
15
      { "Response In", "ros.response_in",
1021
15
  FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
1022
15
  "The response to this remote operation invocation is in this frame", HFILL }},
1023
15
    { &hf_ros_response_to,
1024
15
      { "Response To", "ros.response_to",
1025
15
  FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0x0,
1026
15
  "This is a response to the remote operation invocation in this frame", HFILL }},
1027
15
    { &hf_ros_time,
1028
15
      { "Time", "ros.time",
1029
15
  FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1030
15
  "The time between the Invoke and the Response", HFILL }},
1031
1032
15
    { &hf_ros_invoke,
1033
15
      { "invoke", "ros.invoke_element",
1034
15
        FT_NONE, BASE_NONE, NULL, 0,
1035
15
        NULL, HFILL }},
1036
15
    { &hf_ros_returnResult,
1037
15
      { "returnResult", "ros.returnResult_element",
1038
15
        FT_NONE, BASE_NONE, NULL, 0,
1039
15
        NULL, HFILL }},
1040
15
    { &hf_ros_returnError,
1041
15
      { "returnError", "ros.returnError_element",
1042
15
        FT_NONE, BASE_NONE, NULL, 0,
1043
15
        NULL, HFILL }},
1044
15
    { &hf_ros_reject,
1045
15
      { "reject", "ros.reject_element",
1046
15
        FT_NONE, BASE_NONE, NULL, 0,
1047
15
        NULL, HFILL }},
1048
15
    { &hf_ros_bind_invoke,
1049
15
      { "bind-invoke", "ros.bind_invoke_element",
1050
15
        FT_NONE, BASE_NONE, NULL, 0,
1051
15
        NULL, HFILL }},
1052
15
    { &hf_ros_bind_result,
1053
15
      { "bind-result", "ros.bind_result_element",
1054
15
        FT_NONE, BASE_NONE, NULL, 0,
1055
15
        NULL, HFILL }},
1056
15
    { &hf_ros_bind_error,
1057
15
      { "bind-error", "ros.bind_error_element",
1058
15
        FT_NONE, BASE_NONE, NULL, 0,
1059
15
        NULL, HFILL }},
1060
15
    { &hf_ros_unbind_invoke,
1061
15
      { "unbind-invoke", "ros.unbind_invoke_element",
1062
15
        FT_NONE, BASE_NONE, NULL, 0,
1063
15
        NULL, HFILL }},
1064
15
    { &hf_ros_unbind_result,
1065
15
      { "unbind-result", "ros.unbind_result_element",
1066
15
        FT_NONE, BASE_NONE, NULL, 0,
1067
15
        NULL, HFILL }},
1068
15
    { &hf_ros_unbind_error,
1069
15
      { "unbind-error", "ros.unbind_error_element",
1070
15
        FT_NONE, BASE_NONE, NULL, 0,
1071
15
        NULL, HFILL }},
1072
15
    { &hf_ros_invokeId,
1073
15
      { "invokeId", "ros.invokeId",
1074
15
        FT_UINT32, BASE_DEC, VALS(ros_InvokeId_vals), 0,
1075
15
        NULL, HFILL }},
1076
15
    { &hf_ros_linkedId,
1077
15
      { "linkedId", "ros.linkedId",
1078
15
        FT_INT32, BASE_DEC, NULL, 0,
1079
15
        "INTEGER", HFILL }},
1080
15
    { &hf_ros_opcode,
1081
15
      { "opcode", "ros.opcode",
1082
15
        FT_INT32, BASE_DEC, NULL, 0,
1083
15
        "OperationCode", HFILL }},
1084
15
    { &hf_ros_argument,
1085
15
      { "argument", "ros.argument_element",
1086
15
        FT_NONE, BASE_NONE, NULL, 0,
1087
15
        NULL, HFILL }},
1088
15
    { &hf_ros_result,
1089
15
      { "result", "ros.result_element",
1090
15
        FT_NONE, BASE_NONE, NULL, 0,
1091
15
        NULL, HFILL }},
1092
15
    { &hf_ros_operationResult,
1093
15
      { "result", "ros.operationResult_element",
1094
15
        FT_NONE, BASE_NONE, NULL, 0,
1095
15
        "OperationResult", HFILL }},
1096
15
    { &hf_ros_errcode,
1097
15
      { "errcode", "ros.errcode",
1098
15
        FT_INT32, BASE_DEC, NULL, 0,
1099
15
        "ErrorCode", HFILL }},
1100
15
    { &hf_ros_parameter,
1101
15
      { "parameter", "ros.parameter_element",
1102
15
        FT_NONE, BASE_NONE, NULL, 0,
1103
15
        NULL, HFILL }},
1104
15
    { &hf_ros_problem,
1105
15
      { "problem", "ros.problem",
1106
15
        FT_UINT32, BASE_DEC, VALS(ros_T_problem_vals), 0,
1107
15
        NULL, HFILL }},
1108
15
    { &hf_ros_general,
1109
15
      { "general", "ros.general",
1110
15
        FT_INT32, BASE_DEC, VALS(ros_GeneralProblem_vals), 0,
1111
15
        "GeneralProblem", HFILL }},
1112
15
    { &hf_ros_invokeProblem,
1113
15
      { "invoke", "ros.invokeProblem",
1114
15
        FT_INT32, BASE_DEC, VALS(ros_InvokeProblem_vals), 0,
1115
15
        "InvokeProblem", HFILL }},
1116
15
    { &hf_ros_rejectResult,
1117
15
      { "returnResult", "ros.rejectResult",
1118
15
        FT_INT32, BASE_DEC, VALS(ros_ReturnResultProblem_vals), 0,
1119
15
        "ReturnResultProblem", HFILL }},
1120
15
    { &hf_ros_rejectError,
1121
15
      { "returnError", "ros.rejectError",
1122
15
        FT_INT32, BASE_DEC, VALS(ros_ReturnErrorProblem_vals), 0,
1123
15
        "ReturnErrorProblem", HFILL }},
1124
15
    { &hf_ros_present,
1125
15
      { "present", "ros.present",
1126
15
        FT_INT32, BASE_DEC, NULL, 0,
1127
15
        NULL, HFILL }},
1128
15
    { &hf_ros_absent,
1129
15
      { "absent", "ros.absent_element",
1130
15
        FT_NONE, BASE_NONE, NULL, 0,
1131
15
        NULL, HFILL }},
1132
15
    { &hf_ros_local,
1133
15
      { "local", "ros.local",
1134
15
        FT_INT32, BASE_DEC, NULL, 0,
1135
15
        "INTEGER", HFILL }},
1136
15
    { &hf_ros_global,
1137
15
      { "global", "ros.global",
1138
15
        FT_OID, BASE_NONE, NULL, 0,
1139
15
        "OBJECT_IDENTIFIER", HFILL }},
1140
15
  };
1141
1142
  /* List of subtrees */
1143
15
  static int *ett[] = {
1144
15
    &ett_ros,
1145
15
    &ett_ros_unknown,
1146
15
    &ett_ros_invoke_argument,
1147
15
    &ett_ros_return_result,
1148
15
    &ett_ros_bind_invoke,
1149
15
    &ett_ros_bind_result,
1150
15
    &ett_ros_bind_error,
1151
15
    &ett_ros_unbind_invoke,
1152
15
    &ett_ros_unbind_result,
1153
15
    &ett_ros_unbind_error,
1154
1155
15
    &ett_ros_ROS,
1156
15
    &ett_ros_Invoke,
1157
15
    &ett_ros_ReturnResult,
1158
15
    &ett_ros_T_result,
1159
15
    &ett_ros_ReturnError,
1160
15
    &ett_ros_Reject,
1161
15
    &ett_ros_T_problem,
1162
15
    &ett_ros_InvokeId,
1163
15
    &ett_ros_Code,
1164
15
  };
1165
1166
15
  static ei_register_info ei[] = {
1167
15
     { &ei_ros_dissector_oid_not_implemented, { "ros.dissector_oid_not_implemented", PI_UNDECODED, PI_WARN, "ROS: Dissector for OID not implemented", EXPFILL }},
1168
15
     { &ei_ros_unknown_ros_pdu, { "ros.unknown_ros_pdu", PI_UNDECODED, PI_WARN, "Unknown ROS PDU", EXPFILL }},
1169
15
  };
1170
1171
15
  expert_module_t* expert_ros;
1172
1173
  /* Register protocol */
1174
15
  proto_ros = proto_register_protocol("X.880 OSI Remote Operations Service", "ROS", "ros");
1175
15
  ros_handle = register_dissector("ros", dissect_ros, proto_ros);
1176
  /* Register fields and subtrees */
1177
15
  proto_register_field_array(proto_ros, hf, array_length(hf));
1178
15
  proto_register_subtree_array(ett, array_length(ett));
1179
15
  expert_ros = expert_register_protocol(proto_ros);
1180
15
  expert_register_field_array(expert_ros, ei, array_length(ei));
1181
1182
15
  ros_oid_dissector_table = register_dissector_table("ros.oid", "ROS OID Dissectors", proto_ros, FT_STRING, STRING_CASE_SENSITIVE);
1183
15
  protocol_table = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
1184
15
}
1185
1186
1187
/*--- proto_reg_handoff_ros --- */
1188
15
void proto_reg_handoff_ros(void) {
1189
1190
1191
15
}