diff options
author | Anders Broman <anders.broman@ericsson.com> | 2005-12-04 21:45:38 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2005-12-04 21:45:38 +0000 |
commit | 223506c53791f46282c03f4caba3bafbb64342f8 (patch) | |
tree | 5d7ba0a3a75e985c4387b6578bcdd21d683f3e33 /asn1/snmp | |
parent | d3970d3674861b5e08ee0e2b6b2d87718b3e482f (diff) |
Work in progress an asn2eth generated snmp dissector.
svn path=/trunk/; revision=16674
Diffstat (limited to 'asn1/snmp')
-rw-r--r-- | asn1/snmp/Makefile | 16 | ||||
-rw-r--r-- | asn1/snmp/Makefile.nmake | 42 | ||||
-rw-r--r-- | asn1/snmp/README.txt | 5 | ||||
-rw-r--r-- | asn1/snmp/packet-snmp-template.c | 978 | ||||
-rw-r--r-- | asn1/snmp/packet-snmp-template.h | 38 | ||||
-rw-r--r-- | asn1/snmp/snmp.asn | 545 | ||||
-rw-r--r-- | asn1/snmp/snmp.cnf | 143 |
7 files changed, 1767 insertions, 0 deletions
diff --git a/asn1/snmp/Makefile b/asn1/snmp/Makefile new file mode 100644 index 0000000000..f91fdc645a --- /dev/null +++ b/asn1/snmp/Makefile @@ -0,0 +1,16 @@ +# $Id: Makefile 13071 2005-01-16 10:19:21Z guy $ + +DISSECTOR_FILES=packet-MAP_DialoguePDU.c packet-MAP_DialoguePDU.h + +all: generate_dissector + +generate_dissector: $(DISSECTOR_FILES) + +$(DISSECTOR_FILES): ../../tools/asn2eth.py MAP_DialoguePDU.asn packet-MAP-DialoguePDU-template.c packet-MAP-DialoguePDU-template.h MAP_DialoguePDU.cnf + python ../../tools/asn2eth.py -X -b -e -p MAP_DialoguePDU -c MAP_DialoguePDU.cnf -s packet-MAP-DialoguePDU-template MAP_DialoguePDU.asn + +clean: + rm -f parsetab.py $(DISSECTOR_FILES) + +copy_files: generate_dissector + cp $(DISSECTOR_FILES) ../../epan/dissectors diff --git a/asn1/snmp/Makefile.nmake b/asn1/snmp/Makefile.nmake new file mode 100644 index 0000000000..575340c285 --- /dev/null +++ b/asn1/snmp/Makefile.nmake @@ -0,0 +1,42 @@ +## Use: $(MAKE) /$(MAKEFLAGS) -f makefile.nmake +# +# $Id: Makefile.nmake 13077 2005-01-16 23:26:02Z lroland $ + +include ../../config.nmake + +UNIX2DOS=$(PERL) ../../tools/unix2dos.pl + +PROTOCOL_NAME=snmp +DISSECTOR_FILES=packet-$(PROTOCOL_NAME).c packet-$(PROTOCOL_NAME).h + +all: generate_dissector + +generate_dissector: $(DISSECTOR_FILES) + +$(DISSECTOR_FILES): ../../tools/asn2eth.py snmp.asn packet-snmp-template.c packet-snmp-template.h snmp.cnf +!IFDEF PYTHON + $(PYTHON) ../../tools/asn2eth.py -X -b -e -p $(PROTOCOL_NAME) -c snmp.cnf -s packet-snmp-template snmp.asn +!ELSE + @echo Error: You need Python to use asn2eth.py + @exit 1 +!ENDIF + +clean: + rm -f parsetab.py $(DISSECTOR_FILES) + +# Fix EOL in generated dissectors. Cygwin's python generates files with +# mixed EOL styles, which can't be commited to the SVN repository. +# Stuff included from template and "cnf" files has "\r\n" on windows, while +# the generated stuff has "\n". + +fix_eol: generate_dissector + move packet-$(PROTOCOL_NAME).c packet-$(PROTOCOL_NAME).c.tmp + move packet-$(PROTOCOL_NAME).h packet-$(PROTOCOL_NAME).h.tmp + $(UNIX2DOS) < packet-$(PROTOCOL_NAME).c.tmp > packet-$(PROTOCOL_NAME).c + $(UNIX2DOS) < packet-$(PROTOCOL_NAME).h.tmp > packet-$(PROTOCOL_NAME).h + del /f packet-$(PROTOCOL_NAME).c.tmp packet-$(PROTOCOL_NAME).h.tmp + +copy_files: generate_dissector fix_eol + xcopy packet-$(PROTOCOL_NAME).c ..\..\epan\dissectors /d /y + xcopy packet-$(PROTOCOL_NAME).h ..\..\epan\dissectors /d /y + diff --git a/asn1/snmp/README.txt b/asn1/snmp/README.txt new file mode 100644 index 0000000000..656ccf771e --- /dev/null +++ b/asn1/snmp/README.txt @@ -0,0 +1,5 @@ +This is a work in progress to enhance and replace the existing snmp dissector with an asn2eth generated one. + +To test/use this work in progress dissector you will have to compile it with asn2eth and copy the resulting .c and .h files over to epan/dissectors. + +This dissector is not yet ready for public consumption and lacks many vital features of the existing snmp dissector.
\ No newline at end of file diff --git a/asn1/snmp/packet-snmp-template.c b/asn1/snmp/packet-snmp-template.c new file mode 100644 index 0000000000..cfddea4a14 --- /dev/null +++ b/asn1/snmp/packet-snmp-template.c @@ -0,0 +1,978 @@ +/* packet-snmp.c + * Routines for SNMP (simple network management protocol) + * Copyright (C) 1998 Didier Jorand + * + * See RFC 1157 for SNMPv1. + * + * See RFCs 1901, 1905, and 1906 for SNMPv2c. + * + * See RFCs 1905, 1906, 1909, and 1910 for SNMPv2u [historic]. + * + * See RFCs 2570-2576 for SNMPv3 + * Updated to use the asn2eth compiler made by Tomas Kukosa + * Copyright (C) 2005 Anders Broman [AT] ericsson.com + * + * + * $Id$ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@ethereal.com> + * Copyright 1998 Gerald Combs + * + * Some stuff from: + * + * GXSNMP -- An snmp mangament application + * Copyright (C) 1998 Gregory McLean & Jochen Friedrich + * Beholder RMON ethernet network monitor,Copyright (C) 1993 DNPAP group + * + * 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 <stdio.h> +#include <string.h> + +#include <glib.h> + +#include <epan/packet.h> +#include <epan/conversation.h> +#include "etypes.h" +#include <epan/prefs.h> +#include <epan/sminmpec.h> +#include <epan/emem.h> +#include "packet-ipx.h" +#include "packet-hpext.h" + + +#include "packet-ber.h" + +#ifdef HAVE_SOME_SNMP + +#ifdef HAVE_NET_SNMP +# include <net-snmp/net-snmp-config.h> +# include <net-snmp/mib_api.h> +# include <net-snmp/library/default_store.h> +# include <net-snmp/config_api.h> +#else /* HAVE_NET_SNMP */ +# include <ucd-snmp/ucd-snmp-config.h> +# include <ucd-snmp/asn1.h> +# include <ucd-snmp/snmp_api.h> +# include <ucd-snmp/snmp_impl.h> +# include <ucd-snmp/mib.h> +# include <ucd-snmp/default_store.h> +# include <ucd-snmp/read_config.h> +# include <ucd-snmp/tools.h> +#endif /* HAVE_NET_SNMP */ + +#ifndef NETSNMP_DS_LIBRARY_ID +# define NETSNMP_DS_LIBRARY_ID DS_LIBRARY_ID +# define NETSNMP_DS_LIB_NO_TOKEN_WARNINGS DS_LIB_NO_TOKEN_WARNINGS +# define NETSNMP_DS_LIB_PRINT_SUFFIX_ONLY DS_LIB_PRINT_SUFFIX_ONLY +# define netsnmp_ds_set_boolean ds_set_boolean +# define netsnmp_ds_set_int ds_set_int +#endif + +#ifdef _WIN32 +# include <epan/filesystem.h> +#endif /* _WIN32 */ + + /* + * Define values "sprint_realloc_value()" expects. + */ +# define VALTYPE_INTEGER ASN_INTEGER +# define VALTYPE_COUNTER ASN_COUNTER +# define VALTYPE_GAUGE ASN_GAUGE +# define VALTYPE_TIMETICKS ASN_TIMETICKS +# define VALTYPE_STRING ASN_OCTET_STR +# define VALTYPE_IPADDR ASN_IPADDRESS +# define VALTYPE_OPAQUE ASN_OPAQUE +# define VALTYPE_NSAP ASN_NSAP +# define VALTYPE_OBJECTID ASN_OBJECT_ID +# define VALTYPE_BITSTR ASN_BIT_STR +# define VALTYPE_COUNTER64 ASN_COUNTER64 + +#endif /* HAVE_SOME_SNMP */ + +#include "packet-snmp.h" +#include "format-oid.h" + +#define PNAME "Simple Network Management Protocol" +#define PSNAME "SNMP" +#define PFNAME "snmp" + +#define UDP_PORT_SNMP 161 +#define UDP_PORT_SNMP_TRAP 162 +#define TCP_PORT_SNMP 161 +#define TCP_PORT_SNMP_TRAP 162 +#define TCP_PORT_SMUX 199 + +/* Initialize the protocol and registered fields */ +static int proto_snmp = -1; +static int proto_smux = -1; + +/* Default MIB modules to load */ +/* + * XXX - According to Wes Hardaker, we shouldn't do this: + * http://www.ethereal.com/lists/ethereal-dev/200412/msg00222.html + */ +#ifdef _WIN32 +# define DEF_MIB_MODULES "IP-MIB;IF-MIB;TCP-MIB;UDP-MIB;SNMPv2-MIB;RFC1213-MIB;UCD-SNMP-MIB" +# define IMPORT_SEPARATOR ":" +#else +# define DEF_MIB_MODULES "IP-MIB:IF-MIB:TCP-MIB:UDP-MIB:SNMPv2-MIB:RFC1213-MIB:UCD-SNMP-MIB" +# define IMPORT_SEPARATOR ";" +#endif /* _WIN32 */ + +static const gchar *mib_modules = DEF_MIB_MODULES; +static gboolean display_oid = TRUE; + +/* Subdissector tables */ +static dissector_table_t variable_oid_dissector_table; + +#define TH_AUTH 0x01 +#define TH_CRYPT 0x02 +#define TH_REPORT 0x04 + +/* desegmentation of SNMP-over-TCP */ +static gboolean snmp_desegment = TRUE; + +/* Global variables */ + +guint32 MsgSecurityModel; + +static dissector_handle_t snmp_handle; +static dissector_handle_t data_handle; + +static int hf_snmp_v3_flags_auth = -1; +static int hf_snmp_v3_flags_crypt = -1; +static int hf_snmp_v3_flags_report = -1; + +static int hf_snmp_engineid_conform = -1; +static int hf_snmp_engineid_enterprise = -1; +static int hf_snmp_engineid_format = -1; +static int hf_snmp_engineid_ipv4 = -1; +static int hf_snmp_engineid_ipv6 = -1; +static int hf_snmp_engineid_mac = -1; +static int hf_snmp_engineid_text = -1; +static int hf_snmp_engineid_time = -1; +static int hf_snmp_engineid_data = -1; +#include "packet-snmp-hf.c" + +static int hf_smux_version = -1; +static int hf_smux_pdutype = -1; + +/* Initialize the subtree pointers */ +static gint ett_smux = -1; +static gint ett_snmp = -1; +static gint ett_engineid = -1; +static gint ett_msgFlags = -1; + +#include "packet-snmp-ett.c" + + +/* Security Models */ + +#define SNMP_SEC_ANY 0 +#define SNMP_SEC_V1 1 +#define SNMP_SEC_V2C 2 +#define SNMP_SEC_USM 3 + +static const value_string sec_models[] = { + { SNMP_SEC_ANY, "Any" }, + { SNMP_SEC_V1, "V1" }, + { SNMP_SEC_V2C, "V2C" }, + { SNMP_SEC_USM, "USM" }, + { 0, NULL } +}; + +/* SMUX PDU types */ +#define SMUX_MSG_OPEN 0 +#define SMUX_MSG_CLOSE 1 +#define SMUX_MSG_RREQ 2 +#define SMUX_MSG_RRSP 3 +#define SMUX_MSG_SOUT 4 + +static const value_string smux_types[] = { + { SMUX_MSG_OPEN, "Open" }, + { SMUX_MSG_CLOSE, "Close" }, + { SMUX_MSG_RREQ, "Registration Request" }, + { SMUX_MSG_RRSP, "Registration Response" }, + { SMUX_MSG_SOUT, "Commit Or Rollback" }, + { 0, NULL } +}; + +int oid_to_subid_buf(const guint8 *oid, gint oid_len, subid_t *buf, int buf_len) { + int i, out_len; + guint8 byte; + guint32 value; + + value=0; out_len = 0; + for (i=0; i<oid_len; i++){ + if (out_len >= buf_len) break; + byte = oid[i]; + if (i == 0) { + buf[out_len++] = byte/40; + buf[out_len++] = byte%40; + continue; + } + value = (value << 7) | (byte & 0x7F); + if (byte & 0x80) { + continue; + } + buf[out_len++] = value; + value = 0; + } + + return out_len; +} + +gchar * +format_oid(subid_t *oid, guint oid_length) +{ + char *result; + int result_len; + int len; + unsigned int i; + char *buf; +#ifdef HAVE_SOME_SNMP + guchar *oid_string; + size_t oid_string_len; + size_t oid_out_len; +#endif + + result_len = oid_length * 22; + +#ifdef HAVE_SOME_SNMP + /* + * Get the decoded form of the OID, and add its length to the + * length of the result string. + * + * XXX - check for "sprint_realloc_objid()" failure. + */ + oid_string_len = 256; + oid_string = malloc(oid_string_len); + if (oid_string == NULL) + return NULL; + *oid_string = '\0'; + oid_out_len = 0; + sprint_realloc_objid(&oid_string, &oid_string_len, &oid_out_len, 1, + oid, oid_length); + result_len += strlen(oid_string) + 3; +#endif + + result = ep_alloc(result_len + 1); + buf = result; + len = g_snprintf(buf, result_len + 1 - (buf-result), "%lu", (unsigned long)oid[0]); + buf += len; + for (i = 1; i < oid_length;i++) { + len = g_snprintf(buf, result_len + 1 - (buf-result), ".%lu", (unsigned long)oid[i]); + buf += len; + } + +#ifdef HAVE_SOME_SNMP + /* + * Append the decoded form of the OID. + */ + g_snprintf(buf, result_len + 1 -(buf-result), " (%s)", oid_string); + free(oid_string); +#endif + + return result; +} + +/* returns the decoded (can be NULL) and non_decoded OID strings, + returned pointers shall be freed by the caller */ +void +new_format_oid(subid_t *oid, guint oid_length, + gchar **non_decoded, gchar **decoded) +{ + int non_decoded_len; + int len; + unsigned int i; + char *buf; + +#ifdef HAVE_SOME_SNMP + guchar *oid_string; + size_t oid_string_len; + size_t oid_out_len; + + /* + * Get the decoded form of the OID, and add its length to the + * length of the result string. + */ + + oid_string_len = 256; + oid_string = malloc(oid_string_len); + if (oid_string != NULL) { + *oid_string = '\0'; + oid_out_len = 0; + sprint_realloc_objid(&oid_string, &oid_string_len, &oid_out_len, 1, + oid, oid_length); + } + *decoded = oid_string; +#else + *decoded = NULL; +#endif + + non_decoded_len = oid_length * 22 + 1; + *non_decoded = ep_alloc(non_decoded_len); + buf = *non_decoded; + len = g_snprintf(buf, non_decoded_len-(buf-*non_decoded), "%lu", (unsigned long)oid[0]); + buf += len; + for (i = 1; i < oid_length; i++) { + len = g_snprintf(buf, non_decoded_len-(buf-*non_decoded), ".%lu", (unsigned long)oid[i]); + buf += len; + } +} + + +#define F_SNMP_ENGINEID_CONFORM 0x80 +#define SNMP_ENGINEID_RFC1910 0x00 +#define SNMP_ENGINEID_RFC3411 0x01 + +static const true_false_string tfs_snmp_engineid_conform = { + "RFC3411 (SNMPv3)", + "RFC1910 (Non-SNMPv3)" +}; + +#define SNMP_ENGINEID_FORMAT_IPV4 0x01 +#define SNMP_ENGINEID_FORMAT_IPV6 0x02 +#define SNMP_ENGINEID_FORMAT_MACADDRESS 0x03 +#define SNMP_ENGINEID_FORMAT_TEXT 0x04 +#define SNMP_ENGINEID_FORMAT_OCTETS 0x05 + +static const value_string snmp_engineid_format_vals[] = { + { SNMP_ENGINEID_FORMAT_IPV4, "IPv4 address" }, + { SNMP_ENGINEID_FORMAT_IPV6, "IPv6 address" }, + { SNMP_ENGINEID_FORMAT_MACADDRESS, "MAC address" }, + { SNMP_ENGINEID_FORMAT_TEXT, "Text, administratively assigned" }, + { SNMP_ENGINEID_FORMAT_OCTETS, "Octets, administratively assigned" }, + { 0, NULL } +}; + +/* + * SNMP Engine ID dissection according to RFC 3411 (SnmpEngineID TC) + * or historic RFC 1910 (AgentID) + */ +int +dissect_snmp_engineid(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + proto_item *item = NULL; + guint8 conformance, format; + guint32 enterpriseid, seconds; + nstime_t ts; + int len_remain = len; + + /* first bit: engine id conformance */ + if (len_remain<4) return offset; + conformance = ((tvb_get_guint8(tvb, offset)>>7) && 0x01); + proto_tree_add_item(tree, hf_snmp_engineid_conform, tvb, offset, 1, FALSE); + + /* 4-byte enterprise number/name */ + if (len_remain<4) return offset; + enterpriseid = tvb_get_ntohl(tvb, offset); + if (conformance) + enterpriseid -= 0x80000000; /* ignore first bit */ + proto_tree_add_uint(tree, hf_snmp_engineid_enterprise, tvb, offset, 4, enterpriseid); + offset+=4; + len_remain-=4; + + switch(conformance) { + + case SNMP_ENGINEID_RFC1910: + /* 12-byte AgentID w/ 8-byte trailer */ + if (len_remain==8) { + proto_tree_add_text(tree, tvb, offset, 8, "AgentID Trailer: 0x%s", + tvb_bytes_to_str(tvb, offset, 8)); + offset+=8; + len_remain-=8; + } else { + proto_tree_add_text(tree, tvb, offset, len_remain, "<Data not conforming to RFC1910>"); + return offset; + } + break; + + case SNMP_ENGINEID_RFC3411: /* variable length: 5..32 */ + + /* 1-byte format specifier */ + if (len_remain<1) return offset; + format = tvb_get_guint8(tvb, offset); + item = proto_tree_add_uint_format(tree, hf_snmp_engineid_format, tvb, offset, 1, format, "Engine ID Format: %s (%d)", + val_to_str(format, snmp_engineid_format_vals, "Reserved/Enterprise-specific"), format); + offset+=1; + len_remain-=1; + + switch(format) { + case SNMP_ENGINEID_FORMAT_IPV4: + /* 4-byte IPv4 address */ + if (len_remain==4) { + proto_tree_add_item(tree, hf_snmp_engineid_ipv4, tvb, offset, 4, FALSE); + offset+=4; + len_remain=0; + } + break; + case SNMP_ENGINEID_FORMAT_IPV6: + /* 16-byte IPv6 address */ + if (len_remain==16) { + proto_tree_add_item(tree, hf_snmp_engineid_ipv6, tvb, offset, 16, FALSE); + offset+=16; + len_remain=0; + } + break; + case SNMP_ENGINEID_FORMAT_MACADDRESS: + /* 6-byte MAC address */ + if (len_remain==6) { + proto_tree_add_item(tree, hf_snmp_engineid_mac, tvb, offset, 6, FALSE); + offset+=6; + len_remain=0; + } + break; + case SNMP_ENGINEID_FORMAT_TEXT: + /* max. 27-byte string, administratively assigned */ + if (len_remain<=27) { + proto_tree_add_item(tree, hf_snmp_engineid_text, tvb, offset, len_remain, FALSE); + offset+=len_remain; + len_remain=0; + } + break; + case 128: + /* most common enterprise-specific format: (ucd|net)-snmp random */ + if ((enterpriseid==2021)||(enterpriseid==8072)) { + proto_item_append_text(item, (enterpriseid==2021) ? ": UCD-SNMP Random" : ": Net-SNMP Random"); + /* demystify: 4B random, 4B epoch seconds */ + if (len_remain==8) { + proto_tree_add_item(tree, hf_snmp_engineid_data, tvb, offset, 4, FALSE); + seconds = tvb_get_letohl(tvb, offset+4); + ts.secs = seconds; + proto_tree_add_time_format(tree, hf_snmp_engineid_time, tvb, offset+4, 4, + &ts, "Engine ID Data: Creation Time: %s", + abs_time_secs_to_str(seconds)); + offset+=8; + len_remain=0; + } + } + break; + case SNMP_ENGINEID_FORMAT_OCTETS: + default: + /* max. 27 bytes, administratively assigned or unknown format */ + if (len_remain<=27) { + proto_tree_add_item(tree, hf_snmp_engineid_data, tvb, offset, len_remain, FALSE); + offset+=len_remain; + len_remain=0; + } + break; + } + } + + if (len_remain>0) { + proto_tree_add_text(tree, tvb, offset, len_remain, "<Data not conforming to RFC3411>"); + offset+=len_remain; + } + return offset; +} + +#include "packet-snmp-fn.c" + +guint +dissect_snmp_pdu(tvbuff_t *tvb, int offset, packet_info *pinfo, + proto_tree *tree, int proto, gint ett, gboolean is_tcp) +{ + + guint length_remaining; + gint8 class; + gboolean pc, ind = 0; + gint32 tag; + guint32 len; + guint message_length; + int start_offset = offset; + guint32 version = 0; + + proto_tree *snmp_tree = NULL; + proto_item *item = NULL; + + /* + * This will throw an exception if we don't have any data left. + * That's what we want. (See "tcp_dissect_pdus()", which is + * similar, but doesn't have to deal with ASN.1. + * XXX - can we make "tcp_dissect_pdus()" provide enough + * information to the "get_pdu_len" routine so that we could + * have that routine deal with ASN.1, and just use + * "tcp_dissect_pdus()"?) + */ + length_remaining = tvb_ensure_length_remaining(tvb, offset); + + /* NOTE: we have to parse the message piece by piece, since the + * capture length may be less than the message length: a 'global' + * parsing is likely to fail. + */ + + /* + * If this is SNMP-over-TCP, we might have to do reassembly + * in order to read the "Sequence Of" header. + */ + if (is_tcp && snmp_desegment && pinfo->can_desegment) { + /* + * This is TCP, and we should, and can, do reassembly. + * + * Is the "Sequence Of" header split across segment + * boundaries? We requre at least 6 bytes for the + * header, which allows for a 4-byte length (ASN.1 + * BER). + */ + if (length_remaining < 6) { + pinfo->desegment_offset = offset; + pinfo->desegment_len = 6 - length_remaining; + + /* + * Return 0, which means "I didn't dissect anything + * because I don't have enough data - we need + * to desegment". + */ + return 0; + } + } + + /* + * OK, try to read the "Sequence Of" header; this gets the total + * length of the SNMP message. + */ + /* Set tree to 0 to not display internakl BER fields if option used.*/ + offset = dissect_ber_identifier(pinfo, 0, tvb, offset, &class, &pc, &tag); + offset = dissect_ber_length(pinfo, 0, tvb, offset, &len, &ind); + + message_length = len + 2; + offset = dissect_ber_integer(FALSE, pinfo, 0, tvb, offset, -1, &version); + + + /* + * If this is SNMP-over-TCP, we might have to do reassembly + * to get all of this message. + */ + if (is_tcp && snmp_desegment && pinfo->can_desegment) { + /* + * Yes - is the message split across segment boundaries? + */ + if (length_remaining < message_length) { + /* + * Yes. Tell the TCP dissector where the data + * for this message starts in the data it handed + * us, and how many more bytes we need, and + * return. + */ + pinfo->desegment_offset = start_offset; + pinfo->desegment_len = + message_length - length_remaining; + + /* + * Return 0, which means "I didn't dissect anything + * because I don't have enough data - we need + * to desegment". + */ + return 0; + } + } + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) { + col_set_str(pinfo->cinfo, COL_PROTOCOL, + proto_get_protocol_short_name(find_protocol_by_id(proto))); + } + + if (tree) { + item = proto_tree_add_item(tree, proto, tvb, offset, + message_length, FALSE); + snmp_tree = proto_item_add_subtree(item, ett); + } + + switch (version){ + case 0: /* v1 */ + case 1: /* v2c */ + offset = dissect_snmp_Message(FALSE , tvb, start_offset, pinfo, snmp_tree, -1); + break; + case 2: /* v2u */ + offset = dissect_snmp_Messagev2u(FALSE , tvb, start_offset, pinfo, snmp_tree, -1); + break; + /* v3 */ + case 3: + offset = dissect_snmp_SNMPv3Message(FALSE , tvb, start_offset, pinfo, snmp_tree, -1); + break; + default: + /* + * Return the length remaining in the tvbuff, so + * if this is SNMP-over-TCP, our caller thinks there's + * nothing left to dissect. + */ + proto_tree_add_text(snmp_tree, tvb, offset, -1,"Unknown version"); + return length_remaining; + break; + } + return offset; + + + +} + +static gint +dissect_snmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + conversation_t *conversation; + int offset; + gint8 tmp_class; + gboolean tmp_pc; + gint32 tmp_tag; + guint32 tmp_length; + gboolean tmp_ind; + + /* + * See if this looks like SNMP or not. if not, return 0 so + * ethereal can try som other dissector instead. + */ + /* All SNMP packets are BER encoded and consist of a SEQUENCE + * that spans the entire PDU. The first item is an INTEGER that + * has the values 0-2 (version 1-3). + * if not it is not snmp. + */ + /* SNMP starts with a SEQUENCE */ + offset = get_ber_identifier(tvb, 0, &tmp_class, &tmp_pc, &tmp_tag); + if((tmp_class!=BER_CLASS_UNI)||(tmp_tag!=BER_UNI_TAG_SEQUENCE)){ + return 0; + } + /* then comes a length which spans the rest of the tvb */ + offset = get_ber_length(NULL, tvb, offset, &tmp_length, &tmp_ind); + if(tmp_length!=(guint32)tvb_reported_length_remaining(tvb, offset)){ + return 0; + } + /* then comes an INTEGER (version)*/ + offset = get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag); + if((tmp_class!=BER_CLASS_UNI)||(tmp_tag!=BER_UNI_TAG_INTEGER)){ + return 0; + } + /* do we need to test that version is 0 - 2 (version1-3) ? */ + + + /* + * The first SNMP packet goes to the SNMP port; the second one + * may come from some *other* port, but goes back to the same + * IP address and port as the ones from which the first packet + * came; all subsequent packets presumably go between those two + * IP addresses and ports. + * + * If this packet went to the SNMP port, we check to see if + * there's already a conversation with one address/port pair + * matching the source IP address and port of this packet, + * the other address matching the destination IP address of this + * packet, and any destination port. + * + * If not, we create one, with its address 1/port 1 pair being + * the source address/port of this packet, its address 2 being + * the destination address of this packet, and its port 2 being + * wildcarded, and give it the SNMP dissector as a dissector. + */ + if (pinfo->destport == UDP_PORT_SNMP) { + conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, PT_UDP, + pinfo->srcport, 0, NO_PORT_B); + if( (conversation == NULL) || (conversation->dissector_handle!=snmp_handle) ){ + conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, PT_UDP, + pinfo->srcport, 0, NO_PORT2); + conversation_set_dissector(conversation, snmp_handle); + } + } + + return dissect_snmp_pdu(tvb, 0, pinfo, tree, proto_snmp, ett_snmp, FALSE); +} +static void +dissect_snmp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + int offset = 0; + guint message_len; + + while (tvb_reported_length_remaining(tvb, offset) > 0) { + message_len = dissect_snmp_pdu(tvb, 0, pinfo, tree, + proto_snmp, ett_snmp, TRUE); + if (message_len == 0) { + /* + * We don't have all the data for that message, + * so we need to do desegmentation; + * "dissect_snmp_pdu()" has set that up. + */ + break; + } + offset += message_len; + } +} +static void +dissect_smux_pdu(tvbuff_t *tvb, int offset, packet_info *pinfo, + proto_tree *tree, int proto, gint ett) +{ + /* FIX ME */ +} +static void +dissect_smux(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + dissect_smux_pdu(tvb, 0, pinfo, tree, proto_smux, ett_smux); +} +static void +process_prefs(void) +{ +#ifdef HAVE_SOME_SNMP + gchar *tmp_mib_modules; + static gboolean mibs_loaded = FALSE; + + if (mibs_loaded) { + /* + * Unload the MIBs, as we'll be reloading them based on + * the current preference setting. + */ + shutdown_mib(); /* unload MIBs */ + } + + /* + * Cannot check if MIBS is already set, as it could be set by Ethereal. + * + * If we have a list of modules to load, put that list in MIBS, + * otherwise clear MIBS. + */ + if (mib_modules != NULL) { + tmp_mib_modules = g_strconcat("MIBS=", mib_modules, NULL); + /* + * Try to be clever and replace colons for semicolons under + * Windows. Do the converse on non-Windows systems. This + * handles cases where we've copied a preferences file + * between a non-Windows box and a Windows box or upgraded + * from an older version of Ethereal under Windows. + */ + g_strdelimit(tmp_mib_modules, IMPORT_SEPARATOR, ENV_SEPARATOR_CHAR); + +#ifdef _WIN32 + _putenv(tmp_mib_modules); +#else + putenv(tmp_mib_modules); +#endif /*_WIN32*/ + } else { +#ifdef _WIN32 + _putenv("MIBS"); +#else + putenv("MIBS"); +#endif /* _WIN32 */ + } + + /* + * Load the MIBs. + */ + register_mib_handlers(); + read_premib_configs(); + init_mib(); + read_configs(); + mibs_loaded = TRUE; +#endif /* HAVE_SOME_SNMP */ +} +/*--- proto_register_snmp -------------------------------------------*/ +void proto_register_snmp(void) { + +#if defined(_WIN32) && defined(HAVE_SOME_SNMP) + char *mib_path; + int mib_path_len; +#define MIB_PATH_APPEND "snmp\\mibs" +#endif + gchar *tmp_mib_modules; + + /* List of fields */ + static hf_register_info hf[] = { + { &hf_snmp_v3_flags_auth, + { "Authenticated", "snmp.v3.flags.auth", FT_BOOLEAN, 8, + TFS(&flags_set_truth), TH_AUTH, "", HFILL }}, + { &hf_snmp_v3_flags_crypt, + { "Encrypted", "snmp.v3.flags.crypt", FT_BOOLEAN, 8, + TFS(&flags_set_truth), TH_CRYPT, "", HFILL }}, + { &hf_snmp_v3_flags_report, + { "Reportable", "snmp.v3.flags.report", FT_BOOLEAN, 8, + TFS(&flags_set_truth), TH_REPORT, "", HFILL }}, + { &hf_snmp_engineid_conform, { + "Engine ID Conformance", "snmp.engineid.conform", FT_BOOLEAN, 8, + TFS(&tfs_snmp_engineid_conform), F_SNMP_ENGINEID_CONFORM, "Engine ID RFC3411 Conformance", HFILL }}, + { &hf_snmp_engineid_enterprise, { + "Engine Enterprise ID", "snmp.engineid.enterprise", FT_UINT32, BASE_DEC, + VALS(sminmpec_values), 0, "Engine Enterprise ID", HFILL }}, + { &hf_snmp_engineid_format, { + "Engine ID Format", "snmp.engineid.format", FT_UINT8, BASE_DEC, + VALS(snmp_engineid_format_vals), 0, "Engine ID Format", HFILL }}, + { &hf_snmp_engineid_ipv4, { + "Engine ID Data: IPv4 address", "snmp.engineid.ipv4", FT_IPv4, BASE_NONE, + NULL, 0, "Engine ID Data: IPv4 address", HFILL }}, + { &hf_snmp_engineid_ipv6, { + "Engine ID Data: IPv6 address", "snmp.engineid.ipv6", FT_IPv6, BASE_NONE, + NULL, 0, "Engine ID Data: IPv6 address", HFILL }}, + { &hf_snmp_engineid_mac, { + "Engine ID Data: MAC address", "snmp.engineid.mac", FT_ETHER, BASE_NONE, + NULL, 0, "Engine ID Data: MAC address", HFILL }}, + { &hf_snmp_engineid_text, { + "Engine ID Data: Text", "snmp.engineid.text", FT_STRING, BASE_NONE, + NULL, 0, "Engine ID Data: Text", HFILL }}, + { &hf_snmp_engineid_time, { + "Engine ID Data: Time", "snmp.engineid.time", FT_ABSOLUTE_TIME, BASE_NONE, + NULL, 0, "Engine ID Data: Time", HFILL }}, + { &hf_snmp_engineid_data, { + "Engine ID Data", "snmp.engineid.data", FT_BYTES, BASE_HEX, + NULL, 0, "Engine ID Data", HFILL }}, + +#include "packet-snmp-hfarr.c" + }; + + /* List of subtrees */ + static gint *ett[] = { + &ett_snmp, + &ett_engineid, + &ett_msgFlags, + +#include "packet-snmp-ettarr.c" + }; + module_t *snmp_module; + + #ifdef HAVE_SOME_SNMP + +#ifdef _WIN32 + /* Set MIBDIRS so that the SNMP library can find its mibs. */ + /* XXX - Should we set MIBS or MIBFILES as well? */ + mib_path_len=strlen(get_datafile_dir()) + strlen(MIB_PATH_APPEND) + 20; + mib_path = ep_alloc (mib_path_len); + g_snprintf (mib_path, mib_path_len, "MIBDIRS=%s\\%s", get_datafile_dir(), MIB_PATH_APPEND); + /* Amazingly enough, Windows does not provide setenv(). */ + if (getenv("MIBDIRS") == NULL) + _putenv(mib_path); + +#endif /* _WIN32 */ + + /* + * Suppress warnings about unknown tokens - we aren't initializing + * UCD SNMP in its entirety, we're just initializing the + * MIB-handling part because that's all we're using, which + * means that entries in the configuration file for other + * pars of the library will not be handled, and we don't want + * the config file reading code to whine about that. + */ + netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_NO_TOKEN_WARNINGS, TRUE); + netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_PRINT_SUFFIX_ONLY, 2); +#endif /* HAVE_SOME_SNMP */ + + + /* Register protocol */ + proto_snmp = proto_register_protocol(PNAME, PSNAME, PFNAME); + new_register_dissector("snmp", dissect_snmp, proto_snmp); + + /* Register fields and subtrees */ + proto_register_field_array(proto_snmp, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + + /* Register configuration preferences */ + snmp_module = prefs_register_protocol(proto_snmp, process_prefs); + prefs_register_bool_preference(snmp_module, "display_oid", + "Show SNMP OID in info column", + "Whether the SNMP OID should be shown in the info column", + &display_oid); + + /* + * Set the default value of "mib_modules". + * + * If the MIBS environment variable is set, make its value + * the value of "mib_modules", otherwise, set "mib_modules" + * to DEF_MIB_MODULES. + */ + tmp_mib_modules = getenv("MIBS"); + if (tmp_mib_modules != NULL) + mib_modules = tmp_mib_modules; + prefs_register_string_preference(snmp_module, "mib_modules", + "MIB modules to load", + "List of MIB modules to load (the list is set to environment variable MIBS if the variable is not already set)" + "The list must be separated by colons (:) on non-Windows systems and semicolons (;) on Windows systems", + &mib_modules); + prefs_register_bool_preference(snmp_module, "desegment", + "Reassemble SNMP-over-TCP messages\nspanning multiple TCP segments", + "Whether the SNMP dissector should reassemble messages spanning multiple TCP segments." + " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.", + &snmp_desegment); + +} + + +/*--- proto_reg_handoff_snmp ---------------------------------------*/ +void proto_reg_handoff_snmp(void) { + dissector_handle_t snmp_tcp_handle; + + snmp_handle = find_dissector("snmp"); + + dissector_add("udp.port", UDP_PORT_SNMP, snmp_handle); + dissector_add("udp.port", UDP_PORT_SNMP_TRAP, snmp_handle); + dissector_add("ethertype", ETHERTYPE_SNMP, snmp_handle); + dissector_add("ipx.socket", IPX_SOCKET_SNMP_AGENT, snmp_handle); + dissector_add("ipx.socket", IPX_SOCKET_SNMP_SINK, snmp_handle); + dissector_add("hpext.dxsap", HPEXT_SNMP, snmp_handle); + + snmp_tcp_handle = create_dissector_handle(dissect_snmp_tcp, proto_snmp); + dissector_add("tcp.port", TCP_PORT_SNMP, snmp_tcp_handle); + dissector_add("tcp.port", TCP_PORT_SNMP_TRAP, snmp_tcp_handle); + + data_handle = find_dissector("data"); + + /* + * Process preference settings. + * + * We can't do this in the register routine, as preferences aren't + * read until all dissector register routines have been called (so + * that all dissector preferences have been registered). + */ + process_prefs(); + +} + +void +proto_register_smux(void) +{ + static hf_register_info hf[] = { + { &hf_smux_version, + { "Version", "smux.version", FT_UINT8, BASE_DEC, NULL, + 0x0, "", HFILL }}, + { &hf_smux_pdutype, + { "PDU type", "smux.pdutype", FT_UINT8, BASE_DEC, VALS(smux_types), + 0x0, "", HFILL }}, + }; + static gint *ett[] = { + &ett_smux, + }; + + proto_smux = proto_register_protocol("SNMP Multiplex Protocol", + "SMUX", "smux"); + proto_register_field_array(proto_smux, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + variable_oid_dissector_table = + register_dissector_table("snmp.variable_oid", + "SNMP Variable OID", FT_STRING, BASE_NONE); +} + +void +proto_reg_handoff_smux(void) +{ + dissector_handle_t smux_handle; + + smux_handle = create_dissector_handle(dissect_smux, proto_smux); + dissector_add("tcp.port", TCP_PORT_SMUX, smux_handle); +} + + diff --git a/asn1/snmp/packet-snmp-template.h b/asn1/snmp/packet-snmp-template.h new file mode 100644 index 0000000000..645c041594 --- /dev/null +++ b/asn1/snmp/packet-snmp-template.h @@ -0,0 +1,38 @@ +/* packet-snmp.h + * Routines for snmp packet dissection + * + * $Id$ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@ethereal.com> + * Copyright 1998 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. + */ + +#ifndef PACKET_SNMP_H +#define PACKET_SNMP_H + +/* + * Guts of the SNMP dissector - exported for use by protocols such as + * ILMI. + */ +extern guint dissect_snmp_pdu(tvbuff_t *, int, packet_info *, proto_tree *tree, + int, gint, gboolean); +extern int dissect_snmp_engineid(proto_tree *, tvbuff_t *, int, int); + +/*#include "packet-snmp-exp.h"*/ + +#endif /* PACKET_SNMP_H */ diff --git a/asn1/snmp/snmp.asn b/asn1/snmp/snmp.asn new file mode 100644 index 0000000000..08e92466ac --- /dev/null +++ b/asn1/snmp/snmp.asn @@ -0,0 +1,545 @@ +-- $id:$ + RFC1157-SNMP DEFINITIONS ::= BEGIN + +-- IMPORTS +-- ObjectName, ObjectSyntax, NetworkAddress, IpAddress, TimeTicks +-- FROM RFC1155-SMI; + +-- Local imports +-- IMPORTS +-- ObjectName, ObjectSyntax, NetworkAddress, IpAddress, TimeTicks +-- FROM RFC1155-SMI; + +-- names of objects +-- (Note that these definitions of ObjectName and NotificationName +-- are not to be IMPORTed by MIB modules.) + +ObjectName ::= + OBJECT IDENTIFIER + +NotificationName ::= + OBJECT IDENTIFIER + +-- syntax of objects + +-- the "base types" defined here are: +-- 3 built-in ASN.1 types: INTEGER, OCTET STRING, OBJECT IDENTIFIER +-- 8 application-defined types: Integer32, IpAddress, Counter32, +-- Gauge32, Unsigned32, TimeTicks, Opaque, and Counter64 + +ObjectSyntax ::= + CHOICE { + simple + SimpleSyntax, + + -- note that SEQUENCEs for conceptual tables and + -- rows are not mentioned here... + + application-wide + ApplicationSyntax + } +-- built-in ASN.1 types + +SimpleSyntax ::= + CHOICE { + -- INTEGERs with a more restrictive range + -- may also be used + integer-value -- includes Integer32 + INTEGER (-2147483648..2147483647), + + -- OCTET STRINGs with a more restrictive size + -- may also be used + string-value + OCTET STRING (SIZE (0..65535)), + + objectID-value + OBJECT IDENTIFIER, + empty -- Added from RFC 1155 for Ethereal + NULL + } + +-- indistinguishable from INTEGER, but never needs more than +-- 32-bits for a two's complement representation +Integer32 ::= + INTEGER (-2147483648..2147483647) + + +-- application-wide types + +ApplicationSyntax ::= + CHOICE { + ipAddress-value + IpAddress, + + counter-value + Counter32, + + timeticks-value + TimeTicks, + + arbitrary-value + Opaque, + + big-counter-value + Counter64, + + unsigned-integer-value -- includes Gauge32 + Unsigned32 + } + +NetworkAddress ::= + CHOICE { + internet + IpAddress + } + +-- in network-byte order +-- (this is a tagged type for historical reasons) +IpAddress ::= + [APPLICATION 0] + IMPLICIT OCTET STRING (SIZE (4)) + +-- this wraps +Counter32 ::= + [APPLICATION 1] + IMPLICIT INTEGER (0..4294967295) + +-- this doesn't wrap +Gauge32 ::= + [APPLICATION 2] + IMPLICIT INTEGER (0..4294967295) + +-- an unsigned 32-bit quantity +-- indistinguishable from Gauge32 +Unsigned32 ::= + [APPLICATION 2] + IMPLICIT INTEGER (0..4294967295) + +-- hundredths of seconds since an epoch +TimeTicks ::= + [APPLICATION 3] + IMPLICIT INTEGER (0..4294967295) + +-- for backward-compatibility only +Opaque ::= + [APPLICATION 4] + IMPLICIT OCTET STRING + +-- for counters that wrap in less than one hour with only 32 bits +Counter64 ::= + [APPLICATION 6] + IMPLICIT INTEGER (0..18446744073709551615) + + + + +-- End Import + -- top-level message + + Message ::= + SEQUENCE { + version Version, -- version-1 for this RFC + + community -- community name + OCTET STRING, + + data -- e.g., PDUs if trivial + PDUs +-- ANY +-- authentication is being used + } + +Version ::= INTEGER { + version-1(0), + v2c(1), + v2u (2), + snmpv3(3) + } + + + Messagev2u ::= + SEQUENCE { + version Version, +-- INTEGER { v2 (2) }, + + parameters + OCTET STRING, + -- <model=1> + -- <qoS><agentID><agentBoots><agentTime><maxSize> + -- <userLen><userName><authLen><authDigest> + -- <contextSelector> + + datav2u + CHOICE { + plaintext + PDUs, + encrypted + OCTET STRING + } + } +-- USMSecurityParametersSyntax DEFINITIONS IMPLICIT TAGS ::= BEGIN + + UsmSecurityParameters ::= + SEQUENCE { + -- global User-based security parameters + msgAuthoritativeEngineID SnmpEngineID, + msgAuthoritativeEngineBoots INTEGER (0..2147483647), + msgAuthoritativeEngineTime INTEGER (0..2147483647), + msgUserName OCTET STRING (SIZE(1..32)), + -- authentication protocol specific parameters + msgAuthenticationParameters OCTET STRING, + -- privacy protocol specific parameters + msgPrivacyParameters OCTET STRING + } + -- END USMSecurityParametersSyntax + +SnmpEngineID ::= OCTET STRING + +-- SNMPv3MessageSyntax DEFINITIONS IMPLICIT TAGS ::= BEGIN + + SNMPv3Message ::= SEQUENCE { + -- identify the layout of the SNMPv3Message + -- this element is in same position as in SNMPv1 + -- and SNMPv2c, allowing recognition + -- the value 3 is used for snmpv3 + msgVersion Version, + -- INTEGER ( 0 .. 2147483647 ), + -- administrative parameters + msgGlobalData HeaderData, + -- security model-specific parameters + -- format defined by Security Model + msgSecurityParameters OCTET STRING, + msgData ScopedPduData + } + + HeaderData ::= SEQUENCE { + msgID INTEGER (0..2147483647), + msgMaxSize INTEGER (484..2147483647), + + msgFlags OCTET STRING (SIZE(1)), + -- .... ...1 authFlag + -- .... ..1. privFlag + -- .... .1.. reportableFlag + -- Please observe: + -- .... ..00 is OK, means noAuthNoPriv + -- .... ..01 is OK, means authNoPriv + -- .... ..10 reserved, must NOT be used. + -- .... ..11 is OK, means authPriv + + msgSecurityModel INTEGER (1..2147483647) + } + + + ScopedPduData ::= CHOICE { + plaintext ScopedPDU, + encryptedPDU OCTET STRING -- encrypted scopedPDU value + } + + ScopedPDU ::= SEQUENCE { + contextEngineID OCTET STRING, + contextName OCTET STRING, + data PDUs + -- ANY + -- e.g., PDUs as defined in RFC 1905 + } + +-- END SNMPv3MessageSyntax + -- protocol data units + + PDUs ::= + CHOICE { + get-request + GetRequest-PDU, + + get-next-request + GetNextRequest-PDU, + + get-response + GetResponse-PDU, + + set-request + SetRequest-PDU, + + trap + Trap-PDU + } + + -- PDUs + + GetRequest-PDU ::= + [0] + IMPLICIT PDU + + GetNextRequest-PDU ::= + [1] + IMPLICIT PDU + + GetResponse-PDU ::= + [2] + IMPLICIT PDU + + SetRequest-PDU ::= + [3] + IMPLICIT PDU +-- v2 added + -- [4] is obsolete + + GetBulkRequest-PDU ::= + [5] + IMPLICIT BulkPDU + + InformRequest-PDU ::= + [6] + IMPLICIT PDU + + SNMPv2-Trap-PDU ::= + [7] + IMPLICIT PDU + + -- Usage and precise semantics of Report-PDU are not presently + -- defined. Any SNMP administrative framework making use of + -- this PDU must define its usage and semantics. + Report-PDU ::= + [8] + IMPLICIT PDU + + + PDU ::= + SEQUENCE { + request-id + INTEGER, + + error-status -- sometimes ignored + INTEGER { + noError(0), + tooBig(1), + noSuchName(2), -- for proxy compatibility + badValue(3), -- for proxy compatibility + readOnly(4), -- for proxy compatibility + genErr(5), + noAccess(6), + wrongType(7), + wrongLength(8), + wrongEncoding(9), + wrongValue(10), + noCreation(11), + inconsistentValue(12), + resourceUnavailable(13), + commitFailed(14), + undoFailed(15), + authorizationError(16), + notWritable(17), + inconsistentName(18) + }, + + + error-index -- sometimes ignored + INTEGER, + + variable-bindings -- values are sometimes ignored + VarBindList + } +-- v2 + BulkPDU ::= -- MUST be identical in + SEQUENCE { -- structure to PDU + request-id + Integer32, + + non-repeaters + INTEGER (0..2147483647), + + max-repetitions + INTEGER (0..2147483647), + + variable-bindings -- values are ignored + VarBindList + } + +-- end v2 + Trap-PDU ::= + [4] + IMPLICIT SEQUENCE { + enterprise -- type of object generating + -- trap, see sysObjectID in [5] + + + OBJECT IDENTIFIER, + + agent-addr -- address of object generating + NetworkAddress, -- trap + + generic-trap -- generic trap type + INTEGER { + coldStart(0), + warmStart(1), + linkDown(2), + linkUp(3), + authenticationFailure(4), + egpNeighborLoss(5), + enterpriseSpecific(6) + }, + + specific-trap INTEGER, +-- specific code, present even +-- if generic-trap is not +-- enterpriseSpecific + + time-stamp TimeTicks, +-- time elapsed between the last +-- (re)initialization of the network +-- entity and the generation of the trap + + variable-bindings VarBindList +-- "interesting" information + } + + +-- variable bindings + + VarBind ::= + SEQUENCE { + name + ObjectName, + + valueType ValueType + } + +ValueType ::= + CHOICE { + value + ObjectSyntax, + + unSpecified -- in retrieval requests + NULL, + + -- exceptions in responses + noSuchObject[0] + IMPLICIT NULL, + + noSuchInstance[1] + IMPLICIT NULL, + + endOfMibView[2] + IMPLICIT NULL + } + + + VarBindList ::= + SEQUENCE OF + VarBind + +-- SMUX DEFINITIONS ::= BEGIN RFC 1227 + +SMUX-PDUs ::= + CHOICE { + open -- SMUX peer uses + OpenPDU, -- immediately after TCP open + + close -- either uses immediately before TCP close + ClosePDU, + + registerRequest -- SMUX peer uses + RReqPDU, + +-- registerResponse .. SNMP agent uses +-- RRspPDU, +-- +-- PDUs, +-- Revritten + registerResponse RegisterResponse, + -- note that roles are reversed: + -- SNMP agent does get/get-next/set + -- SMUX peer does get-response/trap + + commitOrRollback -- SNMP agent uses + SOutPDU + } + +RegisterResponse ::= CHOICE { + rRspPDU RRspPDU, + pDUs PDUs + } + + -- open PDU + -- currently only simple authentication + + OpenPDU ::= + CHOICE { + smux-simple + + SimpleOpen + } + + SimpleOpen ::= + [APPLICATION 0] IMPLICIT + SEQUENCE { + smux-version -- of SMUX protocol + INTEGER { + version-1(0) + }, + + identity -- of SMUX peer, authoritative + OBJECT IDENTIFIER, + + description -- of SMUX peer, implementation-specific + DisplayString, + + password -- zero length indicates no authentication + OCTET STRING + } + +DisplayString ::= OCTET STRING + -- close PDU + + ClosePDU ::= + [APPLICATION 1] IMPLICIT + INTEGER { + goingDown(0), + unsupportedVersion(1), + packetFormat(2), + protocolError(3), + internalError(4), + authenticationFailure(5) + } + + + -- insert PDU + + RReqPDU ::= + [APPLICATION 2] IMPLICIT + SEQUENCE { + subtree + ObjectName, + + priority -- the lower the better, "-1" means default + INTEGER (-1..2147483647), + + operation + + INTEGER { + delete(0), -- remove registration + readOnly(1), -- add registration, objects are RO + readWrite(2) -- .., objects are RW + } + } + + RRspPDU ::= + [APPLICATION 3] IMPLICIT + INTEGER { + failure(-1) + + -- on success the non-negative priority is returned + } + + SOutPDU ::= + [APPLICATION 4] IMPLICIT + INTEGER { + commit(0), + rollback(1) + } + + + + END + + diff --git a/asn1/snmp/snmp.cnf b/asn1/snmp/snmp.cnf new file mode 100644 index 0000000000..6f6b025069 --- /dev/null +++ b/asn1/snmp/snmp.cnf @@ -0,0 +1,143 @@ +# snmp.cnf +# snmp conformation file + +# $Id$ + + +#.PDU + +#.NO_EMIT + +#.TYPE_RENAME + +#.FIELD_RENAME +Messagev2u/datav2u/plaintext v2u_plaintext +BulkPDU/request-id bulkPDU_request-id + +#.FN_BODY PDUs/get-request + gint8 class; + gboolean pc, ind_field; + gint32 tag; + guint32 len1; + + if(!implicit_tag){ + /* XXX asn2eth can not yet handle tagged assignment yes so this + * XXX is some conformance file magic to work around that bug + */ + offset = get_ber_identifier(tvb, offset, &class, &pc, &tag); + offset = get_ber_length(tree, tvb, offset, &len1, &ind_field); + } + offset = dissect_snmp_PDU(TRUE, tvb, offset, pinfo, tree, hf_index); + +#.FN_BODY PDUs/get-next-request + gint8 class; + gboolean pc, ind_field; + gint32 tag; + guint32 len1; + + if(!implicit_tag){ + /* XXX asn2eth can not yet handle tagged assignment yes so this + * XXX is some conformance file magic to work around that bug + */ + offset = get_ber_identifier(tvb, offset, &class, &pc, &tag); + offset = get_ber_length(tree, tvb, offset, &len1, &ind_field); + } + offset = dissect_snmp_PDU(TRUE, tvb, offset, pinfo, tree, hf_index); + +#.FN_BODY PDUs/get-response + gint8 class; + gboolean pc, ind_field; + gint32 tag; + guint32 len1; + + if(!implicit_tag){ + /* XXX asn2eth can not yet handle tagged assignment yes so this + * XXX is some conformance file magic to work around that bug + */ + offset = get_ber_identifier(tvb, offset, &class, &pc, &tag); + offset = get_ber_length(tree, tvb, offset, &len1, &ind_field); + } + offset = dissect_snmp_PDU(TRUE, tvb, offset, pinfo, tree, hf_index); + +#.FN_BODY PDUs/set-request + gint8 class; + gboolean pc, ind_field; + gint32 tag; + guint32 len1; + + if(!implicit_tag){ + /* XXX asn2eth can not yet handle tagged assignment yes so this + * XXX is some conformance file magic to work around that bug + */ + offset = get_ber_identifier(tvb, offset, &class, &pc, &tag); + offset = get_ber_length(tree, tvb, offset, &len1, &ind_field); + } + offset = dissect_snmp_PDU(TRUE, tvb, offset, pinfo, tree, hf_index); + +#.FN_BODY PDUs/trap + gint8 class; + gboolean pc, ind_field; + gint32 tag; + guint32 len1; + + if(!implicit_tag){ + /* XXX asn2eth can not yet handle tagged assignment yes so this + * XXX is some conformance file magic to work around that bug + */ + offset = get_ber_identifier(tvb, offset, &class, &pc, &tag); + offset = get_ber_length(tree, tvb, offset, &len1, &ind_field); + } + offset = dissect_snmp_Trap_PDU(TRUE, tvb, offset, pinfo, tree, hf_index); + +#.FN_PARS HeaderData/msgSecurityModel + + VAL_PTR = &MsgSecurityModel + +#.FN_BODY SNMPv3Message/msgSecurityParameters + + switch(MsgSecurityModel){ + case SNMP_SEC_USM: /* 3 */ + offset = dissect_snmp_UsmSecurityParameters(FALSE, tvb, offset+2, pinfo, tree, -1); + break; + case SNMP_SEC_ANY: /* 0 */ + case SNMP_SEC_V1: /* 1 */ + case SNMP_SEC_V2C: /* 2 */ + default: + %(DEFAULT_BODY)s + break; + } + +#.FN_PARS SnmpEngineID + + VAL_PTR = ¶meter_tvb + +#.FN_BODY SnmpEngineID + tvbuff_t *parameter_tvb = NULL; + proto_tree *engineid_tree = NULL; + proto_item *item = NULL; + + %(DEFAULT_BODY)s + if (parameter_tvb) + dissect_snmp_engineid(tree, parameter_tvb, 0, tvb_length_remaining(parameter_tvb,0)); + +#.FN_PARS HeaderData/msgFlags + + VAL_PTR = ¶meter_tvb + +#.FN_BODY HeaderData/msgFlags + tvbuff_t *parameter_tvb = NULL; + + %(DEFAULT_BODY)s + if (parameter_tvb){ + + proto_tree_add_item(tree, hf_snmp_v3_flags_report, parameter_tvb, 0, 1, FALSE); + proto_tree_add_item(tree, hf_snmp_v3_flags_crypt, parameter_tvb, 0, 1, FALSE); + proto_tree_add_item(tree, hf_snmp_v3_flags_auth, parameter_tvb, 0, 1, FALSE); + } + +#.TYPE_ATTR +IpAddress TYPE = FT_IPv4 DISPLAY = BASE_NONE STRINGS = NULL +Message/community TYPE = FT_STRING DISPLAY = BASE_HEX STRINGS = NULL +HeaderData/msgSecurityModel TYPE = FT_UINT32 DISPLAY = BASE_DEC STRINGS = VALS(sec_models) +UsmSecurityParameters/msgUserName TYPE = FT_STRING DISPLAY = BASE_HEX STRINGS = NULL +#.END |