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