/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 | | */ |