From ba7e8f3b8194f65ad7a112e35e4609a6b785ee0b Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Thu, 10 Feb 2005 06:36:21 +0000 Subject: From Oleg Terletsky: AgentX support. svn path=/trunk/; revision=13372 --- plugins/Makefile.am | 2 +- plugins/Makefile.nmake | 7 +- plugins/agentx/AUTHORS | 2 + plugins/agentx/Makefile.am | 44 ++ plugins/agentx/Makefile.nmake | 30 + plugins/agentx/moduleinfo.h | 17 + plugins/agentx/packet-agentx.c | 1260 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 1360 insertions(+), 2 deletions(-) create mode 100644 plugins/agentx/AUTHORS create mode 100644 plugins/agentx/Makefile.am create mode 100644 plugins/agentx/Makefile.nmake create mode 100644 plugins/agentx/moduleinfo.h create mode 100644 plugins/agentx/packet-agentx.c (limited to 'plugins') diff --git a/plugins/Makefile.am b/plugins/Makefile.am index f945b209bd..add61bfc94 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -21,7 +21,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -SUBDIRS = acn artnet asn1 ciscosm docsis enttec giop gryphon irda lwres mate megaco mgcp opsi pcli rdm rlm rtnet rudp v5ua +SUBDIRS = acn agentx artnet asn1 ciscosm docsis enttec giop gryphon irda lwres mate megaco mgcp opsi pcli rdm rlm rtnet rudp v5ua plugindir = @plugindir@ diff --git a/plugins/Makefile.nmake b/plugins/Makefile.nmake index 982592d6ac..8b1f9a1790 100644 --- a/plugins/Makefile.nmake +++ b/plugins/Makefile.nmake @@ -11,7 +11,7 @@ CFLAGS=/DHAVE_CONFIG_H /I.. /I../wiretap /I. $(GLIB_CFLAGS) \ OBJECTS=plugin_api.obj -all: $(OBJECTS) acn artnet asn1 ciscosm docsis enttec giop gryphon irda lwres mate megaco mgcp opsi pcli rdm rlm rtnet rudp v5ua +all: $(OBJECTS) acn agentx artnet asn1 ciscosm docsis enttec giop gryphon irda lwres mate megaco mgcp opsi pcli rdm rlm rtnet rudp v5ua Xplugin_api.c: plugin_gen.py plugin_api_list.c @echo **** Plugin api may be out of date, please generate new files: @@ -33,6 +33,11 @@ acn:: $(MAKE) /$(MAKEFLAGS) -f Makefile.nmake cd .. +agentx:: + cd agentx + $(MAKE) /$(MAKEFLAGS) -f Makefile.nmake + cd .. + artnet:: cd artnet $(MAKE) /$(MAKEFLAGS) -f Makefile.nmake diff --git a/plugins/agentx/AUTHORS b/plugins/agentx/AUTHORS new file mode 100644 index 0000000000..1368ca6057 --- /dev/null +++ b/plugins/agentx/AUTHORS @@ -0,0 +1,2 @@ +Author : +Oleg Terletsky diff --git a/plugins/agentx/Makefile.am b/plugins/agentx/Makefile.am new file mode 100644 index 0000000000..fe4b1f2e3a --- /dev/null +++ b/plugins/agentx/Makefile.am @@ -0,0 +1,44 @@ +# Makefile.am +# Automake file for Ethereal/plugins/agentx +# +# $Id$ +# +# Ethereal - Network traffic analyzer / AgentX SNMP +# By Oleg Terletsky +# Copyright 2003 +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +INCLUDES = -I$(top_srcdir) + +plugindir = @plugindir@ + +plugin_LTLIBRARIES = agentx.la +agentx_la_SOURCES = packet-agentx.c moduleinfo.h +agentx_la_LDFLAGS = -module -avoid-version +agentx_la_LIBADD = @PLUGIN_LIBS@ + +# Libs must be cleared, or else libtool won't create a shared module. +# If your module needs to be linked against any particular libraries, +# add them here. +LIBS = + +CLEANFILES = \ + agentx \ + *~ + +EXTRA_DIST = \ + Makefile.nmake diff --git a/plugins/agentx/Makefile.nmake b/plugins/agentx/Makefile.nmake new file mode 100644 index 0000000000..8b6f4f37d6 --- /dev/null +++ b/plugins/agentx/Makefile.nmake @@ -0,0 +1,30 @@ +# +# $Id$ +# + +include ..\..\config.nmake + +############### no need to modify below this line ######### + +CFLAGS=/DHAVE_CONFIG_H /I../.. /I../../wiretap $(GLIB_CFLAGS) \ + /I$(PCAP_DIR)\include -D_U_="" $(LOCAL_CFLAGS) + +LDFLAGS = /NOLOGO /INCREMENTAL:no /MACHINE:I386 $(LOCAL_LDFLAGS) + +!IFDEF LINK_PLUGINS_WITH_LIBETHEREAL +LINK_PLUGIN_WITH=..\..\epan\libethereal.lib +CFLAGS=/DHAVE_WIN32_LIBETHEREAL_LIB /D_NEED_VAR_IMPORT_ $(CFLAGS) +!ELSE +LINK_PLUGIN_WITH=..\plugin_api.obj +!ENDIF + +OBJECTS=packet-agentx.obj + +agentx.dll agentx.exp agentx.lib : $(OBJECTS) $(LINK_PLUGIN_WITH) + link -dll /out:agentx.dll $(LDFLAGS) $(OBJECTS) $(LINK_PLUGIN_WITH) \ + $(GLIB_LIBS) + +clean: + rm -f $(OBJECTS) agentx.dll agentx.exp agentx.lib *.pdb + +distclean: clean diff --git a/plugins/agentx/moduleinfo.h b/plugins/agentx/moduleinfo.h new file mode 100644 index 0000000000..c1418ebebf --- /dev/null +++ b/plugins/agentx/moduleinfo.h @@ -0,0 +1,17 @@ +/* Included *after* config.h, in order to re-define these macros */ + +#ifdef PACKAGE +#undef PACKAGE +#endif + +/* Name of package */ +#define PACKAGE "agentx" + + +#ifdef VERSION +#undef VERSION +#endif + +/* Version number of package */ +#define VERSION "0.0.1" + diff --git a/plugins/agentx/packet-agentx.c b/plugins/agentx/packet-agentx.c new file mode 100644 index 0000000000..ce2ba9f8b2 --- /dev/null +++ b/plugins/agentx/packet-agentx.c @@ -0,0 +1,1260 @@ +/* packet-agentx.c + * Routines for Agent Extensibility (AgentX) Protocol disassembly + * RFC 2257 + * + * $Id$ + * + * Copyright (c) 2005 by Oleg Terletsky + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * Copyright 1999 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "plugins/plugin_api.h" +#include "moduleinfo.h" + +#include +#include +#include +#include +#include +#include +#include + + + +#include +#include + +#include "plugins/plugin_api_defs.h" + +static guint global_agentx_tcp_port = 705; +static guint agentx_tcp_port = 705; + +#ifndef ENABLE_STATIC +G_MODULE_EXPORT const gchar version[] = VERSION; +#endif + + +void proto_reg_handoff_agentx(void); + + +/* Define the agentx proto */ +static int proto_agentx = -1; + + +static int hf_version = -1; +static int hf_type = -1; +static int hf_flags = -1; +static int hf_session_id = -1; +static int hf_trans_id = -1; +static int hf_packet_id = -1; +static int hf_payload_len = -1; +static int hf_ostring_len = -1; +static int hf_ostring = -1; +static int hf_oid_sub = -1; +static int hf_oid_prefix = -1; +static int hf_oid_include = -1; +static int hf_oid_str = -1; +static int hf_resp_uptime = -1; +static int hf_resp_error = -1; +static int hf_resp_index = -1; +static int hf_vtag = -1; +static int hf_val32 = -1; +static int hf_val64 = -1; +static int hf_open_timeout = -1; +static int hf_close_reason = -1; +static int hf_reg_timeout = -1; +static int hf_reg_prio = -1; +static int hf_reg_rsid = -1; +static int hf_reg_ubound = -1; +static int hf_unreg_timeout = -1; +static int hf_unreg_prio = -1; +static int hf_unreg_rsid = -1; +static int hf_unreg_ubound = -1; +static int hf_gbulk_nrepeat = -1; +static int hf_gbulk_mrepeat = -1; + + +static gint ett_agentx = -1; +static gint ett_pdu_hdr = -1; +static gint ett_get = -1; +static gint ett_getnext = -1; +static gint ett_search_range = -1; +static gint ett_obj_ident = -1; +static gint ett_response = -1; +static gint ett_valrep = -1; +static gint ett_open = -1; +static gint ett_close = -1; +static gint ett_register = -1; +static gint ett_unregister = -1; +static gint ett_getbulk = -1; +static gint ett_testset = -1; +static gint ett_commitset = -1; +static gint ett_undoset = -1; +static gint ett_cleanupset = -1; +static gint ett_notify = -1; +static gint ett_ping = -1; +static gint ett_idxalloc = -1; +static gint ett_idxdalloc = -1; +static gint ett_addcap = -1; +static gint ett_remcap = -1; + + +#define AGENTX_OPEN_PDU 1 +#define AGENTX_CLOSE_PDU 2 +#define AGENTX_REGISTER_PDU 3 +#define AGENTX_UNREGISTER_PDU 4 +#define AGENTX_GET_PDU 5 +#define AGENTX_GETNEXT_PDU 6 +#define AGENTX_GETBULK_PDU 7 +#define AGENTX_TESTSET_PDU 8 +#define AGENTX_COMMITSET_PDU 9 +#define AGENTX_UNDOSET_PDU 10 +#define AGENTX_CLEANUPSET_PDU 11 +#define AGENTX_NOTIFY_PDU 12 +#define AGENTX_PING_PDU 13 +#define AGENTX_INDEX_ALLOC_PDU 14 +#define AGENTX_INDEX_DEALLOC_PDU 15 +#define AGENTX_ADD_AGENT_CAPS_PDU 16 +#define AGENTX_REM_AGENT_CAPS_PDU 17 +#define AGENTX_RESPONSE_PDU 18 + + +static const value_string type_values [] = { + { AGENTX_OPEN_PDU, "Open-PDU" }, + { AGENTX_CLOSE_PDU, "Close-PDU" }, + { AGENTX_REGISTER_PDU, "Register-PDU" }, + { AGENTX_UNREGISTER_PDU, "Unregister-PDU" }, + { AGENTX_GET_PDU, "Get-PDU" }, + { AGENTX_GETNEXT_PDU, "GetNext-PDU" }, + { AGENTX_GETBULK_PDU, "GetBulk-PDU" }, + { AGENTX_TESTSET_PDU, "TestSet-PDU" }, + { AGENTX_COMMITSET_PDU, "CommitSet-PDU" }, + { AGENTX_UNDOSET_PDU, "UndoSet-PDU" }, + { AGENTX_CLEANUPSET_PDU, "CleanupSet-PDU" }, + { AGENTX_NOTIFY_PDU, "Notify-PDU" }, + { AGENTX_PING_PDU, "Ping-PDU" }, + { AGENTX_INDEX_ALLOC_PDU, "IndexAllocate-PDU" }, + { AGENTX_INDEX_DEALLOC_PDU, "IndexDeallocate-PDU" }, + { AGENTX_ADD_AGENT_CAPS_PDU, "AddAgentCaps-PDU" }, + { AGENTX_REM_AGENT_CAPS_PDU, "RemoveAgentCaps-PDU" }, + { AGENTX_RESPONSE_PDU, "Response-PDU" }, +}; + + +/* VarBind types */ + +#define V_INT 2 +#define V_OSTR 4 +#define V_NULL 5 +#define V_OID 6 +#define V_IPADDR 64 +#define V_COUNTER32 65 +#define V_GAUGE32 66 +#define V_TIMETICK 67 +#define V_OPAQUE 68 +#define V_COUNTER64 70 +#define V_NOSUCHOBJ 128 +#define V_NOSUCHINST 129 +#define V_ENDOFMIB 130 + + +static const value_string vtag_values [] = { + { V_INT, "Integer" }, + { V_OSTR, "Octet String" }, + { V_NULL, "Null" }, + { V_OID , "Object Identifier" }, + { V_IPADDR, "IpAddress" }, + { V_COUNTER32, "Counter32" }, + { V_GAUGE32, "Gauge32" }, + { V_TIMETICK, "TimeTicks" }, + { V_OPAQUE, "Opaque" }, + { V_COUNTER64, "Counter64" }, + { V_NOSUCHOBJ, "noSuchObject" }, + { V_NOSUCHINST, "noSuchInstance" }, + { V_ENDOFMIB, "endOfMibView" }, +}; + + +/* Close reasons */ +#define CREASON_OTHER 1 +#define CREASON_PARSE_ERROR 2 +#define CREASON_PROTOCOL_ERROR 3 +#define CREASON_TIMEOUTS 4 +#define CREASON_SHUTDOWN 5 +#define CREASON_BY_MANAGER 6 + + +static const value_string close_reasons[] = { + { CREASON_OTHER, "reasonOther" }, + { CREASON_PARSE_ERROR, "reasonParseError" }, + { CREASON_PROTOCOL_ERROR, "reasonProtocolError" }, + { CREASON_TIMEOUTS, "reasonTimeouts" }, + { CREASON_SHUTDOWN , "reasonShutdown" }, + { CREASON_BY_MANAGER, "reasonByManager" }, +}; + + +/* Response errors */ +#define AGENTX_NO_ERROR 0 +#define AGENTX_TOO_BIG 1 +#define AGENTX_NO_SUCH_NAME 2 +#define AGENTX_BAD_VALUE 3 +#define AGENTX_READ_ONLY 4 +#define AGENTX_GEN_ERROR 5 +#define AGENTX_NO_ACCESS 6 +#define AGENTX_WRONG_TYPE 7 +#define AGENTX_WRONG_LEN 8 +#define AGENTX_WRONG_ENCODE 9 +#define AGENTX_WRONG_VALUE 10 +#define AGENTX_NO_CREATION 11 +#define AGENTX_INCONSIST_VALUE 12 +#define AGENTX_RES_UNAVAIL 13 +#define AGENTX_COMMIT_FAILED 14 +#define AGENTX_UNDO_FAILED 15 +#define AGENTX_AUTH_ERROR 16 +#define AGENTX_NOTWRITABLE 17 +#define AGENTX_INCONSIS_NAME 18 +#define AGENTX_OPEN_FAILED 256 +#define AGENTX_NOT_OPEN 257 +#define AGENTX_IDX_WRONT_TYPE 258 +#define AGENTX_IDX_ALREAY_ALLOC 259 +#define AGENTX_IDX_NONEAVAIL 260 +#define AGENTX_IDX_NOTALLOC 261 +#define AGENTX_UNSUPP_CONTEXT 262 +#define AGENTX_DUP_REGISTR 263 +#define AGENTX_UNKNOWN_REG 264 +#define AGENTX_UNKNOWN_CAPS 265 + + +static const value_string resp_errors[] = { + { AGENTX_NO_ERROR, "noError" }, + { AGENTX_TOO_BIG, "tooBig" }, + { AGENTX_NO_SUCH_NAME, "noSuchName" }, + { AGENTX_BAD_VALUE, "badValue" }, + { AGENTX_READ_ONLY, "readOnly" }, + { AGENTX_GEN_ERROR, "genErr" }, + { AGENTX_NO_ACCESS, "noAccess" }, + { AGENTX_WRONG_TYPE, "wrongType" }, + { AGENTX_WRONG_LEN, "wrongLength" }, + { AGENTX_WRONG_ENCODE, "wrongEncoding" }, + { AGENTX_WRONG_VALUE, "wrongValue" }, + { AGENTX_NO_CREATION, "noCreation" }, + { AGENTX_INCONSIST_VALUE, "inconsistentValue" }, + { AGENTX_RES_UNAVAIL, "resourceUnavailable" }, + { AGENTX_COMMIT_FAILED, "commitFailed" }, + { AGENTX_UNDO_FAILED , "undoFailed" }, + { AGENTX_AUTH_ERROR, "authorizationError" }, + { AGENTX_NOTWRITABLE, "notWritable" }, + { AGENTX_INCONSIS_NAME, "inconsistentName" }, + { AGENTX_OPEN_FAILED, "openFailed" }, + { AGENTX_NOT_OPEN, "notOpen" }, + { AGENTX_IDX_WRONT_TYPE, "indexWrongType" }, + { AGENTX_IDX_ALREAY_ALLOC, "indexAlreadyAllocated" }, + { AGENTX_IDX_NONEAVAIL, "indexNoneAvailable" }, + { AGENTX_IDX_NOTALLOC, "indexNotAllocated" }, + { AGENTX_UNSUPP_CONTEXT, "unsupportedContext" }, + { AGENTX_DUP_REGISTR, "duplicateRegistration" }, + { AGENTX_UNKNOWN_REG, "unknownRegistration" }, + { AGENTX_UNKNOWN_CAPS, "unknownAgentCaps" }, +}; + + + + +/* PDU Header flags */ + +#define INSTANCE_REGISTRATION 0 +#define NEW_INDEX 0x1 +#define ANY_INDEX 0x2 +#define NON_DEFAULT_CONTEXT 0x4 +#define NETWORK_BYTE_ORDER 0x8 + +#define PDU_HDR_LEN 20 +#define PADDING(x) ((((x) + 3) >> 2) << 2) + +#define NORHL(FLAGS,VAR) VAR = (FLAGS & NETWORK_BYTE_ORDER) ? VAR : g_htonl(VAR) +#define NORHS(FLAGS,VAR) VAR = (FLAGS & NETWORK_BYTE_ORDER) ? VAR : g_htons(VAR) + +int dissect_octet_string(tvbuff_t *tvb, proto_tree *tree, int offset, char flags) +{ + guint32 n_oct, p_noct; + char context[1024]; + + n_oct = tvb_get_ntohl(tvb, offset); + NORHL(flags,n_oct); + + p_noct = PADDING(n_oct); + tvb_get_nstringz(tvb, offset + 4, n_oct, context); + context[n_oct]='\0'; + + proto_tree_add_uint(tree,hf_ostring_len,tvb,offset,4,n_oct); + proto_tree_add_string(tree, hf_ostring, tvb, offset + 4, n_oct, context); + return p_noct + 4; + +} + + +int convert_oid_to_str(guint32 *oid, int len, char* str, int slen, char prefix) +{ + int i; + char tlen = 0; + if(!oid) return 0; + if(!str) return 0; + if(!len) return 0; + if(!slen) return 0; + if(slen < len) return 0; + + if(prefix) { + tlen+= sprintf(str,".1.3.6.1.%d",prefix); + } + + for(i=0; i < len; i++) { + printf("->%d<-\n",oid[i]); + tlen += sprintf(str+tlen,".%d",oid[i]); + } + return tlen; +} + +int dissect_object_id(tvbuff_t *tvb, proto_tree *tree, int offset, char flags) +{ + guint8 n_subid; + guint8 prefix; + guint8 include; + proto_item* item; + proto_tree* subtree; + guint32 oid[2048]; + char str_oid[2048]; + int i, slen; + + memset(oid, '\0', sizeof(oid)); + memset(str_oid, '\0', sizeof(str_oid)); + + n_subid = tvb_get_guint8(tvb, offset); + prefix = tvb_get_guint8(tvb, offset + 1); + include = tvb_get_guint8(tvb,offset + 2); + tvb_get_guint8(tvb, offset + 3); + + for(i=0; i offset) { + offset += dissect_varbind(tvb, subtree, offset, len, flags); + } + + return offset; + +} + +int dissect_getnext_pdu(tvbuff_t *tvb, proto_tree *tree,int offset,int len, char flags) +{ + proto_item* item; + proto_tree* subtree; + + if(tree) { + item = proto_tree_add_text(tree, tvb, offset, len, "GetNext-PDU"); + subtree = proto_item_add_subtree(item, ett_getnext); + } else return offset; + + + if(flags & NON_DEFAULT_CONTEXT) { + /* show context */ + offset += dissect_octet_string(tvb, subtree, offset, flags); + } + + while(len > offset) { + offset += dissect_search_range(tvb, subtree, offset, flags); + } + return offset; +} + +int dissect_get_pdu(tvbuff_t *tvb, proto_tree *tree,int offset,int len, char flags) +{ + proto_item* item; + proto_tree* subtree; + + if(tree) { + item = proto_tree_add_text(tree, tvb, offset, len, "Get-PDU"); + subtree = proto_item_add_subtree(item, ett_get); + } else return offset; + + if(flags & NON_DEFAULT_CONTEXT) { + /* show context */ + offset += dissect_octet_string(tvb, subtree, offset, flags); + } + + while(len >= offset) { + offset += dissect_search_range(tvb, subtree, offset, flags); + tvb_get_ntohl(tvb, offset); offset+=4; /* skip 0 end dword */ + } + return offset; +} + +int dissect_getbulk_pdu(tvbuff_t *tvb, proto_tree *tree,int offset,int len, char flags) +{ + proto_item* item; + proto_tree* subtree; + guint16 non_repeaters; + guint16 max_repetitions; + + if(tree) { + item = proto_tree_add_text(tree, tvb, offset, len, "GetBulk-PDU"); + subtree = proto_item_add_subtree(item, ett_getbulk); + } else return offset; + + if(flags & NON_DEFAULT_CONTEXT) { + /* show context */ + offset += dissect_octet_string(tvb, subtree, offset, flags); + } + + non_repeaters = tvb_get_ntohs(tvb, offset); + max_repetitions = tvb_get_ntohs(tvb, offset + 2); + + NORHS(flags,non_repeaters); + NORHS(flags,max_repetitions); + + proto_tree_add_uint(subtree, hf_gbulk_nrepeat, tvb, offset, 2, non_repeaters); + proto_tree_add_uint(subtree, hf_gbulk_mrepeat, tvb, offset + 2, 2, max_repetitions); + offset+=4; + + while(len >= offset) { + offset += dissect_search_range(tvb, subtree, offset, flags); + } + return offset; +} + +int dissect_open_pdu(tvbuff_t *tvb, proto_tree *tree,int offset,int len, char flags) +{ + proto_item* item; + proto_tree* subtree; + guint8 timeout; + + if(tree) { + item = proto_tree_add_text(tree, tvb, offset, len, "Open-PDU"); + subtree = proto_item_add_subtree(item, ett_open); + } else return offset; + + timeout = tvb_get_guint8(tvb, offset); + tvb_get_ntoh24(tvb, offset + 1); + + proto_tree_add_uint(subtree, hf_open_timeout, tvb, offset, 1, timeout); + offset+=4; + + /* Search Range */ + offset += dissect_object_id(tvb, subtree, offset, flags); + + /* Octet string */ + offset += dissect_octet_string(tvb, subtree, offset, flags); + + return offset; +} + +int dissect_close_pdu(tvbuff_t *tvb, proto_tree *tree,int offset,int len) +{ + proto_item* item; + proto_tree* subtree; + guint8 reason; + + if(tree) { + item = proto_tree_add_text(tree, tvb, offset, len, "Close-PDU"); + subtree = proto_item_add_subtree(item, ett_close); + } else return offset; + + reason = tvb_get_guint8(tvb, offset); + tvb_get_ntoh24(tvb, offset + 1); + + proto_tree_add_uint(subtree, hf_close_reason, tvb, offset, 1, reason); + offset+=4; + + return offset; +} + + +int dissect_register_pdu(tvbuff_t *tvb, proto_tree *tree,int offset,int len, char flags) +{ + proto_item* item; + proto_tree* subtree; + guint8 timeout; + guint8 priority; + guint8 range_subid; + guint32 upper_bound; + + if(tree) { + item = proto_tree_add_text(tree, tvb, offset, len, "Register-PDU"); + subtree = proto_item_add_subtree(item, ett_register); + } else return offset; + + if(flags & NON_DEFAULT_CONTEXT) { + /* show context */ + offset += dissect_octet_string(tvb, subtree, offset, flags); + } + + timeout = tvb_get_guint8(tvb, offset); + priority = tvb_get_guint8(tvb, offset+1); + range_subid = tvb_get_guint8(tvb, offset+2); + tvb_get_guint8(tvb, offset + 4); + + proto_tree_add_uint(subtree, hf_reg_timeout, tvb, offset, 1, timeout); + proto_tree_add_uint(subtree, hf_reg_prio, tvb, offset+1, 1, priority); + proto_tree_add_uint(subtree, hf_reg_rsid, tvb, offset+2, 1, range_subid); + offset+=4; + + /* Region */ + + offset += dissect_object_id(tvb, subtree, offset, flags); + + if(len > offset) { + /* Upper bound (opt) */ + upper_bound = tvb_get_ntohl(tvb, offset); + NORHL(flags,upper_bound); + + proto_tree_add_uint(subtree, hf_reg_ubound, tvb, offset, 4, upper_bound); + offset += 4; + } + + return offset; +} + + +int dissect_unregister_pdu(tvbuff_t *tvb, proto_tree *tree,int offset,int len, char flags) +{ + proto_item* item; + proto_tree* subtree; + guint8 timeout; + guint8 priority; + guint8 range_subid; + guint32 upper_bound; + + if(tree) { + item = proto_tree_add_text(tree, tvb, offset, len, "Unregister-PDU"); + subtree = proto_item_add_subtree(item, ett_unregister); + } else return offset; + + if(flags & NON_DEFAULT_CONTEXT) { + /* show context */ + offset += dissect_octet_string(tvb, subtree, offset, flags); + } + + timeout = tvb_get_guint8(tvb, offset); + priority = tvb_get_guint8(tvb, offset+1); + range_subid = tvb_get_guint8(tvb, offset+2); + tvb_get_guint8(tvb, offset + 4); + + proto_tree_add_uint(subtree, hf_unreg_timeout, tvb, offset, 1, timeout); + proto_tree_add_uint(subtree, hf_unreg_prio, tvb, offset+1, 1, priority); + proto_tree_add_uint(subtree, hf_unreg_rsid, tvb, offset+2, 1, range_subid); + offset+=4; + + /* Region */ + offset += dissect_object_id(tvb, subtree, offset, flags); + + if(len > offset) { + /* Upper bound (opt) */ + upper_bound = tvb_get_ntohl(tvb, offset); + NORHL(flags,upper_bound); + + proto_tree_add_uint(subtree, hf_unreg_ubound, tvb, offset, 4, upper_bound); + offset += 4; + } + + return offset; +} + +int dissect_testset_pdu(tvbuff_t *tvb, proto_tree *tree,int offset,int len, char flags) +{ + proto_item* item; + proto_tree* subtree; + + if(tree) { + item = proto_tree_add_text(tree, tvb, offset, len, "Testset-PDU"); + subtree = proto_item_add_subtree(item, ett_testset); + } else return offset; + + if(flags & NON_DEFAULT_CONTEXT) { + /* show context */ + offset += dissect_octet_string(tvb, subtree, offset, flags); + } + + while(len > offset) { + offset += dissect_varbind(tvb, subtree, offset, len, flags); + } + + return offset; +} + +int dissect_notify_pdu(tvbuff_t *tvb, proto_tree *tree,int offset,int len, char flags) +{ + proto_item* item; + proto_tree* subtree; + + if(tree) { + item = proto_tree_add_text(tree, tvb, offset, len, "Notify-PDU"); + subtree = proto_item_add_subtree(item, ett_notify); + } else return offset; + + if(flags & NON_DEFAULT_CONTEXT) { + /* show context */ + offset += dissect_octet_string(tvb, subtree, offset, flags); + } + + while(len > offset) { + offset += dissect_varbind(tvb, subtree, offset, len, flags); + } + return offset; +} + +int dissect_ping_pdu(tvbuff_t *tvb, proto_tree *tree,int offset,int len, char flags) +{ + proto_item* item; + proto_tree* subtree; + + if(tree) { + item = proto_tree_add_text(tree, tvb, offset, len, "Ping-PDU"); + subtree = proto_item_add_subtree(item, ett_ping); + } else return offset; + + if(flags & NON_DEFAULT_CONTEXT) { + /* show context */ + offset += dissect_octet_string(tvb, subtree, offset, flags); + } + + return offset; +} + +int dissect_idx_alloc_pdu(tvbuff_t *tvb, proto_tree *tree,int offset,int len, char flags) +{ + proto_item* item; + proto_tree* subtree; + + if(tree) { + item = proto_tree_add_text(tree, tvb, offset, len, "IndexAllocate-PDU"); + subtree = proto_item_add_subtree(item, ett_idxalloc); + } else return offset; + + if(flags & NON_DEFAULT_CONTEXT) { + /* show context */ + offset += dissect_octet_string(tvb, subtree, offset, flags); + } + + while(len > offset) { + offset += dissect_varbind(tvb, subtree, offset, len, flags); + } + return offset; +} + + +int dissect_idx_dealloc_pdu(tvbuff_t *tvb, proto_tree *tree,int offset,int len, char flags) +{ + proto_item* item; + proto_tree* subtree; + + if(tree) { + item = proto_tree_add_text(tree, tvb, offset, len, "IndexDeallocate-PDU"); + subtree = proto_item_add_subtree(item, ett_idxdalloc); + } else return offset; + + if(flags & NON_DEFAULT_CONTEXT) { + /* show context */ + offset += dissect_octet_string(tvb, subtree, offset, flags); + } + + while(len > offset) { + offset += dissect_varbind(tvb, subtree, offset, len, flags); + } + return offset; +} + +int dissect_add_caps_pdu(tvbuff_t *tvb, proto_tree *tree,int offset,int len, char flags) +{ + proto_item* item; + proto_tree* subtree; + + if(tree) { + item = proto_tree_add_text(tree, tvb, offset, len, "AddAgentCaps-PDU"); + subtree = proto_item_add_subtree(item, ett_addcap); + } else return offset; + + if(flags & NON_DEFAULT_CONTEXT) { + /* show context */ + offset += dissect_octet_string(tvb, subtree, offset, flags); + } + + offset += dissect_object_id(tvb, subtree, offset, flags); + + offset += dissect_octet_string(tvb, subtree, offset, flags); + + return offset; +} + +int dissect_rem_caps_pdu(tvbuff_t *tvb, proto_tree *tree,int offset,int len, char flags) +{ + proto_item* item; + proto_tree* subtree; + + if(tree) { + item = proto_tree_add_text(tree, tvb, offset, len, "RemoveAgentCaps-PDU"); + subtree = proto_item_add_subtree(item, ett_remcap); + } else return offset; + + if(flags & NON_DEFAULT_CONTEXT) { + /* show context */ + offset += dissect_octet_string(tvb, subtree, offset, flags); + } + + offset += dissect_object_id(tvb, subtree, offset, flags); + + return offset; +} + + +int dissect_agentx_pdu(tvbuff_t *tvb, int offset, packet_info *pinfo, + proto_tree *tree) +{ + int length_remaining; + proto_tree* agentx_tree ,*pdu_hdr_tree; + proto_item* pdu_item , *t_item; + guint8 version; + guint8 type; + guint8 flags; + guint32 session_id; + guint32 trans_id; + guint32 packet_id; + guint32 payload_len; + + length_remaining = tvb_ensure_length_remaining(tvb, offset); + + if(pinfo->can_desegment) { + if(length_remaining < 5) { + pinfo->desegment_offset = offset; + pinfo->desegment_len = 5 - length_remaining; + return (0); + } + } + + version = tvb_get_guint8(tvb,0); offset+=1; + type = tvb_get_guint8(tvb,1); offset+=1; + flags = tvb_get_guint8(tvb,2); offset+=1; + /* skip reserved byte */ + tvb_get_guint8(tvb,3); offset+=1; + + session_id = tvb_get_ntohl(tvb, 4); offset+=4; + trans_id = tvb_get_ntohl(tvb, 8); offset+=4; + packet_id = tvb_get_ntohl(tvb, 12); offset+=4; + payload_len = tvb_get_ntohl(tvb, 16); offset+=4; + + NORHL(flags,session_id); + NORHL(flags,trans_id); + NORHL(flags,packet_id); + NORHL(flags,payload_len); + + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "AgentX"); + + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "%s: sid=%d, tid=%d, packid=%d, plen=%d", + val_to_str(type,type_values,"unknown"), + session_id,trans_id,packet_id,payload_len); + + + if(tree) { + //t_item = proto_tree_add_item(tree, proto_agentx, tvb, 0, -1, FALSE); + + t_item = proto_tree_add_protocol_format(tree, proto_agentx, tvb, 0, -1, + "Agent Extensibility (AgentX) Protocol: %s, sid=%d, tid=%d, packid=%d, plen=%d", + val_to_str(type,type_values,"unknown"), + session_id,trans_id,packet_id,payload_len); + + + + + agentx_tree = proto_item_add_subtree(t_item, ett_agentx); + } + else return (0); + + pdu_item = proto_tree_add_text(agentx_tree, tvb, 0, 5, "PDU Header: Type[%u], len=%d, sid=%d, tid=%d, packid=%d", + (char)type,payload_len,session_id,trans_id,packet_id); + + pdu_hdr_tree = proto_item_add_subtree(pdu_item, ett_pdu_hdr); + + proto_tree_add_uint(pdu_hdr_tree,hf_version,tvb,0,1,version); + proto_tree_add_uint(pdu_hdr_tree,hf_type,tvb,1,1,type); + proto_tree_add_uint(pdu_hdr_tree,hf_flags,tvb,2,1,flags); + proto_tree_add_uint(pdu_hdr_tree,hf_session_id,tvb,4,4,session_id); + proto_tree_add_uint(pdu_hdr_tree,hf_trans_id,tvb,8,4,trans_id); + proto_tree_add_uint(pdu_hdr_tree,hf_packet_id,tvb,12,4,packet_id); + proto_tree_add_uint(pdu_hdr_tree,hf_payload_len,tvb,16,4,payload_len); + + switch(type) { + case AGENTX_OPEN_PDU: + offset += dissect_open_pdu(tvb, pdu_hdr_tree, offset,payload_len,flags); + break; + + case AGENTX_CLOSE_PDU: + offset += dissect_close_pdu(tvb, pdu_hdr_tree, offset,payload_len); + break; + + case AGENTX_REGISTER_PDU: + offset += dissect_register_pdu(tvb, pdu_hdr_tree, offset,payload_len,flags); + break; + + case AGENTX_UNREGISTER_PDU: + offset += dissect_unregister_pdu(tvb, pdu_hdr_tree, offset,payload_len,flags); + break; + + case AGENTX_GET_PDU: + offset += dissect_get_pdu(tvb, pdu_hdr_tree, offset,payload_len,flags); + break; + + case AGENTX_GETNEXT_PDU: + offset += dissect_getnext_pdu(tvb, pdu_hdr_tree, offset,payload_len,flags); + break; + + case AGENTX_GETBULK_PDU: + offset += dissect_getbulk_pdu(tvb, pdu_hdr_tree, offset,payload_len,flags); + break; + + case AGENTX_TESTSET_PDU: + offset += dissect_testset_pdu(tvb, pdu_hdr_tree, offset,payload_len,flags); + break; + + case AGENTX_COMMITSET_PDU: + case AGENTX_UNDOSET_PDU: + case AGENTX_CLEANUPSET_PDU: + /* there is no parameters */ + break; + + case AGENTX_NOTIFY_PDU: + offset += dissect_notify_pdu(tvb, pdu_hdr_tree, offset,payload_len,flags); + break; + + case AGENTX_PING_PDU: + offset += dissect_ping_pdu(tvb, pdu_hdr_tree, offset,payload_len,flags); + break; + + case AGENTX_INDEX_ALLOC_PDU: + offset += dissect_idx_alloc_pdu(tvb, pdu_hdr_tree, offset,payload_len,flags); + break; + + case AGENTX_INDEX_DEALLOC_PDU: + offset += dissect_idx_dealloc_pdu(tvb, pdu_hdr_tree, offset,payload_len,flags); + break; + + case AGENTX_ADD_AGENT_CAPS_PDU: + offset += dissect_add_caps_pdu(tvb, pdu_hdr_tree, offset,payload_len,flags); + break; + + case AGENTX_REM_AGENT_CAPS_PDU: + offset += dissect_rem_caps_pdu(tvb, pdu_hdr_tree, offset,payload_len,flags); + break; + + case AGENTX_RESPONSE_PDU: + offset += dissect_response_pdu(tvb, pdu_hdr_tree, offset, payload_len, flags); + break; + } + + + return offset; +} + +static void +dissect_agentx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + volatile int offset = 0; + int len; + + + while (tvb_reported_length_remaining(tvb, offset) > 0) { + + /* dissect mssage here */ + len = dissect_agentx_pdu(tvb, offset, pinfo, tree); + if(len == 0) { + break; + } + offset+=len; + } + +} + + + + +void +proto_register_agentx(void) +{ + static hf_register_info hf[] = { + + { &hf_version, + { "Version ", "agentx.version", FT_UINT8, BASE_DEC, NULL, 0x0, + "header version", HFILL }}, + + { &hf_type, + { "Type ", "agentx.type", FT_UINT8, BASE_DEC, VALS(type_values), 0x0, + "header type", HFILL }}, + + { &hf_flags, + { "Flags ", "agentx.flags", FT_UINT8, BASE_DEC, NULL, 0x0, + "header type", HFILL }}, + + { &hf_session_id, + { "sessionID ", "agentx.session_id", FT_UINT32, BASE_DEC, NULL, 0x0, + "Session ID", HFILL }}, + + { &hf_trans_id, + { "TransactionID ", "agentx.transaction_id", FT_UINT32, BASE_DEC, NULL, 0x0, + "Transaction ID", HFILL }}, + + { &hf_packet_id, + { "PacketID ", "agentx.packet_id", FT_UINT32, BASE_DEC, NULL, 0x0, + "Packet ID", HFILL }}, + + { &hf_payload_len, + { "Payload length ", "agentx.payload_len", FT_UINT32, BASE_DEC, NULL, 0x0, + "Payload length", HFILL }}, + + { &hf_ostring, + { "Octet String", "agentx.ostring", FT_STRING, BASE_NONE, NULL, 0x0, + "Octet String", HFILL }}, + + { &hf_ostring_len, + { "OString len", "agentx.ostring_len", FT_UINT32, BASE_DEC, NULL, 0x0, + "Octet String Length", HFILL }}, + + { &hf_oid_sub, + { "Number subids ", "agentx.n_subid", FT_UINT8, BASE_DEC, NULL, 0x0, + "Number subids", HFILL }}, + + { &hf_oid_prefix, + { "OID prefix ", "agentx.oid_prefix", FT_UINT8, BASE_DEC, NULL, 0x0, + "OID prefix", HFILL }}, + + { &hf_oid_include, + { "OID include ", "agentx.oid_include", FT_UINT8, BASE_DEC, NULL, 0x0, + "OID include", HFILL }}, + + { &hf_oid_str, + { "OID", "agentx.oid", FT_STRING, BASE_DEC, NULL, 0x0, + "OID", HFILL }}, + + { &hf_resp_uptime, + { "sysUpTime", "agentx.r.uptime", FT_UINT32, BASE_DEC, NULL, 0x0, + "sysUpTime", HFILL }}, + + { &hf_resp_error, + { "Resp. error", "agentx.r.error", FT_UINT16, BASE_DEC, VALS(resp_errors), 0x0, + "response error", HFILL }}, + + { &hf_resp_index, + { "Resp. index", "agentx.r.index", FT_UINT16, BASE_DEC, NULL, 0x0, + "response index", HFILL }}, + + { &hf_vtag, + { "Variable type", "agentx.v.tag", FT_UINT16, BASE_DEC, VALS(vtag_values), 0x0, + "vtag", HFILL }}, + + { &hf_val32, + { "Value(32)", "agentx.v.val32", FT_UINT32, BASE_DEC, NULL, 0x0, + "val32", HFILL }}, + + { &hf_val64, + { "Value(64)", "agentx.v.val64", FT_UINT64, BASE_DEC, NULL, 0x0, + "val64", HFILL }}, + + { &hf_open_timeout, + { "Timeout", "agentx.o.timeout", FT_UINT8, BASE_DEC, NULL, 0x0, + "open timeout", HFILL }}, + + { &hf_close_reason, + { "Reason", "agentx.c.reason", FT_UINT8, BASE_DEC, VALS(close_reasons), 0x0, + "close reason", HFILL }}, + + { &hf_reg_timeout, + { "Timeout", "agentx.r.timeout", FT_UINT8, BASE_DEC, NULL, 0x0, + "Register timeout", HFILL }}, + + { &hf_reg_prio, + { "Priority", "agentx.r.priority", FT_UINT8, BASE_DEC, NULL, 0x0, + "Register Priority", HFILL }}, + + { &hf_reg_rsid, + { "Range_subid", "agentx.r.range_subid", FT_UINT8, BASE_DEC, NULL, 0x0, + "Register range_subid", HFILL }}, + + { &hf_reg_ubound, + { "Upper bound", "agentx.r.upper_bound", FT_UINT32, BASE_DEC, NULL, 0x0, + "Register upper bound", HFILL }}, + + { &hf_unreg_timeout, + { "Timeout", "agentx.u.timeout", FT_UINT8, BASE_DEC, NULL, 0x0, + "Unregister timeout", HFILL }}, + + { &hf_unreg_prio, + { "Priority", "agentx.u.priority", FT_UINT8, BASE_DEC, NULL, 0x0, + "Unegister Priority", HFILL }}, + + { &hf_unreg_rsid, + { "Range_subid", "agentx.u.range_subid", FT_UINT8, BASE_DEC, NULL, 0x0, + "Unegister range_subid", HFILL }}, + + { &hf_unreg_ubound, + { "Upper bound", "agentx.u.upper_bound", FT_UINT32, BASE_DEC, NULL, 0x0, + "Register upper bound", HFILL }}, + + { &hf_gbulk_nrepeat, + { "Repeaters", "agentx.gb.nrepeat", FT_UINT16, BASE_DEC, NULL, 0x0, + "getBulk Num. repeaters", HFILL }}, + + { &hf_gbulk_mrepeat, + { "Max Repetition", "agentx.gb.mrepeat", FT_UINT16, BASE_DEC, NULL, 0x0, + "getBulk Max repetition", HFILL }}, + + + /* Add more fields here */ + + }; + + static gint *ett[] = { + &ett_agentx, + &ett_pdu_hdr, + &ett_get, + &ett_getnext, + &ett_search_range, + &ett_obj_ident, + &ett_response, + &ett_valrep, + &ett_open, + &ett_close, + &ett_register, + &ett_unregister, + &ett_getbulk, + &ett_testset, + &ett_commitset, + &ett_undoset, + &ett_cleanupset, + &ett_notify, + &ett_ping, + &ett_idxalloc, + &ett_idxdalloc, + &ett_addcap, + &ett_remcap, + }; + + + module_t *agentx_module; + + proto_agentx = proto_register_protocol("AgentX", + "AgentX", "agentx"); + + proto_register_field_array(proto_agentx, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + agentx_module = prefs_register_protocol(proto_agentx, proto_reg_handoff_agentx); + + prefs_register_uint_preference(agentx_module, "tcp.agentx_port", + "AgentX listener TCP Port", + "Set the TCP port for AgentX" + "(if other than the default of 705)", + 10, &global_agentx_tcp_port); + +} + +/* The registration hand-off routine */ +void +proto_reg_handoff_agentx(void) +{ + static int agentx_prefs_initialized = FALSE; + static dissector_handle_t agentx_handle; + + if(!agentx_prefs_initialized) { + agentx_handle = create_dissector_handle(dissect_agentx, proto_agentx); + agentx_prefs_initialized = TRUE; + } + else { + dissector_delete("tcp.port",global_agentx_tcp_port, agentx_handle); + + } + + agentx_tcp_port = global_agentx_tcp_port; + + dissector_add("tcp.port", agentx_tcp_port, agentx_handle); + +} + +/* Start the functions we need for the plugin stuff */ + +#ifndef ENABLE_STATIC + +G_MODULE_EXPORT void +plugin_reg_handoff(void){ + proto_reg_handoff_agentx(); +} + +G_MODULE_EXPORT void +plugin_init(plugin_address_table_t *pat +#ifndef PLUGINS_NEED_ADDRESS_TABLE +_U_ +#endif +){ + /* initialise the table of pointers needed in Win32 DLLs */ + plugin_address_table_init(pat); + /* register the new protocol, protocol fields, and subtrees */ + if (proto_agentx == -1) { /* execute protocol initialization only once */ + proto_register_agentx(); + } +} + +#endif + +/* End the functions we need for plugin stuff */ -- cgit v1.2.3