Coverage Report

Created: 2026-11-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-agentx.c
Line
Count
Source
1
/* packet-agentx.c
2
 * Routines for Agent Extensibility (AgentX) Protocol disassembly
3
 * RFC 2257
4
 *
5
 * Copyright (c) 2005 by Oleg Terletsky <oleg.terletsky@comverse.com>
6
 *
7
 * Wireshark - Network traffic analyzer
8
 * By Gerald Combs <gerald@wireshark.org>
9
 * Copyright 1999 Gerald Combs
10
 *
11
 * SPDX-License-Identifier: GPL-2.0-or-later
12
 */
13
14
#include "config.h"
15
16
#include <epan/packet.h>
17
#include <epan/to_str.h>
18
#include <epan/tfs.h>
19
#include <wsutil/ws_roundup.h>
20
21
#include "packet-tcp.h"
22
23
16
#define AGENTX_TCP_PORT     705
24
25
void proto_register_agentx(void);
26
void proto_reg_handoff_agentx(void);
27
28
static dissector_handle_t agentx_handle;
29
30
/* Define the agentx proto */
31
static int proto_agentx;
32
33
34
static int hf_version;
35
static int hf_type;
36
static int hf_flags;
37
static int hf_flags_register;
38
static int hf_flags_newindex;
39
static int hf_flags_anyindex;
40
static int hf_flags_context;
41
static int hf_flags_byteorder;
42
static int hf_session_id;
43
static int hf_trans_id;
44
static int hf_packet_id;
45
static int hf_payload_len;
46
static int hf_ostring_len;
47
static int hf_ostring;
48
static int hf_oid_sub;
49
static int hf_oid_prefix;
50
static int hf_oid_include;
51
static int hf_oid_str;
52
static int hf_resp_uptime;
53
static int hf_resp_error;
54
static int hf_resp_index;
55
static int hf_vtag;
56
static int hf_val32;
57
static int hf_val64;
58
static int hf_open_timeout;
59
static int hf_close_reason;
60
static int hf_reg_timeout;
61
static int hf_reg_prio;
62
static int hf_reg_rsid;
63
static int hf_reg_ubound;
64
static int hf_unreg_timeout;
65
static int hf_unreg_prio;
66
static int hf_unreg_rsid;
67
static int hf_unreg_ubound;
68
static int hf_gbulk_nrepeat;
69
static int hf_gbulk_mrepeat;
70
71
72
static int ett_flags;
73
static int ett_agentx;
74
static int ett_pdu_hdr;
75
static int ett_get;
76
static int ett_getnext;
77
static int ett_search_range;
78
static int ett_obj_ident;
79
static int ett_response;
80
static int ett_valrep;
81
static int ett_open;
82
static int ett_close;
83
static int ett_register;
84
static int ett_unregister;
85
static int ett_getbulk;
86
static int ett_testset;
87
static int ett_commitset;
88
static int ett_undoset;
89
static int ett_cleanupset;
90
static int ett_notify;
91
static int ett_ping;
92
static int ett_idxalloc;
93
static int ett_idxdalloc;
94
static int ett_addcap;
95
static int ett_remcap;
96
97
98
2
#define   AGENTX_OPEN_PDU      1
99
1
#define         AGENTX_CLOSE_PDU       2
100
4
#define         AGENTX_REGISTER_PDU    3
101
2
#define         AGENTX_UNREGISTER_PDU      4
102
271
#define         AGENTX_GET_PDU       5
103
9
#define         AGENTX_GETNEXT_PDU     6
104
12
#define         AGENTX_GETBULK_PDU     7
105
7
#define         AGENTX_TESTSET_PDU     8
106
0
#define         AGENTX_COMMITSET_PDU     9
107
0
#define         AGENTX_UNDOSET_PDU    10
108
0
#define         AGENTX_CLEANUPSET_PDU   11
109
7
#define         AGENTX_NOTIFY_PDU   12
110
1
#define         AGENTX_PING_PDU     13
111
5
#define         AGENTX_INDEX_ALLOC_PDU    14
112
8
#define         AGENTX_INDEX_DEALLOC_PDU  15
113
1
#define         AGENTX_ADD_AGENT_CAPS_PDU 16
114
1
#define         AGENTX_REM_AGENT_CAPS_PDU 17
115
9
#define         AGENTX_RESPONSE_PDU   18
116
117
118
static const value_string type_values [] = {
119
  { AGENTX_OPEN_PDU,    "Open-PDU" },
120
  { AGENTX_CLOSE_PDU,   "Close-PDU" },
121
  { AGENTX_REGISTER_PDU,    "Register-PDU" },
122
  { AGENTX_UNREGISTER_PDU,  "Unregister-PDU" },
123
  { AGENTX_GET_PDU,   "Get-PDU" },
124
  { AGENTX_GETNEXT_PDU,   "GetNext-PDU" },
125
  { AGENTX_GETBULK_PDU,   "GetBulk-PDU" },
126
  { AGENTX_TESTSET_PDU,   "TestSet-PDU" },
127
  { AGENTX_COMMITSET_PDU,   "CommitSet-PDU" },
128
  { AGENTX_UNDOSET_PDU,   "UndoSet-PDU" },
129
  { AGENTX_CLEANUPSET_PDU,  "CleanupSet-PDU" },
130
  { AGENTX_NOTIFY_PDU,    "Notify-PDU" },
131
  { AGENTX_PING_PDU,    "Ping-PDU" },
132
  { AGENTX_INDEX_ALLOC_PDU, "IndexAllocate-PDU" },
133
  { AGENTX_INDEX_DEALLOC_PDU, "IndexDeallocate-PDU" },
134
  { AGENTX_ADD_AGENT_CAPS_PDU,  "AddAgentCaps-PDU" },
135
  { AGENTX_REM_AGENT_CAPS_PDU,  "RemoveAgentCaps-PDU" },
136
  { AGENTX_RESPONSE_PDU,    "Response-PDU" },
137
  { 0, NULL }
138
};
139
static value_string_ext type_values_ext = VALUE_STRING_EXT_INIT(type_values);
140
141
/* VarBind types */
142
143
2
#define VB_INT      2
144
1
#define VB_OSTR     4
145
0
#define VB_NULL     5
146
1
#define VB_OID      6
147
2
#define VB_IPADDR  64
148
1
#define VB_COUNTER32   65
149
2
#define VB_GAUGE32   66
150
1
#define VB_TIMETICK  67
151
0
#define VB_OPAQUE  68
152
0
#define VB_COUNTER64   70
153
0
#define VB_NOSUCHOBJ  128
154
0
#define VB_NOSUCHINST 129
155
0
#define VB_ENDOFMIB 130
156
157
158
static const value_string vtag_values [] = {
159
  { VB_INT,   "Integer" },
160
  { VB_OSTR,    "Octet String" },
161
  { VB_NULL,    "Null" },
162
  { VB_OID,   "Object Identifier" },
163
  { VB_IPADDR,    "IpAddress" },
164
  { VB_COUNTER32,   "Counter32" },
165
  { VB_GAUGE32,   "Gauge32" },
166
  { VB_TIMETICK,    "TimeTicks" },
167
  { VB_OPAQUE,    "Opaque" },
168
  { VB_COUNTER64,   "Counter64" },
169
  { VB_NOSUCHOBJ,   "noSuchObject" },
170
  { VB_NOSUCHINST,  "noSuchInstance" },
171
  { VB_ENDOFMIB,    "endOfMibView" },
172
  { 0, NULL }
173
};
174
static value_string_ext vtag_values_ext = VALUE_STRING_EXT_INIT(vtag_values);
175
176
/* Close reasons */
177
#define CREASON_OTHER     1
178
#define CREASON_PARSE_ERROR   2
179
#define CREASON_PROTOCOL_ERROR  3
180
#define CREASON_TIMEOUTS  4
181
#define CREASON_SHUTDOWN  5
182
#define CREASON_BY_MANAGER  6
183
184
185
static const value_string close_reasons[] = {
186
  { CREASON_OTHER,    "reasonOther" },
187
  { CREASON_PARSE_ERROR,    "reasonParseError" },
188
  { CREASON_PROTOCOL_ERROR,   "reasonProtocolError" },
189
  { CREASON_TIMEOUTS,     "reasonTimeouts" },
190
  { CREASON_SHUTDOWN ,    "reasonShutdown" },
191
  { CREASON_BY_MANAGER,     "reasonByManager" },
192
  { 0, NULL }
193
};
194
195
196
/* Response errors */
197
#define AGENTX_NO_ERROR     0
198
#define AGENTX_TOO_BIG      1
199
#define AGENTX_NO_SUCH_NAME   2
200
#define AGENTX_BAD_VALUE    3
201
#define AGENTX_READ_ONLY    4
202
#define AGENTX_GEN_ERROR    5
203
#define AGENTX_NO_ACCESS    6
204
#define AGENTX_WRONG_TYPE   7
205
#define AGENTX_WRONG_LEN    8
206
#define AGENTX_WRONG_ENCODE   9
207
#define AGENTX_WRONG_VALUE   10
208
#define AGENTX_NO_CREATION   11
209
#define AGENTX_INCONSIST_VALUE   12
210
#define AGENTX_RES_UNAVAIL   13
211
#define AGENTX_COMMIT_FAILED   14
212
#define AGENTX_UNDO_FAILED   15
213
#define AGENTX_AUTH_ERROR  16
214
#define AGENTX_NOTWRITABLE   17
215
#define AGENTX_INCONSIS_NAME   18
216
#define AGENTX_OPEN_FAILED  256
217
#define AGENTX_NOT_OPEN   257
218
#define AGENTX_IDX_WRONT_TYPE 258
219
#define AGENTX_IDX_ALREAY_ALLOC 259
220
#define AGENTX_IDX_NONEAVAIL  260
221
#define AGENTX_IDX_NOTALLOC 261
222
#define AGENTX_UNSUPP_CONTEXT 262
223
#define AGENTX_DUP_REGISTR  263
224
#define AGENTX_UNKNOWN_REG  264
225
#define AGENTX_UNKNOWN_CAPS 265
226
227
228
static const value_string resp_errors[] = {
229
  { AGENTX_NO_ERROR,     "noError" },
230
  { AGENTX_TOO_BIG,    "tooBig" },
231
  { AGENTX_NO_SUCH_NAME,     "noSuchName" },
232
  { AGENTX_BAD_VALUE,    "badValue" },
233
  { AGENTX_READ_ONLY,    "readOnly" },
234
  { AGENTX_GEN_ERROR,    "genErr" },
235
  { AGENTX_NO_ACCESS,    "noAccess" },
236
  { AGENTX_WRONG_TYPE,     "wrongType" },
237
  { AGENTX_WRONG_LEN,      "wrongLength" },
238
  { AGENTX_WRONG_ENCODE,     "wrongEncoding" },
239
  { AGENTX_WRONG_VALUE,    "wrongValue" },
240
  { AGENTX_NO_CREATION,    "noCreation" },
241
  { AGENTX_INCONSIST_VALUE,  "inconsistentValue" },
242
  { AGENTX_RES_UNAVAIL,    "resourceUnavailable" },
243
  { AGENTX_COMMIT_FAILED,    "commitFailed" },
244
  { AGENTX_UNDO_FAILED ,     "undoFailed" },
245
  { AGENTX_AUTH_ERROR,     "authorizationError" },
246
  { AGENTX_NOTWRITABLE,    "notWritable" },
247
  { AGENTX_INCONSIS_NAME,    "inconsistentName" },
248
  { AGENTX_OPEN_FAILED,    "openFailed" },
249
  { AGENTX_NOT_OPEN,     "notOpen" },
250
  { AGENTX_IDX_WRONT_TYPE,   "indexWrongType" },
251
  { AGENTX_IDX_ALREAY_ALLOC, "indexAlreadyAllocated" },
252
  { AGENTX_IDX_NONEAVAIL,    "indexNoneAvailable" },
253
  { AGENTX_IDX_NOTALLOC,     "indexNotAllocated" },
254
  { AGENTX_UNSUPP_CONTEXT,   "unsupportedContext" },
255
  { AGENTX_DUP_REGISTR,    "duplicateRegistration" },
256
  { AGENTX_UNKNOWN_REG,    "unknownRegistration" },
257
  { AGENTX_UNKNOWN_CAPS,     "unknownAgentCaps" },
258
  { 0, NULL }
259
};
260
static value_string_ext resp_errors_ext = VALUE_STRING_EXT_INIT(resp_errors);
261
262
/* OID usage indicators */
263
264
enum OID_USAGE { OID_START_RANGE, OID_END_RANGE, OID_EXACT };
265
266
/* PDU Header flags */
267
268
16
#define INSTANCE_REGISTRATION   0x01
269
16
#define NEW_INDEX     0x02
270
16
#define ANY_INDEX   0x04
271
78
#define NON_DEFAULT_CONTEXT 0x08
272
3.92k
#define NETWORK_BYTE_ORDER  0x10
273
274
16
#define OID_IS_INCLUSIVE  0x01
275
276
107
#define PDU_HDR_LEN 20
277
278
#define NORLEL(flags,var,tvb,offset) \
279
3.67k
  var = (flags & NETWORK_BYTE_ORDER) ? \
