diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index d4e631ecf4..7e3840df0a 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -2775,6 +2775,130 @@ export { } module GLOBAL; +@load base/bif/plugins/Bro_SNMP.types.bif + +module SNMP; +export { + + ## The top-level message data structure of an SNMPv1 datagram, not + ## including the PDU data. See :rfc:`1157`. + type SNMP::HeaderV1: record { + community: string; + }; + + ## The top-level message data structure of an SNMPv2 datagram, not + ## including the PDU data. See :rfc:`1901`. + type SNMP::HeaderV2: record { + community: string; + }; + + ## The ``ScopedPduData`` data structure of an SNMPv3 datagram, not + ## including the PDU data (i.e. just the "context" fields). + ## See :rfc:`3412`. + type SNMP::ScopedPDU_Context: record { + engine_id: string; + name: string; + }; + + ## The top-level message data structure of an SNMPv3 datagram, not + ## including the PDU data. See :rfc:`3412`. + type SNMP::HeaderV3: record { + id: count; + max_size: count; + flags: count; + auth_flag: bool; + priv_flag: bool; + reportable_flag: bool; + security_model: count; + security_params: string; + pdu_context: SNMP::ScopedPDU_Context &optional; + }; + + ## A generic SNMP header data structure that may include data from + ## any version of SNMP. The value of the ``version`` field + ## determines what header field is initialized. + type SNMP::Header: record { + version: count; + v1: SNMP::HeaderV1 &optional; ##< Set when ``version`` is 0. + v2: SNMP::HeaderV2 &optional; ##< Set when ``version`` is 1. + v3: SNMP::HeaderV3 &optional; ##< Set when ``version`` is 3. + }; + + ## A generic SNMP object value, that may include any of the + ## valid ``ObjectSyntax`` values from :rfc:`1155` or :rfc:`3416`. + ## The value is decoded whenever possible and assigned to + ## the appropriate field, which can be determined from the value + ## of the ``tag`` field. For tags that can't be mapped to an + ## appropriate type, the ``octets`` field holds the BER encoded + ## ASN.1 content if there is any (though, ``octets`` is may also + ## be used for other tags such as OCTET STRINGS or Opaque). Null + ## values will only have their corresponding tag value set. + type SNMP::ObjectValue: record { + tag: count; + oid: string &optional; + signed: int &optional; + unsigned: count &optional; + address: addr &optional; + octets: string &optional; + }; + + # These aren't an enum because it's easier to type fields as count. + # That way don't have to deal with type conversion, plus doesn't + # mislead that these are the only valid tag values (it's just the set + # of known tags). + const SNMP::OBJ_INTEGER_TAG : count = 0x02; ##< Signed 64-bit integer. + const SNMP::OBJ_OCTETSTRING_TAG : count = 0x04; ##< An octet string. + const SNMP::OBJ_UNSPECIFIED_TAG : count = 0x05; ##< A NULL value. + const SNMP::OBJ_OID_TAG : count = 0x06; ##< An Object Identifier. + const SNMP::OBJ_IPADDRESS_TAG : count = 0x40; ##< An IP address. + const SNMP::OBJ_COUNTER32_TAG : count = 0x41; ##< Unsigned 32-bit integer. + const SNMP::OBJ_UNSIGNED32_TAG : count = 0x42; ##< Unsigned 32-bit integer. + const SNMP::OBJ_TIMETICKS_TAG : count = 0x43; ##< Unsigned 32-bit integer. + const SNMP::OBJ_OPAQUE_TAG : count = 0x44; ##< An octet string. + const SNMP::OBJ_COUNTER64_TAG : count = 0x46; ##< Unsigned 64-bit integer. + const SNMP::OBJ_NOSUCHOBJECT_TAG : count = 0x80; ##< A NULL value. + const SNMP::OBJ_NOSUCHINSTANCE_TAG: count = 0x81; ##< A NULL value. + const SNMP::OBJ_ENDOFMIBVIEW_TAG : count = 0x82; ##< A NULL value. + + ## The ``VarBind`` data structure from either :rfc:`1157` or + ## :rfc:`3416`, which maps an Object Identifier to a value. + type SNMP::Binding: record { + oid: string; + value: SNMP::ObjectValue; + }; + + ## A ``VarBindList`` data structure from either :rfc:`1157` or :rfc:`3416`. + ## A sequences of :bro:see:`SNMP::Binding`, which maps an OIDs to values. + type SNMP::Bindings: vector of SNMP::Binding; + + ## A ``PDU`` data structure from either :rfc:`1157` or :rfc:`3416`. + type SNMP::PDU: record { + request_id: int; + error_status: int; + error_index: int; + bindings: SNMP::Bindings; + }; + + ## A ``Trap-PDU`` data structure from :rfc:`1157`. + type SNMP::TrapPDU: record { + enterprise: string; + agent: addr; + generic_trap: int; + specific_trap: int; + time_stamp: count; + bindings: SNMP::Bindings; + }; + + ## A ``BulkPDU`` data structure from :rfc:`3416`. + type SNMP::BulkPDU: record { + request_id: int; + non_repeaters: count; + max_repititions: count; + bindings: SNMP::Bindings; + }; +} +module GLOBAL; + @load base/bif/event.bif ## BPF filter the user has set via the -f command line options. Empty if none. diff --git a/scripts/base/init-default.bro b/scripts/base/init-default.bro index d87574f4e5..edf6e21f56 100644 --- a/scripts/base/init-default.bro +++ b/scripts/base/init-default.bro @@ -47,6 +47,7 @@ @load base/protocols/irc @load base/protocols/modbus @load base/protocols/pop3 +@load base/protocols/snmp @load base/protocols/smtp @load base/protocols/socks @load base/protocols/ssh diff --git a/scripts/base/protocols/snmp/README b/scripts/base/protocols/snmp/README new file mode 100644 index 0000000000..524c3266cc --- /dev/null +++ b/scripts/base/protocols/snmp/README @@ -0,0 +1 @@ +Support for Simple Network Management Protocol (SNMP) analysis. diff --git a/scripts/base/protocols/snmp/__load__.bro b/scripts/base/protocols/snmp/__load__.bro new file mode 100644 index 0000000000..a10fe855df --- /dev/null +++ b/scripts/base/protocols/snmp/__load__.bro @@ -0,0 +1 @@ +@load ./main diff --git a/scripts/base/protocols/snmp/main.bro b/scripts/base/protocols/snmp/main.bro new file mode 100644 index 0000000000..a2fbb23713 --- /dev/null +++ b/scripts/base/protocols/snmp/main.bro @@ -0,0 +1,15 @@ +##! Enables analysis of SNMP datagrams. + +module SNMP; + +export { +} + +const ports = { 161/udp, 162/udp }; + +redef likely_server_ports += { ports }; + +event bro_init() &priority=5 + { + Analyzer::register_for_ports(Analyzer::ANALYZER_SNMP, ports); + } diff --git a/src/analyzer/protocol/CMakeLists.txt b/src/analyzer/protocol/CMakeLists.txt index fc63aa4b66..bf063dfafc 100644 --- a/src/analyzer/protocol/CMakeLists.txt +++ b/src/analyzer/protocol/CMakeLists.txt @@ -28,6 +28,7 @@ add_subdirectory(ntp) add_subdirectory(pia) add_subdirectory(pop3) add_subdirectory(rpc) +add_subdirectory(snmp) add_subdirectory(smb) add_subdirectory(smtp) add_subdirectory(socks) diff --git a/src/analyzer/protocol/snmp/CMakeLists.txt b/src/analyzer/protocol/snmp/CMakeLists.txt new file mode 100644 index 0000000000..7f1ffe2ed6 --- /dev/null +++ b/src/analyzer/protocol/snmp/CMakeLists.txt @@ -0,0 +1,11 @@ +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro SNMP) +bro_plugin_cc(SNMP.cc Plugin.cc) +bro_plugin_bif(types.bif) +bro_plugin_bif(events.bif) +bro_plugin_pac(snmp.pac snmp-protocol.pac snmp-analyzer.pac) +bro_plugin_end() diff --git a/src/analyzer/protocol/snmp/Plugin.cc b/src/analyzer/protocol/snmp/Plugin.cc new file mode 100644 index 0000000000..e9e74f67a6 --- /dev/null +++ b/src/analyzer/protocol/snmp/Plugin.cc @@ -0,0 +1,9 @@ +#include "plugin/Plugin.h" +#include "SNMP.h" + +BRO_PLUGIN_BEGIN(Bro, SNMP) + BRO_PLUGIN_DESCRIPTION("SNMP Analyzer"); + BRO_PLUGIN_ANALYZER("SNMP", snmp::SNMP_Analyzer); + BRO_PLUGIN_BIF_FILE(types); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END diff --git a/src/analyzer/protocol/snmp/SNMP.cc b/src/analyzer/protocol/snmp/SNMP.cc new file mode 100644 index 0000000000..110479406c --- /dev/null +++ b/src/analyzer/protocol/snmp/SNMP.cc @@ -0,0 +1,38 @@ +#include "SNMP.h" +#include "Func.h" +#include "types.bif.h" +#include "events.bif.h" + +using namespace analyzer::snmp; + +SNMP_Analyzer::SNMP_Analyzer(Connection* conn) + : Analyzer("SNMP", conn) + { + interp = new binpac::SNMP::SNMP_Conn(this); + } + +SNMP_Analyzer::~SNMP_Analyzer() + { + delete interp; + } + +void SNMP_Analyzer::Done() + { + Analyzer::Done(); + Event(udp_session_done); + } + +void SNMP_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, + int seq, const IP_Hdr* ip, int caplen) + { + Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); + + try + { + interp->NewData(orig, data, data + len); + } + catch ( const binpac::Exception& e ) + { + ProtocolViolation(e.c_msg()); + } + } diff --git a/src/analyzer/protocol/snmp/SNMP.h b/src/analyzer/protocol/snmp/SNMP.h new file mode 100644 index 0000000000..f6dedc7b87 --- /dev/null +++ b/src/analyzer/protocol/snmp/SNMP.h @@ -0,0 +1,29 @@ +#ifndef ANALYZER_PROTOCOL_SNMP_SNMP_H +#define ANALYZER_PROTOCOL_SNMP_SNMP_H + +#include "snmp_pac.h" + +namespace analyzer { namespace snmp { + +class SNMP_Analyzer : public analyzer::Analyzer { + +public: + + SNMP_Analyzer(Connection* conn); + virtual ~SNMP_Analyzer(); + + virtual void Done(); + virtual void DeliverPacket(int len, const u_char* data, bool orig, + int seq, const IP_Hdr* ip, int caplen); + + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) + { return new SNMP_Analyzer(conn); } + +protected: + + binpac::SNMP::SNMP_Conn* interp; +}; + +} } // namespace analyzer::* + +#endif diff --git a/src/analyzer/protocol/snmp/events.bif b/src/analyzer/protocol/snmp/events.bif new file mode 100644 index 0000000000..af5f2ba969 --- /dev/null +++ b/src/analyzer/protocol/snmp/events.bif @@ -0,0 +1,166 @@ + +## An SNMP ``GetRequest-PDU`` message from either :rfc:`1157` or :rfc:`3416`. +## +## c: The connection overwhich the SNMP datagram is sent. +## +## is_orig: The endpoint which sent the SNMP datagram. +## +## header: SNMP version-dependent data that precedes PDU data in the top-level +## SNMP message structure. +## +## pdu: An SNMP PDU data structure. +event snmp_get_request%(c: connection, is_orig: bool, header: SNMP::Header, + pdu: SNMP::PDU%); + +## An SNMP ``GetNextRequest-PDU`` message from either :rfc:`1157` or +## :rfc:`3416`. +## +## c: The connection overwhich the SNMP datagram is sent. +## +## is_orig: The endpoint which sent the SNMP datagram. +## +## header: SNMP version-dependent data that precedes PDU data in the top-level +## SNMP message structure. +## +## pdu: An SNMP PDU data structure. +event snmp_get_next_request%(c: connection, is_orig: bool, + header: SNMP::Header, pdu: SNMP::PDU%); + +## An SNMP ``GetResponse-PDU`` message from :rfc:`1157` or a +## ``Response-PDU`` from :rfc:`3416`. +## +## c: The connection overwhich the SNMP datagram is sent. +## +## is_orig: The endpoint which sent the SNMP datagram. +## +## header: SNMP version-dependent data that precedes PDU data in the top-level +## SNMP message structure. +## +## pdu: An SNMP PDU data structure. +event snmp_response%(c: connection, is_orig: bool, header: SNMP::Header, + pdu: SNMP::PDU%); + +## An SNMP ``SetRequest-PDU`` message from either :rfc:`1157` or :rfc:`3416`. +## +## c: The connection overwhich the SNMP datagram is sent. +## +## is_orig: The endpoint which sent the SNMP datagram. +## +## header: SNMP version-dependent data that precedes PDU data in the top-level +## SNMP message structure. +## +## pdu: An SNMP PDU data structure. +event snmp_set_request%(c: connection, is_orig: bool, header: SNMP::Header, + pdu: SNMP::PDU%); + +## An SNMP ``Trap-PDU`` message from :rfc:`1157`. +## +## c: The connection overwhich the SNMP datagram is sent. +## +## is_orig: The endpoint which sent the SNMP datagram. +## +## header: SNMP version-dependent data that precedes PDU data in the top-level +## SNMP message structure. +## +## pdu: An SNMP PDU data structure. +event snmp_trap%(c: connection, is_orig: bool, header: SNMP::Header, + pdu: SNMP::TrapPDU%); + +## An SNMP ``GetBulkRequest-PDU`` message from :rfc:`3416`. +## +## c: The connection overwhich the SNMP datagram is sent. +## +## is_orig: The endpoint which sent the SNMP datagram. +## +## header: SNMP version-dependent data that precedes PDU data in the top-level +## SNMP message structure. +## +## pdu: An SNMP PDU data structure. +event snmp_get_bulk_request%(c: connection, is_orig: bool, + header: SNMP::Header, pdu: SNMP::BulkPDU%); + +## An SNMP ``InformRequest-PDU`` message from :rfc:`3416`. +## +## c: The connection overwhich the SNMP datagram is sent. +## +## is_orig: The endpoint which sent the SNMP datagram. +## +## header: SNMP version-dependent data that precedes PDU data in the top-level +## SNMP message structure. +## +## pdu: An SNMP PDU data structure. +event snmp_inform_request%(c: connection, is_orig: bool, header: SNMP::Header, + pdu: SNMP::PDU%); + +## An SNMP ``SNMPv2-Trap-PDU`` message from :rfc:`1157`. +## +## c: The connection overwhich the SNMP datagram is sent. +## +## is_orig: The endpoint which sent the SNMP datagram. +## +## header: SNMP version-dependent data that precedes PDU data in the top-level +## SNMP message structure. +## +## pdu: An SNMP PDU data structure. +event snmp_trapV2%(c: connection, is_orig: bool, header: SNMP::Header, + pdu: SNMP::PDU%); + +## An SNMP ``Report-PDU`` message from :rfc:`3416`. +## +## c: The connection overwhich the SNMP datagram is sent. +## +## is_orig: The endpoint which sent the SNMP datagram. +## +## header: SNMP version-dependent data that precedes PDU data in the top-level +## SNMP message structure. +## +## pdu: An SNMP PDU data structure. +event snmp_report%(c: connection, is_orig: bool, header: SNMP::Header, + pdu: SNMP::PDU%); + +## An SNMP PDU message of unknown type. +## +## c: The connection overwhich the SNMP datagram is sent. +## +## is_orig: The endpoint which sent the SNMP datagram. +## +## header: SNMP version-dependent data that precedes PDU data in the top-level +## SNMP message structure. +## +## tag: The tag of the unknown SNMP PDU. +event snmp_unknown_pdu%(c: connection, is_orig: bool, header: SNMP::Header, + tag: count%); + +## An SNMPv3 ``ScopedPDUData`` of unknown type (neither plaintext or +## an encrypted PDU was in the datagram). +## +## c: The connection overwhich the SNMP datagram is sent. +## +## is_orig: The endpoint which sent the SNMP datagram. +## +## header: SNMP version-dependent data that precedes PDU data in the top-level +## SNMP message structure. +## +## tag: The tag of the unknown SNMP PDU scope. +event snmp_unknown_scoped_pdu%(c: connection, is_orig: bool, + header: SNMP::Header, tag: count%); + +## An SNMPv3 encrypted PDU message. +## +## c: The connection overwhich the SNMP datagram is sent. +## +## is_orig: The endpoint which sent the SNMP datagram. +## +## header: SNMP version-dependent data that precedes PDU data in the top-level +## SNMP message structure. +event snmp_encrypted_pdu%(c: connection, is_orig: bool, header: SNMP::Header%); + +## A datagram with an unknown SNMP version. +## +## c: The connection overwhich the SNMP datagram is sent. +## +## is_orig: The endpoint which sent the SNMP datagram. +## +## version: The value of the unknown SNMP version. +event snmp_unknown_header_version%(c: connection, is_orig: bool, + version: count%); diff --git a/src/analyzer/protocol/snmp/snmp-analyzer.pac b/src/analyzer/protocol/snmp/snmp-analyzer.pac new file mode 100644 index 0000000000..1a864df8b9 --- /dev/null +++ b/src/analyzer/protocol/snmp/snmp-analyzer.pac @@ -0,0 +1,590 @@ + +%header{ +StringVal* asn1_oid_to_val(const ASN1Encoding* oid); +StringVal* asn1_oid_to_val(const ASN1ObjectIdentifier* oid); + +Val* asn1_integer_to_val(const ASN1Encoding* i, TypeTag t); +Val* asn1_integer_to_val(const ASN1Integer* i, TypeTag t); + +StringVal* asn1_octet_string_to_val(const ASN1Encoding* s); +StringVal* asn1_octet_string_to_val(const ASN1OctetString* s); + +AddrVal* network_address_to_val(const ASN1Encoding* na); +AddrVal* network_address_to_val(const NetworkAddress* na); + +Val* asn1_obj_to_val(const ASN1Encoding* obj); + +RecordVal* build_hdr(const Header* header); +RecordVal* build_hdrV3(const Header* header); +VectorVal* build_bindings(const VarBindList* vbl); +RecordVal* build_pdu(const CommonPDU* pdu); +RecordVal* build_trap_pdu(const TrapPDU* pdu); +RecordVal* build_bulk_pdu(const GetBulkRequestPDU* pdu); +%} + +%code{ + +StringVal* asn1_oid_to_val(const ASN1ObjectIdentifier* oid) + { + return asn1_oid_to_val(oid->encoding()); + } + +StringVal* asn1_oid_to_val(const ASN1Encoding* oid) + { + vector oid_components; + vector > subidentifiers; + vector subidentifier_values; + vector subidentifier; + bytestring const& bs = oid->content(); + + for ( int i = 0; i < bs.length(); ++i ) + { + if ( bs[i] & 0x80 ) + subidentifier.push_back(bs[i] & 0x7f); + else + { + subidentifier.push_back(bs[i]); + subidentifiers.push_back(subidentifier); + subidentifier.clear(); + } + } + + if ( ! subidentifier.empty() || subidentifiers.size() < 1 ) + // Underflow. + return new StringVal(""); + + for ( size_t i = 0; i < subidentifiers.size(); ++i ) + { + subidentifier = subidentifiers[i]; + uint64 value = 0; + + for ( size_t j = 0; j < subidentifier.size(); ++j ) + { + uint64 byte = subidentifier[j]; + value |= byte << (7 * (subidentifier.size() - (j + 1))); + } + + subidentifier_values.push_back(value); + } + + string rval; + + for ( size_t i = 0; i < subidentifier_values.size(); ++i ) + { + char tmp[32]; + + if ( i > 0 ) + { + rval += "."; + snprintf(tmp, sizeof(tmp), "%"PRIu64, subidentifier_values[i]); + rval += tmp; + } + else + { + std::div_t result = div(subidentifier_values[i], 40); + snprintf(tmp, sizeof(tmp), "%d", result.quot); + rval += tmp; + rval += "."; + snprintf(tmp, sizeof(tmp), "%d", result.rem); + rval += tmp; + } + } + + return new StringVal(rval); + } + +Val* asn1_obj_to_val(const ASN1Encoding* obj) + { + RecordVal* rval = new RecordVal(BifType::Record::SNMP::ObjectValue); + uint8 tag = obj->meta()->tag(); + + rval->Assign(0, new Val(tag, TYPE_COUNT)); + + switch ( tag ) { + case VARBIND_UNSPECIFIED_TAG: + case VARBIND_NOSUCHOBJECT_TAG: + case VARBIND_NOSUCHINSTANCE_TAG: + case VARBIND_ENDOFMIBVIEW_TAG: + break; + + case ASN1_OBJECT_IDENTIFIER_TAG: + rval->Assign(1, asn1_oid_to_val(obj)); + break; + + case ASN1_INTEGER_TAG: + rval->Assign(2, asn1_integer_to_val(obj, TYPE_INT)); + break; + + case APP_COUNTER32_TAG: + case APP_UNSIGNED32_TAG: + case APP_TIMETICKS_TAG: + case APP_COUNTER64_TAG: + rval->Assign(3, asn1_integer_to_val(obj, TYPE_COUNT)); + break; + + case APP_IPADDRESS_TAG: + rval->Assign(4, network_address_to_val(obj)); + break; + + case ASN1_OCTET_STRING_TAG: + case APP_OPAQUE_TAG: + default: + rval->Assign(5, asn1_octet_string_to_val(obj)); + break; + } + + return rval; + } + +StringVal* asn1_octet_string_to_val(const ASN1OctetString* s) + { + return asn1_octet_string_to_val(s->encoding()); + } + +StringVal* asn1_octet_string_to_val(const ASN1Encoding* s) + { + bytestring const& bs = s->content(); + return new StringVal(bs.length(), reinterpret_cast(bs.data())); + } + +Val* asn1_integer_to_val(const ASN1Integer* i, TypeTag t) + { + return asn1_integer_to_val(i->encoding(), t); + } + +Val* asn1_integer_to_val(const ASN1Encoding* i, TypeTag t) + { + return new Val(binary_to_int64(i->content()), t); + } + +AddrVal* network_address_to_val(const NetworkAddress* na) + { + return network_address_to_val(na->encoding()); + } + +AddrVal* network_address_to_val(const ASN1Encoding* na) + { + bytestring const& bs = na->content(); + + // IPv6 can probably be presumed to be a octet string of length 16, + // but standards don't seem to currently make any provisions for IPv6, + // so ignore anything that can't be IPv4. + if ( bs.length() != 4 ) + return new AddrVal(IPAddr()); + + const u_char* data = reinterpret_cast(bs.data()); + uint32 network_order = extract_uint32(data); + return new AddrVal(network_order); + } + +Val* time_ticks_to_val(const TimeTicks* tt) + { + return asn1_integer_to_val(tt->asn1_integer(), TYPE_COUNT); + } + +RecordVal* build_hdr(const Header* header) + { + RecordVal* rv = new RecordVal(BifType::Record::SNMP::Header); + rv->Assign(0, new Val(header->version(), TYPE_COUNT)); + + switch ( header->version() ) { + case SNMPV1_TAG: + { + RecordVal* v1 = new RecordVal(BifType::Record::SNMP::HeaderV1); + v1->Assign(0, asn1_octet_string_to_val(header->v1()->community())); + rv->Assign(1, v1); + } + break; + + case SNMPV2_TAG: + { + RecordVal* v2 = new RecordVal(BifType::Record::SNMP::HeaderV2); + v2->Assign(0, asn1_octet_string_to_val(header->v2()->community())); + rv->Assign(2, v2); + } + break; + + case SNMPV3_TAG: + { + rv->Assign(3, build_hdrV3(header)); + } + break; + } + + return rv; + } + +RecordVal* build_hdrV3(const Header* header) + { + RecordVal* v3 = new RecordVal(BifType::Record::SNMP::HeaderV3); + const v3Header* v3hdr = header->v3(); + const v3HeaderData* global_data = v3hdr->global_data(); + bytestring const& flags = global_data->flags()->encoding()->content(); + uint8 flags_byte = flags.length() > 0 ? flags[0] : 0; + + v3->Assign(0, asn1_integer_to_val(global_data->id(), TYPE_COUNT)); + v3->Assign(1, asn1_integer_to_val(global_data->max_size(), + TYPE_COUNT)); + v3->Assign(2, new Val(flags_byte, TYPE_COUNT)); + v3->Assign(3, new Val(flags_byte & 0x01, TYPE_BOOL)); + v3->Assign(4, new Val(flags_byte & 0x02, TYPE_BOOL)); + v3->Assign(5, new Val(flags_byte & 0x04, TYPE_BOOL)); + v3->Assign(6, asn1_integer_to_val(global_data->security_model(), + TYPE_COUNT)); + v3->Assign(7, asn1_octet_string_to_val(v3hdr->security_parameters())); + + if ( v3hdr->next()->tag() == ASN1_SEQUENCE_TAG ) + { + const v3ScopedPDU* spdu = v3hdr->plaintext_pdu(); + RecordVal* rv = new RecordVal(BifType::Record::SNMP::ScopedPDU_Context); + rv->Assign(0, asn1_octet_string_to_val(spdu->context_engine_id())); + rv->Assign(1, asn1_octet_string_to_val(spdu->context_name())); + v3->Assign(8, rv); + } + + return v3; + } + +VectorVal* build_bindings(const VarBindList* vbl) + { + VectorVal* vv = new VectorVal(BifType::Vector::SNMP::Bindings); + + for ( size_t i = 0; i < vbl->bindings()->size(); ++i ) + { + VarBind* vb = (*vbl->bindings())[i]; + RecordVal* binding = new RecordVal(BifType::Record::SNMP::Binding); + binding->Assign(0, asn1_oid_to_val(vb->name()->oid())); + binding->Assign(1, asn1_obj_to_val(vb->value()->encoding())); + vv->Assign(i, binding); + } + + return vv; + } + +RecordVal* build_pdu(const CommonPDU* pdu) + { + RecordVal* rv = new RecordVal(BifType::Record::SNMP::PDU); + rv->Assign(0, asn1_integer_to_val(pdu->request_id(), TYPE_INT)); + rv->Assign(1, asn1_integer_to_val(pdu->error_status(), TYPE_INT)); + rv->Assign(2, asn1_integer_to_val(pdu->error_index(), TYPE_INT)); + rv->Assign(3, build_bindings(pdu->var_bindings())); + return rv; + } + +RecordVal* build_trap_pdu(const TrapPDU* pdu) + { + RecordVal* rv = new RecordVal(BifType::Record::SNMP::TrapPDU); + rv->Assign(0, asn1_oid_to_val(pdu->enterprise())); + rv->Assign(1, network_address_to_val(pdu->agent_addr())); + rv->Assign(2, asn1_integer_to_val(pdu->generic_trap(), TYPE_INT)); + rv->Assign(3, asn1_integer_to_val(pdu->specific_trap(), TYPE_INT)); + rv->Assign(4, time_ticks_to_val(pdu->time_stamp())); + rv->Assign(5, build_bindings(pdu->var_bindings())); + return rv; + } + +RecordVal* build_bulk_pdu(const GetBulkRequestPDU* pdu) + { + RecordVal* rv = new RecordVal(BifType::Record::SNMP::BulkPDU); + rv->Assign(0, asn1_integer_to_val(pdu->request_id(), TYPE_INT)); + rv->Assign(1, asn1_integer_to_val(pdu->non_repeaters(), TYPE_COUNT)); + rv->Assign(2, asn1_integer_to_val(pdu->max_repititions(), TYPE_COUNT)); + rv->Assign(3, build_bindings(pdu->var_bindings())); + return rv; + } +%} + +refine connection SNMP_Conn += { + + function proc_get_request(pdu: GetRequestPDU): bool + %{ + if ( ! snmp_get_request ) + return false; + + BifEvent::generate_snmp_get_request(bro_analyzer(), + bro_analyzer()->Conn(), + ${pdu.header.is_orig}, + build_hdr(${pdu.header}), + build_pdu(${pdu.pdu})); + return true; + %} + + function proc_get_next_request(pdu: GetNextRequestPDU): bool + %{ + if ( ! snmp_get_next_request ) + return false; + + BifEvent::generate_snmp_get_next_request(bro_analyzer(), + bro_analyzer()->Conn(), + ${pdu.header.is_orig}, + build_hdr(${pdu.header}), + build_pdu(${pdu.pdu})); + return true; + %} + + function proc_response(pdu: ResponsePDU): bool + %{ + if ( ! snmp_response ) + return false; + + BifEvent::generate_snmp_response(bro_analyzer(), + bro_analyzer()->Conn(), + ${pdu.header.is_orig}, + build_hdr(${pdu.header}), + build_pdu(${pdu.pdu})); + return true; + %} + + function proc_set_request(pdu: SetRequestPDU): bool + %{ + if ( ! snmp_set_request ) + return false; + + BifEvent::generate_snmp_set_request(bro_analyzer(), + bro_analyzer()->Conn(), + ${pdu.header.is_orig}, + build_hdr(${pdu.header}), + build_pdu(${pdu.pdu})); + return true; + %} + + function proc_trap(pdu: TrapPDU): bool + %{ + if ( ! snmp_trap ) + return false; + + BifEvent::generate_snmp_trap(bro_analyzer(), + bro_analyzer()->Conn(), + ${pdu.header.is_orig}, + build_hdr(${pdu.header}), + build_trap_pdu(${pdu})); + return true; + %} + + function proc_get_bulk_request(pdu: GetBulkRequestPDU): bool + %{ + if ( ! snmp_get_bulk_request ) + return false; + + BifEvent::generate_snmp_get_bulk_request(bro_analyzer(), + bro_analyzer()->Conn(), + ${pdu.header.is_orig}, + build_hdr(${pdu.header}), + build_bulk_pdu(${pdu})); + return true; + %} + + function proc_inform_request(pdu: InformRequestPDU): bool + %{ + if ( ! snmp_inform_request ) + return false; + + BifEvent::generate_snmp_inform_request(bro_analyzer(), + bro_analyzer()->Conn(), + ${pdu.header.is_orig}, + build_hdr(${pdu.header}), + build_pdu(${pdu.pdu})); + return true; + %} + + function proc_v2_trap(pdu: v2TrapPDU): bool + %{ + if ( ! snmp_trapV2 ) + return false; + + BifEvent::generate_snmp_trapV2(bro_analyzer(), + bro_analyzer()->Conn(), + ${pdu.header.is_orig}, + build_hdr(${pdu.header}), + build_pdu(${pdu.pdu})); + return true; + %} + + function proc_report(pdu: ReportPDU): bool + %{ + if ( ! snmp_report ) + return false; + + BifEvent::generate_snmp_report(bro_analyzer(), + bro_analyzer()->Conn(), + ${pdu.header.is_orig}, + build_hdr(${pdu.header}), + build_pdu(${pdu.pdu})); + return true; + %} + + function proc_unknown_version_header(rec: UnknownVersionHeader): bool + %{ + if ( ! snmp_unknown_header_version ) + return false; + + BifEvent::generate_snmp_unknown_header_version(bro_analyzer(), + bro_analyzer()->Conn(), + ${rec.header.is_orig}, + ${rec.header.version}); + return true; + %} + + function proc_unknown_pdu(rec: UnknownPDU): bool + %{ + if ( ! snmp_unknown_pdu ) + return false; + + BifEvent::generate_snmp_unknown_pdu(bro_analyzer(), + bro_analyzer()->Conn(), + ${rec.header.is_orig}, + build_hdr(${rec.header}), + ${rec.tag}); + return true; + %} + + function proc_unknown_scoped_pdu(rec: UnknownScopedPDU): bool + %{ + if ( ! snmp_unknown_scoped_pdu ) + return false; + + BifEvent::generate_snmp_unknown_scoped_pdu(bro_analyzer(), + bro_analyzer()->Conn(), + ${rec.header.is_orig}, + build_hdr(${rec.header}), + ${rec.tag}); + return true; + %} + + function proc_encrypted_pdu(rec: EncryptedPDU): bool + %{ + if ( ! snmp_encrypted_pdu ) + return false; + + BifEvent::generate_snmp_encrypted_pdu(bro_analyzer(), + bro_analyzer()->Conn(), + ${rec.header.is_orig}, + build_hdr(${rec.header})); + return true; + %} + + function proc_header(rec: Header): bool + %{ + if ( rec->unknown() ) + return false; + + bro_analyzer()->ProtocolConfirmation(); + return true; + %} + + function proc_v3_header_data(rec: v3HeaderData): bool + %{ + if ( rec->flags()->encoding()->content().length() == 1 ) + return true; + + bro_analyzer()->ProtocolViolation("Invalid v3 HeaderData msgFlags"); + return false; + %} + + function check_tag(rec: ASN1EncodingMeta, expect: uint8): bool + %{ + if ( rec->tag() == expect ) + return true; + + // Unwind now to stop parsing because it's definitely the + // wrong protocol and parsing further could be expensive. + // Upper layer of analyzer will catch and call ProtocolViolation(). + throw binpac::Exception(fmt("Got ASN.1 tag %d, expect %d", + rec->tag(), expect)); + return false; + %} + + function check_int_width(rec: ASN1Integer): bool + %{ + int len = rec->encoding()->content().length(); + + if ( len <= 9 ) + // All integers use two's complement form, so an unsigned 64-bit + // integer value can require 9 octets to encode if the highest + // order bit is set. + return true; + + throw binpac::Exception(fmt("ASN.1 integer width overflow: %d", len)); + return false; + %} + + function check_int(rec: ASN1Integer): bool + %{ + return check_tag(rec->encoding()->meta(), ASN1_INTEGER_TAG) && + check_int_width(rec); + %} +}; + +refine typeattr GetRequestPDU += &let { + proc: bool = $context.connection.proc_get_request(this); +}; +refine typeattr GetNextRequestPDU += &let { + proc: bool = $context.connection.proc_get_next_request(this); +}; +refine typeattr ResponsePDU += &let { + proc: bool = $context.connection.proc_response(this); +}; +refine typeattr SetRequestPDU += &let { + proc: bool = $context.connection.proc_set_request(this); +}; +refine typeattr TrapPDU += &let { + proc: bool = $context.connection.proc_trap(this); +}; +refine typeattr GetBulkRequestPDU += &let { + proc: bool = $context.connection.proc_get_bulk_request(this); +}; +refine typeattr InformRequestPDU += &let { + proc: bool = $context.connection.proc_inform_request(this); +}; +refine typeattr v2TrapPDU += &let { + proc: bool = $context.connection.proc_v2_trap(this); +}; +refine typeattr ReportPDU += &let { + proc: bool = $context.connection.proc_report(this); +}; + +refine typeattr UnknownVersionHeader += &let { + proc: bool = $context.connection.proc_unknown_version_header(this); +}; +refine typeattr UnknownPDU += &let { + proc: bool = $context.connection.proc_unknown_pdu(this); +}; +refine typeattr UnknownScopedPDU += &let { + proc: bool = $context.connection.proc_unknown_scoped_pdu(this); +}; +refine typeattr EncryptedPDU += &let { + proc: bool = $context.connection.proc_encrypted_pdu(this); +}; + +refine typeattr Header += &let { + proc: bool = $context.connection.proc_header(this); +}; + +refine typeattr v3HeaderData += &let { + proc: bool = $context.connection.proc_v3_header_data(this); +}; + +refine typeattr NetworkAddress += &let { + valid: bool = $context.connection.check_tag(encoding.meta, + APP_IPADDRESS_TAG); +}; +refine typeattr TimeTicks += &let { + valid: bool = $context.connection.check_tag(asn1_integer.meta, + APP_TIMETICKS_TAG); +}; + +refine typeattr ASN1SequenceMeta += &let { + valid: bool = $context.connection.check_tag(encoding, + ASN1_SEQUENCE_TAG); +}; +refine typeattr ASN1Integer += &let { + valid: bool = $context.connection.check_int(this); +}; +refine typeattr ASN1OctetString += &let { + valid: bool = $context.connection.check_tag(encoding.meta, + ASN1_OCTET_STRING_TAG); +}; +refine typeattr ASN1ObjectIdentifier += &let { + valid: bool = $context.connection.check_tag(encoding.meta, + ASN1_OBJECT_IDENTIFIER_TAG); +}; diff --git a/src/analyzer/protocol/snmp/snmp-protocol.pac b/src/analyzer/protocol/snmp/snmp-protocol.pac new file mode 100644 index 0000000000..8d9b602ea2 --- /dev/null +++ b/src/analyzer/protocol/snmp/snmp-protocol.pac @@ -0,0 +1,272 @@ +# SNMPv1: RFC 1157 +# SNMPv2: RFC 1901 and 3416 +# SNMPv3: RFC 3412 +# Variable Bindings use definitions from RFC 1155 (and 3416). +# +# The SNMP protocol uses a well-defined subset of ASN.1 with the +# Basic Encoding Rules (BER). Definite-length encodings are always +# used. Primitive or non-constructor encodings are preferred over +# constructor encodings. + +type TopLevelMessage(is_orig: bool) = record { + asn1_sequence_meta: ASN1SequenceMeta; + version: ASN1Integer; + header: Header(version_value, is_orig); + pdu_or_not: case have_plaintext_pdu(header) of { + false -> none: empty; + true -> pdu: PDU_Choice(header); + }; +} &let { + version_value: int64 = binary_to_int64(version.encoding.content); +}; + +############################## SNMP Header Versions + +enum SNMP_VersionTag { + SNMPV1_TAG = 0, + SNMPV2_TAG = 1, + SNMPV3_TAG = 3, +}; + +type Header(version: int64, is_orig: bool) = case version of { + SNMPV1_TAG -> v1: v1Header(this); + SNMPV2_TAG -> v2: v2Header(this); + SNMPV3_TAG -> v3: v3Header(this); + default -> unknown: UnknownVersionHeader(this); +}; + +function have_plaintext_pdu(header: Header): bool = + case header.version of { + SNMPV1_TAG -> true; + SNMPV2_TAG -> true; + SNMPV3_TAG -> header.v3.next.tag == ASN1_SEQUENCE_TAG; + default -> false; + }; + +type PDU_Choice(header: Header) = record { + choice: ASN1EncodingMeta; + pdu: PDU(choice.tag, header); +}; + +type PDU(choice: uint8, header: Header) = case choice of { + default -> unknown: UnknownPDU(choice, header); +}; + +refine casetype PDU += { + # PDU choices from RFC 1157. + 0xa0 -> get_request: GetRequestPDU(header); + 0xa1 -> get_next_request: GetNextRequestPDU(header); + 0xa2 -> response: ResponsePDU(header); + 0xa3 -> set_request: SetRequestPDU(header); + 0xa4 -> trap: TrapPDU(header); +}; + +refine casetype PDU += { + # PDU choices from RFC 3416. + 0xa5 -> get_bulk_request: GetBulkRequestPDU(header); + 0xa6 -> inform_request: InformRequestPDU(header); + 0xa7 -> v2_trap: v2TrapPDU(header); + 0xa8 -> report: ReportPDU(header); +}; + +type v1Header(header: Header) = record { + community: ASN1OctetString; +}; + +type v2Header(header: Header) = record { + community: ASN1OctetString; +}; + +type v3Header(header: Header) = record { + global_data: v3HeaderData; + security_parameters: ASN1OctetString; + next: ASN1EncodingMeta; + scoped_pdu_data: case next.tag of { + ASN1_SEQUENCE_TAG -> plaintext_pdu: v3ScopedPDU; + ASN1_OCTET_STRING_TAG -> encrypted_pdu: EncryptedPDU(header); + default -> unknown_pdu: UnknownScopedPDU(next.tag, + header); + }; +}; + +type v3HeaderData = record { + asn1_sequence_meta: ASN1SequenceMeta; + id: ASN1Integer; + max_size: ASN1Integer; + flags: ASN1OctetString; + security_model: ASN1Integer; +}; + +type v3ScopedPDU = record { + context_engine_id: ASN1OctetString; + context_name: ASN1OctetString; +}; + +type EncryptedPDU(header: Header) = record { + data: bytestring &restofdata &transient; +}; + +type UnknownScopedPDU(tag: uint8, header: Header) = record { + data: bytestring &restofdata &transient; +}; + +type UnknownVersionHeader(header: Header) = record { + data: bytestring &restofdata &transient; +}; + +############################## SNMP PDUs + +type CommonPDU(header: Header) = record { + request_id: ASN1Integer; + error_status: ASN1Integer; + error_index: ASN1Integer; + var_bindings: VarBindList; +}; + +type GetRequestPDU(header: Header) = record { + pdu: CommonPDU(header); +}; + +type GetNextRequestPDU(header: Header) = record { + pdu: CommonPDU(header); +}; + +type ResponsePDU(header: Header) = record { + pdu: CommonPDU(header); +}; + +type SetRequestPDU(header: Header) = record { + pdu: CommonPDU(header); +}; + +type TrapPDU(header: Header) = record { + enterprise: ASN1ObjectIdentifier; + agent_addr: NetworkAddress; + generic_trap: ASN1Integer; + specific_trap: ASN1Integer; + time_stamp: TimeTicks; + var_bindings: VarBindList; +}; + +type GetBulkRequestPDU(header: Header) = record { + request_id: ASN1Integer; + non_repeaters: ASN1Integer; + max_repititions: ASN1Integer; + var_bindings: VarBindList; +}; + +type InformRequestPDU(header: Header) = record { + pdu: CommonPDU(header); +}; + +type v2TrapPDU(header: Header) = record { + pdu: CommonPDU(header); +}; + +type ReportPDU(header: Header) = record { + pdu: CommonPDU(header); +}; + +type UnknownPDU(tag: uint8, header: Header) = record { + data: bytestring &restofdata &transient; +}; + +type VarBindList = record { + asn1_sequence_meta: ASN1SequenceMeta; + bindings: VarBind[]; +}; + +type VarBind = record { + asn1_sequence_meta: ASN1SequenceMeta; + name: ObjectName; + value: ObjectSyntax; +}; + +############################## Variable Binding Encodings (RFC 1155 and 3416) + +type ObjectName = record { + oid: ASN1ObjectIdentifier; +}; + +type ObjectSyntax = record { + encoding: ASN1Encoding; # The tag may be a CHOICE among several; +}; + +type NetworkAddress = record { + encoding: ASN1Encoding; +}; + +type TimeTicks = record { + asn1_integer: ASN1Encoding; +}; + +enum AppSyntaxTypeTag { + APP_IPADDRESS_TAG = 0x40, + APP_COUNTER32_TAG = 0x41, + APP_UNSIGNED32_TAG = 0x42, + APP_TIMETICKS_TAG = 0x43, + APP_OPAQUE_TAG = 0x44, + APP_COUNTER64_TAG = 0x46, +}; + +enum VarBindNullTag { + VARBIND_UNSPECIFIED_TAG = 0x05, + VARBIND_NOSUCHOBJECT_TAG = 0x80, + VARBIND_NOSUCHINSTANCE_TAG = 0x81, + VARBIND_ENDOFMIBVIEW_TAG = 0x82, +}; + +############################## ASN.1 Encodings + +enum ASN1TypeTag { + ASN1_INTEGER_TAG = 0x02, + ASN1_OCTET_STRING_TAG = 0x04, + ASN1_NULL_TAG = 0x05, + ASN1_OBJECT_IDENTIFIER_TAG = 0x06, + ASN1_SEQUENCE_TAG = 0x30, +}; + +type ASN1Encoding = record { + meta: ASN1EncodingMeta; + content: bytestring &length = meta.length; +}; + +type ASN1EncodingMeta = record { + tag: uint8; + len: uint8; + more_len: bytestring &length = long_len ? len & 0x7f : 0; +} &let { + long_len: bool = len & 0x80; + length: uint64 = long_len ? binary_to_int64(more_len) : len & 0x7f; +}; + +type ASN1SequenceMeta = record { + encoding: ASN1EncodingMeta; +}; + +type ASN1Integer = record { + encoding: ASN1Encoding; +}; + +type ASN1OctetString = record { + encoding: ASN1Encoding; +}; + +type ASN1ObjectIdentifier = record { + encoding: ASN1Encoding; +}; + +############################## ASN.1 Conversion Functions + +function binary_to_int64(bs: bytestring): int64 + %{ + int64 rval = 0; + + for ( int i = 0; i < bs.length(); ++i ) + { + uint64 byte = bs[i]; + rval |= byte << (8 * (bs.length() - (i + 1))); + } + + return rval; + %} diff --git a/src/analyzer/protocol/snmp/snmp.pac b/src/analyzer/protocol/snmp/snmp.pac new file mode 100644 index 0000000000..29b9d32e73 --- /dev/null +++ b/src/analyzer/protocol/snmp/snmp.pac @@ -0,0 +1,25 @@ +%include binpac.pac +%include bro.pac + +%extern{ +#include "types.bif.h" +#include "events.bif.h" +%} + +analyzer SNMP withcontext { + connection: SNMP_Conn; + flow: SNMP_Flow; +}; + +connection SNMP_Conn(bro_analyzer: BroAnalyzer) { + upflow = SNMP_Flow(true); + downflow = SNMP_Flow(false); +}; + +%include snmp-protocol.pac + +flow SNMP_Flow(is_orig: bool) { + datagram = TopLevelMessage(is_orig) withcontext(connection, this); +}; + +%include snmp-analyzer.pac diff --git a/src/analyzer/protocol/snmp/types.bif b/src/analyzer/protocol/snmp/types.bif new file mode 100644 index 0000000000..40d995284d --- /dev/null +++ b/src/analyzer/protocol/snmp/types.bif @@ -0,0 +1,18 @@ + +module SNMP; + +type Header: record; +type HeaderV1: record; +type HeaderV2: record; +type HeaderV3: record; + +type PDU: record; +type TrapPDU: record; +type BulkPDU: record; +type ScopedPDU_Context: record; + +type ObjectValue: record; +type Binding: record; +type Bindings: vector; + +module GLOBAL; diff --git a/testing/btest/Baseline/core.print-bpf-filters/output2 b/testing/btest/Baseline/core.print-bpf-filters/output2 index daa23f3b7a..f2825e6cb8 100644 --- a/testing/btest/Baseline/core.print-bpf-filters/output2 +++ b/testing/btest/Baseline/core.print-bpf-filters/output2 @@ -1,5 +1,7 @@ 2 1080 1 137 +1 161 +1 162 1 20000 1 21 1 2123 @@ -39,8 +41,8 @@ 1 992 1 993 1 995 -43 and -42 or -43 port +45 and +44 or +45 port 32 tcp -11 udp +13 udp diff --git a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log index 0218611d1c..6828e6aa58 100644 --- a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path loaded_scripts -#open 2013-10-30-16-52-11 +#open 2014-02-18-18-10-43 #fields name #types string scripts/base/init-bare.bro @@ -12,6 +12,7 @@ scripts/base/init-bare.bro build/scripts/base/bif/strings.bif.bro build/scripts/base/bif/bro.bif.bro build/scripts/base/bif/reporter.bif.bro + build/scripts/base/bif/plugins/Bro_SNMP.types.bif.bro build/scripts/base/bif/event.bif.bro build/scripts/base/bif/plugins/__load__.bro build/scripts/base/bif/plugins/Bro_ARP.events.bif.bro @@ -53,6 +54,7 @@ scripts/base/init-bare.bro build/scripts/base/bif/plugins/Bro_SMB.events.bif.bro build/scripts/base/bif/plugins/Bro_SMTP.events.bif.bro build/scripts/base/bif/plugins/Bro_SMTP.functions.bif.bro + build/scripts/base/bif/plugins/Bro_SNMP.events.bif.bro build/scripts/base/bif/plugins/Bro_SOCKS.events.bif.bro build/scripts/base/bif/plugins/Bro_SSH.events.bif.bro build/scripts/base/bif/plugins/Bro_SSL.events.bif.bro @@ -101,4 +103,4 @@ scripts/base/init-bare.bro build/scripts/base/bif/top-k.bif.bro scripts/policy/misc/loaded-scripts.bro scripts/base/utils/paths.bro -#close 2013-10-30-16-52-11 +#close 2014-02-18-18-10-43 diff --git a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log index 76b3f3a596..5d32b25823 100644 --- a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path loaded_scripts -#open 2014-01-31-22-54-38 +#open 2014-02-18-18-10-44 #fields name #types string scripts/base/init-bare.bro @@ -12,6 +12,7 @@ scripts/base/init-bare.bro build/scripts/base/bif/strings.bif.bro build/scripts/base/bif/bro.bif.bro build/scripts/base/bif/reporter.bif.bro + build/scripts/base/bif/plugins/Bro_SNMP.types.bif.bro build/scripts/base/bif/event.bif.bro build/scripts/base/bif/plugins/__load__.bro build/scripts/base/bif/plugins/Bro_ARP.events.bif.bro @@ -53,6 +54,7 @@ scripts/base/init-bare.bro build/scripts/base/bif/plugins/Bro_SMB.events.bif.bro build/scripts/base/bif/plugins/Bro_SMTP.events.bif.bro build/scripts/base/bif/plugins/Bro_SMTP.functions.bif.bro + build/scripts/base/bif/plugins/Bro_SNMP.events.bif.bro build/scripts/base/bif/plugins/Bro_SOCKS.events.bif.bro build/scripts/base/bif/plugins/Bro_SSH.events.bif.bro build/scripts/base/bif/plugins/Bro_SSL.events.bif.bro @@ -200,6 +202,8 @@ scripts/base/init-default.bro scripts/base/protocols/modbus/consts.bro scripts/base/protocols/modbus/main.bro scripts/base/protocols/pop3/__load__.bro + scripts/base/protocols/snmp/__load__.bro + scripts/base/protocols/snmp/main.bro scripts/base/protocols/smtp/__load__.bro scripts/base/protocols/smtp/main.bro scripts/base/protocols/smtp/entities.bro @@ -222,4 +226,4 @@ scripts/base/init-default.bro scripts/base/misc/find-checksum-offloading.bro scripts/base/misc/find-filtered-trace.bro scripts/policy/misc/loaded-scripts.bro -#close 2014-01-31-22-54-38 +#close 2014-02-18-18-10-44 diff --git a/testing/btest/Baseline/scripts.base.protocols.snmp.v1/out1 b/testing/btest/Baseline/scripts.base.protocols.snmp.v1/out1 new file mode 100644 index 0000000000..f564ee0c62 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.snmp.v1/out1 @@ -0,0 +1,598 @@ +snmp_get_request + [orig_h=172.31.19.54, orig_p=15916/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 38 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.2.0 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15916/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 38 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.2.0 + value (tag=0x06): 1.3.6.1.4.1.2001.1.1.1.297.93.1.27.2.2.1 +snmp_get_request + [orig_h=172.31.19.54, orig_p=15917/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 39 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.5.0 + value (tag=0x05): + oid: 1.3.6.1.2.1.1.6.0 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15917/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 39 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.5.0 + value (tag=0x04): B6300 + oid: 1.3.6.1.2.1.1.6.0 + value (tag=0x04): Chandra's cube +snmp_get_request + [orig_h=172.31.19.54, orig_p=15918/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 40 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.2.2.1.6.1 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15918/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 40 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.2.2.1.6.1 + value (tag=0x04): ^H\07^U\xe6\xbc +snmp_get_request + [orig_h=172.31.19.54, orig_p=15919/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 41 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.64.4.2.1.7.10.14130104 + value (tag=0x05): + oid: 1.3.6.1.4.1.253.8.64.4.2.1.7.10.14130102 + value (tag=0x05): + oid: 1.3.6.1.4.1.253.8.64.4.2.1.5.10.14130400 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15919/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 41 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.64.4.2.1.7.10.14130104 + value (tag=0x04): 172.31.19.2 + oid: 1.3.6.1.4.1.253.8.64.4.2.1.7.10.14130102 + value (tag=0x04): 255.255.255.0 + oid: 1.3.6.1.4.1.253.8.64.4.2.1.5.10.14130400 + value (tag=0x02): 1 +snmp_get_request + [orig_h=172.31.19.54, orig_p=15920/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 42 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.43.14.1.1.6.1.5 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15920/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 42 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.43.14.1.1.6.1.5 + value (tag=0x02): 3 +snmp_get_request + [orig_h=172.31.19.54, orig_p=15921/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 43 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.64.4.2.1.5.10.14150900 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15921/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 43 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.64.4.2.1.5.10.14150900 + value (tag=0x02): 1 +snmp_get_request + [orig_h=172.31.19.54, orig_p=15922/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 44 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.2.0 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15922/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 44 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.2.0 + value (tag=0x06): 1.3.6.1.4.1.2001.1.1.1.297.93.1.27.2.2.1 +snmp_get_request + [orig_h=172.31.19.54, orig_p=15923/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 45 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.5.0 + value (tag=0x05): + oid: 1.3.6.1.2.1.1.6.0 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15923/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 45 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.5.0 + value (tag=0x04): B6300 + oid: 1.3.6.1.2.1.1.6.0 + value (tag=0x04): Chandra's cube +snmp_get_request + [orig_h=172.31.19.54, orig_p=15924/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 46 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.2.2.1.6.1 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15924/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 46 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.2.2.1.6.1 + value (tag=0x04): ^H\07^U\xe6\xbc +snmp_get_request + [orig_h=172.31.19.54, orig_p=15925/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 47 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.64.4.2.1.7.10.14130104 + value (tag=0x05): + oid: 1.3.6.1.4.1.253.8.64.4.2.1.7.10.14130102 + value (tag=0x05): + oid: 1.3.6.1.4.1.253.8.64.4.2.1.5.10.14130400 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15925/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 47 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.64.4.2.1.7.10.14130104 + value (tag=0x04): 172.31.19.2 + oid: 1.3.6.1.4.1.253.8.64.4.2.1.7.10.14130102 + value (tag=0x04): 255.255.255.0 + oid: 1.3.6.1.4.1.253.8.64.4.2.1.5.10.14130400 + value (tag=0x02): 1 +snmp_get_request + [orig_h=172.31.19.54, orig_p=15926/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 48 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.43.14.1.1.6.1.5 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15926/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 48 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.43.14.1.1.6.1.5 + value (tag=0x02): 3 +snmp_get_request + [orig_h=172.31.19.54, orig_p=15927/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 49 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.64.4.2.1.5.10.14150900 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15927/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 49 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.64.4.2.1.5.10.14150900 + value (tag=0x02): 1 +snmp_get_request + [orig_h=172.31.19.54, orig_p=15928/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 50 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.2.0 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15928/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 50 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.2.0 + value (tag=0x06): 1.3.6.1.4.1.2001.1.1.1.297.93.1.27.2.2.1 +snmp_get_request + [orig_h=172.31.19.54, orig_p=15929/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 51 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.5.0 + value (tag=0x05): + oid: 1.3.6.1.2.1.1.6.0 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15929/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 51 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.5.0 + value (tag=0x04): B6300 + oid: 1.3.6.1.2.1.1.6.0 + value (tag=0x04): Chandra's cube +snmp_get_request + [orig_h=172.31.19.54, orig_p=15930/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 52 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.2.2.1.6.1 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15930/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 52 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.2.2.1.6.1 + value (tag=0x04): ^H\07^U\xe6\xbc +snmp_get_request + [orig_h=172.31.19.54, orig_p=15931/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 53 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.64.4.2.1.7.10.14130104 + value (tag=0x05): + oid: 1.3.6.1.4.1.253.8.64.4.2.1.7.10.14130102 + value (tag=0x05): + oid: 1.3.6.1.4.1.253.8.64.4.2.1.5.10.14130400 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15931/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 53 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.64.4.2.1.7.10.14130104 + value (tag=0x04): 172.31.19.2 + oid: 1.3.6.1.4.1.253.8.64.4.2.1.7.10.14130102 + value (tag=0x04): 255.255.255.0 + oid: 1.3.6.1.4.1.253.8.64.4.2.1.5.10.14130400 + value (tag=0x02): 1 +snmp_get_request + [orig_h=172.31.19.54, orig_p=15932/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 54 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.43.14.1.1.6.1.5 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15932/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 54 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.43.14.1.1.6.1.5 + value (tag=0x02): 3 +snmp_get_request + [orig_h=172.31.19.54, orig_p=15933/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 55 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.64.4.2.1.5.10.14150900 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15933/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 55 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.64.4.2.1.5.10.14150900 + value (tag=0x02): 1 +snmp_get_request + [orig_h=172.31.19.54, orig_p=15934/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 56 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.2.0 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15934/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 56 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.2.0 + value (tag=0x06): 1.3.6.1.4.1.2001.1.1.1.297.93.1.27.2.2.1 +snmp_get_request + [orig_h=172.31.19.54, orig_p=15935/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 57 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.51.8.1.3.0 + value (tag=0x05): + oid: 1.3.6.1.4.1.253.8.51.8.1.1.0 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15935/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 57 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.51.8.1.3.0 + value (tag=0x02): 0 + oid: 1.3.6.1.4.1.253.8.51.8.1.1.0 + value (tag=0x02): 300 +snmp_set_request + [orig_h=172.31.19.54, orig_p=15936/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 58 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.51.8.2.1.2.1 + value (tag=0x02): 4 + oid: 1.3.6.1.4.1.253.8.51.8.2.1.3.1 + value (tag=0x04): FujiXeroxExodus + oid: 1.3.6.1.4.1.253.8.51.8.2.1.4.1 + value (tag=0x06): 1.3.6.1.4.1.253.8.51.8.2 + oid: 1.3.6.1.4.1.253.8.51.8.2.1.5.1 + value (tag=0x02): 300 +snmp_response + [orig_h=172.31.19.54, orig_p=15936/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 58 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.51.8.2.1.2.1 + value (tag=0x02): 4 + oid: 1.3.6.1.4.1.253.8.51.8.2.1.3.1 + value (tag=0x04): FujiXeroxExodus + oid: 1.3.6.1.4.1.253.8.51.8.2.1.4.1 + value (tag=0x06): 1.3.6.1.4.1.253.8.51.8.2 + oid: 1.3.6.1.4.1.253.8.51.8.2.1.5.1 + value (tag=0x02): 300 +snmp_set_request + [orig_h=172.31.19.54, orig_p=15937/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 59 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.51.9.2.1.2.10.1 + value (tag=0x02): 6 +snmp_response + [orig_h=172.31.19.54, orig_p=15937/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 59 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.51.9.2.1.2.10.1 + value (tag=0x02): 6 +snmp_set_request + [orig_h=172.31.19.54, orig_p=15938/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 60 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.51.10.2.1.7.10.14130101 + value (tag=0x04): 172.31.19.73 + oid: 1.3.6.1.4.1.253.8.51.10.2.1.5.10.14130400 + value (tag=0x02): 2 + oid: 1.3.6.1.4.1.253.8.51.10.2.1.7.10.14130102 + value (tag=0x04): 255.255.255.0 + oid: 1.3.6.1.4.1.253.8.51.10.2.1.7.10.14130104 + value (tag=0x04): 172.31.19.2 +snmp_response + [orig_h=172.31.19.54, orig_p=15938/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 60 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.51.10.2.1.7.10.14130101 + value (tag=0x04): 172.31.19.73 + oid: 1.3.6.1.4.1.253.8.51.10.2.1.5.10.14130400 + value (tag=0x02): 2 + oid: 1.3.6.1.4.1.253.8.51.10.2.1.7.10.14130102 + value (tag=0x04): 255.255.255.0 + oid: 1.3.6.1.4.1.253.8.51.10.2.1.7.10.14130104 + value (tag=0x04): 172.31.19.2 +snmp_set_request + [orig_h=172.31.19.54, orig_p=15939/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 61 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.51.9.2.1.2.10.1 + value (tag=0x02): 4 + oid: 1.3.6.1.4.1.253.8.51.9.2.1.4.10.1 + value (tag=0x02): 4 + oid: 1.3.6.1.4.1.253.8.51.9.2.1.3.10.1 + value (tag=0x02): 10 +snmp_response + [orig_h=172.31.19.54, orig_p=15939/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 61 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.51.9.2.1.2.10.1 + value (tag=0x02): 4 + oid: 1.3.6.1.4.1.253.8.51.9.2.1.4.10.1 + value (tag=0x02): 4 + oid: 1.3.6.1.4.1.253.8.51.9.2.1.3.10.1 + value (tag=0x02): 10 +snmp_get_request + [orig_h=172.31.19.54, orig_p=15940/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 62 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.51.9.2.1.5.10.1 + value (tag=0x05): + oid: 1.3.6.1.4.1.253.8.51.9.2.1.6.10.1 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15940/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 62 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.51.9.2.1.5.10.1 + value (tag=0x02): 0 + oid: 1.3.6.1.4.1.253.8.51.9.2.1.6.10.1 + value (tag=0x02): 0 +snmp_set_request + [orig_h=172.31.19.54, orig_p=15941/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 63 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.51.9.2.1.4.10.1 + value (tag=0x02): 8 +snmp_response + [orig_h=172.31.19.54, orig_p=15941/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 63 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.4.1.253.8.51.9.2.1.4.10.1 + value (tag=0x02): 8 +snmp_get_request + [orig_h=172.31.19.54, orig_p=15942/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 64 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.3.0 + value (tag=0x05): +snmp_get_request + [orig_h=172.31.19.54, orig_p=15945/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 65 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.3.0 + value (tag=0x05): +snmp_get_request + [orig_h=172.31.19.54, orig_p=15952/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 66 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.3.0 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15952/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 66 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.3.0 + value (tag=0x43): 300 +snmp_get_request + [orig_h=172.31.19.54, orig_p=15953/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 67 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.2.0 + value (tag=0x05): +snmp_response + [orig_h=172.31.19.54, orig_p=15953/udp, resp_h=172.31.19.73, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 67 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.2.0 + value (tag=0x06): 1.3.6.1.4.1.2001.1.1.1.297.93.1.27.2.2.1 diff --git a/testing/btest/Baseline/scripts.base.protocols.snmp.v1/out2 b/testing/btest/Baseline/scripts.base.protocols.snmp.v1/out2 new file mode 100644 index 0000000000..743f18bbf1 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.snmp.v1/out2 @@ -0,0 +1,26 @@ +snmp_get_request + [orig_h=203.143.168.235, orig_p=1026/udp, resp_h=129.94.135.39, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 1567 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.25.3.2.1.5.1 + value (tag=0x05): + oid: 1.3.6.1.2.1.25.3.5.1.1.1 + value (tag=0x05): + oid: 1.3.6.1.2.1.25.3.5.1.2.1 + value (tag=0x05): +snmp_response + [orig_h=203.143.168.235, orig_p=1026/udp, resp_h=129.94.135.39, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 1567 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.25.3.2.1.5.1 + value (tag=0x02): 5 + oid: 1.3.6.1.2.1.25.3.5.1.1.1 + value (tag=0x02): 1 + oid: 1.3.6.1.2.1.25.3.5.1.2.1 + value (tag=0x04): \xc0 diff --git a/testing/btest/Baseline/scripts.base.protocols.snmp.v1/out3 b/testing/btest/Baseline/scripts.base.protocols.snmp.v1/out3 new file mode 100644 index 0000000000..b8319b67ec --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.snmp.v1/out3 @@ -0,0 +1,18 @@ +snmp_set_request + [orig_h=127.0.0.1, orig_p=63034/udp, resp_h=127.0.0.1, resp_p=161/udp] + is_orig: T + [community=] + request_id: 2064150121 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.5.0 + value (tag=0x04): musec +snmp_response + [orig_h=127.0.0.1, orig_p=63034/udp, resp_h=127.0.0.1, resp_p=161/udp] + is_orig: F + [community=] + request_id: 2064150121 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.5.0 + value (tag=0x05): diff --git a/testing/btest/Baseline/scripts.base.protocols.snmp.v1/out4 b/testing/btest/Baseline/scripts.base.protocols.snmp.v1/out4 new file mode 100644 index 0000000000..0854c7096c --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.snmp.v1/out4 @@ -0,0 +1,11 @@ +snmp_trap + [orig_h=127.0.0.1, orig_p=57150/udp, resp_h=127.0.0.1, resp_p=162/udp] + is_orig: T + [community=public] + enterprise: 1.3.6.1.4.1.31337.0 + agent: 1.0.0.127 + generic_trap: 0 + specific_trap: 0 + time_stamp: 0 + oid: 1.3.6.1.2.1.2.1.0 + value (tag=0x02): 33 diff --git a/testing/btest/Baseline/scripts.base.protocols.snmp.v2/out1 b/testing/btest/Baseline/scripts.base.protocols.snmp.v2/out1 new file mode 100644 index 0000000000..cb18518552 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.snmp.v2/out1 @@ -0,0 +1,18 @@ +snmp_get_request + [orig_h=10.10.1.159, orig_p=51217/udp, resp_h=10.10.3.109, resp_p=161/udp] + is_orig: T + [community=public] + request_id: 895734538 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.2.2.1.17.1 + value (tag=0x05): +snmp_response + [orig_h=10.10.1.159, orig_p=51217/udp, resp_h=10.10.3.109, resp_p=161/udp] + is_orig: F + [community=public] + request_id: 895734538 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.2.2.1.17.1 + value (tag=0x41): 854387 diff --git a/testing/btest/Baseline/scripts.base.protocols.snmp.v2/out2 b/testing/btest/Baseline/scripts.base.protocols.snmp.v2/out2 new file mode 100644 index 0000000000..0c1971c9f5 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.snmp.v2/out2 @@ -0,0 +1,18 @@ +snmp_get_bulk_request + [orig_h=127.0.0.1, orig_p=28456/udp, resp_h=127.0.0.1, resp_p=161/udp] + is_orig: T + [community=] + request_id: 1817072941 + non_repeaters: 0 + max_repititions: 0 + oid: 1.3.6.1.2.1.1.5.0 + value (tag=0x05): +snmp_response + [orig_h=127.0.0.1, orig_p=28456/udp, resp_h=127.0.0.1, resp_p=161/udp] + is_orig: F + [community=] + request_id: 1817072941 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.5.0 + value (tag=0x05): diff --git a/testing/btest/Baseline/scripts.base.protocols.snmp.v2/out3 b/testing/btest/Baseline/scripts.base.protocols.snmp.v2/out3 new file mode 100644 index 0000000000..4abbb8f819 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.snmp.v2/out3 @@ -0,0 +1,72 @@ +snmp_get_request + [orig_h=10.144.246.184, orig_p=33938/udp, resp_h=10.144.246.161, resp_p=161/udp] + is_orig: T + [community=[R0_C@cti!]] + request_id: 722681733 + error_stat: 0 + error_idx: 0 + oid: 0.1 + value (tag=0x05): +snmp_response + [orig_h=10.144.246.184, orig_p=33938/udp, resp_h=10.144.246.161, resp_p=161/udp] + is_orig: F + [community=[R0_C@cti!]] + request_id: 722681733 + error_stat: 0 + error_idx: 0 + oid: 1.0.8802.1.1.1.1.1.1.0 + value (tag=0x02): 2 +snmp_get_request + [orig_h=10.144.246.184, orig_p=43824/udp, resp_h=10.144.246.161, resp_p=161/udp] + is_orig: T + [community=[R0_C@cti!]] + request_id: 555232471 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.3.0 + value (tag=0x05): +snmp_response + [orig_h=10.144.246.184, orig_p=43824/udp, resp_h=10.144.246.161, resp_p=161/udp] + is_orig: F + [community=[R0_C@cti!]] + request_id: 555232471 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.3.0 + value (tag=0x43): 76705700 +snmp_get_request + [orig_h=10.144.246.184, orig_p=40807/udp, resp_h=10.144.246.161, resp_p=161/udp] + is_orig: T + [community=[R0_C@cti!]] + request_id: 349867006 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.31.1.1.1.10.1 + value (tag=0x05): +snmp_response + [orig_h=10.144.246.184, orig_p=40807/udp, resp_h=10.144.246.161, resp_p=161/udp] + is_orig: F + [community=[R0_C@cti!]] + request_id: 349867006 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.31.1.1.1.10.1 + value (tag=0x46): 2232821312 +snmp_get_request + [orig_h=10.144.246.184, orig_p=54059/udp, resp_h=10.144.246.161, resp_p=161/udp] + is_orig: T + [community=[R0_C@cti!]] + request_id: 107891391 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.31.1.1.1.6.1 + value (tag=0x05): +snmp_response + [orig_h=10.144.246.184, orig_p=54059/udp, resp_h=10.144.246.161, resp_p=161/udp] + is_orig: F + [community=[R0_C@cti!]] + request_id: 107891391 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.31.1.1.1.6.1 + value (tag=0x46): 12606463906 diff --git a/testing/btest/Baseline/scripts.base.protocols.snmp.v3/out1 b/testing/btest/Baseline/scripts.base.protocols.snmp.v3/out1 new file mode 100644 index 0000000000..20f6d45ab0 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.snmp.v3/out1 @@ -0,0 +1,34 @@ +snmp_get_request + [orig_h=127.0.0.1, orig_p=54211/udp, resp_h=127.0.0.1, resp_p=161/udp] + is_orig: T + [id=544943986, max_size=16384, flags=4, auth_flag=F, priv_flag=F, reportable_flag=T, security_model=3, security_params=0^N^D\0^B^A*^B^A*^D\0^D\0^D\0, pdu_context=[engine_id=, name=]] + request_id: 544943986 + error_stat: 0 + error_idx: 0 +snmp_report + [orig_h=127.0.0.1, orig_p=54211/udp, resp_h=127.0.0.1, resp_p=161/udp] + is_orig: F + [id=544943986, max_size=16384, flags=0, auth_flag=F, priv_flag=F, reportable_flag=F, security_model=3, security_params=0\x1b^D^M\x80\0\x1f\x88\x80\xa9I\x8e^:,0C^B^A\xdd^B^A\xdd^D\0^D\0^D\0, pdu_context=[engine_id=\x80\0\x1f\x88\x80\xa9I\x8e^:,0C, name=]] + request_id: 544943986 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.6.3.15.1.1.0 + value (tag=0x41): 3 +snmp_get_request + [orig_h=127.0.0.1, orig_p=54211/udp, resp_h=127.0.0.1, resp_p=161/udp] + is_orig: T + [id=544943986, max_size=16384, flags=4, auth_flag=F, priv_flag=F, reportable_flag=T, security_model=3, security_params=0/^D^M\x80\0\x1f\x88\x80\xa9I\x8e^:,0C^B^A\xdd^B^A\xdd^D^Husername^D^L\0\0\0\0\0\0\0\0\0\0\0\0^D\0, pdu_context=[engine_id=\x80\0\x1f\x88\x80\xa9I\x8e^:,0C, name=]] + request_id: 544943986 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.6.0 + value (tag=0x05): +snmp_response + [orig_h=127.0.0.1, orig_p=54211/udp, resp_h=127.0.0.1, resp_p=161/udp] + is_orig: F + [id=544943986, max_size=16384, flags=0, auth_flag=F, priv_flag=F, reportable_flag=F, security_model=3, security_params=0#^D^M\x80\0\x1f\x88\x80\xa9I\x8e^:,0C^B^A\xdd^B^A\xdd^D^Husername^D\0^D\0, pdu_context=[engine_id=\x80\0\x1f\x88\x80\xa9I\x8e^:,0C, name=]] + request_id: 544943986 + error_stat: 0 + error_idx: 0 + oid: 1.3.6.1.2.1.1.6.0 + value (tag=0x04): diff --git a/testing/btest/Traces/snmp/snmpv1_get.pcap b/testing/btest/Traces/snmp/snmpv1_get.pcap new file mode 100644 index 0000000000..de8505b529 Binary files /dev/null and b/testing/btest/Traces/snmp/snmpv1_get.pcap differ diff --git a/testing/btest/Traces/snmp/snmpv1_get_short.pcap b/testing/btest/Traces/snmp/snmpv1_get_short.pcap new file mode 100644 index 0000000000..a765af6640 Binary files /dev/null and b/testing/btest/Traces/snmp/snmpv1_get_short.pcap differ diff --git a/testing/btest/Traces/snmp/snmpv1_set.pcap b/testing/btest/Traces/snmp/snmpv1_set.pcap new file mode 100644 index 0000000000..dc0701408a Binary files /dev/null and b/testing/btest/Traces/snmp/snmpv1_set.pcap differ diff --git a/testing/btest/Traces/snmp/snmpv1_trap.pcap b/testing/btest/Traces/snmp/snmpv1_trap.pcap new file mode 100644 index 0000000000..e77219efd2 Binary files /dev/null and b/testing/btest/Traces/snmp/snmpv1_trap.pcap differ diff --git a/testing/btest/Traces/snmp/snmpv2_get.pcap b/testing/btest/Traces/snmp/snmpv2_get.pcap new file mode 100644 index 0000000000..705af973ba Binary files /dev/null and b/testing/btest/Traces/snmp/snmpv2_get.pcap differ diff --git a/testing/btest/Traces/snmp/snmpv2_get_bulk.pcap b/testing/btest/Traces/snmp/snmpv2_get_bulk.pcap new file mode 100644 index 0000000000..5099c7a323 Binary files /dev/null and b/testing/btest/Traces/snmp/snmpv2_get_bulk.pcap differ diff --git a/testing/btest/Traces/snmp/snmpv2_get_next.pcap b/testing/btest/Traces/snmp/snmpv2_get_next.pcap new file mode 100644 index 0000000000..d3c6c2b987 Binary files /dev/null and b/testing/btest/Traces/snmp/snmpv2_get_next.pcap differ diff --git a/testing/btest/Traces/snmp/snmpv3_get_next.pcap b/testing/btest/Traces/snmp/snmpv3_get_next.pcap new file mode 100644 index 0000000000..13ed2e7646 Binary files /dev/null and b/testing/btest/Traces/snmp/snmpv3_get_next.pcap differ diff --git a/testing/btest/scripts/base/protocols/snmp/v1.bro b/testing/btest/scripts/base/protocols/snmp/v1.bro new file mode 100644 index 0000000000..7dd5bd4a68 --- /dev/null +++ b/testing/btest/scripts/base/protocols/snmp/v1.bro @@ -0,0 +1,11 @@ +# @TEST-EXEC: bro -b -r $TRACES/snmp/snmpv1_get.pcap %INPUT $SCRIPTS/snmp-test.bro >out1 +# @TEST-EXEC: bro -b -r $TRACES/snmp/snmpv1_get_short.pcap %INPUT $SCRIPTS/snmp-test.bro >out2 +# @TEST-EXEC: bro -b -r $TRACES/snmp/snmpv1_set.pcap %INPUT $SCRIPTS/snmp-test.bro >out3 +# @TEST-EXEC: bro -b -r $TRACES/snmp/snmpv1_trap.pcap %INPUT $SCRIPTS/snmp-test.bro >out4 + +# @TEST-EXEC: btest-diff out1 +# @TEST-EXEC: btest-diff out2 +# @TEST-EXEC: btest-diff out3 +# @TEST-EXEC: btest-diff out4 + +@load base/protocols/snmp diff --git a/testing/btest/scripts/base/protocols/snmp/v2.bro b/testing/btest/scripts/base/protocols/snmp/v2.bro new file mode 100644 index 0000000000..a2b9885fbb --- /dev/null +++ b/testing/btest/scripts/base/protocols/snmp/v2.bro @@ -0,0 +1,9 @@ +# @TEST-EXEC: bro -b -r $TRACES/snmp/snmpv2_get.pcap %INPUT $SCRIPTS/snmp-test.bro >out1 +# @TEST-EXEC: bro -b -r $TRACES/snmp/snmpv2_get_bulk.pcap %INPUT $SCRIPTS/snmp-test.bro >out2 +# @TEST-EXEC: bro -b -r $TRACES/snmp/snmpv2_get_next.pcap %INPUT $SCRIPTS/snmp-test.bro >out3 + +# @TEST-EXEC: btest-diff out1 +# @TEST-EXEC: btest-diff out2 +# @TEST-EXEC: btest-diff out3 + +@load base/protocols/snmp diff --git a/testing/btest/scripts/base/protocols/snmp/v3.bro b/testing/btest/scripts/base/protocols/snmp/v3.bro new file mode 100644 index 0000000000..43edbdc2df --- /dev/null +++ b/testing/btest/scripts/base/protocols/snmp/v3.bro @@ -0,0 +1,5 @@ +# @TEST-EXEC: bro -b -r $TRACES/snmp/snmpv3_get_next.pcap %INPUT $SCRIPTS/snmp-test.bro >out1 + +# @TEST-EXEC: btest-diff out1 + +@load base/protocols/snmp diff --git a/testing/scripts/snmp-test.bro b/testing/scripts/snmp-test.bro new file mode 100644 index 0000000000..399935db4c --- /dev/null +++ b/testing/scripts/snmp-test.bro @@ -0,0 +1,208 @@ + +function format_snmp_val(tag: count, s: string): string + { + return fmt(" value (tag=0x%02x): %s", tag, s); + } + +function print_snmp_value(val: SNMP::ObjectValue) + { + switch ( val$tag ) { + case SNMP::OBJ_OID_TAG: + print format_snmp_val(val$tag, fmt("%s", val$oid)); + break; + + case SNMP::OBJ_INTEGER_TAG: + print format_snmp_val(val$tag, fmt("%s", val$signed)); + break; + + case SNMP::OBJ_COUNTER32_TAG, + SNMP::OBJ_UNSIGNED32_TAG, + SNMP::OBJ_TIMETICKS_TAG, + SNMP::OBJ_COUNTER64_TAG: + print format_snmp_val(val$tag, fmt("%s", val$unsigned)); + break; + + case SNMP::OBJ_IPADDRESS_TAG: + print format_snmp_val(val$tag, fmt("%s", val$address)); + break; + + case SNMP::OBJ_OCTETSTRING_TAG, + SNMP::OBJ_OPAQUE_TAG: + print format_snmp_val(val$tag, fmt("%s", val$octets)); + break; + + case SNMP::OBJ_UNSPECIFIED_TAG: + print format_snmp_val(val$tag, fmt("%s", "")); + break; + + case SNMP::OBJ_NOSUCHOBJECT_TAG: + print format_snmp_val(val$tag, fmt("%s", "")); + break; + + case SNMP::OBJ_NOSUCHINSTANCE_TAG: + print format_snmp_val(val$tag, fmt("%s", "")); + break; + + case SNMP::OBJ_ENDOFMIBVIEW_TAG: + print format_snmp_val(val$tag, fmt("%s", "")); + break; + + default: + print format_snmp_val(val$tag, ""); + break; + } + } + +function print_snmp_binding(binding: SNMP::Binding) + { + print fmt(" oid: %s", binding$oid); + print_snmp_value(binding$value); + } + +function print_snmp_bindings(bindings: SNMP::Bindings) + { + for ( i in bindings ) + print_snmp_binding(bindings[i]); + } + +function print_snmp_pdu(pdu: SNMP::PDU) + { + print fmt(" request_id: %s", pdu$request_id); + print fmt(" error_stat: %s", pdu$error_status); + print fmt(" error_idx: %s", pdu$error_index); + print_snmp_bindings(pdu$bindings); + } + +function print_snmp_trap_pdu(pdu: SNMP::TrapPDU) + { + print fmt(" enterprise: %s", pdu$enterprise); + print fmt(" agent: %s", pdu$agent); + print fmt(" generic_trap: %s", pdu$generic_trap); + print fmt(" specific_trap: %s", pdu$specific_trap); + print fmt(" time_stamp: %s", pdu$time_stamp); + print_snmp_bindings(pdu$bindings); + } + +function print_snmp_bulk_pdu(pdu: SNMP::BulkPDU) + { + print fmt(" request_id: %s", pdu$request_id); + print fmt(" non_repeaters: %s", pdu$non_repeaters); + print fmt(" max_repititions: %s", pdu$max_repititions); + print_snmp_bindings(pdu$bindings); + } + +function print_snmp_conn(c: connection, is_orig: bool) + { + print fmt(" %s", c$id); + print fmt(" is_orig: %s", is_orig); + } + +function print_snmp_header(header: SNMP::Header) + { + switch ( header$version ) { + case 0: + print fmt(" %s", header$v1); + break; + + case 1: + print fmt(" %s", header$v2); + break; + + case 3: + print fmt(" %s", header$v3); + break; + + default: + break; + } + } + +function print_snmp(msg: string, c: connection, is_orig: bool, + header: SNMP::Header, pdu: SNMP::PDU) + { + print msg; + print_snmp_conn(c, is_orig); + print_snmp_header(header); + print_snmp_pdu(pdu); + } + +event snmp_get_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) + { + print_snmp("snmp_get_request", c, is_orig, header, pdu); + } + +event snmp_get_next_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) + { + print_snmp("snmp_get_request", c, is_orig, header, pdu); + } + +event snmp_response(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) + { + print_snmp("snmp_response", c, is_orig, header, pdu); + } + +event snmp_set_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) + { + print_snmp("snmp_set_request", c, is_orig, header, pdu); + } + +event snmp_trap(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::TrapPDU) + { + print "snmp_trap"; + print_snmp_conn(c, is_orig); + print_snmp_header(header); + print_snmp_trap_pdu(pdu); + } + +event snmp_get_bulk_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::BulkPDU) + { + print "snmp_get_bulk_request"; + print_snmp_conn(c, is_orig); + print_snmp_header(header); + print_snmp_bulk_pdu(pdu); + } + +event snmp_inform_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) + { + print_snmp("snmp_inform_request", c, is_orig, header, pdu); + } + +event snmp_trapV2(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) + { + print_snmp("snmp_trapv2", c, is_orig, header, pdu); + } + +event snmp_report(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) + { + print_snmp("snmp_report", c, is_orig, header, pdu); + } + +event snmp_unknown_pdu(c: connection, is_orig: bool, header: SNMP::Header, tag: count) + { + print "snmp_unknown_pdu"; + print_snmp_conn(c, is_orig); + print_snmp_header(header); + print fmt(" tag: %s", tag); + } + +event snmp_unknown_scoped_pdu(c: connection, is_orig: bool, header: SNMP::Header, tag: count) + { + print "snmp_unknown_scoped_pdu"; + print_snmp_conn(c, is_orig); + print_snmp_header(header); + print fmt(" tag: %s", tag); + } + +event snmp_encrypted_pdu(c: connection, is_orig: bool, header: SNMP::Header) + { + print "snmp_encrypted_pdu"; + print_snmp_conn(c, is_orig); + print_snmp_header(header); + } + +event snmp_unknown_header_version(c: connection, is_orig: bool, version: count) + { + print "snmp_unknown_header_version"; + print_snmp_conn(c, is_orig); + print fmt(" version %s", version); + }