280
3.67k
    tvb_get_ntohl(tvb, offset) : \
281
3.67k
    tvb_get_letohl(tvb, offset)
282
#define NORLES(flags,var,tvb,offset) \
283
203
  var = (flags & NETWORK_BYTE_ORDER) ? \
284
203
    tvb_get_ntohs(tvb, offset) : \
285
203
    tvb_get_letohs(tvb, offset)
286
287
static int
288
dissect_octet_string(tvbuff_t *tvb, proto_tree *tree, int offset, uint8_t flags)
289
11
{
290
11
  uint32_t n_oct, p_noct;
291
292
11
  NORLEL(flags, n_oct, tvb, offset);
293
294
11
  p_noct = WS_ROUNDUP_4(n_oct);
295
296
11
  proto_tree_add_uint(tree, hf_ostring_len, tvb, offset, 4, n_oct);
297
  /*
298
   * XXX - an "octet string" is not necessarily a text string, so
299
   * having hf_ostring be FT_STRING is not necessarily appropriate.
300
   */
301
11
  proto_tree_add_item(tree, hf_ostring, tvb, offset + 4, n_oct, ENC_ASCII);
302
11
  return p_noct + 4;
303
304
11
}
305
306
/* XXX - Is there a particular reason we're not using oid_encoded2string() here? */
307
static int
308
convert_oid_to_str(uint32_t *oid, int len, char* str, int slen, char prefix)
309
391
{
310
391
  int i, tlen = 0;
311
391
  if(!oid)  return 0;
312
391
  if(!str)  return 0;
313
391
  if(!len)  return 0;
314
106
  if(!slen) return 0;
315
106
  if(slen < len) return 0;
316
317
106
  if(prefix) {
318
86
    tlen += snprintf(str, slen, ".1.3.6.1.%d", prefix);
319
86
  }
320
321
2.14k
  for(i=0; i < len && tlen < slen; i++) {
322
2.03k
        tlen += snprintf(str+tlen, slen-tlen, ".%u", oid[i]);
323
2.03k
  }
324
106
  return tlen;
325
106
}
326
327
static int
328
dissect_object_id(tvbuff_t *tvb, proto_tree *tree, int offset, uint8_t flags, enum OID_USAGE oid_usage)
329
443
{
330
443
  uint8_t n_subid;
331
443
  uint8_t prefix;
332
443
  uint8_t include;
333
443
  proto_tree* subtree;
334
443
  uint32_t oid[2048];
335
443
  char str_oid[2048];
336
443
  int i;
337
338
443
  memset(oid, '\0', sizeof(oid));
339
443
  memset(str_oid, '\0', sizeof(str_oid));
340
341
443
  n_subid = tvb_get_uint8(tvb, offset);
342
443
  prefix  = tvb_get_uint8(tvb, offset + 1);
343
443
  include = tvb_get_uint8(tvb, offset + 2);
344
443
  tvb_get_uint8(tvb, offset + 3);
345
346
3.55k
  for(i=0; i<n_subid; i++) {
347
3.11k
    NORLEL(flags, oid[i], tvb, (offset+4) + (i*4));
348
3.11k
  }
349
350
443
  if(!convert_oid_to_str(&oid[0], n_subid, &str_oid[0], 2048, prefix))
351
443
    snprintf(&str_oid[0], 2048, "(null)");
352
353
443
  if(tree) {
354
391
    const char *range = "";
355
391
    const char *inclusion = (include) ? " (Inclusive)" : " (Exclusive)";
356
391
    switch (oid_usage) {
357
93
      case OID_START_RANGE: range = "(Range Start) "; break;
358
84
      case OID_END_RANGE: range = "  (Range End) "; break;
359
214
      default:    inclusion = "";     break;
360
391
      }
361
391
    subtree = proto_tree_add_subtree_format(tree, tvb, offset, 4 + (n_subid * 4) ,
362
391
        ett_obj_ident, NULL, "Object Identifier: %s%s%s", range, str_oid, inclusion);
363
391
  } else
364
52
    return offset;
365
366
391
  proto_tree_add_uint(subtree, hf_oid_sub, tvb, offset, 1, n_subid);
367
391
  proto_tree_add_uint(subtree, hf_oid_prefix, tvb, offset + 1, 1, prefix);
368
391
  proto_tree_add_boolean(subtree, hf_oid_include, tvb, offset + 2, 1, include);
369
391
  proto_tree_add_string(subtree, hf_oid_str, tvb, offset + 4, (n_subid * 4), str_oid);
370
371
391
  return 4 + (n_subid * 4);
372
443
}
373
374
static int
375
dissect_search_range(tvbuff_t *tvb, proto_tree *tree, int start_offset, uint8_t flags, uint8_t pdu_type)
376
123
{
377
123
  int offset = start_offset;
378
123
  offset += dissect_object_id(tvb, tree, offset, flags, (pdu_type == AGENTX_GET_PDU) ? OID_EXACT : OID_START_RANGE);
379
123
  offset += dissect_object_id(tvb, tree, offset, flags, (pdu_type == AGENTX_GET_PDU) ? OID_EXACT : OID_END_RANGE);
380
381
123
  return (offset - start_offset);
382
123
}
383
384
static int
385
dissect_val64(tvbuff_t *tvb, proto_tree *tree, int offset, uint8_t flags)
386
0
{
387
0
  unsigned encoding = (flags & NETWORK_BYTE_ORDER) ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN;
388
389
0
  proto_tree_add_item(tree, hf_val64, tvb, offset, 8, encoding);
390
391
0
  return 8;
392
0
}
393
394
static int
395
dissect_val32(tvbuff_t *tvb, proto_tree *tree, int offset, uint8_t flags)
396
2
{
397
2
  unsigned encoding = (flags & NETWORK_BYTE_ORDER) ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN;
398
399
2
  proto_tree_add_item(tree, hf_val32, tvb, offset, 4, encoding);
400
401
2
  return 4;
402
2
}
403
404
static int
405
dissect_varbind(tvbuff_t *tvb, proto_tree *tree, int offset, int len, uint8_t flags)
406
203
{
407
203
  uint16_t vtag;
408
203
  int tlen;
409
203
  proto_tree* subtree;
410
411
203
  NORLES(flags, vtag, tvb, offset);
412
  /* 2 reserved bytes after this */
413
414
203
  if(tree) {
415
201
    subtree = proto_tree_add_subtree(tree, tvb, offset, len, ett_valrep, NULL, "Value Representation");
416
201
  } else return len;
417
418
201
  proto_tree_add_uint(subtree, hf_vtag, tvb, offset, 2, vtag);
419
201
  tlen = dissect_object_id(tvb, subtree, offset + 4, flags, OID_EXACT);
420
421
201
  switch(vtag)
422
201
  {
423
1
    case  VB_OID:
424
1
      tlen += dissect_object_id(tvb, subtree, offset + tlen + 4, flags, OID_EXACT);
425
1
      break;
426
427
0
    case  VB_OPAQUE:
428
1
    case  VB_OSTR:
429
2
    case  VB_IPADDR:
430
2
      tlen += dissect_octet_string(tvb, subtree, offset + tlen + 4, flags);
431
2
      break;
432
433
1
    case  VB_TIMETICK:
434
1
    case  VB_COUNTER32:
435
2
    case  VB_INT:
436
2
    case  VB_GAUGE32:
437
2
      tlen += dissect_val32(tvb, subtree, offset + tlen + 4, flags);
438
2
      break;
439
440
0
    case  VB_COUNTER64:
441
0
      tlen += dissect_val64(tvb, subtree, offset + tlen + 4, flags);
442
0
      break;
443
444
0
    case  VB_NULL:
445
0
    case  VB_NOSUCHOBJ:
446
0
    case  VB_NOSUCHINST:
447
0
    case  VB_ENDOFMIB:
448
0
      break;
449
201
  }
450
175
  return tlen + 4;
451
201
}
452
453
static void
454
dissect_response_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint8_t flags)
455
9
{
456
9
  proto_tree* subtree;
457
9
  unsigned offset = 0;
458
9
  unsigned encoding = (flags & NETWORK_BYTE_ORDER) ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN;
459
9
  uint32_t r_uptime;
460
461
9
  subtree = proto_tree_add_subtree(tree, tvb, offset, len, ett_response, NULL, "Response-PDU");
462
463
9
  NORLEL(flags, r_uptime, tvb, offset);
464
9
  proto_tree_add_uint_format(subtree, hf_resp_uptime, tvb, offset, 4, r_uptime,
465
9
      "sysUptime: %s", signed_time_msecs_to_str(pinfo->pool, r_uptime));
466
9
  proto_tree_add_item(subtree, hf_resp_error,  tvb, offset + 4, 2, encoding);
467
9
  proto_tree_add_item(subtree, hf_resp_index,  tvb, offset + 6, 2, encoding);
468
9
  offset += 8;
469
470
50
  while(tvb_reported_length_remaining(tvb, offset)) {
471
41
    offset += dissect_varbind(tvb, subtree, offset, len, flags);
472
41
  }
473
9
}
474
475
static void
476
dissect_getnext_pdu(tvbuff_t *tvb, proto_tree *tree, unsigned len, uint8_t flags)
477
9
{
478
9
  proto_tree* subtree;
479
9
  unsigned offset = 0;
480
481
9
  subtree = proto_tree_add_subtree(tree, tvb, offset, len, ett_getnext, NULL, "GetNext-PDU");
482
483
9
  if(flags & NON_DEFAULT_CONTEXT) {
484
    /* show context */
485
2
    offset += dissect_octet_string(tvb, subtree, offset, flags);
486
2
  }
487
488
51
  while(tvb_reported_length_remaining(tvb, offset)) {
489
42
    offset += dissect_search_range(tvb, subtree, offset, flags, 0);
490
42
  }
491
9
}
492
493
static void
494
dissect_get_pdu(tvbuff_t *tvb, proto_tree *tree, unsigned len, uint8_t flags)
495
5
{
496
5
  proto_tree* subtree;
497
5
  unsigned offset = 0;
498
499
5
  subtree = proto_tree_add_subtree(tree, tvb, offset, len, ett_get, NULL, "Get-PDU");
500
501
5
  if(flags & NON_DEFAULT_CONTEXT) {
502
    /* show context */
503
0
    offset += dissect_octet_string(tvb, subtree, offset, flags);
504
0
  }
505
506
25
  while(tvb_reported_length_remaining(tvb, offset)) {
507
20
    offset += dissect_search_range(tvb, subtree, offset, flags, AGENTX_GET_PDU);
508
20
  }
509
5
}
510
511
static void
512
dissect_getbulk_pdu(tvbuff_t *tvb, proto_tree *tree, unsigned len, uint8_t flags)
513
12
{
514
12
  proto_tree* subtree;
515
12
  unsigned offset = 0;
516
12
  unsigned encoding = (flags & NETWORK_BYTE_ORDER) ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN;
517
518
12
  subtree = proto_tree_add_subtree(tree, tvb, offset, len, ett_getbulk, NULL, "GetBulk-PDU");
519
520
12
  if(flags & NON_DEFAULT_CONTEXT) {
521
    /* show context */
522
1
    offset += dissect_octet_string(tvb, subtree, offset, flags);
523
1
  }
524
525
12
  proto_tree_add_item(subtree, hf_gbulk_nrepeat,  tvb, offset, 2, encoding);
526
12
  proto_tree_add_item(subtree, hf_gbulk_mrepeat,  tvb, offset + 2, 2, encoding);
527
12
  offset+=4;
528
529
73
  while(tvb_reported_length_remaining(tvb, offset)) {
530
61
    offset += dissect_search_range(tvb, subtree, offset, flags, 0);
531
61
  }
532
12
}
533
534
static int
535
dissect_open_pdu(tvbuff_t *tvb, proto_tree *tree, unsigned len, uint8_t flags)
536
2
{
537
2
  proto_tree* subtree;
538
2
  unsigned offset = 0;
539
2
  uint8_t timeout;
540
541
2
  subtree = proto_tree_add_subtree(tree, tvb, offset, len, ett_open, NULL, "Open-PDU");
542
543
2
  timeout = tvb_get_uint8(tvb, offset);
544
2
  tvb_get_ntoh24(tvb, offset + 1);
545
546
2
  proto_tree_add_uint(subtree, hf_open_timeout, tvb, offset, 1, timeout);
547
2
  offset+=4;
548
549
  /* Search Range */
550
2
  offset += dissect_object_id(tvb, subtree, offset, flags, OID_EXACT);
551
552
  /* Octet string */
553
2
  offset += dissect_octet_string(tvb, subtree, offset, flags);
554
2
  return offset;
555
2
}
556
557
static int
558
dissect_close_pdu(tvbuff_t *tvb, proto_tree *tree, unsigned len)
559
1
{
560
1
  proto_tree* subtree;
561
1
  unsigned offset = 0;
562
563
1
  subtree = proto_tree_add_subtree(tree, tvb, offset, len, ett_close, NULL, "Close-PDU");
564
565
1
  proto_tree_add_item(subtree, hf_close_reason, tvb, offset, 1, ENC_NA);
566
1
  tvb_get_ntoh24(tvb, offset + 1);
567
1
  offset+=4;
568
1
  return offset;
569
1
}
570
571
572
static int
573
dissect_register_pdu(tvbuff_t *tvb, proto_tree *tree, unsigned len, uint8_t flags)
574
4
{
575
4
  proto_tree* subtree;
576
4
  unsigned offset = 0;
577
4
  unsigned encoding = (flags & NETWORK_BYTE_ORDER) ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN;
578
579
4
  subtree = proto_tree_add_subtree(tree, tvb, offset, len, ett_register, NULL, "Register-PDU");
580
581
4
  if(flags & NON_DEFAULT_CONTEXT) {
582
    /* show context */
583
2
    offset += dissect_octet_string(tvb, subtree, offset, flags);
584
2
  }
585
586
4
  proto_tree_add_item(subtree, hf_reg_timeout, tvb, offset, 1, encoding);
587
4
  proto_tree_add_item(subtree, hf_reg_prio, tvb, offset+1, 1, encoding);
588
4
  proto_tree_add_item(subtree, hf_reg_rsid, tvb, offset+2, 1, encoding);
589
4
  offset+=4;
590
591
  /* Region */
592
593
4
  offset += dissect_object_id(tvb, subtree, offset, flags, OID_EXACT);
594
595
4
  if(tvb_reported_length_remaining(tvb, offset)) {
596
    /* Upper bound (opt) */
597
2
    proto_tree_add_item(subtree, hf_reg_ubound, tvb, offset, 4, encoding);
598
2
    offset += 4;
599
2
  }
600
4
  return offset;
601
4
}
602
603
604
static int
605
dissect_unregister_pdu(tvbuff_t *tvb, proto_tree *tree, unsigned len, uint8_t flags)
606
2
{
607
2
  proto_tree* subtree;
608
2
  unsigned offset = 0;
609
2
  unsigned encoding = (flags & NETWORK_BYTE_ORDER) ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN;
610
611
2
  subtree = proto_tree_add_subtree(tree, tvb, offset, len, ett_unregister, NULL, "Unregister-PDU");
612
613
2
  if(flags & NON_DEFAULT_CONTEXT) {
614
    /* show context */
615
0
    offset += dissect_octet_string(tvb, subtree, offset, flags);
616
0
  }
617
618
2
  proto_tree_add_item(subtree, hf_unreg_timeout, tvb, offset, 1, encoding);
619
2
  proto_tree_add_item(subtree, hf_unreg_prio, tvb, offset+1, 1, encoding);
620
2
  proto_tree_add_item(subtree, hf_unreg_rsid, tvb, offset+2, 1, encoding);
621
2
  offset+=4;
622
623
  /* Region */
624
2
  offset += dissect_object_id(tvb, subtree, offset, flags, OID_EXACT);
625
626
2
  if(tvb_reported_length_remaining(tvb, offset)) {
627
    /* Upper bound (opt) */
628
1
    proto_tree_add_item(subtree, hf_unreg_ubound, tvb, offset, 4, encoding);
629
1
    offset += 4;
630
1
  }
631
632
2
  return offset;
633
2
}
634
635
static void
636
dissect_testset_pdu(tvbuff_t *tvb, proto_tree *tree, unsigned len, uint8_t flags)
637
7
{
638
7
  proto_tree* subtree;
639
7
  unsigned offset = 0;
640
641
7
  subtree = proto_tree_add_subtree(tree, tvb, offset, len, ett_testset, NULL, "Testset-PDU");
642
643
7
  if(flags & NON_DEFAULT_CONTEXT) {
644
    /* show context */
645
1
    offset += dissect_octet_string(tvb, subtree, offset, flags);
646
1
  }
647
648
54
  while(tvb_reported_length_remaining(tvb, offset)) {
649
47
    offset += dissect_varbind(tvb, subtree, offset, len, flags);
650
47
  }
651
7
}
652
653
static void
654
dissect_notify_pdu(tvbuff_t *tvb, proto_tree *tree, unsigned len, uint8_t flags)
655
7
{
656
7
  proto_tree* subtree;
657
7
  unsigned offset = 0;
658
659
7
  subtree = proto_tree_add_subtree(tree, tvb, offset, len, ett_notify, NULL, "Notify-PDU");
660
661
7
  if(flags & NON_DEFAULT_CONTEXT) {
662
    /* show context */
663
0
    offset += dissect_octet_string(tvb, subtree, offset, flags);
664
0
  }
665
666
62
  while(tvb_reported_length_remaining(tvb, offset)) {
667
55
    offset += dissect_varbind(tvb, subtree, offset, len, flags);
668
55
  }
669
7
}
670
671
static int
672
dissect_ping_pdu(tvbuff_t *tvb, proto_tree *tree, unsigned len, uint8_t flags)
673
1
{
674
1
  proto_tree* subtree;
675
1
  unsigned offset = 0;
676
677
1
  subtree = proto_tree_add_subtree(tree, tvb, offset, len, ett_ping, NULL, "Ping-PDU");
678
679
1
  if(flags & NON_DEFAULT_CONTEXT) {
680
    /* show context */
681
0
    offset += dissect_octet_string(tvb, subtree, offset, flags);
682
0
  }
683
1
  return offset;
684
1
}
685
686
static void
687
dissect_idx_alloc_pdu(tvbuff_t *tvb, proto_tree *tree, unsigned len, uint8_t flags)
688
5
{
689
5
  proto_tree* subtree;
690
5
  unsigned offset = 0;
691
692
5
  subtree = proto_tree_add_subtree(tree, tvb, offset, len, ett_idxalloc, NULL, "IndexAllocate-PDU");
693
694
5
  if(flags & NON_DEFAULT_CONTEXT) {
695
    /* show context */
696
0
    offset += dissect_octet_string(tvb, subtree, offset, flags);
697
0
  }
698
699
22
  while(tvb_reported_length_remaining(tvb, offset)) {
700
17
    offset += dissect_varbind(tvb, subtree, offset, len, flags);
701
17
  }
702
5
}
703
704
705
static void
706
dissect_idx_dealloc_pdu(tvbuff_t *tvb, proto_tree *tree, unsigned len, uint8_t flags)
707
8
{
708
8
  proto_tree* subtree;
709
8
  unsigned offset = 0;
710
711
8
  subtree = proto_tree_add_subtree(tree, tvb, offset, len, ett_idxdalloc, NULL, "IndexDeallocate-PDU");
712
713
8
  if(flags & NON_DEFAULT_CONTEXT) {
714
    /* show context */
715
1
    offset += dissect_octet_string(tvb, subtree, offset, flags);
716
1
  }
717
718
51
  while(tvb_reported_length_remaining(tvb, offset)) {
719
43
    offset += dissect_varbind(tvb, subtree, offset, len, flags);
720
43
  }
721
8
}
722
723
static int
724
dissect_add_caps_pdu(tvbuff_t *tvb, proto_tree *tree, unsigned len, uint8_t flags)
725
1
{
726
1
  proto_tree* subtree;
727
1
  unsigned offset = 0;
728
729
1
  subtree = proto_tree_add_subtree(tree, tvb, offset, len, ett_addcap, NULL, "AddAgentCaps-PDU");
730
731
1
  if(flags & NON_DEFAULT_CONTEXT) {
732
    /* show context */
733
0
    offset += dissect_octet_string(tvb, subtree, offset, flags);
734
0
  }
735
736
1
  offset += dissect_object_id(tvb, subtree, offset, flags, OID_EXACT);
737
738
1
  offset += dissect_octet_string(tvb, subtree, offset, flags);
739
740
1
  return offset;
741
1
}
742
743
static int
744
dissect_rem_caps_pdu(tvbuff_t *tvb, proto_tree *tree, unsigned len, uint8_t flags)
745
1
{
746
1
  proto_tree* subtree;
747
1
  unsigned offset = 0;
748
749
1
  subtree = proto_tree_add_subtree(tree, tvb, offset, len, ett_remcap, NULL, "RemoveAgentCaps-PDU");
750
751
1
  if(flags & NON_DEFAULT_CONTEXT) {
752
    /* show context */
753
0
    offset += dissect_octet_string(tvb, subtree, offset, flags);
754
0
  }
755
756
1
  offset += dissect_object_id(tvb, subtree, offset, flags, OID_EXACT);
757
758
1
  return offset;
759
1
}
760
761
762
static unsigned
763
get_agentx_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
764
110
{
765
110
  uint8_t flags;
766
110
  uint32_t plen;
767
768
  /*
769
   * Get the payload length.
770
   */
771
110
  flags = tvb_get_uint8(tvb, offset + 2);
772
110
  NORLEL(flags, plen, tvb, offset + 16);
773
774
  /*
775
   * Arbitrarily limit it to 2^24, so we don't have to worry about
776
   * overflow.
777
   */
778
110
  if (plen > 0xFFFFFF)
779
44
    plen = 0xFFFFFF;
780
781
  /*
782
   * That length doesn't include the header; add that in.
783
   */
784
110
  return plen + 20;
785
110
}
786
787
static int
788
dissect_agentx_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
789
107
{
790
107
  unsigned offset = 0;
791
107
  proto_tree* agentx_tree, *pdu_hdr_tree;
792
107
  proto_item *t_item;
793
107
  tvbuff_t *payload_tvb;
794
107
  uint8_t version;
795
107
  uint8_t type;
796
107
  uint8_t flags;
797
107
  uint32_t session_id;
798
107
  uint32_t trans_id;
799
107
  uint32_t packet_id;
800
107
  uint32_t payload_len;
801
107
  static int * const pdu_flags[] = {
802
107
    &hf_flags_register,
803
107
    &hf_flags_newindex,
804
107
    &hf_flags_anyindex,
805
107
    &hf_flags_context,
806
107
    &hf_flags_byteorder,
807
107
    NULL
808
107
  };
809
810
107
  version = tvb_get_uint8(tvb, 0); offset+=1;
811
107
  type = tvb_get_uint8(tvb, 1); offset+=1;
812
107
  flags = tvb_get_uint8(tvb, 2); offset+=1;
813
  /* skip reserved byte */
814
107
  offset+=1;
815
816
107
  NORLEL(flags, session_id, tvb, 4); offset+=4;
817
107
  NORLEL(flags, trans_id, tvb, 8); offset+=4;
818
107
  NORLEL(flags, packet_id, tvb, 12); offset+=4;
819
107
  NORLEL(flags, payload_len, tvb, 16); offset+=4;
820
821
107
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "AgentX");
822
823
107
  col_add_fstr(pinfo->cinfo, COL_INFO, "%s: sid=%d, tid=%d, packid=%d, plen=%d",
824
107
         val_to_str_ext_const(type, &type_values_ext, "unknown"),
825
107
         session_id, trans_id, packet_id, payload_len);
826
827
828
107
  if(!tree)
829
0
    return tvb_captured_length(tvb);
830
831
  /*t_item = proto_tree_add_item(tree, proto_agentx, tvb, 0, -1, ENC_NA);*/
832
107
  t_item = proto_tree_add_protocol_format(tree, proto_agentx, tvb, 0, -1,
833
107
      "Agent Extensibility (AgentX) Protocol: %s, sid=%d, tid=%d, packid=%d, plen=%d",
834
107
      val_to_str_ext_const(type, &type_values_ext, "unknown"),
835
107
      session_id, trans_id, packet_id, payload_len);
836
107
  agentx_tree = proto_item_add_subtree(t_item, ett_agentx);
837
838
107
  pdu_hdr_tree = proto_tree_add_subtree_format(agentx_tree, tvb, 0, PDU_HDR_LEN,
839
107
      ett_pdu_hdr, NULL, "PDU Header: Type[%u], len=%d, sid=%d, tid=%d, packid=%d",
840
107
      (char)type, payload_len, session_id, trans_id, packet_id);
841
842
107
  proto_tree_add_uint(pdu_hdr_tree, hf_version, tvb, 0, 1, version);
843
107
  proto_tree_add_uint(pdu_hdr_tree, hf_type, tvb, 1, 1, type);
844
107
  proto_tree_add_bitmask(pdu_hdr_tree, tvb, 2, hf_flags, ett_flags, pdu_flags, ENC_NA);
845
846
107
  proto_tree_add_uint(pdu_hdr_tree, hf_session_id, tvb, 4, 4, session_id);
847
107
  proto_tree_add_uint(pdu_hdr_tree, hf_trans_id, tvb, 8, 4, trans_id);
848
107
  proto_tree_add_uint(pdu_hdr_tree, hf_packet_id, tvb, 12, 4, packet_id);
849
107
  proto_tree_add_uint(pdu_hdr_tree, hf_payload_len, tvb, 16, 4, payload_len);
850
851
107
  payload_tvb = tvb_new_subset_length(tvb, offset, payload_len);
852
853
107
  switch(type) {
854
2
    case AGENTX_OPEN_PDU:
855
2
    dissect_open_pdu(payload_tvb, agentx_tree, payload_len, flags);
856
2
    break;
857
858
1
    case AGENTX_CLOSE_PDU:
859
1
    dissect_close_pdu(payload_tvb, agentx_tree, payload_len);
860
1
    break;
861
862
4
    case AGENTX_REGISTER_PDU:
863
4
    dissect_register_pdu(payload_tvb, agentx_tree, payload_len, flags);
864
4
    break;
865
866
2
    case AGENTX_UNREGISTER_PDU:
867
2
    dissect_unregister_pdu(payload_tvb, agentx_tree, payload_len, flags);
868
2
    break;
869
870
5
    case AGENTX_GET_PDU:
871
5
    dissect_get_pdu(payload_tvb, agentx_tree, payload_len, flags);
872
5
    break;
873
874
9
    case AGENTX_GETNEXT_PDU:
875
9
    dissect_getnext_pdu(payload_tvb, agentx_tree, payload_len, flags);
876
9
    break;
877
878
12
    case AGENTX_GETBULK_PDU:
879
12
    dissect_getbulk_pdu(payload_tvb, agentx_tree, payload_len, flags);
880
12
    break;
881
882
7
    case AGENTX_TESTSET_PDU:
883
7
    dissect_testset_pdu(payload_tvb, agentx_tree, payload_len, flags);
884
7
    break;
885
886
0
    case AGENTX_COMMITSET_PDU:
887
0
    case AGENTX_UNDOSET_PDU:
888
0
    case AGENTX_CLEANUPSET_PDU:
889
      /* there is no parameters */
890
0
    break;
891
892
7
    case AGENTX_NOTIFY_PDU:
893
7
    dissect_notify_pdu(payload_tvb, agentx_tree, payload_len, flags);
894
7
    break;
895
896
1
    case AGENTX_PING_PDU:
897
1
    dissect_ping_pdu(payload_tvb, agentx_tree, payload_len, flags);
898
1
    break;
899
900
5
    case AGENTX_INDEX_ALLOC_PDU:
901
5
    dissect_idx_alloc_pdu(payload_tvb, agentx_tree, payload_len, flags);
902
5
    break;
903
904
8
    case AGENTX_INDEX_DEALLOC_PDU:
905
8
    dissect_idx_dealloc_pdu(payload_tvb, agentx_tree, payload_len, flags);
906
8
    break;
907
908
1
    case AGENTX_ADD_AGENT_CAPS_PDU:
909
1
    dissect_add_caps_pdu(payload_tvb, agentx_tree, payload_len, flags);
910
1
    break;
911
912
1
    case AGENTX_REM_AGENT_CAPS_PDU:
913
1
    dissect_rem_caps_pdu(payload_tvb, agentx_tree, payload_len, flags);
914
1
    break;
915
916
9
    case AGENTX_RESPONSE_PDU:
917
9
    dissect_response_pdu(payload_tvb, pinfo, agentx_tree, payload_len, flags);
918
9
    break;
919
107
  }
920
921
43
  return tvb_captured_length(tvb);
922
107
}
923
924
static int
925
dissect_agentx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
926
75
{
927
75
  tcp_dissect_pdus(tvb, pinfo, tree, true, 20, get_agentx_pdu_len,
928
75
       dissect_agentx_pdu, data);
929
75
  return tvb_captured_length(tvb);
930
75
}
931
932
static const true_false_string tfs_agentx_context = { "Provided",     "None"  };
933
static const true_false_string tfs_agentx_byteorder = { "MSB (network order)",  "LSB" };
934
935
void
936
proto_register_agentx(void)
937
16
{
938
16
  static hf_register_info hf[] = {
939
940
16
    { &hf_version,
941
16
      { "Version", "agentx.version", FT_UINT8, BASE_DEC, NULL, 0x0,
942
16
        "header version", HFILL }},
943
944
16
    { &hf_type,
945
16
      { "Type", "agentx.type", FT_UINT8, BASE_DEC | BASE_EXT_STRING, &type_values_ext, 0x0,
946
16
        "header type", HFILL }},
947
948
16
    { &hf_flags,
949
16
      { "Flags", "agentx.flags", FT_UINT8, BASE_DEC, NULL, 0x0,
950
16
        "header type", HFILL }},
951
952
16
    { &hf_flags_register,
953
16
      { "Register", "agentx.flags.register", FT_BOOLEAN, 8, TFS(&tfs_yes_no),
954
16
        INSTANCE_REGISTRATION, "Instance Registration",  HFILL }},
955
956
16
    { &hf_flags_newindex,
957
16
      { "New Index", "agentx.flags.newindex", FT_BOOLEAN, 8, TFS(&tfs_yes_no),
958
16
        NEW_INDEX, "New Index Requested",  HFILL }},
959
960
16
    { &hf_flags_anyindex,
961
16
      { "Any Index", "agentx.flags.anyindex", FT_BOOLEAN, 8, TFS(&tfs_yes_no),
962
16
        ANY_INDEX, "Any Index Requested",  HFILL }},
963
964
16
    { &hf_flags_context,
965
16
      { "Non-default Context", "agentx.flags.context", FT_BOOLEAN, 8, TFS(&tfs_agentx_context),
966
16
        NON_DEFAULT_CONTEXT, NULL,  HFILL }},
967
968
16
    { &hf_flags_byteorder,
969
16
      { "Byte Order", "agentx.flags.byteorder", FT_BOOLEAN, 8, TFS(&tfs_agentx_byteorder),
970
16
        NETWORK_BYTE_ORDER, NULL,  HFILL }},
971
972
16
    { &hf_session_id,
973
16
      { "sessionID", "agentx.session_id", FT_UINT32, BASE_DEC, NULL, 0x0,
974
16
        "Session ID", HFILL }},
975
976
16
    { &hf_trans_id,
977
16
      { "TransactionID", "agentx.transaction_id", FT_UINT32, BASE_DEC, NULL, 0x0,
978
16
        "Transaction ID", HFILL }},
979
980
16
    { &hf_packet_id,
981
16
      { "PacketID", "agentx.packet_id", FT_UINT32, BASE_DEC, NULL, 0x0,
982
16
        "Packet ID", HFILL }},
983
984
16
    { &hf_payload_len,
985
16
      { "Payload length", "agentx.payload_len", FT_UINT32, BASE_DEC, NULL, 0x0,
986
16
        NULL, HFILL }},
987
988
16
    { &hf_ostring,
989
16
      { "Octet String", "agentx.ostring", FT_STRING, BASE_NONE, NULL, 0x0,
990
16
        NULL, HFILL }},
991
992
16
    { &hf_ostring_len,
993
16
      { "OString len", "agentx.ostring_len", FT_UINT32, BASE_DEC, NULL, 0x0,
994
16
        "Octet String Length", HFILL }},
995
996
16
    { &hf_oid_sub,
997
16
      { "Number subids", "agentx.n_subid", FT_UINT8, BASE_DEC, NULL, 0x0,
998
16
        NULL, HFILL }},
999
1000
16
    { &hf_oid_prefix,
1001
16
      { "OID prefix", "agentx.oid_prefix", FT_UINT8, BASE_DEC, NULL, 0x0,
1002
16
        NULL, HFILL }},
1003
1004
16
    { &hf_oid_include,
1005
16
      { "OID include", "agentx.oid_include", FT_BOOLEAN, 8, TFS(&tfs_yes_no),
1006
16
        OID_IS_INCLUSIVE, NULL, HFILL }},
1007
1008
16
    { &hf_oid_str,
1009
16
      { "OID", "agentx.oid", FT_STRING, BASE_NONE, NULL, 0x0,
1010
16
        NULL, HFILL }},
1011
1012
16
    { &hf_resp_uptime,
1013
16
      { "sysUpTime", "agentx.r.uptime", FT_UINT32, BASE_DEC, NULL, 0x0,
1014
16
        NULL, HFILL }},
1015
1016
16
    { &hf_resp_error,
1017
16
      { "Resp. error", "agentx.r.error", FT_UINT16, BASE_DEC | BASE_EXT_STRING, &resp_errors_ext, 0x0,
1018
16
        "response error", HFILL }},
1019
1020
16
    { &hf_resp_index,
1021
16
      { "Resp. index", "agentx.r.index", FT_UINT16, BASE_DEC, NULL, 0x0,
1022
16
        "response index", HFILL }},
1023
1024
16
    { &hf_vtag,
1025
16
      { "Variable type", "agentx.v.tag", FT_UINT16, BASE_DEC | BASE_EXT_STRING, &vtag_values_ext, 0x0,
1026
16
        "vtag", HFILL }},
1027
1028
16
    { &hf_val32,
1029
16
      { "Value(32)", "agentx.v.val32", FT_UINT32, BASE_DEC, NULL, 0x0,
1030
16
        "val32", HFILL }},
1031
1032
16
    { &hf_val64,
1033
16
      { "Value(64)", "agentx.v.val64", FT_UINT64, BASE_DEC, NULL, 0x0,
1034
16
        "val64", HFILL }},
1035
1036
16
    { &hf_open_timeout,
1037
16
      { "Timeout", "agentx.o.timeout", FT_UINT8, BASE_DEC, NULL, 0x0,
1038
16
        "open timeout", HFILL }},
1039
1040
16
    { &hf_close_reason,
1041
16
      { "Reason", "agentx.c.reason", FT_UINT8, BASE_DEC, VALS(close_reasons), 0x0,
1042
16
        "close reason", HFILL }},
1043
1044
16
    { &hf_reg_timeout,
1045
16
      { "Timeout", "agentx.r.timeout", FT_UINT8, BASE_DEC, NULL, 0x0,
1046
16
        "Register timeout", HFILL }},
1047
1048
16
    { &hf_reg_prio,
1049
16
      { "Priority", "agentx.r.priority", FT_UINT8, BASE_DEC, NULL, 0x0,
1050
16
        "Register Priority", HFILL }},
1051
1052
16
    { &hf_reg_rsid,
1053
16
      { "Range_subid", "agentx.r.range_subid", FT_UINT8, BASE_DEC, NULL, 0x0,
1054
16
        "Register range_subid", HFILL }},
1055
1056
16
    { &hf_reg_ubound,
1057
16
      { "Upper bound", "agentx.r.upper_bound", FT_UINT32, BASE_DEC, NULL, 0x0,
1058
16
        "Register upper bound", HFILL }},
1059
1060
16
    { &hf_unreg_timeout,
1061
16
      { "Timeout", "agentx.u.timeout", FT_UINT8, BASE_DEC, NULL, 0x0,
1062
16
        "Unregister timeout", HFILL }},
1063
1064
16
    { &hf_unreg_prio,
1065
16
      { "Priority", "agentx.u.priority", FT_UINT8, BASE_DEC, NULL, 0x0,
1066
16
        "Unregister Priority", HFILL }},
1067
1068
16
    { &hf_unreg_rsid,
1069
16
      { "Range_subid", "agentx.u.range_subid", FT_UINT8, BASE_DEC, NULL, 0x0,
1070
16
        "Unregister range_subid", HFILL }},
1071
1072
16
    { &hf_unreg_ubound,
1073
16
      { "Upper bound", "agentx.u.upper_bound", FT_UINT32, BASE_DEC, NULL, 0x0,
1074
16
        "Register upper bound", HFILL }},
1075
1076
16
    { &hf_gbulk_nrepeat,
1077
16
      { "Repeaters", "agentx.gb.nrepeat", FT_UINT16, BASE_DEC, NULL, 0x0,
1078
16
        "getBulk Num. repeaters", HFILL }},
1079
1080
16
    { &hf_gbulk_mrepeat,
1081
16
      { "Max Repetition", "agentx.gb.mrepeat", FT_UINT16, BASE_DEC, NULL, 0x0,
1082
16
        "getBulk Max repetition", HFILL }},
1083
1084
1085
    /* Add more fields here */
1086
1087
16
  };
1088
1089
16
  static int *ett[] = {
1090
16
    &ett_agentx,
1091
16
    &ett_pdu_hdr,
1092
16
    &ett_get,
1093
16
    &ett_getnext,
1094
16
    &ett_search_range,
1095
16
    &ett_obj_ident,
1096
16
    &ett_response,
1097
16
    &ett_valrep,
1098
16
    &ett_open,
1099
16
    &ett_close,
1100
16
    &ett_register,
1101
16
    &ett_unregister,
1102
16
    &ett_getbulk,
1103
16
    &ett_testset,
1104
16
    &ett_commitset,
1105
16
    &ett_undoset,
1106
16
    &ett_cleanupset,
1107
16
    &ett_notify,
1108
16
    &ett_ping,
1109
16
    &ett_idxalloc,
1110
16
    &ett_idxdalloc,
1111
16
    &ett_addcap,
1112
16
    &ett_remcap,
1113
16
    &ett_flags,
1114
16
  };
1115
1116
16
  proto_agentx = proto_register_protocol("AgentX", "AgentX", "agentx");
1117
1118
16
  proto_register_field_array(proto_agentx, hf, array_length(hf));
1119
16
  proto_register_subtree_array(ett, array_length(ett));
1120
1121
16
  agentx_handle = register_dissector("agentx", dissect_agentx, proto_agentx);
1122
16
}
1123
1124
/* The registration hand-off routine */
1125
void
1126
proto_reg_handoff_agentx(void)
1127
16
{
1128
16
  dissector_add_uint_with_preference("tcp.port", AGENTX_TCP_PORT, agentx_handle);
1129
16
}
1130
1131
/*
1132
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1133
 *
1134
 * Local variables:
1135
 * c-basic-offset: 8
1136
 * tab-width: 8
1137
 * indent-tabs-mode: t
1138
 * End:
1139
 *
1140
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1141
 * :indentSize=8:tabSize=8:noTabs=false:
1142
 */