2005-12-04 21:45:38 +00:00
/* 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
2006-05-23 15:17:14 +00:00
* Updated to use the asn2wrs compiler made by Tomas Kukosa
2006-03-15 06:20:23 +00:00
* Copyright ( C ) 2005 - 2006 Anders Broman [ AT ] ericsson . com
2005-12-04 21:45:38 +00:00
*
2007-01-09 18:38:55 +00:00
* See RFC 3414 for User - based Security Model for SNMPv3
2007-01-10 02:30:22 +00:00
* See RFC 3826 for ( AES ) Cipher Algorithm in the SNMP USM
2007-08-25 01:14:24 +00:00
* See RFC 2578 for Structure of Management Information Version 2 ( SMIv2 )
2008-08-05 21:03:46 +00:00
* Copyright ( C ) 2007 Luis E . Garcia Ontanon < luis @ ontanon . org >
2005-12-04 21:45:38 +00:00
*
2006-05-21 05:12:17 +00:00
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . org >
2005-12-04 21:45:38 +00:00
* 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
*
2018-02-12 11:23:27 +00:00
* SPDX - License - Identifier : GPL - 2.0 - or - later
2005-12-04 21:45:38 +00:00
*/
2014-12-23 05:32:58 +00:00
#if 0
# include <stdio.h>
2007-08-21 21:32:00 +00:00
# define D(args) do {printf args; fflush(stdout); } while(0)
2014-12-23 05:32:58 +00:00
# endif
2007-08-21 21:32:00 +00:00
2012-09-20 01:29:52 +00:00
# include "config.h"
2005-12-04 21:45:38 +00:00
# include <epan/packet.h>
2006-03-15 06:20:23 +00:00
# include <epan/strutil.h>
2005-12-04 21:45:38 +00:00
# include <epan/conversation.h>
2009-08-21 20:32:50 +00:00
# include <epan/etypes.h>
2005-12-04 21:45:38 +00:00
# include <epan/prefs.h>
2017-06-24 13:25:41 +00:00
# include <epan/addr_resolv.h>
2006-06-13 13:21:12 +00:00
# include <epan/next_tvb.h>
2007-02-07 14:54:35 +00:00
# include <epan/uat.h>
2007-05-13 20:58:29 +00:00
# include <epan/asn1.h>
2013-08-01 23:34:47 +00:00
# include <epan/expert.h>
# include <epan/oids.h>
2019-11-05 22:32:50 +00:00
# include <epan/srt_table.h>
# include <epan/tap.h>
2014-12-23 05:32:58 +00:00
# include "packet-ipx.h"
# include "packet-hpext.h"
2005-12-04 21:45:38 +00:00
# include "packet-ber.h"
# include "packet-snmp.h"
2013-02-21 18:23:29 +00:00
# include <wsutil/wsgcrypt.h>
2007-01-09 18:38:55 +00:00
2005-12-04 21:45:38 +00:00
# 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
2007-08-28 15:18:32 +00:00
# define UDP_PORT_SNMP_PATROL 8161
2019-11-05 22:32:50 +00:00
# define SNMP_NUM_PROCEDURES 8
2005-12-04 21:45:38 +00:00
/* Initialize the protocol and registered fields */
2019-11-05 22:32:50 +00:00
static int snmp_tap = - 1 ;
2005-12-04 21:45:38 +00:00
static int proto_snmp = - 1 ;
static int proto_smux = - 1 ;
static gboolean display_oid = TRUE ;
2007-11-12 18:44:29 +00:00
static gboolean snmp_var_in_tree = TRUE ;
2007-02-07 14:54:35 +00:00
2013-03-20 05:59:22 +00:00
void proto_register_snmp ( void ) ;
void proto_reg_handoff_snmp ( void ) ;
void proto_register_smux ( void ) ;
void proto_reg_handoff_smux ( void ) ;
2017-07-30 14:07:43 +00:00
static void snmp_usm_password_to_key ( const snmp_usm_auth_model_t model , const guint8 * password , guint passwordlen ,
const guint8 * engineID , guint engineLength , guint8 * key ) ;
2007-02-07 14:54:35 +00:00
2016-07-20 21:54:35 +00:00
static tvbuff_t * snmp_usm_priv_des ( snmp_usm_params_t * , tvbuff_t * , packet_info * pinfo , gchar const * * ) ;
static tvbuff_t * snmp_usm_priv_aes128 ( snmp_usm_params_t * , tvbuff_t * , packet_info * pinfo , gchar const * * ) ;
static tvbuff_t * snmp_usm_priv_aes192 ( snmp_usm_params_t * , tvbuff_t * , packet_info * pinfo , gchar const * * ) ;
static tvbuff_t * snmp_usm_priv_aes256 ( snmp_usm_params_t * , tvbuff_t * , packet_info * pinfo , gchar const * * ) ;
2007-02-07 14:54:35 +00:00
2021-08-23 21:41:43 +00:00
static gboolean snmp_usm_auth ( const packet_info * pinfo , const snmp_usm_auth_model_t model , snmp_usm_params_t * p , guint8 * * , guint * , gchar const * * ) ;
2007-02-07 14:54:35 +00:00
2017-07-30 14:07:43 +00:00
static const value_string auth_types [ ] = {
{ SNMP_USM_AUTH_MD5 , " MD5 " } ,
{ SNMP_USM_AUTH_SHA1 , " SHA1 " } ,
{ SNMP_USM_AUTH_SHA2_224 , " SHA2-224 " } ,
{ SNMP_USM_AUTH_SHA2_256 , " SHA2-256 " } ,
{ SNMP_USM_AUTH_SHA2_384 , " SHA2-384 " } ,
{ SNMP_USM_AUTH_SHA2_512 , " SHA2-512 " } ,
{ 0 , NULL }
} ;
2007-02-07 14:54:35 +00:00
2017-07-30 14:07:43 +00:00
static const guint auth_hash_len [ ] = {
HASH_MD5_LENGTH ,
HASH_SHA1_LENGTH ,
HASH_SHA2_224_LENGTH ,
HASH_SHA2_256_LENGTH ,
HASH_SHA2_384_LENGTH ,
HASH_SHA2_512_LENGTH
} ;
2007-02-07 14:54:35 +00:00
2017-07-30 14:07:43 +00:00
static const guint auth_tag_len [ ] = {
12 ,
12 ,
16 ,
24 ,
32 ,
48
} ;
2007-02-07 14:54:35 +00:00
2017-07-30 14:07:43 +00:00
static const enum gcry_md_algos auth_hash_algo [ ] = {
GCRY_MD_MD5 ,
GCRY_MD_SHA1 ,
GCRY_MD_SHA224 ,
GCRY_MD_SHA256 ,
GCRY_MD_SHA384 ,
GCRY_MD_SHA512
2007-02-07 14:54:35 +00:00
} ;
2014-08-11 07:35:11 +00:00
# define PRIV_DES 0
2014-08-13 06:51:20 +00:00
# define PRIV_AES128 1
# define PRIV_AES192 2
# define PRIV_AES256 3
2007-02-07 14:54:35 +00:00
2009-04-21 05:33:32 +00:00
static const value_string priv_types [ ] = {
2013-02-26 11:38:39 +00:00
{ PRIV_DES , " DES " } ,
{ PRIV_AES128 , " AES " } ,
{ PRIV_AES192 , " AES192 " } ,
{ PRIV_AES256 , " AES256 " } ,
{ 0 , NULL }
2007-02-07 14:54:35 +00:00
} ;
2013-02-26 11:38:39 +00:00
static snmp_usm_decoder_t priv_protos [ ] = {
snmp_usm_priv_des ,
snmp_usm_priv_aes128 ,
snmp_usm_priv_aes192 ,
snmp_usm_priv_aes256
2013-02-16 02:10:50 +00:00
} ;
2007-02-07 14:54:35 +00:00
static snmp_ue_assoc_t * ueas = NULL ;
static guint num_ueas = 0 ;
2007-01-11 00:29:50 +00:00
static snmp_ue_assoc_t * localized_ues = NULL ;
static snmp_ue_assoc_t * unlocalized_ues = NULL ;
2007-02-07 14:54:35 +00:00
/****/
2016-02-03 23:02:08 +00:00
/* Variables used for handling enterprise specific trap types */
2009-11-01 18:45:43 +00:00
typedef struct _snmp_st_assoc_t {
char * enterprise ;
guint trap ;
char * desc ;
} snmp_st_assoc_t ;
static guint num_specific_traps = 0 ;
static snmp_st_assoc_t * specific_traps = NULL ;
2009-11-09 13:03:15 +00:00
static const char * enterprise_oid = NULL ;
2009-11-01 18:45:43 +00:00
static guint generic_trap = 0 ;
2014-08-29 17:36:59 +00:00
static guint32 snmp_version = 0 ;
2019-11-05 22:32:50 +00:00
static guint32 RequestID = - 1 ;
2007-01-11 00:29:50 +00:00
static snmp_usm_params_t usm_p = { FALSE , FALSE , 0 , 0 , 0 , 0 , NULL , NULL , NULL , NULL , NULL , NULL , NULL , FALSE } ;
2007-01-09 18:38:55 +00:00
2005-12-04 21:45:38 +00:00
# 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 ;
2006-03-15 06:20:23 +00:00
tvbuff_t * oid_tvb = NULL ;
2006-06-13 13:21:12 +00:00
tvbuff_t * value_tvb = NULL ;
2005-12-04 21:45:38 +00:00
static dissector_handle_t snmp_handle ;
static dissector_handle_t data_handle ;
2021-09-07 18:33:39 +00:00
static next_tvb_list_t * var_list ;
2006-06-13 13:21:12 +00:00
2019-11-05 22:32:50 +00:00
static int hf_snmp_response_in = - 1 ;
static int hf_snmp_response_to = - 1 ;
static int hf_snmp_time = - 1 ;
2005-12-04 21:45:38 +00:00
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 ;
2010-03-05 20:09:37 +00:00
static int hf_snmp_engineid_cisco_type = - 1 ;
2005-12-04 21:45:38 +00:00
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 ;
2007-01-09 18:38:55 +00:00
static int hf_snmp_decryptedPDU = - 1 ;
static int hf_snmp_msgAuthentication = - 1 ;
2007-08-19 23:00:47 +00:00
2007-08-23 19:45:31 +00:00
static int hf_snmp_noSuchObject = - 1 ;
static int hf_snmp_noSuchInstance = - 1 ;
static int hf_snmp_endOfMibView = - 1 ;
static int hf_snmp_unSpecified = - 1 ;
2007-08-19 23:00:47 +00:00
static int hf_snmp_integer32_value = - 1 ;
2008-03-09 11:24:37 +00:00
static int hf_snmp_octetstring_value = - 1 ;
2007-08-19 23:00:47 +00:00
static int hf_snmp_oid_value = - 1 ;
static int hf_snmp_null_value = - 1 ;
static int hf_snmp_ipv4_value = - 1 ;
static int hf_snmp_ipv6_value = - 1 ;
static int hf_snmp_anyaddress_value = - 1 ;
static int hf_snmp_unsigned32_value = - 1 ;
static int hf_snmp_unknown_value = - 1 ;
static int hf_snmp_opaque_value = - 1 ;
static int hf_snmp_nsap_value = - 1 ;
static int hf_snmp_counter_value = - 1 ;
static int hf_snmp_timeticks_value = - 1 ;
static int hf_snmp_big_counter_value = - 1 ;
static int hf_snmp_gauge32_value = - 1 ;
2007-08-23 19:45:31 +00:00
2007-08-19 23:00:47 +00:00
static int hf_snmp_objectname = - 1 ;
2007-08-23 19:45:31 +00:00
static int hf_snmp_scalar_instance_index = - 1 ;
2013-06-04 20:05:16 +00:00
static int hf_snmp_var_bind_str = - 1 ;
2014-08-08 13:19:29 +00:00
static int hf_snmp_agentid_trailer = - 1 ;
2006-03-15 06:20:23 +00:00
2005-12-04 21:45:38 +00:00
# include "packet-snmp-hf.c"
/* Initialize the subtree pointers */
static gint ett_smux = - 1 ;
static gint ett_snmp = - 1 ;
static gint ett_engineid = - 1 ;
static gint ett_msgFlags = - 1 ;
2007-01-09 18:38:55 +00:00
static gint ett_encryptedPDU = - 1 ;
static gint ett_decrypted = - 1 ;
static gint ett_authParameters = - 1 ;
2007-04-05 22:16:12 +00:00
static gint ett_internet = - 1 ;
2007-08-19 23:00:47 +00:00
static gint ett_varbind = - 1 ;
2007-08-23 19:45:31 +00:00
static gint ett_name = - 1 ;
2007-08-28 15:18:32 +00:00
static gint ett_value = - 1 ;
2007-08-19 23:00:47 +00:00
static gint ett_decoding_error = - 1 ;
2005-12-04 21:45:38 +00:00
# include "packet-snmp-ett.c"
2013-06-03 03:42:36 +00:00
static expert_field ei_snmp_failed_decrypted_data_pdu = EI_INIT ;
static expert_field ei_snmp_decrypted_data_bad_formatted = EI_INIT ;
static expert_field ei_snmp_verify_authentication_error = EI_INIT ;
static expert_field ei_snmp_authentication_ok = EI_INIT ;
static expert_field ei_snmp_authentication_error = EI_INIT ;
static expert_field ei_snmp_varbind_not_uni_class_seq = EI_INIT ;
static expert_field ei_snmp_varbind_has_indicator = EI_INIT ;
static expert_field ei_snmp_objectname_not_oid = EI_INIT ;
static expert_field ei_snmp_objectname_has_indicator = EI_INIT ;
static expert_field ei_snmp_value_not_primitive_encoding = EI_INIT ;
static expert_field ei_snmp_invalid_oid = EI_INIT ;
static expert_field ei_snmp_varbind_wrong_tag = EI_INIT ;
static expert_field ei_snmp_varbind_response = EI_INIT ;
static expert_field ei_snmp_no_instance_subid = EI_INIT ;
static expert_field ei_snmp_wrong_num_of_subids = EI_INIT ;
static expert_field ei_snmp_index_suboid_too_short = EI_INIT ;
static expert_field ei_snmp_unimplemented_instance_index = EI_INIT ;
static expert_field ei_snmp_index_suboid_len0 = EI_INIT ;
static expert_field ei_snmp_index_suboid_too_long = EI_INIT ;
static expert_field ei_snmp_index_string_too_long = EI_INIT ;
static expert_field ei_snmp_column_parent_not_row = EI_INIT ;
static expert_field ei_snmp_uint_too_large = EI_INIT ;
static expert_field ei_snmp_int_too_large = EI_INIT ;
static expert_field ei_snmp_integral_value0 = EI_INIT ;
static expert_field ei_snmp_missing_mib = EI_INIT ;
static expert_field ei_snmp_varbind_wrong_length_value = EI_INIT ;
static expert_field ei_snmp_varbind_wrong_class_tag = EI_INIT ;
2014-08-08 13:19:29 +00:00
static expert_field ei_snmp_rfc1910_non_conformant = EI_INIT ;
static expert_field ei_snmp_rfc3411_non_conformant = EI_INIT ;
static expert_field ei_snmp_version_unknown = EI_INIT ;
2014-08-29 17:36:59 +00:00
static expert_field ei_snmp_trap_pdu_obsolete = EI_INIT ;
2013-06-03 03:42:36 +00:00
2007-01-09 18:38:55 +00:00
static const true_false_string auth_flags = {
" OK " ,
" Failed "
} ;
2005-12-04 21:45:38 +00:00
/* Security Models */
# define SNMP_SEC_ANY 0
2014-08-11 07:35:11 +00:00
# define SNMP_SEC_V1 1
2005-12-04 21:45:38 +00:00
# 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 }
} ;
2014-11-08 17:01:25 +00:00
#if 0
2005-12-04 21:45:38 +00:00
/* 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 }
} ;
2014-11-08 17:01:25 +00:00
# endif
2005-12-04 21:45:38 +00:00
2019-11-05 22:32:50 +00:00
/* Procedure names (used in Service Response Time) */
const value_string snmp_procedure_names [ ] = {
{ 0 , " Get " } ,
{ 1 , " GetNext " } ,
{ 3 , " Set " } ,
2019-11-07 15:38:25 +00:00
{ 4 , " Register " } ,
2019-11-05 22:32:50 +00:00
{ 5 , " Bulk " } ,
{ 6 , " Inform " } ,
{ 0 , NULL }
} ;
2006-03-15 06:20:23 +00:00
# define SNMP_IPA 0 /* IP Address */
# define SNMP_CNT 1 /* Counter (Counter32) */
# define SNMP_GGE 2 /* Gauge (Gauge32) */
# define SNMP_TIT 3 /* TimeTicks */
# define SNMP_OPQ 4 /* Opaque */
# define SNMP_NSP 5 /* NsapAddress */
# define SNMP_C64 6 /* Counter64 */
# define SNMP_U32 7 /* Uinteger32 */
# define SERR_NSO 0
# define SERR_NSI 1
# define SERR_EOM 2
2007-08-27 17:05:11 +00:00
dissector_table_t value_sub_dissectors_table ;
2019-11-05 22:32:50 +00:00
/*
* Data structure attached to a conversation , request / response information
*/
typedef struct snmp_conv_info_t {
wmem_map_t * request_response ;
} snmp_conv_info_t ;
static snmp_request_response_t *
snmp_get_request_response_pointer ( wmem_map_t * map , guint32 requestId )
{
snmp_request_response_t * srrp = ( snmp_request_response_t * ) wmem_map_lookup ( map , & requestId ) ;
if ( ! srrp ) {
srrp = wmem_new0 ( wmem_file_scope ( ) , snmp_request_response_t ) ;
srrp - > requestId = requestId ;
wmem_map_insert ( map , & ( srrp - > requestId ) , ( void * ) srrp ) ;
}
return srrp ;
}
static snmp_request_response_t *
snmp_match_request_response ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , guint requestId , guint procedure_id , snmp_conv_info_t * snmp_info )
{
snmp_request_response_t * srrp = NULL ;
DISSECTOR_ASSERT_HINT ( snmp_info , " No SNMP info from ASN1 context " ) ;
/* get or create request/response pointer based on request id */
srrp = ( snmp_request_response_t * ) snmp_get_request_response_pointer ( snmp_info - > request_response , requestId ) ;
// if not visited fill the request/response data
2019-11-07 15:38:25 +00:00
if ( ! PINFO_FD_VISITED ( pinfo ) ) {
2019-11-05 22:32:50 +00:00
switch ( procedure_id )
{
case SNMP_REQ_GET :
case SNMP_REQ_GETNEXT :
case SNMP_REQ_SET :
case SNMP_REQ_GETBULK :
case SNMP_REQ_INFORM :
srrp - > request_frame_id = pinfo - > fd - > num ;
srrp - > response_frame_id = 0 ;
srrp - > request_time = pinfo - > abs_ts ;
srrp - > request_procedure_id = procedure_id ;
break ;
case SNMP_RES_GET :
srrp - > response_frame_id = pinfo - > fd - > num ;
break ;
default :
return NULL ;
}
}
/* if request and response was matched */
if ( srrp - > request_frame_id ! = 0 & & srrp - > response_frame_id ! = 0 )
{
proto_item * it ;
// if it is a request
if ( srrp - > request_frame_id = = pinfo - > fd - > num )
{
it = proto_tree_add_uint ( tree , hf_snmp_response_in , tvb , 0 , 0 , srrp - > response_frame_id ) ;
proto_item_set_generated ( it ) ;
} else {
nstime_t ns ;
it = proto_tree_add_uint ( tree , hf_snmp_response_to , tvb , 0 , 0 , srrp - > request_frame_id ) ;
proto_item_set_generated ( it ) ;
nstime_delta ( & ns , & pinfo - > abs_ts , & srrp - > request_time ) ;
it = proto_tree_add_time ( tree , hf_snmp_time , tvb , 0 , 0 , & ns ) ;
proto_item_set_generated ( it ) ;
return srrp ;
}
}
return NULL ;
}
static void
snmpstat_init ( struct register_srt * srt _U_ , GArray * srt_array )
{
srt_stat_table * snmp_srt_table ;
guint32 i ;
snmp_srt_table = init_srt_table ( " SNMP Commands " , NULL , srt_array , SNMP_NUM_PROCEDURES , NULL , " snmp.data " , NULL ) ;
for ( i = 0 ; i < SNMP_NUM_PROCEDURES ; i + + )
{
init_srt_table_row ( snmp_srt_table , i , val_to_str_const ( i , snmp_procedure_names , " <unknown> " ) ) ;
}
}
/* This is called only if request and response was matched -> no need to return anything than TAP_PACKET_REDRAW */
static tap_packet_status
2022-06-09 15:47:35 +00:00
snmpstat_packet ( void * psnmp , packet_info * pinfo , epan_dissect_t * edt _U_ , const void * psi , tap_flags_t flags _U_ )
2019-11-05 22:32:50 +00:00
{
guint i = 0 ;
srt_stat_table * snmp_srt_table ;
const snmp_request_response_t * snmp = ( const snmp_request_response_t * ) psi ;
srt_data_t * data = ( srt_data_t * ) psnmp ;
snmp_srt_table = g_array_index ( data - > srt_array , srt_stat_table * , i ) ;
add_srt_table_data ( snmp_srt_table , snmp - > request_procedure_id , & snmp - > request_time , pinfo ) ;
return TAP_PACKET_REDRAW ;
}
2009-11-01 18:45:43 +00:00
static const gchar *
snmp_lookup_specific_trap ( guint specific_trap )
{
guint i ;
2009-12-21 21:06:01 +00:00
2009-11-01 18:45:43 +00:00
for ( i = 0 ; i < num_specific_traps ; i + + ) {
snmp_st_assoc_t * u = & ( specific_traps [ i ] ) ;
if ( ( u - > trap = = specific_trap ) & &
( strcmp ( u - > enterprise , enterprise_oid ) = = 0 ) )
{
return u - > desc ;
}
}
return NULL ;
}
2013-06-04 20:05:16 +00:00
static int
dissect_snmp_variable_string ( tvbuff_t * tvb , packet_info * pinfo _U_ , proto_tree * tree , void * data _U_ )
{
2022-03-28 12:24:53 +00:00
proto_tree_add_item ( tree , hf_snmp_var_bind_str , tvb , 0 , - 1 , ENC_ASCII ) ;
2013-06-04 20:05:16 +00:00
2014-06-21 00:36:59 +00:00
return tvb_captured_length ( tvb ) ;
2013-06-04 20:05:16 +00:00
}
2013-06-12 15:08:08 +00:00
/*
DateAndTime : : = TEXTUAL - CONVENTION
DISPLAY - HINT " 2d-1d-1d,1d:1d:1d.1d,1a1d:1d "
STATUS current
DESCRIPTION
" A date-time specification.
field octets contents range
- - - - - - - - - - - - - - - - - - - - - - - -
1 1 - 2 year * 0. .65536
2 3 month 1. .12
3 4 day 1. .31
4 5 hour 0. .23
5 6 minutes 0. .59
6 7 seconds 0. .60
( use 60 for leap - second )
7 8 deci - seconds 0. .9
8 9 direction from UTC ' + ' / ' - '
9 10 hours from UTC * 0. .13
10 11 minutes from UTC 0. .59
* Notes :
- the value of year is in network - byte order
- daylight saving time in New Zealand is + 13
For example , Tuesday May 26 , 1992 at 1 : 30 : 15 PM EDT would be
displayed as :
1992 - 5 - 26 , 13 : 30 : 15.0 , - 4 : 0
Note that if only local time is known , then timezone
information ( fields 8 - 10 ) is not present . "
SYNTAX OCTET STRING ( SIZE ( 8 | 11 ) )
2014-08-11 07:35:11 +00:00
*/
2013-06-12 15:08:08 +00:00
static proto_item *
2021-08-23 21:41:43 +00:00
dissect_snmp_variable_date_and_time ( proto_tree * tree , packet_info * pinfo , int hfid , tvbuff_t * tvb , int offset , int length )
2013-06-12 15:08:08 +00:00
{
2014-08-11 07:35:11 +00:00
guint16 year ;
guint8 month ;
guint8 day ;
guint8 hour ;
guint8 minutes ;
guint8 seconds ;
guint8 deci_seconds ;
guint8 hour_from_utc ;
guint8 min_from_utc ;
gchar * str ;
year = tvb_get_ntohs ( tvb , offset ) ;
month = tvb_get_guint8 ( tvb , offset + 2 ) ;
day = tvb_get_guint8 ( tvb , offset + 3 ) ;
hour = tvb_get_guint8 ( tvb , offset + 4 ) ;
minutes = tvb_get_guint8 ( tvb , offset + 5 ) ;
seconds = tvb_get_guint8 ( tvb , offset + 6 ) ;
deci_seconds = tvb_get_guint8 ( tvb , offset + 7 ) ;
if ( length > 8 ) {
hour_from_utc = tvb_get_guint8 ( tvb , offset + 9 ) ;
min_from_utc = tvb_get_guint8 ( tvb , offset + 10 ) ;
2013-06-12 15:08:08 +00:00
2021-08-23 21:41:43 +00:00
str = wmem_strdup_printf ( pinfo - > pool ,
2014-08-11 07:35:11 +00:00
" %u-%u-%u, %u:%u:%u.%u UTC %s%u:%u " ,
year ,
month ,
day ,
hour ,
minutes ,
seconds ,
deci_seconds ,
2021-08-23 21:41:43 +00:00
tvb_get_string_enc ( pinfo - > pool , tvb , offset + 8 , 1 , ENC_ASCII | ENC_NA ) ,
2014-08-11 07:35:11 +00:00
hour_from_utc ,
min_from_utc ) ;
} else {
2021-08-23 21:41:43 +00:00
str = wmem_strdup_printf ( pinfo - > pool ,
2014-08-11 07:35:11 +00:00
" %u-%u-%u, %u:%u:%u.%u " ,
year ,
month ,
day ,
hour ,
minutes ,
seconds ,
deci_seconds ) ;
}
return proto_tree_add_string ( tree , hfid , tvb , offset , length , str ) ;
2013-06-12 15:08:08 +00:00
}
2007-08-23 19:45:31 +00:00
/*
* dissect_snmp_VarBind
* this routine dissects variable bindings , looking for the oid information in our oid reporsitory
* to format and add the value adequatelly .
*
* The choice to handwrite this code instead of using the asn compiler is to avoid having tons
* of uses of global variables distributed in very different parts of the code .
* Other than that there ' s a cosmetic thing : the tree from ASN generated code would be so
* convoluted due to the nesting of CHOICEs in the definition of VarBind / value .
*
* XXX : the length of this function ( ~ 400 lines ) is an aberration !
* oid_key_t : key_type could become a series of callbacks instead of an enum
* the ( ! oid_info_is_ok ) switch could be made into an array ( would be slower )
2007-11-12 18:44:29 +00:00
*
2007-08-23 19:45:31 +00:00
NetworkAddress : : = CHOICE { internet IpAddress }
IpAddress : : = [ APPLICATION 0 ] IMPLICIT OCTET STRING ( SIZE ( 4 ) )
TimeTicks : : = [ APPLICATION 3 ] IMPLICIT INTEGER ( 0. .4294967295 )
Integer32 : : = INTEGER ( - 2147483648. .2147483647 )
ObjectName : : = OBJECT IDENTIFIER
Counter32 : : = [ APPLICATION 1 ] IMPLICIT INTEGER ( 0. .4294967295 )
Gauge32 : : = [ APPLICATION 2 ] IMPLICIT INTEGER ( 0. .4294967295 )
Unsigned32 : : = [ APPLICATION 2 ] IMPLICIT INTEGER ( 0. .4294967295 )
Integer - value : : = INTEGER ( - 2147483648. .2147483647 )
Integer32 : : = INTEGER ( - 2147483648. .2147483647 )
ObjectID - value : : = OBJECT IDENTIFIER
Empty : : = NULL
2007-11-12 18:44:29 +00:00
TimeTicks : : = [ APPLICATION 3 ] IMPLICIT INTEGER ( 0. .4294967295 )
2007-08-23 19:45:31 +00:00
Opaque : : = [ APPLICATION 4 ] IMPLICIT OCTET STRING
Counter64 : : = [ APPLICATION 6 ] IMPLICIT INTEGER ( 0. .18446744073709551615 )
ObjectSyntax : : = CHOICE {
simple SimpleSyntax ,
application - wide ApplicationSyntax
}
SimpleSyntax : : = CHOICE {
integer - value Integer - value ,
string - value String - value ,
objectID - value ObjectID - value ,
empty Empty
}
ApplicationSyntax : : = CHOICE {
ipAddress - value IpAddress ,
counter - value Counter32 ,
timeticks - value TimeTicks ,
arbitrary - value Opaque ,
big - counter - value Counter64 ,
unsigned - integer - value Unsigned32
}
ValueType : : = CHOICE {
value ObjectSyntax ,
unSpecified NULL ,
noSuchObject [ 0 ] IMPLICIT NULL ,
noSuchInstance [ 1 ] IMPLICIT NULL ,
endOfMibView [ 2 ] IMPLICIT NULL
}
VarBind : : = SEQUENCE {
name ObjectName ,
valueType ValueType
}
2007-11-12 18:44:29 +00:00
2007-08-23 19:45:31 +00:00
*/
2007-08-27 17:05:11 +00:00
2014-01-14 02:06:42 +00:00
static int
2010-10-14 01:44:27 +00:00
dissect_snmp_VarBind ( gboolean implicit_tag _U_ , tvbuff_t * tvb , int offset ,
asn1_ctx_t * actx , proto_tree * tree , int hf_index _U_ )
{
2007-08-19 23:00:47 +00:00
int seq_offset , name_offset , value_offset , value_start ;
guint32 seq_len , name_len , value_len ;
gint8 ber_class ;
gboolean pc ;
gint32 tag ;
gboolean ind ;
2007-08-21 21:32:00 +00:00
guint32 * subids ;
2007-08-19 23:00:47 +00:00
guint8 * oid_bytes ;
2007-08-28 23:19:30 +00:00
oid_info_t * oid_info = NULL ;
2007-08-19 23:00:47 +00:00
guint oid_matched , oid_left ;
2007-08-23 19:45:31 +00:00
proto_item * pi_name , * pi_varbind , * pi_value = NULL ;
2007-08-28 15:18:32 +00:00
proto_tree * pt , * pt_varbind , * pt_name , * pt_value ;
2007-08-21 21:32:00 +00:00
char label [ ITEM_LABEL_LENGTH ] ;
2010-07-02 03:50:30 +00:00
const char * repr = NULL ;
2008-03-09 14:20:28 +00:00
const char * info_oid = NULL ;
2007-08-21 21:32:00 +00:00
char * valstr ;
2007-08-19 23:00:47 +00:00
int hfid = - 1 ;
int min_len = 0 , max_len = 0 ;
2007-08-23 19:45:31 +00:00
gboolean oid_info_is_ok ;
2007-08-28 15:18:32 +00:00
const char * oid_string = NULL ;
2007-09-14 06:51:07 +00:00
enum { BER_NO_ERROR , BER_WRONG_LENGTH , BER_WRONG_TAG } format_error = BER_NO_ERROR ;
2007-09-13 16:49:51 +00:00
2007-08-19 23:00:47 +00:00
seq_offset = offset ;
2007-11-12 18:44:29 +00:00
2007-08-23 19:45:31 +00:00
/* first have the VarBind's sequence header */
2014-09-14 09:57:05 +00:00
offset = dissect_ber_identifier ( actx - > pinfo , tree , tvb , offset , & ber_class , & pc , & tag ) ;
offset = dissect_ber_length ( actx - > pinfo , tree , tvb , offset , & seq_len , & ind ) ;
2007-11-12 18:44:29 +00:00
2007-08-19 23:00:47 +00:00
if ( ! pc & & ber_class = = BER_CLASS_UNI & & tag = = BER_UNI_TAG_SEQUENCE ) {
2014-06-21 01:35:40 +00:00
proto_item * pi ;
2014-09-14 09:57:05 +00:00
pt = proto_tree_add_subtree ( tree , tvb , seq_offset , seq_len + ( offset - seq_offset ) ,
2014-06-21 01:35:40 +00:00
ett_decoding_error , & pi , " VarBind must be an universal class sequence " ) ;
2013-06-03 03:42:36 +00:00
expert_add_info ( actx - > pinfo , pi , & ei_snmp_varbind_not_uni_class_seq ) ;
2007-08-19 23:00:47 +00:00
return dissect_unknown_ber ( actx - > pinfo , tvb , seq_offset , pt ) ;
2005-12-04 21:45:38 +00:00
}
2007-11-12 18:44:29 +00:00
2010-10-14 01:44:27 +00:00
if ( ind ) {
2014-06-21 01:35:40 +00:00
proto_item * pi ;
2014-09-14 09:57:05 +00:00
pt = proto_tree_add_subtree ( tree , tvb , seq_offset , seq_len + ( offset - seq_offset ) ,
2014-06-21 01:35:40 +00:00
ett_decoding_error , & pi , " Indicator must be clear in VarBind " ) ;
2013-06-03 03:42:36 +00:00
expert_add_info ( actx - > pinfo , pi , & ei_snmp_varbind_has_indicator ) ;
2007-08-19 23:00:47 +00:00
return dissect_unknown_ber ( actx - > pinfo , tvb , seq_offset , pt ) ;
2006-07-09 22:12:02 +00:00
}
2007-11-12 18:44:29 +00:00
2014-09-14 09:57:05 +00:00
/* we add the varbind tree root with a dummy label we'll fill later on */
pt_varbind = proto_tree_add_subtree ( tree , tvb , offset , seq_len , ett_varbind , & pi_varbind , " VarBind " ) ;
* label = ' \0 ' ;
seq_len + = offset - seq_offset ;
2007-08-23 19:45:31 +00:00
/* then we have the ObjectName's header */
2007-11-12 18:44:29 +00:00
2014-09-14 09:57:05 +00:00
offset = dissect_ber_identifier ( actx - > pinfo , pt_varbind , tvb , offset , & ber_class , & pc , & tag ) ;
name_offset = offset = dissect_ber_length ( actx - > pinfo , pt_varbind , tvb , offset , & name_len , & ind ) ;
2007-11-12 18:44:29 +00:00
2007-08-19 23:00:47 +00:00
if ( ! ( ! pc & & ber_class = = BER_CLASS_UNI & & tag = = BER_UNI_TAG_OID ) ) {
2014-06-21 01:35:40 +00:00
proto_item * pi ;
pt = proto_tree_add_subtree ( tree , tvb , seq_offset , seq_len ,
ett_decoding_error , & pi , " ObjectName must be an OID in primitive encoding " ) ;
2013-06-03 03:42:36 +00:00
expert_add_info ( actx - > pinfo , pi , & ei_snmp_objectname_not_oid ) ;
2007-08-19 23:00:47 +00:00
return dissect_unknown_ber ( actx - > pinfo , tvb , seq_offset , pt ) ;
2005-12-04 21:45:38 +00:00
}
2007-11-12 18:44:29 +00:00
2010-10-14 01:44:27 +00:00
if ( ind ) {
2014-06-21 01:35:40 +00:00
proto_item * pi ;
pt = proto_tree_add_subtree ( tree , tvb , seq_offset , seq_len ,
ett_decoding_error , & pi , " Indicator must be clear in ObjectName " ) ;
2013-06-03 03:42:36 +00:00
expert_add_info ( actx - > pinfo , pi , & ei_snmp_objectname_has_indicator ) ;
2007-08-19 23:00:47 +00:00
return dissect_unknown_ber ( actx - > pinfo , tvb , seq_offset , pt ) ;
2005-12-04 21:45:38 +00:00
}
2007-11-12 18:44:29 +00:00
2014-09-14 09:57:05 +00:00
pi_name = proto_tree_add_item ( pt_varbind , hf_snmp_objectname , tvb , name_offset , name_len , ENC_NA ) ;
pt_name = proto_item_add_subtree ( pi_name , ett_name ) ;
2007-08-19 23:00:47 +00:00
offset + = name_len ;
value_start = offset ;
2014-08-13 06:51:20 +00:00
/* then we have the value's header */
2014-09-14 09:57:05 +00:00
offset = dissect_ber_identifier ( actx - > pinfo , pt_varbind , tvb , offset , & ber_class , & pc , & tag ) ;
value_offset = dissect_ber_length ( actx - > pinfo , pt_varbind , tvb , offset , & value_len , & ind ) ;
2007-11-12 18:44:29 +00:00
2007-08-19 23:00:47 +00:00
if ( ! ( ! pc ) ) {
2014-06-21 01:35:40 +00:00
proto_item * pi ;
2014-09-14 09:57:05 +00:00
pt = proto_tree_add_subtree ( pt_varbind , tvb , value_start , value_len ,
2014-06-21 01:35:40 +00:00
ett_decoding_error , & pi , " the value must be in primitive encoding " ) ;
2013-06-03 03:42:36 +00:00
expert_add_info ( actx - > pinfo , pi , & ei_snmp_value_not_primitive_encoding ) ;
2014-09-14 09:57:05 +00:00
return dissect_unknown_ber ( actx - > pinfo , tvb , value_start , pt ) ;
2006-03-15 06:20:23 +00:00
}
2007-08-23 19:45:31 +00:00
/* Now, we know where everithing is */
2007-11-12 18:44:29 +00:00
2007-12-28 22:19:33 +00:00
/* fetch ObjectName and its relative oid_info */
2021-07-23 19:21:02 +00:00
oid_bytes = ( guint8 * ) tvb_memdup ( actx - > pinfo - > pool , tvb , name_offset , name_len ) ;
oid_info = oid_get_from_encoded ( actx - > pinfo - > pool , oid_bytes , name_len , & subids , & oid_matched , & oid_left ) ;
2007-11-12 18:44:29 +00:00
2007-12-28 22:19:33 +00:00
add_oid_debug_subtree ( oid_info , pt_name ) ;
2009-10-05 21:39:07 +00:00
if ( ! subids ) {
2010-07-02 03:50:30 +00:00
proto_item * pi ;
2021-07-23 19:21:02 +00:00
repr = oid_encoded2string ( actx - > pinfo - > pool , oid_bytes , name_len ) ;
2014-06-21 01:35:40 +00:00
pt = proto_tree_add_subtree_format ( pt_name , tvb , 0 , 0 , ett_decoding_error , & pi , " invalid oid: %s " , repr ) ;
2013-09-09 00:28:48 +00:00
expert_add_info_format ( actx - > pinfo , pi , & ei_snmp_invalid_oid , " invalid oid: %s " , repr ) ;
2009-10-05 21:39:07 +00:00
return dissect_unknown_ber ( actx - > pinfo , tvb , name_offset , pt ) ;
}
if ( oid_matched + oid_left ) {
2021-07-23 19:21:02 +00:00
oid_string = oid_subid2string ( actx - > pinfo - > pool , subids , oid_matched + oid_left ) ;
2007-12-28 22:19:33 +00:00
}
2007-11-12 18:44:29 +00:00
2007-08-19 23:00:47 +00:00
if ( ber_class = = BER_CLASS_CON ) {
2007-08-23 19:45:31 +00:00
/* if we have an error value just add it and get out the way ASAP */
proto_item * pi ;
const char * note ;
2007-11-12 18:44:29 +00:00
if ( value_len ! = 0 ) {
2007-09-13 16:49:51 +00:00
min_len = max_len = 0 ;
2007-09-14 06:51:07 +00:00
format_error = BER_WRONG_LENGTH ;
2007-09-13 16:49:51 +00:00
}
2007-11-12 18:44:29 +00:00
2007-08-19 23:00:47 +00:00
switch ( tag ) {
case SERR_NSO :
2007-08-23 19:45:31 +00:00
hfid = hf_snmp_noSuchObject ;
note = " noSuchObject " ;
2007-08-19 23:00:47 +00:00
break ;
case SERR_NSI :
2007-08-23 19:45:31 +00:00
hfid = hf_snmp_noSuchInstance ;
note = " noSuchInstance " ;
2007-08-19 23:00:47 +00:00
break ;
case SERR_EOM :
2007-08-23 19:45:31 +00:00
hfid = hf_snmp_endOfMibView ;
note = " endOfMibView " ;
2007-08-19 23:00:47 +00:00
break ;
default : {
2014-06-21 01:35:40 +00:00
pt = proto_tree_add_subtree_format ( pt_varbind , tvb , 0 , 0 , ett_decoding_error , & pi ,
" Wrong tag for Error Value: expected 0, 1, or 2 but got: %d " , tag ) ;
2013-06-03 03:42:36 +00:00
expert_add_info ( actx - > pinfo , pi , & ei_snmp_varbind_wrong_tag ) ;
2007-09-13 16:49:51 +00:00
return dissect_unknown_ber ( actx - > pinfo , tvb , value_start , pt ) ;
2007-11-12 18:44:29 +00:00
}
2007-08-19 23:00:47 +00:00
}
2007-11-12 18:44:29 +00:00
2011-07-19 10:51:12 +00:00
pi = proto_tree_add_item ( pt_varbind , hfid , tvb , value_offset , value_len , ENC_BIG_ENDIAN ) ;
2013-09-09 00:28:48 +00:00
expert_add_info_format ( actx - > pinfo , pi , & ei_snmp_varbind_response , " %s " , note ) ;
2021-04-30 10:18:25 +00:00
( void ) g_strlcpy ( label , note , ITEM_LABEL_LENGTH ) ;
2007-08-24 00:26:30 +00:00
goto set_label ;
2007-08-23 19:45:31 +00:00
}
2007-11-12 18:44:29 +00:00
2007-08-23 19:45:31 +00:00
/* now we'll try to figure out which are the indexing sub-oids and whether the oid we know about is the one oid we have to use */
switch ( oid_info - > kind ) {
case OID_KIND_SCALAR :
2014-08-13 06:51:20 +00:00
if ( oid_left = = 1 ) {
2007-08-23 19:45:31 +00:00
/* OK: we got the instance sub-id */
proto_tree_add_uint64 ( pt_name , hf_snmp_scalar_instance_index , tvb , name_offset , name_len , subids [ oid_matched ] ) ;
oid_info_is_ok = TRUE ;
goto indexing_done ;
2014-08-13 06:51:20 +00:00
} else if ( oid_left = = 0 ) {
2007-08-23 19:45:31 +00:00
if ( ber_class = = BER_CLASS_UNI & & tag = = BER_UNI_TAG_NULL ) {
/* unSpecified does not require an instance sub-id add the new value and get off the way! */
2011-10-05 02:39:04 +00:00
pi_value = proto_tree_add_item ( pt_varbind , hf_snmp_unSpecified , tvb , value_offset , value_len , ENC_NA ) ;
2007-08-24 00:26:30 +00:00
goto set_label ;
2007-08-23 19:45:31 +00:00
} else {
2014-08-08 13:19:29 +00:00
proto_tree_add_expert ( pt_name , actx - > pinfo , & ei_snmp_no_instance_subid , tvb , 0 , 0 ) ;
2007-08-23 19:45:31 +00:00
oid_info_is_ok = FALSE ;
goto indexing_done ;
}
} else {
2014-08-08 13:19:29 +00:00
proto_tree_add_expert_format ( pt_name , actx - > pinfo , & ei_snmp_wrong_num_of_subids , tvb , 0 , 0 , " A scalar should have only one instance sub-id this has: %d " , oid_left ) ;
2007-08-23 19:45:31 +00:00
oid_info_is_ok = FALSE ;
goto indexing_done ;
}
break ;
case OID_KIND_COLUMN :
if ( oid_info - > parent - > kind = = OID_KIND_ROW ) {
oid_key_t * k = oid_info - > parent - > key ;
guint key_start = oid_matched ;
guint key_len = oid_left ;
oid_info_is_ok = TRUE ;
2007-08-24 00:33:35 +00:00
if ( key_len = = 0 & & ber_class = = BER_CLASS_UNI & & tag = = BER_UNI_TAG_NULL ) {
2007-08-24 00:26:30 +00:00
/* unSpecified does not require an instance sub-id add the new value and get off the way! */
2011-10-05 02:39:04 +00:00
pi_value = proto_tree_add_item ( pt_varbind , hf_snmp_unSpecified , tvb , value_offset , value_len , ENC_NA ) ;
2007-08-24 00:26:30 +00:00
goto set_label ;
}
2007-11-12 18:44:29 +00:00
2007-08-23 19:45:31 +00:00
if ( k ) {
for ( ; k ; k = k - > next ) {
2007-09-13 16:49:51 +00:00
guint suboid_len ;
2007-11-12 18:44:29 +00:00
2007-08-24 00:26:30 +00:00
if ( key_start > = oid_matched + oid_left ) {
2014-08-08 13:19:29 +00:00
proto_tree_add_expert ( pt_name , actx - > pinfo , & ei_snmp_index_suboid_too_short , tvb , 0 , 0 ) ;
2007-08-23 19:45:31 +00:00
oid_info_is_ok = FALSE ;
goto indexing_done ;
}
2007-11-12 18:44:29 +00:00
switch ( k - > key_type ) {
2007-08-23 19:45:31 +00:00
case OID_KEY_TYPE_WRONG : {
2014-08-08 13:19:29 +00:00
proto_tree_add_expert ( pt_name , actx - > pinfo , & ei_snmp_unimplemented_instance_index , tvb , 0 , 0 ) ;
2007-08-23 19:45:31 +00:00
oid_info_is_ok = FALSE ;
goto indexing_done ;
}
case OID_KEY_TYPE_INTEGER : {
2008-02-25 00:00:41 +00:00
if ( IS_FT_INT ( k - > ft_type ) ) {
proto_tree_add_int ( pt_name , k - > hfid , tvb , name_offset , name_len , ( guint ) subids [ key_start ] ) ;
} else { /* if it's not an unsigned int let proto_tree_add_uint throw a warning */
2011-06-05 20:12:44 +00:00
proto_tree_add_uint64 ( pt_name , k - > hfid , tvb , name_offset , name_len , ( guint ) subids [ key_start ] ) ;
2008-02-25 00:00:41 +00:00
}
2007-08-23 19:45:31 +00:00
key_start + + ;
key_len - - ;
2007-08-27 17:05:11 +00:00
continue ; /* k->next */
2007-08-23 19:45:31 +00:00
}
2007-09-13 16:49:51 +00:00
case OID_KEY_TYPE_IMPLIED_OID :
suboid_len = key_len ;
goto show_oid_index ;
2007-11-12 18:44:29 +00:00
2007-08-23 19:45:31 +00:00
case OID_KEY_TYPE_OID : {
guint8 * suboid_buf ;
guint suboid_buf_len ;
2007-09-13 16:49:51 +00:00
guint32 * suboid ;
suboid_len = subids [ key_start + + ] ;
key_len - - ;
2007-11-12 18:44:29 +00:00
2007-09-13 16:49:51 +00:00
show_oid_index :
suboid = & ( subids [ key_start ] ) ;
2007-08-28 23:19:30 +00:00
if ( suboid_len = = 0 ) {
2014-08-08 13:19:29 +00:00
proto_tree_add_expert ( pt_name , actx - > pinfo , & ei_snmp_index_suboid_len0 , tvb , 0 , 0 ) ;
2007-08-28 23:19:30 +00:00
oid_info_is_ok = FALSE ;
goto indexing_done ;
}
2007-11-12 18:44:29 +00:00
2007-09-13 16:49:51 +00:00
if ( key_len < suboid_len ) {
2014-08-08 13:19:29 +00:00
proto_tree_add_expert ( pt_name , actx - > pinfo , & ei_snmp_index_suboid_too_long , tvb , 0 , 0 ) ;
2007-08-23 19:45:31 +00:00
oid_info_is_ok = FALSE ;
goto indexing_done ;
}
2007-11-12 18:44:29 +00:00
2021-07-23 19:21:02 +00:00
suboid_buf_len = oid_subid2encoded ( actx - > pinfo - > pool , suboid_len , suboid , & suboid_buf ) ;
2007-11-12 18:44:29 +00:00
2007-08-28 23:19:30 +00:00
DISSECTOR_ASSERT ( suboid_buf_len ) ;
proto_tree_add_oid ( pt_name , k - > hfid , tvb , name_offset , suboid_buf_len , suboid_buf ) ;
2007-11-12 18:44:29 +00:00
2007-08-23 19:45:31 +00:00
key_start + = suboid_len ;
key_len - = suboid_len + 1 ;
2007-08-27 17:05:11 +00:00
continue ; /* k->next */
2007-08-23 19:45:31 +00:00
}
default : {
guint8 * buf ;
2007-09-13 16:49:51 +00:00
guint buf_len ;
guint32 * suboid ;
2007-08-23 19:45:31 +00:00
guint i ;
2007-11-12 18:44:29 +00:00
2007-09-13 16:49:51 +00:00
switch ( k - > key_type ) {
case OID_KEY_TYPE_IPADDR :
suboid = & ( subids [ key_start ] ) ;
buf_len = 4 ;
break ;
case OID_KEY_TYPE_IMPLIED_STRING :
case OID_KEY_TYPE_IMPLIED_BYTES :
2008-11-10 20:25:38 +00:00
case OID_KEY_TYPE_ETHER :
2007-09-13 16:49:51 +00:00
suboid = & ( subids [ key_start ] ) ;
buf_len = key_len ;
break ;
default :
buf_len = k - > num_subids ;
suboid = & ( subids [ key_start ] ) ;
2007-11-12 18:44:29 +00:00
2007-09-13 16:49:51 +00:00
if ( ! buf_len ) {
buf_len = * suboid + + ;
key_len - - ;
key_start + + ;
}
break ;
2007-11-12 18:44:29 +00:00
}
2007-08-23 19:45:31 +00:00
if ( key_len < buf_len ) {
2014-08-08 13:19:29 +00:00
proto_tree_add_expert ( pt_name , actx - > pinfo , & ei_snmp_index_string_too_long , tvb , 0 , 0 ) ;
2007-08-23 19:45:31 +00:00
oid_info_is_ok = FALSE ;
goto indexing_done ;
}
2007-11-12 18:44:29 +00:00
2021-07-23 19:21:02 +00:00
buf = ( guint8 * ) wmem_alloc ( actx - > pinfo - > pool , buf_len + 1 ) ;
2007-08-23 19:45:31 +00:00
for ( i = 0 ; i < buf_len ; i + + )
buf [ i ] = ( guint8 ) suboid [ i ] ;
buf [ i ] = ' \0 ' ;
2007-11-12 18:44:29 +00:00
2007-08-23 19:45:31 +00:00
switch ( k - > key_type ) {
case OID_KEY_TYPE_STRING :
2007-09-13 16:49:51 +00:00
case OID_KEY_TYPE_IMPLIED_STRING :
2007-08-23 19:45:31 +00:00
proto_tree_add_string ( pt_name , k - > hfid , tvb , name_offset , buf_len , buf ) ;
break ;
case OID_KEY_TYPE_BYTES :
case OID_KEY_TYPE_NSAP :
2007-11-12 18:44:29 +00:00
case OID_KEY_TYPE_IMPLIED_BYTES :
2007-08-23 19:45:31 +00:00
proto_tree_add_bytes ( pt_name , k - > hfid , tvb , name_offset , buf_len , buf ) ;
break ;
2008-11-10 20:25:38 +00:00
case OID_KEY_TYPE_ETHER :
proto_tree_add_ether ( pt_name , k - > hfid , tvb , name_offset , buf_len , buf ) ;
break ;
2007-08-23 19:45:31 +00:00
case OID_KEY_TYPE_IPADDR : {
2013-03-20 05:59:22 +00:00
guint32 * ipv4_p = ( guint32 * ) buf ;
2007-08-23 19:45:31 +00:00
proto_tree_add_ipv4 ( pt_name , k - > hfid , tvb , name_offset , buf_len , * ipv4_p ) ;
2011-04-12 09:05:43 +00:00
}
2007-08-23 19:45:31 +00:00
break ;
default :
DISSECTOR_ASSERT_NOT_REACHED ( ) ;
break ;
}
2007-11-12 18:44:29 +00:00
2007-08-23 19:45:31 +00:00
key_start + = buf_len ;
key_len - = buf_len ;
continue ; /* k->next*/
}
}
}
goto indexing_done ;
} else {
2014-08-08 13:19:29 +00:00
proto_tree_add_expert ( pt_name , actx - > pinfo , & ei_snmp_unimplemented_instance_index , tvb , 0 , 0 ) ;
2007-08-23 19:45:31 +00:00
oid_info_is_ok = FALSE ;
goto indexing_done ;
}
} else {
2014-08-08 13:19:29 +00:00
proto_tree_add_expert ( pt_name , actx - > pinfo , & ei_snmp_column_parent_not_row , tvb , 0 , 0 ) ;
2007-08-23 19:45:31 +00:00
oid_info_is_ok = FALSE ;
goto indexing_done ;
}
default : {
2014-08-08 13:19:29 +00:00
/* proto_tree_add_expert (pt_name,actx->pinfo,PI_MALFORMED, PI_WARN,tvb,0,0,"This kind OID should have no value"); */
2007-08-23 19:45:31 +00:00
oid_info_is_ok = FALSE ;
goto indexing_done ;
}
}
indexing_done :
2007-11-12 18:44:29 +00:00
2009-07-16 17:00:58 +00:00
if ( oid_info_is_ok & & oid_info - > value_type ) {
2007-08-23 19:45:31 +00:00
if ( ber_class = = BER_CLASS_UNI & & tag = = BER_UNI_TAG_NULL ) {
2011-10-05 02:39:04 +00:00
pi_value = proto_tree_add_item ( pt_varbind , hf_snmp_unSpecified , tvb , value_offset , value_len , ENC_NA ) ;
2011-01-20 08:58:03 +00:00
} else {
/* Provide a tree_item to attach errors to, if needed. */
pi_value = pi_name ;
2007-08-23 19:45:31 +00:00
if ( ( oid_info - > value_type - > ber_class ! = BER_CLASS_ANY ) & &
( ber_class ! = oid_info - > value_type - > ber_class ) )
2007-09-14 06:51:07 +00:00
format_error = BER_WRONG_TAG ;
2011-01-20 08:58:03 +00:00
else if ( ( oid_info - > value_type - > ber_tag ! = BER_TAG_ANY ) & &
2007-08-23 19:45:31 +00:00
( tag ! = oid_info - > value_type - > ber_tag ) )
2007-09-14 06:51:07 +00:00
format_error = BER_WRONG_TAG ;
2011-01-20 08:58:03 +00:00
else {
max_len = oid_info - > value_type - > max_len = = - 1 ? 0xffffff : oid_info - > value_type - > max_len ;
2014-08-13 06:51:20 +00:00
min_len = oid_info - > value_type - > min_len ;
2007-11-12 18:44:29 +00:00
2011-01-20 08:58:03 +00:00
if ( ( int ) value_len < min_len | | ( int ) value_len > max_len )
format_error = BER_WRONG_LENGTH ;
}
2007-11-12 18:44:29 +00:00
2011-01-20 08:58:03 +00:00
if ( format_error = = BER_NO_ERROR )
2011-07-19 10:51:12 +00:00
pi_value = proto_tree_add_item ( pt_varbind , oid_info - > value_hfid , tvb , value_offset , value_len , ENC_BIG_ENDIAN ) ;
2007-08-23 19:45:31 +00:00
}
} else {
2007-08-19 23:00:47 +00:00
switch ( ber_class | ( tag < < 4 ) ) {
case BER_CLASS_UNI | ( BER_UNI_TAG_INTEGER < < 4 ) :
2010-03-04 13:54:21 +00:00
{
gint64 val = 0 ;
2012-10-09 08:40:02 +00:00
unsigned int int_val_offset = value_offset ;
unsigned int i ;
2010-09-17 14:03:05 +00:00
2012-04-25 20:20:23 +00:00
max_len = 4 ; min_len = 1 ;
if ( value_len > ( guint ) max_len | | value_len < ( guint ) min_len ) {
hfid = hf_snmp_integer32_value ;
2010-03-04 13:54:21 +00:00
format_error = BER_WRONG_LENGTH ;
break ;
}
2010-09-17 14:03:05 +00:00
2010-03-04 13:54:21 +00:00
if ( value_len > 0 ) {
/* extend sign bit */
2011-04-07 23:52:37 +00:00
if ( tvb_get_guint8 ( tvb , int_val_offset ) & 0x80 ) {
2010-03-04 13:54:21 +00:00
val = - 1 ;
}
2010-10-14 01:44:27 +00:00
for ( i = 0 ; i < value_len ; i + + ) {
2011-04-07 23:52:37 +00:00
val = ( val < < 8 ) | tvb_get_guint8 ( tvb , int_val_offset ) ;
int_val_offset + + ;
2010-03-04 13:54:21 +00:00
}
}
2016-10-13 19:16:55 +00:00
pi_value = proto_tree_add_int64 ( pt_varbind , hf_snmp_integer32_value , tvb , value_offset , value_len , val ) ;
2010-03-04 13:54:21 +00:00
goto already_added ;
}
2007-08-19 23:00:47 +00:00
case BER_CLASS_UNI | ( BER_UNI_TAG_OCTETSTRING < < 4 ) :
2013-06-12 15:08:08 +00:00
if ( oid_info - > value_hfid > - 1 ) {
2013-06-11 16:35:06 +00:00
hfid = oid_info - > value_hfid ;
} else {
hfid = hf_snmp_octetstring_value ;
}
2007-08-19 23:00:47 +00:00
break ;
case BER_CLASS_UNI | ( BER_UNI_TAG_OID < < 4 ) :
2007-09-13 16:49:51 +00:00
max_len = - 1 ; min_len = 1 ;
2007-11-12 18:44:29 +00:00
if ( value_len < ( guint ) min_len ) format_error = BER_WRONG_LENGTH ;
2007-08-19 23:00:47 +00:00
hfid = hf_snmp_oid_value ;
break ;
case BER_CLASS_UNI | ( BER_UNI_TAG_NULL < < 4 ) :
max_len = 0 ; min_len = 0 ;
2007-11-12 18:44:29 +00:00
if ( value_len ! = 0 ) format_error = BER_WRONG_LENGTH ;
2007-08-19 23:00:47 +00:00
hfid = hf_snmp_null_value ;
break ;
case BER_CLASS_APP : /* | (SNMP_IPA<<4)*/
switch ( value_len ) {
case 4 : hfid = hf_snmp_ipv4_value ; break ;
case 16 : hfid = hf_snmp_ipv6_value ; break ;
default : hfid = hf_snmp_anyaddress_value ; break ;
}
break ;
case BER_CLASS_APP | ( SNMP_U32 < < 4 ) :
hfid = hf_snmp_unsigned32_value ;
break ;
case BER_CLASS_APP | ( SNMP_GGE < < 4 ) :
hfid = hf_snmp_gauge32_value ;
break ;
case BER_CLASS_APP | ( SNMP_CNT < < 4 ) :
hfid = hf_snmp_counter_value ;
break ;
case BER_CLASS_APP | ( SNMP_TIT < < 4 ) :
hfid = hf_snmp_timeticks_value ;
break ;
case BER_CLASS_APP | ( SNMP_OPQ < < 4 ) :
hfid = hf_snmp_opaque_value ;
break ;
case BER_CLASS_APP | ( SNMP_NSP < < 4 ) :
hfid = hf_snmp_nsap_value ;
break ;
case BER_CLASS_APP | ( SNMP_C64 < < 4 ) :
hfid = hf_snmp_big_counter_value ;
break ;
2007-11-12 18:44:29 +00:00
default :
2007-08-19 23:00:47 +00:00
hfid = hf_snmp_unknown_value ;
break ;
}
2011-11-14 18:42:11 +00:00
if ( value_len > 8 ) {
/*
* Too long for an FT_UINT64 or an FT_INT64 .
*/
2011-10-29 18:26:57 +00:00
header_field_info * hfinfo = proto_registrar_get_nth ( hfid ) ;
if ( hfinfo - > type = = FT_UINT64 ) {
2011-11-14 18:42:11 +00:00
/*
* Check if this is an unsigned int64 with
* a big value .
*/
if ( value_len > 9 | | tvb_get_guint8 ( tvb , value_offset ) ! = 0 ) {
/* It is. Fail. */
2014-08-08 13:19:29 +00:00
proto_tree_add_expert_format ( pt_varbind , actx - > pinfo , & ei_snmp_uint_too_large , tvb , value_offset , value_len , " Integral value too large " ) ;
2011-11-14 18:42:11 +00:00
goto already_added ;
}
2011-10-29 18:26:57 +00:00
/* Cheat and skip the leading 0 byte */
value_len - - ;
value_offset + + ;
2011-11-14 18:42:11 +00:00
} else if ( hfinfo - > type = = FT_INT64 ) {
/*
* For now , just reject these .
*/
2014-08-08 13:19:29 +00:00
proto_tree_add_expert_format ( pt_varbind , actx - > pinfo , & ei_snmp_int_too_large , tvb , value_offset , value_len , " Integral value too large or too small " ) ;
2011-11-14 18:42:11 +00:00
goto already_added ;
}
} else if ( value_len = = 0 ) {
/*
* X .690 section 8.3 .1 " Encoding of an integer value " :
* " The encoding of an integer value shall be
* primitive . The contents octets shall consist of
* one or more octets . "
*
* Zero is not " one or more " .
*/
header_field_info * hfinfo = proto_registrar_get_nth ( hfid ) ;
if ( hfinfo - > type = = FT_UINT64 | | hfinfo - > type = = FT_INT64 ) {
2014-08-08 13:19:29 +00:00
proto_tree_add_expert_format ( pt_varbind , actx - > pinfo , & ei_snmp_integral_value0 , tvb , value_offset , value_len , " Integral value is zero-length " ) ;
2011-11-14 18:42:11 +00:00
goto already_added ;
2011-10-29 18:26:57 +00:00
}
}
2013-06-12 15:08:08 +00:00
/* Special case DATE AND TIME */
if ( ( oid_info - > value_type ) & & ( oid_info - > value_type - > keytype = = OID_KEY_TYPE_DATE_AND_TIME ) & & ( value_len > 7 ) ) {
2021-08-23 21:41:43 +00:00
pi_value = dissect_snmp_variable_date_and_time ( pt_varbind , actx - > pinfo , hfid , tvb , value_offset , value_len ) ;
2013-06-12 15:08:08 +00:00
} else {
2014-08-11 07:35:11 +00:00
pi_value = proto_tree_add_item ( pt_varbind , hfid , tvb , value_offset , value_len , ENC_BIG_ENDIAN ) ;
2013-06-12 15:08:08 +00:00
}
2009-08-08 00:27:31 +00:00
if ( format_error ! = BER_NO_ERROR ) {
2013-06-03 03:42:36 +00:00
expert_add_info ( actx - > pinfo , pi_value , & ei_snmp_missing_mib ) ;
2009-08-08 00:27:31 +00:00
}
2010-09-17 14:03:05 +00:00
2007-11-12 18:44:29 +00:00
}
2014-08-11 07:16:18 +00:00
already_added :
2007-08-28 15:18:32 +00:00
pt_value = proto_item_add_subtree ( pi_value , ett_value ) ;
2007-11-12 18:44:29 +00:00
2007-08-28 15:18:32 +00:00
if ( value_len > 0 & & oid_string ) {
2014-06-06 14:35:50 +00:00
tvbuff_t * sub_tvb = tvb_new_subset_length ( tvb , value_offset , value_len ) ;
2007-11-12 18:44:29 +00:00
2021-09-07 18:33:39 +00:00
next_tvb_add_string ( var_list , sub_tvb , ( snmp_var_in_tree ) ? pt_value : NULL , value_sub_dissectors_table , oid_string ) ;
2007-08-28 15:18:32 +00:00
}
2007-11-12 18:44:29 +00:00
2007-08-24 00:26:30 +00:00
set_label :
2009-08-09 17:57:31 +00:00
if ( pi_value ) proto_item_fill_label ( PITEM_FINFO ( pi_value ) , label ) ;
2007-11-12 18:44:29 +00:00
2007-08-28 23:19:30 +00:00
if ( oid_info & & oid_info - > name ) {
2007-08-21 21:32:00 +00:00
if ( oid_left > = 1 ) {
2021-07-23 19:21:02 +00:00
repr = wmem_strdup_printf ( actx - > pinfo - > pool , " %s.%s (%s) " , oid_info - > name ,
oid_subid2string ( actx - > pinfo - > pool , & ( subids [ oid_matched ] ) , oid_left ) ,
oid_subid2string ( actx - > pinfo - > pool , subids , oid_matched + oid_left ) ) ;
info_oid = wmem_strdup_printf ( actx - > pinfo - > pool , " %s.%s " , oid_info - > name ,
oid_subid2string ( actx - > pinfo - > pool , & ( subids [ oid_matched ] ) , oid_left ) ) ;
2007-08-21 21:32:00 +00:00
} else {
2021-07-23 19:21:02 +00:00
repr = wmem_strdup_printf ( actx - > pinfo - > pool , " %s (%s) " , oid_info - > name ,
oid_subid2string ( actx - > pinfo - > pool , subids , oid_matched ) ) ;
2008-03-09 13:58:58 +00:00
info_oid = oid_info - > name ;
2007-08-21 21:32:00 +00:00
}
2008-02-26 01:17:18 +00:00
} else if ( oid_string ) {
2021-07-23 19:21:02 +00:00
repr = wmem_strdup ( actx - > pinfo - > pool , oid_string ) ;
2008-03-09 13:58:58 +00:00
info_oid = oid_string ;
2007-08-21 21:32:00 +00:00
} else {
2021-07-23 19:21:02 +00:00
repr = wmem_strdup ( actx - > pinfo - > pool , " [Bad OID] " ) ;
2007-08-21 21:32:00 +00:00
}
2007-11-12 18:44:29 +00:00
2007-08-21 21:32:00 +00:00
valstr = strstr ( label , " : " ) ;
2007-08-24 00:26:30 +00:00
valstr = valstr ? valstr + 2 : label ;
2007-11-12 18:44:29 +00:00
2007-08-21 21:32:00 +00:00
proto_item_set_text ( pi_varbind , " %s: %s " , repr , valstr ) ;
2007-11-12 18:44:29 +00:00
2009-11-01 18:45:43 +00:00
if ( display_oid & & info_oid ) {
2014-08-13 06:51:20 +00:00
col_append_fstr ( actx - > pinfo - > cinfo , COL_INFO , " %s " , info_oid ) ;
2008-03-09 13:58:58 +00:00
}
2007-09-13 16:49:51 +00:00
switch ( format_error ) {
2007-09-14 06:51:07 +00:00
case BER_WRONG_LENGTH : {
2014-06-21 01:35:40 +00:00
proto_item * pi ;
2012-06-04 13:21:44 +00:00
proto_tree * p_tree = proto_item_add_subtree ( pi_value , ett_decoding_error ) ;
2014-06-21 01:35:40 +00:00
pt = proto_tree_add_subtree_format ( p_tree , tvb , 0 , 0 , ett_decoding_error , & pi ,
" Wrong value length: %u expecting: %u <= len <= %u " ,
2010-10-14 01:44:27 +00:00
value_len , min_len , max_len = = - 1 ? 0xFFFFFF : max_len ) ;
2013-06-03 03:42:36 +00:00
expert_add_info ( actx - > pinfo , pi , & ei_snmp_varbind_wrong_length_value ) ;
2007-09-13 16:49:51 +00:00
return dissect_unknown_ber ( actx - > pinfo , tvb , value_start , pt ) ;
}
2007-09-14 06:51:07 +00:00
case BER_WRONG_TAG : {
2014-06-21 01:35:40 +00:00
proto_item * pi ;
2012-06-04 13:21:44 +00:00
proto_tree * p_tree = proto_item_add_subtree ( pi_value , ett_decoding_error ) ;
2014-06-21 01:35:40 +00:00
pt = proto_tree_add_subtree_format ( p_tree , tvb , 0 , 0 , ett_decoding_error , & pi ,
" Wrong class/tag for Value expected: %d,%d got: %d,%d " ,
2010-10-14 01:44:27 +00:00
oid_info - > value_type - > ber_class , oid_info - > value_type - > ber_tag ,
ber_class , tag ) ;
2013-06-03 03:42:36 +00:00
expert_add_info ( actx - > pinfo , pi , & ei_snmp_varbind_wrong_class_tag ) ;
2007-09-13 16:49:51 +00:00
return dissect_unknown_ber ( actx - > pinfo , tvb , value_start , pt ) ;
}
default :
break ;
2007-08-19 23:00:47 +00:00
}
2007-11-12 18:44:29 +00:00
2007-09-13 16:49:51 +00:00
return seq_offset + seq_len ;
2007-08-19 23:00:47 +00:00
}
2006-03-15 06:20:23 +00:00
2005-12-04 21:45:38 +00:00
# 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 = {
2014-08-13 06:51:20 +00:00
" RFC3411 (SNMPv3) " ,
" RFC1910 (Non-SNMPv3) "
2005-12-04 21:45:38 +00:00
} ;
# 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 " } ,
2014-08-13 06:51:20 +00:00
{ 0 , NULL }
2005-12-04 21:45:38 +00:00
} ;
2010-03-05 20:09:37 +00:00
# define SNMP_ENGINEID_CISCO_AGENT 0x00
# define SNMP_ENGINEID_CISCO_MANAGER 0x01
static const value_string snmp_engineid_cisco_type_vals [ ] = {
{ SNMP_ENGINEID_CISCO_AGENT , " Agent " } ,
{ SNMP_ENGINEID_CISCO_MANAGER , " Manager " } ,
{ 0 , NULL }
} ;
2006-01-18 20:02:19 +00:00
/*
2005-12-04 21:45:38 +00:00
* SNMP Engine ID dissection according to RFC 3411 ( SnmpEngineID TC )
* or historic RFC 1910 ( AgentID )
*/
2010-10-14 01:44:27 +00:00
int
2014-08-08 13:19:29 +00:00
dissect_snmp_engineid ( proto_tree * tree , packet_info * pinfo , tvbuff_t * tvb , int offset , int len )
2010-10-14 01:44:27 +00:00
{
2014-08-11 07:35:11 +00:00
proto_item * item = NULL ;
guint8 conformance , format ;
2019-10-20 18:36:53 +00:00
guint32 enterpriseid ;
time_t seconds ;
2014-08-11 07:35:11 +00:00
nstime_t ts ;
int len_remain = len ;
/* first bit: engine id conformance */
if ( len_remain < 1 ) return offset ;
conformance = ( ( tvb_get_guint8 ( tvb , offset ) > > 7 ) & 0x01 ) ;
proto_tree_add_item ( tree , hf_snmp_engineid_conform , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
/* 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_item ( tree , hf_snmp_agentid_trailer , tvb , offset , 8 , ENC_NA ) ;
offset + = 8 ;
len_remain - = 8 ;
} else {
proto_tree_add_expert ( tree , pinfo , & ei_snmp_rfc1910_non_conformant , tvb , offset , len_remain ) ;
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 , ENC_BIG_ENDIAN ) ;
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 , ENC_NA ) ;
offset + = 16 ;
len_remain = 0 ;
}
break ;
case SNMP_ENGINEID_FORMAT_MACADDRESS :
/* See: https://supportforums.cisco.com/message/3010617#3010617 for details. */
if ( ( enterpriseid = = 9 ) & & ( len_remain = = 7 ) ) {
proto_tree_add_item ( tree , hf_snmp_engineid_cisco_type , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
offset + + ;
len_remain - - ;
}
/* 6-byte MAC address */
if ( len_remain = = 6 ) {
proto_tree_add_item ( tree , hf_snmp_engineid_mac , tvb , offset , 6 , ENC_NA ) ;
offset + = 6 ;
len_remain = 0 ;
}
break ;
case SNMP_ENGINEID_FORMAT_TEXT :
/* max. 27-byte string, administratively assigned */
if ( len_remain < = 27 ) {
2022-03-28 12:24:53 +00:00
proto_tree_add_item ( tree , hf_snmp_engineid_text , tvb , offset , len_remain , ENC_ASCII ) ;
2014-08-11 07:35:11 +00:00
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 " ) ;
2019-10-20 18:36:53 +00:00
/* demystify: 4B random, 4B/8B epoch seconds */
2019-09-14 07:42:57 +00:00
if ( ( len_remain = = 8 ) | | ( len_remain = = 12 ) ) {
2019-10-20 18:36:53 +00:00
proto_tree_add_item ( tree , hf_snmp_engineid_data , tvb , offset , 4 , ENC_NA ) ;
if ( len_remain = = 8 ) {
seconds = ( time_t ) tvb_get_letohl ( tvb , offset + 4 ) ;
} else {
seconds = ( time_t ) tvb_get_letohi64 ( tvb , offset + 4 ) ;
}
2014-08-11 07:35:11 +00:00
ts . secs = seconds ;
ts . nsecs = 0 ;
2019-10-20 18:36:53 +00:00
proto_tree_add_time_format_value ( tree , hf_snmp_engineid_time , tvb , offset + 4 , len_remain - 4 ,
2014-08-11 07:35:11 +00:00
& ts , " %s " ,
2021-07-23 19:21:02 +00:00
abs_time_secs_to_str ( pinfo - > pool , seconds , ABSOLUTE_TIME_LOCAL , TRUE ) ) ;
2019-09-14 07:42:57 +00:00
offset + = len_remain ;
2014-08-11 07:35:11 +00:00
len_remain = 0 ;
}
break ;
}
/* fall through */
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 , ENC_NA ) ;
offset + = len_remain ;
len_remain = 0 ;
}
break ;
}
2005-12-04 21:45:38 +00:00
}
2014-08-11 07:35:11 +00:00
if ( len_remain > 0 ) {
proto_tree_add_expert ( tree , pinfo , & ei_snmp_rfc3411_non_conformant , tvb , offset , len_remain ) ;
offset + = len_remain ;
2005-12-04 21:45:38 +00:00
}
2014-08-11 07:35:11 +00:00
return offset ;
2005-12-04 21:45:38 +00:00
}
2007-01-10 01:15:18 +00:00
2007-02-07 14:54:35 +00:00
static void set_ue_keys ( snmp_ue_assoc_t * n ) {
2017-07-30 14:07:43 +00:00
guint key_size = auth_hash_len [ n - > user . authModel ] ;
2007-07-19 13:43:36 +00:00
2014-06-15 16:40:42 +00:00
n - > user . authKey . data = ( guint8 * ) g_malloc ( key_size ) ;
2007-02-07 14:54:35 +00:00
n - > user . authKey . len = key_size ;
2017-07-30 14:07:43 +00:00
snmp_usm_password_to_key ( n - > user . authModel ,
n - > user . authPassword . data ,
n - > user . authPassword . len ,
n - > engine . data ,
n - > engine . len ,
n - > user . authKey . data ) ;
2007-07-19 13:43:36 +00:00
2013-02-26 11:38:39 +00:00
if ( n - > priv_proto = = PRIV_AES128 | | n - > priv_proto = = PRIV_AES192 | | n - > priv_proto = = PRIV_AES256 ) {
2013-06-19 18:33:49 +00:00
guint need_key_len =
2013-02-26 11:38:39 +00:00
( n - > priv_proto = = PRIV_AES128 ) ? 16 :
( n - > priv_proto = = PRIV_AES192 ) ? 24 :
( n - > priv_proto = = PRIV_AES256 ) ? 32 :
0 ;
guint key_len = key_size ;
while ( key_len < need_key_len )
key_len + = key_size ;
2014-06-15 16:40:42 +00:00
n - > user . privKey . data = ( guint8 * ) g_malloc ( key_len ) ;
2013-02-26 11:38:39 +00:00
n - > user . privKey . len = need_key_len ;
2017-07-30 14:07:43 +00:00
snmp_usm_password_to_key ( n - > user . authModel ,
n - > user . privPassword . data ,
n - > user . privPassword . len ,
n - > engine . data ,
n - > engine . len ,
n - > user . privKey . data ) ;
2013-02-26 11:38:39 +00:00
key_len = key_size ;
/* extend key if needed */
while ( key_len < need_key_len ) {
2017-07-30 14:07:43 +00:00
snmp_usm_password_to_key ( n - > user . authModel ,
n - > user . privKey . data ,
key_len ,
n - > engine . data ,
n - > engine . len ,
n - > user . privKey . data + key_len ) ;
2013-02-26 11:38:39 +00:00
key_len + = key_size ;
}
} else {
2014-06-15 16:40:42 +00:00
n - > user . privKey . data = ( guint8 * ) g_malloc ( key_size ) ;
2013-02-26 11:38:39 +00:00
n - > user . privKey . len = key_size ;
2017-07-30 14:07:43 +00:00
snmp_usm_password_to_key ( n - > user . authModel ,
n - > user . privPassword . data ,
n - > user . privPassword . len ,
n - > engine . data ,
n - > engine . len ,
n - > user . privKey . data ) ;
2013-02-26 11:38:39 +00:00
}
2007-02-07 14:54:35 +00:00
}
2010-10-14 01:44:27 +00:00
static snmp_ue_assoc_t *
2014-06-15 16:40:42 +00:00
ue_dup ( snmp_ue_assoc_t * o )
2010-10-14 01:44:27 +00:00
{
2021-03-23 15:41:54 +00:00
snmp_ue_assoc_t * d = ( snmp_ue_assoc_t * ) g_memdup2 ( o , sizeof ( snmp_ue_assoc_t ) ) ;
2007-07-19 13:43:36 +00:00
2007-02-07 14:54:35 +00:00
d - > user . authModel = o - > user . authModel ;
2007-07-19 13:43:36 +00:00
2007-02-07 14:54:35 +00:00
d - > user . privProtocol = o - > user . privProtocol ;
2007-07-19 13:43:36 +00:00
2021-03-23 15:41:54 +00:00
d - > user . userName . data = ( guint8 * ) g_memdup2 ( o - > user . userName . data , o - > user . userName . len ) ;
2007-02-07 14:54:35 +00:00
d - > user . userName . len = o - > user . userName . len ;
2007-07-19 13:43:36 +00:00
2021-03-23 15:41:54 +00:00
d - > user . authPassword . data = o - > user . authPassword . data ? ( guint8 * ) g_memdup2 ( o - > user . authPassword . data , o - > user . authPassword . len ) : NULL ;
2007-02-07 14:54:35 +00:00
d - > user . authPassword . len = o - > user . authPassword . len ;
2007-07-19 13:43:36 +00:00
2021-03-23 15:41:54 +00:00
d - > user . privPassword . data = o - > user . privPassword . data ? ( guint8 * ) g_memdup2 ( o - > user . privPassword . data , o - > user . privPassword . len ) : NULL ;
2007-02-07 14:54:35 +00:00
d - > user . privPassword . len = o - > user . privPassword . len ;
2007-07-19 13:43:36 +00:00
2007-02-07 14:54:35 +00:00
d - > engine . len = o - > engine . len ;
2007-07-19 13:43:36 +00:00
2007-02-07 14:54:35 +00:00
if ( d - > engine . len ) {
2021-03-23 15:41:54 +00:00
d - > engine . data = ( guint8 * ) g_memdup2 ( o - > engine . data , o - > engine . len ) ;
2007-02-07 14:54:35 +00:00
set_ue_keys ( d ) ;
}
2007-07-19 13:43:36 +00:00
2007-02-07 14:54:35 +00:00
return d ;
2007-07-19 13:43:36 +00:00
2007-02-07 14:54:35 +00:00
}
2007-01-10 01:15:18 +00:00
2014-06-15 16:40:42 +00:00
static void *
snmp_users_copy_cb ( void * dest , const void * orig , size_t len _U_ )
{
const snmp_ue_assoc_t * o = ( const snmp_ue_assoc_t * ) orig ;
snmp_ue_assoc_t * d = ( snmp_ue_assoc_t * ) dest ;
d - > auth_model = o - > auth_model ;
2017-07-30 14:07:43 +00:00
d - > user . authModel = ( snmp_usm_auth_model_t ) o - > auth_model ;
2014-06-15 16:40:42 +00:00
d - > priv_proto = o - > priv_proto ;
d - > user . privProtocol = priv_protos [ o - > priv_proto ] ;
2021-03-23 15:41:54 +00:00
d - > user . userName . data = ( guint8 * ) g_memdup2 ( o - > user . userName . data , o - > user . userName . len ) ;
2014-06-15 16:40:42 +00:00
d - > user . userName . len = o - > user . userName . len ;
2021-03-23 15:41:54 +00:00
d - > user . authPassword . data = o - > user . authPassword . data ? ( guint8 * ) g_memdup2 ( o - > user . authPassword . data , o - > user . authPassword . len ) : NULL ;
2014-06-15 16:40:42 +00:00
d - > user . authPassword . len = o - > user . authPassword . len ;
2021-03-23 15:41:54 +00:00
d - > user . privPassword . data = o - > user . privPassword . data ? ( guint8 * ) g_memdup2 ( o - > user . privPassword . data , o - > user . privPassword . len ) : NULL ;
2014-06-15 16:40:42 +00:00
d - > user . privPassword . len = o - > user . privPassword . len ;
d - > engine . len = o - > engine . len ;
if ( o - > engine . data ) {
2021-03-23 15:41:54 +00:00
d - > engine . data = ( guint8 * ) g_memdup2 ( o - > engine . data , o - > engine . len ) ;
2014-06-15 16:40:42 +00:00
}
2021-03-23 15:41:54 +00:00
d - > user . authKey . data = o - > user . authKey . data ? ( guint8 * ) g_memdup2 ( o - > user . authKey . data , o - > user . authKey . len ) : NULL ;
2014-06-15 16:40:42 +00:00
d - > user . authKey . len = o - > user . authKey . len ;
2021-03-23 15:41:54 +00:00
d - > user . privKey . data = o - > user . privKey . data ? ( guint8 * ) g_memdup2 ( o - > user . privKey . data , o - > user . privKey . len ) : NULL ;
2014-06-15 16:40:42 +00:00
d - > user . privKey . len = o - > user . privKey . len ;
return d ;
}
static void
snmp_users_free_cb ( void * p )
{
snmp_ue_assoc_t * ue = ( snmp_ue_assoc_t * ) p ;
g_free ( ue - > user . userName . data ) ;
g_free ( ue - > user . authPassword . data ) ;
g_free ( ue - > user . privPassword . data ) ;
g_free ( ue - > user . authKey . data ) ;
g_free ( ue - > user . privKey . data ) ;
g_free ( ue - > engine . data ) ;
}
2015-02-18 01:21:25 +00:00
static gboolean
2015-01-13 20:13:45 +00:00
snmp_users_update_cb ( void * p _U_ , char * * err )
2014-06-15 16:40:42 +00:00
{
snmp_ue_assoc_t * ue = ( snmp_ue_assoc_t * ) p ;
GString * es = g_string_new ( " " ) ;
unsigned int i ;
* err = NULL ;
2017-02-19 21:02:04 +00:00
if ( ! ue - > user . userName . len ) {
2014-06-15 16:40:42 +00:00
g_string_append_printf ( es , " no userName \n " ) ;
2017-02-19 21:02:04 +00:00
} else if ( ( ue - > engine . len > 0 ) & & ( ue - > engine . len < 5 | | ue - > engine . len > 32 ) ) {
2014-06-15 16:40:42 +00:00
/* RFC 3411 section 5 */
2017-02-19 21:02:04 +00:00
g_string_append_printf ( es , " Invalid engineId length (%u). Must be between 5 and 32 (10 and 64 hex digits) \n " , ue - > engine . len ) ;
} else if ( num_ueas ) {
for ( i = 0 ; i < num_ueas - 1 ; i + + ) {
snmp_ue_assoc_t * u = & ( ueas [ i ] ) ;
if ( u - > user . userName . len = = ue - > user . userName . len
& & u - > engine . len = = ue - > engine . len & & ( u ! = ue ) ) {
if ( u - > engine . len > 0 & & memcmp ( u - > engine . data , ue - > engine . data , u - > engine . len ) = = 0 ) {
if ( memcmp ( u - > user . userName . data , ue - > user . userName . data , ue - > user . userName . len ) = = 0 ) {
/* XXX: make a string for the engineId */
g_string_append_printf ( es , " Duplicate key (userName='%s') \n " , ue - > user . userName . data ) ;
break ;
}
2014-06-15 16:40:42 +00:00
}
2017-02-19 21:02:04 +00:00
if ( u - > engine . len = = 0 ) {
if ( memcmp ( u - > user . userName . data , ue - > user . userName . data , ue - > user . userName . len ) = = 0 ) {
g_string_append_printf ( es , " Duplicate key (userName='%s' engineId=NONE) \n " , ue - > user . userName . data ) ;
break ;
}
2014-06-15 16:40:42 +00:00
}
}
}
}
if ( es - > len ) {
es = g_string_truncate ( es , es - > len - 1 ) ;
* err = g_string_free ( es , FALSE ) ;
2015-02-18 01:21:25 +00:00
return FALSE ;
2014-06-15 16:40:42 +00:00
}
2015-02-18 01:21:25 +00:00
return TRUE ;
2014-06-15 16:40:42 +00:00
}
static void
free_ue_cache ( snmp_ue_assoc_t * * cache )
{
static snmp_ue_assoc_t * a , * nxt ;
for ( a = * cache ; a ; a = nxt ) {
nxt = a - > next ;
snmp_users_free_cb ( a ) ;
g_free ( a ) ;
}
* cache = NULL ;
}
2007-01-10 01:15:18 +00:00
2007-01-11 00:29:50 +00:00
# define CACHE_INSERT(c,a) if (c) { snmp_ue_assoc_t* t = c; c = a; c->next = t; } else { c = a; a->next = NULL; }
2010-10-14 01:44:27 +00:00
static void
2015-06-27 22:33:42 +00:00
init_ue_cache ( void )
2010-10-14 01:44:27 +00:00
{
2015-06-27 22:33:42 +00:00
guint i ;
2007-07-19 13:43:36 +00:00
2015-06-27 22:33:42 +00:00
for ( i = 0 ; i < num_ueas ; i + + ) {
snmp_ue_assoc_t * a = ue_dup ( & ( ueas [ i ] ) ) ;
2007-02-07 14:54:35 +00:00
2015-06-27 22:33:42 +00:00
if ( a - > engine . len ) {
CACHE_INSERT ( localized_ues , a ) ;
2007-01-12 00:33:32 +00:00
2015-06-27 22:33:42 +00:00
} else {
CACHE_INSERT ( unlocalized_ues , a ) ;
2007-01-11 00:29:50 +00:00
}
2015-06-27 22:33:42 +00:00
2007-01-11 00:29:50 +00:00
}
}
2015-06-27 22:33:42 +00:00
static void
cleanup_ue_cache ( void )
{
free_ue_cache ( & localized_ues ) ;
free_ue_cache ( & unlocalized_ues ) ;
}
/* Called when the user applies changes to UAT preferences. */
static void
renew_ue_cache ( void )
{
cleanup_ue_cache ( ) ;
init_ue_cache ( ) ;
}
2007-01-11 00:29:50 +00:00
2010-10-14 01:44:27 +00:00
static snmp_ue_assoc_t *
localize_ue ( snmp_ue_assoc_t * o , const guint8 * engine , guint engine_len )
{
2021-03-23 15:41:54 +00:00
snmp_ue_assoc_t * n = ( snmp_ue_assoc_t * ) g_memdup2 ( o , sizeof ( snmp_ue_assoc_t ) ) ;
2007-01-12 00:33:32 +00:00
2021-03-23 15:41:54 +00:00
n - > user . userName . data = ( guint8 * ) g_memdup2 ( o - > user . userName . data , o - > user . userName . len ) ;
2018-02-19 14:27:21 +00:00
n - > user . authModel = o - > user . authModel ;
2021-03-23 15:41:54 +00:00
n - > user . authPassword . data = ( guint8 * ) g_memdup2 ( o - > user . authPassword . data , o - > user . authPassword . len ) ;
2018-02-19 14:27:21 +00:00
n - > user . authPassword . len = o - > user . authPassword . len ;
2021-03-23 15:41:54 +00:00
n - > user . privPassword . data = ( guint8 * ) g_memdup2 ( o - > user . privPassword . data , o - > user . privPassword . len ) ;
2018-02-19 14:27:21 +00:00
n - > user . privPassword . len = o - > user . privPassword . len ;
2021-03-23 15:41:54 +00:00
n - > user . authKey . data = ( guint8 * ) g_memdup2 ( o - > user . authKey . data , o - > user . authKey . len ) ;
n - > user . privKey . data = ( guint8 * ) g_memdup2 ( o - > user . privKey . data , o - > user . privKey . len ) ;
n - > engine . data = ( guint8 * ) g_memdup2 ( engine , engine_len ) ;
2007-01-11 00:29:50 +00:00
n - > engine . len = engine_len ;
2018-02-19 14:27:21 +00:00
n - > priv_proto = o - > priv_proto ;
2007-01-12 00:33:32 +00:00
2007-02-07 14:54:35 +00:00
set_ue_keys ( n ) ;
2007-07-19 13:43:36 +00:00
2007-01-11 00:29:50 +00:00
return n ;
}
# define localized_match(a,u,ul,e,el) \
( a - > user . userName . len = = ul \
& & a - > engine . len = = el \
2010-03-02 05:44:04 +00:00
& & memcmp ( a - > user . userName . data , u , ul ) = = 0 \
& & memcmp ( a - > engine . data , e , el ) = = 0 )
2007-01-11 00:29:50 +00:00
# define unlocalized_match(a,u,l) \
2010-03-02 05:44:04 +00:00
( a - > user . userName . len = = l & & memcmp ( a - > user . userName . data , u , l ) = = 0 )
2007-01-10 01:15:18 +00:00
2010-10-14 01:44:27 +00:00
static snmp_ue_assoc_t *
2021-08-23 21:41:43 +00:00
get_user_assoc ( tvbuff_t * engine_tvb , tvbuff_t * user_tvb , packet_info * pinfo )
2010-10-14 01:44:27 +00:00
{
2007-01-09 18:38:55 +00:00
static snmp_ue_assoc_t * a ;
guint given_username_len ;
guint8 * given_username ;
2018-02-19 14:27:21 +00:00
guint given_engine_len = 0 ;
guint8 * given_engine = NULL ;
2007-01-12 00:33:32 +00:00
2007-01-11 00:29:50 +00:00
if ( ! ( localized_ues | | unlocalized_ues ) ) return NULL ;
2007-01-09 18:38:55 +00:00
if ( ! ( user_tvb & & engine_tvb ) ) return NULL ;
2007-01-12 00:33:32 +00:00
2014-06-21 00:36:59 +00:00
given_username_len = tvb_captured_length ( user_tvb ) ;
given_engine_len = tvb_captured_length ( engine_tvb ) ;
2012-07-10 15:43:03 +00:00
if ( ! ( given_engine_len & & given_username_len ) ) return NULL ;
2021-08-23 21:41:43 +00:00
given_username = ( guint8 * ) tvb_memdup ( pinfo - > pool , user_tvb , 0 , - 1 ) ;
given_engine = ( guint8 * ) tvb_memdup ( pinfo - > pool , engine_tvb , 0 , - 1 ) ;
2007-01-12 00:33:32 +00:00
2007-01-11 00:29:50 +00:00
for ( a = localized_ues ; a ; a = a - > next ) {
if ( localized_match ( a , given_username , given_username_len , given_engine , given_engine_len ) ) {
return a ;
}
}
2007-01-12 00:33:32 +00:00
2007-01-11 00:29:50 +00:00
for ( a = unlocalized_ues ; a ; a = a - > next ) {
if ( unlocalized_match ( a , given_username , given_username_len ) ) {
snmp_ue_assoc_t * n = localize_ue ( a , given_engine , given_engine_len ) ;
CACHE_INSERT ( localized_ues , n ) ;
return n ;
2007-01-09 18:38:55 +00:00
}
}
2007-01-12 00:33:32 +00:00
2007-01-09 18:38:55 +00:00
return NULL ;
}
2010-10-14 01:44:27 +00:00
static gboolean
2021-08-23 21:41:43 +00:00
snmp_usm_auth ( const packet_info * pinfo , const snmp_usm_auth_model_t model , snmp_usm_params_t * p , guint8 * * calc_auth_p ,
2017-07-30 14:07:43 +00:00
guint * calc_auth_len_p , gchar const * * error )
2010-10-14 01:44:27 +00:00
{
2012-07-13 20:47:08 +00:00
gint msg_len ;
2007-01-09 18:38:55 +00:00
guint8 * msg ;
guint auth_len ;
guint8 * auth ;
guint8 * key ;
guint key_len ;
2008-10-13 06:56:27 +00:00
guint8 * calc_auth ;
2007-01-09 18:38:55 +00:00
guint start ;
guint end ;
guint i ;
2007-01-12 00:33:32 +00:00
2007-01-09 18:38:55 +00:00
if ( ! p - > auth_tvb ) {
* error = " No Authenticator " ;
2007-01-12 00:33:32 +00:00
return FALSE ;
2007-01-09 18:38:55 +00:00
}
2007-01-12 00:33:32 +00:00
2007-01-09 18:38:55 +00:00
key = p - > user_assoc - > user . authKey . data ;
key_len = p - > user_assoc - > user . authKey . len ;
2007-01-12 00:33:32 +00:00
2007-01-09 18:38:55 +00:00
if ( ! key ) {
* error = " User has no authKey " ;
return FALSE ;
}
2007-01-12 00:33:32 +00:00
2014-06-21 00:36:59 +00:00
auth_len = tvb_captured_length ( p - > auth_tvb ) ;
2007-01-12 00:33:32 +00:00
2017-07-30 14:07:43 +00:00
if ( auth_len ! = auth_tag_len [ model ] ) {
2007-01-09 18:38:55 +00:00
* error = " Authenticator length wrong " ;
return FALSE ;
}
2007-01-12 00:33:32 +00:00
2014-06-21 00:36:59 +00:00
msg_len = tvb_captured_length ( p - > msg_tvb ) ;
2012-05-24 23:35:23 +00:00
if ( msg_len < = 0 ) {
* error = " Not enough data remaining " ;
return FALSE ;
}
2021-08-23 21:41:43 +00:00
msg = ( guint8 * ) tvb_memdup ( pinfo - > pool , p - > msg_tvb , 0 , msg_len ) ;
2007-01-12 00:33:32 +00:00
2021-08-23 21:41:43 +00:00
auth = ( guint8 * ) tvb_memdup ( pinfo - > pool , p - > auth_tvb , 0 , auth_len ) ;
2007-01-09 18:38:55 +00:00
start = p - > auth_offset - p - > start_offset ;
2017-07-30 14:07:43 +00:00
end = start + auth_len ;
2007-01-09 18:38:55 +00:00
/* fill the authenticator with zeros */
for ( i = start ; i < end ; i + + ) {
msg [ i ] = ' \0 ' ;
}
2021-08-23 21:41:43 +00:00
calc_auth = ( guint8 * ) wmem_alloc ( pinfo - > pool , auth_hash_len [ model ] ) ;
2008-10-13 06:56:27 +00:00
2017-07-30 14:07:43 +00:00
if ( ws_hmac_buffer ( auth_hash_algo [ model ] , calc_auth , msg , msg_len , key , key_len ) ) {
2017-02-13 18:31:26 +00:00
return FALSE ;
}
2007-01-12 00:33:32 +00:00
2007-01-11 17:39:16 +00:00
if ( calc_auth_p ) * calc_auth_p = calc_auth ;
2017-07-30 14:07:43 +00:00
if ( calc_auth_len_p ) * calc_auth_len_p = auth_len ;
2007-01-11 17:39:16 +00:00
2017-07-30 14:07:43 +00:00
return ( memcmp ( auth , calc_auth , auth_len ) ! = 0 ) ? FALSE : TRUE ;
2007-01-09 18:38:55 +00:00
}
2010-10-14 01:44:27 +00:00
static tvbuff_t *
2017-02-09 14:00:19 +00:00
snmp_usm_priv_des ( snmp_usm_params_t * p , tvbuff_t * encryptedData , packet_info * pinfo , gchar const * * error )
2010-10-14 01:44:27 +00:00
{
2014-08-11 07:35:11 +00:00
gcry_error_t err ;
gcry_cipher_hd_t hd = NULL ;
2007-01-12 00:33:32 +00:00
2007-01-09 18:38:55 +00:00
guint8 * cleartext ;
guint8 * des_key = p - > user_assoc - > user . privKey . data ; /* first 8 bytes */
guint8 * pre_iv = & ( p - > user_assoc - > user . privKey . data [ 8 ] ) ; /* last 8 bytes */
guint8 * salt ;
gint salt_len ;
gint cryptgrm_len ;
guint8 * cryptgrm ;
tvbuff_t * clear_tvb ;
2007-01-10 01:15:18 +00:00
guint8 iv [ 8 ] ;
2007-01-09 18:38:55 +00:00
guint i ;
2007-01-12 00:33:32 +00:00
2014-06-21 00:36:59 +00:00
salt_len = tvb_captured_length ( p - > priv_tvb ) ;
2007-01-12 00:33:32 +00:00
2014-08-13 06:51:20 +00:00
if ( salt_len ! = 8 ) {
2007-07-19 13:43:36 +00:00
* error = " decryptionError: msgPrivacyParameters length != 8 " ;
2007-01-09 18:38:55 +00:00
return NULL ;
2007-01-12 00:33:32 +00:00
}
2007-01-09 18:38:55 +00:00
2021-07-23 19:21:02 +00:00
salt = ( guint8 * ) tvb_memdup ( pinfo - > pool , p - > priv_tvb , 0 , salt_len ) ;
2007-01-09 18:38:55 +00:00
/*
The resulting " salt " is XOR - ed with the pre - IV to obtain the IV .
*/
for ( i = 0 ; i < 8 ; i + + ) {
iv [ i ] = pre_iv [ i ] ^ salt [ i ] ;
}
2014-06-21 00:36:59 +00:00
cryptgrm_len = tvb_captured_length ( encryptedData ) ;
2007-01-09 18:38:55 +00:00
2012-05-24 23:35:23 +00:00
if ( ( cryptgrm_len < = 0 ) | | ( cryptgrm_len % 8 ) ) {
2015-11-15 20:06:10 +00:00
* error = " decryptionError: the length of the encrypted data is not a multiple of 8 octets " ;
2007-01-09 18:38:55 +00:00
return NULL ;
}
2007-01-12 00:33:32 +00:00
2021-07-23 19:21:02 +00:00
cryptgrm = ( guint8 * ) tvb_memdup ( pinfo - > pool , encryptedData , 0 , - 1 ) ;
2007-01-09 18:38:55 +00:00
2016-07-20 21:54:35 +00:00
cleartext = ( guint8 * ) wmem_alloc ( pinfo - > pool , cryptgrm_len ) ;
2007-01-12 00:33:32 +00:00
2007-01-09 18:38:55 +00:00
err = gcry_cipher_open ( & hd , GCRY_CIPHER_DES , GCRY_CIPHER_MODE_CBC , 0 ) ;
if ( err ! = GPG_ERR_NO_ERROR ) goto on_gcry_error ;
2007-01-12 00:33:32 +00:00
2010-10-14 01:44:27 +00:00
err = gcry_cipher_setiv ( hd , iv , 8 ) ;
2007-01-09 18:38:55 +00:00
if ( err ! = GPG_ERR_NO_ERROR ) goto on_gcry_error ;
2007-01-12 00:33:32 +00:00
2007-01-09 18:38:55 +00:00
err = gcry_cipher_setkey ( hd , des_key , 8 ) ;
if ( err ! = GPG_ERR_NO_ERROR ) goto on_gcry_error ;
2007-01-12 00:33:32 +00:00
2007-01-09 18:38:55 +00:00
err = gcry_cipher_decrypt ( hd , cleartext , cryptgrm_len , cryptgrm , cryptgrm_len ) ;
if ( err ! = GPG_ERR_NO_ERROR ) goto on_gcry_error ;
2007-01-12 00:33:32 +00:00
2007-01-09 18:38:55 +00:00
gcry_cipher_close ( hd ) ;
2007-01-12 00:33:32 +00:00
2009-05-14 20:04:28 +00:00
clear_tvb = tvb_new_child_real_data ( encryptedData , cleartext , cryptgrm_len , cryptgrm_len ) ;
2007-01-12 00:33:32 +00:00
2007-01-09 18:38:55 +00:00
return clear_tvb ;
2007-01-12 00:33:32 +00:00
2007-01-09 18:38:55 +00:00
on_gcry_error :
2017-12-29 12:15:05 +00:00
* error = ( const gchar * ) gcry_strerror ( err ) ;
2007-01-09 18:38:55 +00:00
if ( hd ) gcry_cipher_close ( hd ) ;
return NULL ;
}
2010-10-14 01:44:27 +00:00
static tvbuff_t *
2016-07-20 21:54:35 +00:00
snmp_usm_priv_aes_common ( snmp_usm_params_t * p , tvbuff_t * encryptedData , packet_info * pinfo , gchar const * * error , int algo )
2010-10-14 01:44:27 +00:00
{
gcry_error_t err ;
gcry_cipher_hd_t hd = NULL ;
2007-01-12 00:33:32 +00:00
2007-01-10 02:30:22 +00:00
guint8 * cleartext ;
2013-02-26 11:38:39 +00:00
guint8 * aes_key = p - > user_assoc - > user . privKey . data ;
int aes_key_len = p - > user_assoc - > user . privKey . len ;
2007-01-11 17:39:16 +00:00
guint8 iv [ 16 ] ;
gint priv_len ;
2007-01-10 02:30:22 +00:00
gint cryptgrm_len ;
guint8 * cryptgrm ;
tvbuff_t * clear_tvb ;
2014-06-21 00:36:59 +00:00
priv_len = tvb_captured_length ( p - > priv_tvb ) ;
2007-01-12 00:33:32 +00:00
2014-08-13 06:51:20 +00:00
if ( priv_len ! = 8 ) {
2007-07-19 13:43:36 +00:00
* error = " decryptionError: msgPrivacyParameters length != 8 " ;
2007-01-10 02:30:22 +00:00
return NULL ;
2007-01-12 00:33:32 +00:00
}
2007-01-10 02:30:22 +00:00
iv [ 0 ] = ( p - > boots & 0xff000000 ) > > 24 ;
iv [ 1 ] = ( p - > boots & 0x00ff0000 ) > > 16 ;
iv [ 2 ] = ( p - > boots & 0x0000ff00 ) > > 8 ;
iv [ 3 ] = ( p - > boots & 0x000000ff ) ;
2015-09-10 15:39:07 +00:00
iv [ 4 ] = ( p - > snmp_time & 0xff000000 ) > > 24 ;
iv [ 5 ] = ( p - > snmp_time & 0x00ff0000 ) > > 16 ;
iv [ 6 ] = ( p - > snmp_time & 0x0000ff00 ) > > 8 ;
iv [ 7 ] = ( p - > snmp_time & 0x000000ff ) ;
2007-01-10 02:30:22 +00:00
tvb_memcpy ( p - > priv_tvb , & ( iv [ 8 ] ) , 0 , 8 ) ;
2007-01-12 00:33:32 +00:00
2014-06-21 00:36:59 +00:00
cryptgrm_len = tvb_captured_length ( encryptedData ) ;
2012-05-24 23:35:23 +00:00
if ( cryptgrm_len < = 0 ) {
* error = " Not enough data remaining " ;
return NULL ;
}
2021-07-23 19:21:02 +00:00
cryptgrm = ( guint8 * ) tvb_memdup ( pinfo - > pool , encryptedData , 0 , - 1 ) ;
2007-01-12 00:33:32 +00:00
2016-07-20 21:54:35 +00:00
cleartext = ( guint8 * ) wmem_alloc ( pinfo - > pool , cryptgrm_len ) ;
2007-01-12 00:33:32 +00:00
2013-02-26 11:38:39 +00:00
err = gcry_cipher_open ( & hd , algo , GCRY_CIPHER_MODE_CFB , 0 ) ;
2007-01-10 02:30:22 +00:00
if ( err ! = GPG_ERR_NO_ERROR ) goto on_gcry_error ;
2007-01-12 00:33:32 +00:00
2010-10-14 01:44:27 +00:00
err = gcry_cipher_setiv ( hd , iv , 16 ) ;
2007-01-10 02:30:22 +00:00
if ( err ! = GPG_ERR_NO_ERROR ) goto on_gcry_error ;
2007-01-12 00:33:32 +00:00
2013-02-26 11:38:39 +00:00
err = gcry_cipher_setkey ( hd , aes_key , aes_key_len ) ;
2007-01-10 02:30:22 +00:00
if ( err ! = GPG_ERR_NO_ERROR ) goto on_gcry_error ;
2007-01-12 00:33:32 +00:00
2007-01-10 02:30:22 +00:00
err = gcry_cipher_decrypt ( hd , cleartext , cryptgrm_len , cryptgrm , cryptgrm_len ) ;
if ( err ! = GPG_ERR_NO_ERROR ) goto on_gcry_error ;
2007-01-12 00:33:32 +00:00
2007-01-10 02:30:22 +00:00
gcry_cipher_close ( hd ) ;
2007-01-12 00:33:32 +00:00
2009-05-14 20:04:28 +00:00
clear_tvb = tvb_new_child_real_data ( encryptedData , cleartext , cryptgrm_len , cryptgrm_len ) ;
2007-01-12 00:33:32 +00:00
2007-01-10 02:30:22 +00:00
return clear_tvb ;
2007-01-12 00:33:32 +00:00
2007-01-10 02:30:22 +00:00
on_gcry_error :
2017-12-29 12:15:05 +00:00
* error = ( const gchar * ) gcry_strerror ( err ) ;
2007-01-10 02:30:22 +00:00
if ( hd ) gcry_cipher_close ( hd ) ;
2007-01-09 18:38:55 +00:00
return NULL ;
2013-02-26 11:38:39 +00:00
}
static tvbuff_t *
2017-02-09 14:00:19 +00:00
snmp_usm_priv_aes128 ( snmp_usm_params_t * p , tvbuff_t * encryptedData , packet_info * pinfo , gchar const * * error )
2013-02-26 11:38:39 +00:00
{
2016-07-20 21:54:35 +00:00
return snmp_usm_priv_aes_common ( p , encryptedData , pinfo , error , GCRY_CIPHER_AES ) ;
2013-02-26 11:38:39 +00:00
}
static tvbuff_t *
2017-02-09 14:00:19 +00:00
snmp_usm_priv_aes192 ( snmp_usm_params_t * p , tvbuff_t * encryptedData , packet_info * pinfo , gchar const * * error )
2013-02-26 11:38:39 +00:00
{
2016-07-20 21:54:35 +00:00
return snmp_usm_priv_aes_common ( p , encryptedData , pinfo , error , GCRY_CIPHER_AES192 ) ;
2007-01-09 18:38:55 +00:00
}
2013-02-26 11:38:39 +00:00
static tvbuff_t *
2017-02-09 14:00:19 +00:00
snmp_usm_priv_aes256 ( snmp_usm_params_t * p , tvbuff_t * encryptedData , packet_info * pinfo , gchar const * * error )
2013-02-26 11:38:39 +00:00
{
2016-07-20 21:54:35 +00:00
return snmp_usm_priv_aes_common ( p , encryptedData , pinfo , error , GCRY_CIPHER_AES256 ) ;
2013-02-26 11:38:39 +00:00
}
2007-01-10 01:15:18 +00:00
2013-03-20 05:59:22 +00:00
static gboolean
2010-10-14 01:44:27 +00:00
check_ScopedPdu ( tvbuff_t * tvb )
{
2007-01-11 17:39:16 +00:00
int offset ;
2011-11-20 08:59:19 +00:00
gint8 ber_class ;
2007-01-11 17:39:16 +00:00
gboolean pc ;
gint32 tag ;
int hoffset , eoffset ;
guint32 len ;
2011-11-20 08:59:19 +00:00
offset = get_ber_identifier ( tvb , 0 , & ber_class , & pc , & tag ) ;
2007-08-24 07:12:04 +00:00
offset = get_ber_length ( tvb , offset , NULL , NULL ) ;
2007-01-12 00:33:32 +00:00
2011-11-20 08:59:19 +00:00
if ( ! ( ( ( ber_class ! = BER_CLASS_APP ) & & ( ber_class ! = BER_CLASS_PRI ) )
& & ( ( ! pc ) | | ( ber_class ! = BER_CLASS_UNI ) | | ( tag ! = BER_UNI_TAG_ENUMERATED ) )
2007-01-11 17:39:16 +00:00
) ) return FALSE ;
if ( ( tvb_get_guint8 ( tvb , offset ) = = 0 ) & & ( tvb_get_guint8 ( tvb , offset + 1 ) = = 0 ) )
return TRUE ;
2007-01-12 00:33:32 +00:00
2007-01-11 17:39:16 +00:00
hoffset = offset ;
2007-01-10 01:15:18 +00:00
2011-11-20 08:59:19 +00:00
offset = get_ber_identifier ( tvb , offset , & ber_class , & pc , & tag ) ;
2007-08-24 07:12:04 +00:00
offset = get_ber_length ( tvb , offset , & len , NULL ) ;
2007-01-11 17:39:16 +00:00
eoffset = offset + len ;
2007-01-12 00:33:32 +00:00
2007-01-11 17:39:16 +00:00
if ( eoffset < = hoffset ) return FALSE ;
2007-01-12 00:33:32 +00:00
2011-11-20 08:59:19 +00:00
if ( ( ber_class ! = BER_CLASS_APP ) & & ( ber_class ! = BER_CLASS_PRI ) )
if ( ( ber_class ! = BER_CLASS_UNI )
2007-01-11 17:39:16 +00:00
| | ( ( tag < BER_UNI_TAG_NumericString ) & & ( tag ! = BER_UNI_TAG_OCTETSTRING ) & & ( tag ! = BER_UNI_TAG_UTF8String ) ) )
return FALSE ;
2007-01-12 00:33:32 +00:00
2007-01-11 17:39:16 +00:00
return TRUE ;
2007-01-12 00:33:32 +00:00
2007-01-11 17:39:16 +00:00
}
2007-01-10 01:15:18 +00:00
2005-12-04 21:45:38 +00:00
# include "packet-snmp-fn.c"
2019-11-05 22:32:50 +00:00
static snmp_conv_info_t *
2019-11-07 15:38:25 +00:00
snmp_find_conversation_and_get_conv_data ( packet_info * pinfo ) {
2019-11-05 22:32:50 +00:00
conversation_t * conversation ;
snmp_conv_info_t * snmp_info = NULL ;
2022-08-26 02:42:38 +00:00
conversation = find_conversation ( pinfo - > fd - > num , & pinfo - > src , & pinfo - > dst , conversation_pt_to_conversation_type ( pinfo - > ptype ) ,
2019-11-05 22:32:50 +00:00
pinfo - > srcport , pinfo - > destport , 0 ) ;
if ( ( conversation = = NULL ) | | ( conversation_get_dissector ( conversation , pinfo - > num ) ! = snmp_handle ) ) {
2022-08-26 02:42:38 +00:00
conversation = conversation_new ( pinfo - > num , & pinfo - > src , & pinfo - > dst , conversation_pt_to_conversation_type ( pinfo - > ptype ) ,
2019-11-05 22:32:50 +00:00
pinfo - > srcport , pinfo - > destport , 0 ) ;
conversation_set_dissector ( conversation , snmp_handle ) ;
}
snmp_info = ( snmp_conv_info_t * ) conversation_get_proto_data ( conversation , proto_snmp ) ;
if ( snmp_info = = NULL ) {
snmp_info = wmem_new0 ( wmem_file_scope ( ) , snmp_conv_info_t ) ;
snmp_info - > request_response = wmem_map_new ( wmem_file_scope ( ) , g_int_hash , g_int_equal ) ;
conversation_add_proto_data ( conversation , proto_snmp , snmp_info ) ;
}
return snmp_info ;
}
2007-01-09 18:38:55 +00:00
2005-12-04 21:45:38 +00:00
guint
dissect_snmp_pdu ( tvbuff_t * tvb , int offset , packet_info * pinfo ,
2010-10-14 01:44:27 +00:00
proto_tree * tree , int proto , gint ett , gboolean is_tcp )
2005-12-04 21:45:38 +00:00
{
guint length_remaining ;
2011-11-20 08:59:19 +00:00
gint8 ber_class ;
2005-12-04 21:45:38 +00:00
gboolean pc , ind = 0 ;
gint32 tag ;
guint32 len ;
guint message_length ;
int start_offset = offset ;
guint32 version = 0 ;
2009-07-09 21:43:57 +00:00
tvbuff_t * next_tvb ;
2005-12-04 21:45:38 +00:00
proto_tree * snmp_tree = NULL ;
proto_item * item = NULL ;
2019-11-05 22:32:50 +00:00
2019-11-07 15:38:25 +00:00
snmp_conv_info_t * snmp_info = snmp_find_conversation_and_get_conv_data ( pinfo ) ;
2019-11-05 22:32:50 +00:00
2007-05-13 20:58:29 +00:00
asn1_ctx_t asn1_ctx ;
asn1_ctx_init ( & asn1_ctx , ASN1_ENC_BER , TRUE , pinfo ) ;
2019-11-05 22:32:50 +00:00
asn1_ctx . private_data = snmp_info ;
2005-12-04 21:45:38 +00:00
2007-01-09 18:38:55 +00:00
usm_p . msg_tvb = tvb ;
2009-09-10 16:54:02 +00:00
usm_p . start_offset = tvb_offset_from_real_beginning ( tvb ) ;
2007-01-09 18:38:55 +00:00
usm_p . engine_tvb = NULL ;
usm_p . user_tvb = NULL ;
usm_p . auth_item = NULL ;
usm_p . auth_tvb = NULL ;
usm_p . auth_offset = 0 ;
usm_p . priv_tvb = NULL ;
usm_p . user_assoc = NULL ;
usm_p . authenticated = FALSE ;
usm_p . encrypted = FALSE ;
2007-01-10 02:30:22 +00:00
usm_p . boots = 0 ;
2015-09-10 15:39:07 +00:00
usm_p . snmp_time = 0 ;
2007-01-11 00:29:50 +00:00
usm_p . authOK = FALSE ;
2007-01-12 00:33:32 +00:00
2005-12-04 21:45:38 +00:00
/*
* 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() " ? )
*/
2015-04-10 12:57:55 +00:00
length_remaining = tvb_ensure_captured_length_remaining ( tvb , offset ) ;
2005-12-04 21:45:38 +00:00
/* 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
2010-12-06 01:34:58 +00:00
* boundaries ? We require at least 6 bytes for the
2005-12-04 21:45:38 +00:00
* header , which allows for a 4 - byte length ( ASN .1
* BER ) .
*/
if ( length_remaining < 6 ) {
2011-03-25 19:02:18 +00:00
/*
* Yes . Tell the TCP dissector where the data
* for this message starts in the data it handed
* us and that we need " some more data. " Don ' t tell
* it exactly how many bytes we need because if / when
* we ask for even more ( after the header ) that will
* break reassembly .
*/
2005-12-04 21:45:38 +00:00
pinfo - > desegment_offset = offset ;
2011-03-25 19:02:18 +00:00
pinfo - > desegment_len = DESEGMENT_ONE_MORE_SEGMENT ;
2016-05-01 16:31:55 +00:00
return - 1 ;
2005-12-04 21:45:38 +00:00
}
}
/*
* OK , try to read the " Sequence Of " header ; this gets the total
* length of the SNMP message .
*/
2014-09-14 09:57:05 +00:00
offset = get_ber_identifier ( tvb , offset , & ber_class , & pc , & tag ) ;
2009-07-09 21:43:57 +00:00
/*Get the total octet length of the SNMP data*/
2014-09-14 09:57:05 +00:00
offset = get_ber_length ( tvb , offset , & len , & ind ) ;
2013-01-20 10:01:34 +00:00
message_length = len + offset ;
2009-07-09 21:43:57 +00:00
/*Get the SNMP version data*/
2014-08-11 07:05:18 +00:00
/*offset =*/ dissect_ber_integer ( FALSE , & asn1_ctx , 0 , tvb , offset , - 1 , & version ) ;
2005-12-04 21:45:38 +00:00
/*
* 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 =
2009-07-09 21:43:57 +00:00
message_length - length_remaining ;
2005-12-04 21:45:38 +00:00
/*
* Return 0 , which means " I didn't dissect anything
* because I don ' t have enough data - we need
* to desegment " .
*/
return 0 ;
}
}
2021-09-07 18:33:39 +00:00
var_list = next_tvb_list_new ( pinfo - > pool ) ;
2006-06-13 13:21:12 +00:00
2014-08-11 07:35:11 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , proto_get_protocol_short_name ( find_protocol_by_id ( proto ) ) ) ;
2005-12-04 21:45:38 +00:00
2014-08-11 07:35:11 +00:00
item = proto_tree_add_item ( tree , proto , tvb , start_offset , message_length , ENC_BIG_ENDIAN ) ;
2014-08-08 13:19:29 +00:00
snmp_tree = proto_item_add_subtree ( item , ett ) ;
2005-12-04 21:45:38 +00:00
2010-10-14 01:44:27 +00:00
switch ( version ) {
2005-12-04 21:45:38 +00:00
case 0 : /* v1 */
case 1 : /* v2c */
2007-05-13 20:58:29 +00:00
offset = dissect_snmp_Message ( FALSE , tvb , start_offset , & asn1_ctx , snmp_tree , - 1 ) ;
2005-12-04 21:45:38 +00:00
break ;
case 2 : /* v2u */
2007-05-13 20:58:29 +00:00
offset = dissect_snmp_Messagev2u ( FALSE , tvb , start_offset , & asn1_ctx , snmp_tree , - 1 ) ;
2005-12-04 21:45:38 +00:00
break ;
/* v3 */
case 3 :
2007-05-13 20:58:29 +00:00
offset = dissect_snmp_SNMPv3Message ( FALSE , tvb , start_offset , & asn1_ctx , snmp_tree , - 1 ) ;
2005-12-04 21:45:38 +00:00
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 .
*/
2014-08-08 13:19:29 +00:00
expert_add_info ( pinfo , item , & ei_snmp_version_unknown ) ;
2005-12-04 21:45:38 +00:00
return length_remaining ;
break ;
}
2009-09-10 16:54:02 +00:00
2009-07-09 21:43:57 +00:00
/* There may be appended data after the SNMP data, so treat as raw
* data which needs to be dissected in case of UDP as UDP is PDU oriented .
*/
if ( ( ! is_tcp ) & & ( length_remaining > ( guint ) offset ) ) {
2009-08-16 12:36:22 +00:00
next_tvb = tvb_new_subset_remaining ( tvb , offset ) ;
2009-07-09 21:43:57 +00:00
call_dissector ( data_handle , next_tvb , pinfo , tree ) ;
2010-10-14 01:44:27 +00:00
} else {
2021-09-07 18:33:39 +00:00
next_tvb_call ( var_list , pinfo , tree , NULL , data_handle ) ;
2009-07-09 21:43:57 +00:00
}
2005-12-04 21:45:38 +00:00
2006-06-13 13:21:12 +00:00
return offset ;
2005-12-04 21:45:38 +00:00
}
static gint
2012-09-10 21:40:21 +00:00
dissect_snmp ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data _U_ )
2005-12-04 21:45:38 +00:00
{
int offset ;
gint8 tmp_class ;
gboolean tmp_pc ;
gint32 tmp_tag ;
guint32 tmp_length ;
gboolean tmp_ind ;
2006-01-18 20:02:19 +00:00
/*
* See if this looks like SNMP or not . if not , return 0 so
2016-02-03 23:02:08 +00:00
* wireshark can try some other dissector instead .
2005-12-04 21:45:38 +00:00
*/
/* 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 ) ;
2010-10-14 01:44:27 +00:00
if ( ( tmp_class ! = BER_CLASS_UNI ) | | ( tmp_tag ! = BER_UNI_TAG_SEQUENCE ) ) {
2005-12-04 21:45:38 +00:00
return 0 ;
}
/* then comes a length which spans the rest of the tvb */
2007-08-24 07:12:04 +00:00
offset = get_ber_length ( tvb , offset , & tmp_length , & tmp_ind ) ;
2010-10-14 01:44:27 +00:00
/* if(tmp_length!=(guint32)tvb_reported_length_remaining(tvb, offset)) {
2016-02-03 23:02:08 +00:00
* Loosen the heuristic a bit to handle the case where data has intentionally
2009-07-09 21:43:57 +00:00
* been added after the snmp PDU ( UDP case )
*/
2010-10-14 01:44:27 +00:00
if ( pinfo - > ptype = = PT_UDP ) {
if ( tmp_length > ( guint32 ) tvb_reported_length_remaining ( tvb , offset ) ) {
2009-07-09 21:43:57 +00:00
return 0 ;
}
} else {
2010-10-14 01:44:27 +00:00
if ( tmp_length ! = ( guint32 ) tvb_reported_length_remaining ( tvb , offset ) ) {
2009-07-09 21:43:57 +00:00
return 0 ;
}
2005-12-04 21:45:38 +00:00
}
/* then comes an INTEGER (version)*/
2011-04-21 16:00:38 +00:00
get_ber_identifier ( tvb , offset , & tmp_class , & tmp_pc , & tmp_tag ) ;
2010-10-14 01:44:27 +00:00
if ( ( tmp_class ! = BER_CLASS_UNI ) | | ( tmp_tag ! = BER_UNI_TAG_INTEGER ) ) {
2005-12-04 21:45:38 +00:00
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 .
*/
return dissect_snmp_pdu ( tvb , 0 , pinfo , tree , proto_snmp , ett_snmp , FALSE ) ;
}
2010-10-14 01:44:27 +00:00
2015-11-24 18:13:18 +00:00
static int
dissect_snmp_tcp ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data _U_ )
2005-12-04 21:45:38 +00:00
{
int offset = 0 ;
guint message_len ;
while ( tvb_reported_length_remaining ( tvb , offset ) > 0 ) {
2014-08-11 07:35:11 +00:00
message_len = dissect_snmp_pdu ( tvb , 0 , pinfo , tree , proto_snmp , ett_snmp , TRUE ) ;
2005-12-04 21:45:38 +00:00
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 ;
}
2015-11-24 18:13:18 +00:00
return tvb_captured_length ( tvb ) ;
2005-12-04 21:45:38 +00:00
}
2006-03-15 06:20:23 +00:00
2014-10-06 13:31:47 +00:00
static int
dissect_smux ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data )
2005-12-04 21:45:38 +00:00
{
2011-04-13 15:48:24 +00:00
proto_tree * smux_tree = NULL ;
2006-03-15 06:20:23 +00:00
proto_item * item = NULL ;
2021-09-07 18:33:39 +00:00
var_list = next_tvb_list_new ( pinfo - > pool ) ;
2007-11-12 18:44:29 +00:00
2009-08-09 06:26:46 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " SMUX " ) ;
2006-03-15 06:20:23 +00:00
2014-10-06 13:31:47 +00:00
item = proto_tree_add_item ( tree , proto_smux , tvb , 0 , - 1 , ENC_NA ) ;
smux_tree = proto_item_add_subtree ( item , ett_smux ) ;
2006-03-15 06:20:23 +00:00
2014-10-06 13:31:47 +00:00
return dissect_SMUX_PDUs_PDU ( tvb , pinfo , smux_tree , data ) ;
2005-12-04 21:45:38 +00:00
}
2006-03-15 06:20:23 +00:00
2007-01-09 18:38:55 +00:00
/*
2017-07-30 14:07:43 +00:00
MD5 Password to Key Algorithm from RFC 3414 A .2 .1
SHA1 Password to Key Algorithm from RFC 3414 A .2 .2
SHA2 Password to Key Algorithm from RFC 7860 9.3
2007-01-09 18:38:55 +00:00
*/
2010-10-14 01:44:27 +00:00
static void
2017-07-30 14:07:43 +00:00
snmp_usm_password_to_key ( const snmp_usm_auth_model_t model , const guint8 * password ,
guint passwordlen , const guint8 * engineID , guint engineLength , guint8 * key )
2010-10-14 01:44:27 +00:00
{
2017-07-30 14:07:43 +00:00
gcry_md_hd_t hash_handle ;
guint8 * cp , password_buf [ 64 ] ;
guint32 password_index = 0 ;
guint32 count = 0 , i ;
guint hash_len ;
2007-01-12 00:33:32 +00:00
2017-07-30 14:07:43 +00:00
if ( gcry_md_open ( & hash_handle , auth_hash_algo [ model ] , 0 ) ) {
2017-02-13 18:31:26 +00:00
return ;
}
2007-01-09 18:38:55 +00:00
2017-07-30 14:07:43 +00:00
hash_len = auth_hash_len [ model ] ;
2007-01-12 00:33:32 +00:00
2007-01-09 18:38:55 +00:00
/**********************************************/
/* Use while loop until we've done 1 Megabyte */
/**********************************************/
while ( count < 1048576 ) {
cp = password_buf ;
2013-05-01 23:59:16 +00:00
if ( passwordlen ! = 0 ) {
for ( i = 0 ; i < 64 ; i + + ) {
/*************************************************/
/* Take the next octet of the password, wrapping */
/* to the beginning of the password as necessary.*/
/*************************************************/
* cp + + = password [ password_index + + % passwordlen ] ;
}
} else {
* cp = 0 ;
2007-01-09 18:38:55 +00:00
}
2017-07-30 14:07:43 +00:00
gcry_md_write ( hash_handle , password_buf , 64 ) ;
2007-01-09 18:38:55 +00:00
count + = 64 ;
}
2017-07-30 14:07:43 +00:00
memcpy ( key , gcry_md_read ( hash_handle , 0 ) , hash_len ) ;
gcry_md_close ( hash_handle ) ;
2007-01-12 00:33:32 +00:00
2007-01-09 18:38:55 +00:00
/*****************************************************/
2017-07-30 14:07:43 +00:00
/* Now localise the key with the engineID and pass */
/* through hash function to produce final key */
2010-12-29 20:09:27 +00:00
/* We ignore invalid engineLengths here. More strict */
/* checking is done in snmp_users_update_cb. */
2007-01-09 18:38:55 +00:00
/*****************************************************/
2017-07-30 14:07:43 +00:00
if ( gcry_md_open ( & hash_handle , auth_hash_algo [ model ] , 0 ) ) {
2017-02-13 18:31:26 +00:00
return ;
}
2017-07-30 14:07:43 +00:00
gcry_md_write ( hash_handle , key , hash_len ) ;
gcry_md_write ( hash_handle , engineID , engineLength ) ;
gcry_md_write ( hash_handle , key , hash_len ) ;
memcpy ( key , gcry_md_read ( hash_handle , 0 ) , hash_len ) ;
gcry_md_close ( hash_handle ) ;
2007-01-09 18:38:55 +00:00
return ;
2017-07-30 14:07:43 +00:00
}
2007-01-12 00:33:32 +00:00
2010-10-14 01:44:27 +00:00
static void
process_prefs ( void )
{
2010-03-02 05:44:04 +00:00
}
2007-01-12 00:33:32 +00:00
2007-02-07 14:54:35 +00:00
UAT_LSTRING_CB_DEF ( snmp_users , userName , snmp_ue_assoc_t , user . userName . data , user . userName . len )
UAT_LSTRING_CB_DEF ( snmp_users , authPassword , snmp_ue_assoc_t , user . authPassword . data , user . authPassword . len )
UAT_LSTRING_CB_DEF ( snmp_users , privPassword , snmp_ue_assoc_t , user . privPassword . data , user . privPassword . len )
UAT_BUFFER_CB_DEF ( snmp_users , engine_id , snmp_ue_assoc_t , engine . data , engine . len )
2013-03-12 06:40:13 +00:00
UAT_VS_DEF ( snmp_users , auth_model , snmp_ue_assoc_t , guint , 0 , " MD5 " )
UAT_VS_DEF ( snmp_users , priv_proto , snmp_ue_assoc_t , guint , 0 , " DES " )
2007-01-12 00:33:32 +00:00
2009-11-01 18:45:43 +00:00
static void *
2010-10-29 21:55:04 +00:00
snmp_specific_trap_copy_cb ( void * dest , const void * orig , size_t len _U_ )
2009-11-01 18:45:43 +00:00
{
2011-11-20 08:59:19 +00:00
snmp_st_assoc_t * u = ( snmp_st_assoc_t * ) dest ;
const snmp_st_assoc_t * o = ( const snmp_st_assoc_t * ) orig ;
2009-11-01 18:45:43 +00:00
u - > enterprise = g_strdup ( o - > enterprise ) ;
u - > trap = o - > trap ;
u - > desc = g_strdup ( o - > desc ) ;
return dest ;
}
static void
snmp_specific_trap_free_cb ( void * r )
{
2011-11-20 08:59:19 +00:00
snmp_st_assoc_t * u = ( snmp_st_assoc_t * ) r ;
2009-11-01 18:45:43 +00:00
g_free ( u - > enterprise ) ;
g_free ( u - > desc ) ;
}
UAT_CSTRING_CB_DEF ( specific_traps , enterprise , snmp_st_assoc_t )
UAT_DEC_CB_DEF ( specific_traps , trap , snmp_st_assoc_t )
UAT_CSTRING_CB_DEF ( specific_traps , desc , snmp_st_assoc_t )
2007-01-09 18:38:55 +00:00
/*--- proto_register_snmp -------------------------------------------*/
2007-01-12 00:33:32 +00:00
void proto_register_snmp ( void ) {
2014-08-11 07:35:11 +00:00
/* List of fields */
static hf_register_info hf [ ] = {
2019-11-05 22:32:50 +00:00
{ & hf_snmp_response_in ,
{ " Response In " , " snmp.response_in " , FT_FRAMENUM , BASE_NONE , NULL , 0x0 ,
" The response to this SNMP request is in this frame " , HFILL } } ,
{ & hf_snmp_response_to ,
{ " Response To " , " snmp.response_to " , FT_FRAMENUM , BASE_NONE , NULL , 0x0 ,
" This is a response to the SNMP request in this frame " , HFILL } } ,
{ & hf_snmp_time ,
{ " Time " , " snmp.time " , FT_RELATIVE_TIME , BASE_NONE , NULL , 0x0 ,
2019-11-07 15:38:25 +00:00
" The time between the Request and the Response " , HFILL } } ,
2005-12-04 21:45:38 +00:00
{ & hf_snmp_v3_flags_auth ,
{ " Authenticated " , " snmp.v3.flags.auth " , FT_BOOLEAN , 8 ,
2009-07-07 14:54:15 +00:00
TFS ( & tfs_set_notset ) , TH_AUTH , NULL , HFILL } } ,
2005-12-04 21:45:38 +00:00
{ & hf_snmp_v3_flags_crypt ,
{ " Encrypted " , " snmp.v3.flags.crypt " , FT_BOOLEAN , 8 ,
2009-07-07 14:54:15 +00:00
TFS ( & tfs_set_notset ) , TH_CRYPT , NULL , HFILL } } ,
2005-12-04 21:45:38 +00:00
{ & hf_snmp_v3_flags_report ,
{ " Reportable " , " snmp.v3.flags.report " , FT_BOOLEAN , 8 ,
2009-07-07 14:54:15 +00:00
TFS ( & tfs_set_notset ) , TH_REPORT , NULL , HFILL } } ,
2005-12-04 21:45:38 +00:00
{ & 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 , {
2017-06-24 13:25:41 +00:00
" Engine Enterprise ID " , " snmp.engineid.enterprise " , FT_UINT32 , BASE_ENTERPRISES ,
STRINGS_ENTERPRISES , 0 , NULL , HFILL } } ,
2005-12-04 21:45:38 +00:00
{ & hf_snmp_engineid_format , {
" Engine ID Format " , " snmp.engineid.format " , FT_UINT8 , BASE_DEC ,
2009-06-22 05:18:37 +00:00
VALS ( snmp_engineid_format_vals ) , 0 , NULL , HFILL } } ,
2005-12-04 21:45:38 +00:00
{ & hf_snmp_engineid_ipv4 , {
" Engine ID Data: IPv4 address " , " snmp.engineid.ipv4 " , FT_IPv4 , BASE_NONE ,
2009-06-22 05:18:37 +00:00
NULL , 0 , NULL , HFILL } } ,
2005-12-04 21:45:38 +00:00
{ & hf_snmp_engineid_ipv6 , {
" Engine ID Data: IPv6 address " , " snmp.engineid.ipv6 " , FT_IPv6 , BASE_NONE ,
2009-06-22 05:18:37 +00:00
NULL , 0 , NULL , HFILL } } ,
2010-03-05 20:09:37 +00:00
{ & hf_snmp_engineid_cisco_type , {
2012-06-09 17:56:08 +00:00
" Engine ID Data: Cisco type " , " snmp.engineid.cisco.type " , FT_UINT8 , BASE_HEX ,
2010-03-05 20:09:37 +00:00
VALS ( snmp_engineid_cisco_type_vals ) , 0 , NULL , HFILL } } ,
2005-12-04 21:45:38 +00:00
{ & hf_snmp_engineid_mac , {
" Engine ID Data: MAC address " , " snmp.engineid.mac " , FT_ETHER , BASE_NONE ,
2009-06-22 05:18:37 +00:00
NULL , 0 , NULL , HFILL } } ,
2005-12-04 21:45:38 +00:00
{ & hf_snmp_engineid_text , {
" Engine ID Data: Text " , " snmp.engineid.text " , FT_STRING , BASE_NONE ,
2009-06-22 05:18:37 +00:00
NULL , 0 , NULL , HFILL } } ,
2005-12-04 21:45:38 +00:00
{ & hf_snmp_engineid_time , {
2009-12-19 03:17:44 +00:00
" Engine ID Data: Creation Time " , " snmp.engineid.time " , FT_ABSOLUTE_TIME , ABSOLUTE_TIME_LOCAL ,
2009-06-22 05:18:37 +00:00
NULL , 0 , NULL , HFILL } } ,
2005-12-04 21:45:38 +00:00
{ & hf_snmp_engineid_data , {
2009-06-22 05:18:37 +00:00
" Engine ID Data " , " snmp.engineid.data " , FT_BYTES , BASE_NONE ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_msgAuthentication , {
2009-07-06 18:35:05 +00:00
" Authentication " , " snmp.v3.auth " , FT_BOOLEAN , BASE_NONE ,
2009-06-22 05:18:37 +00:00
TFS ( & auth_flags ) , 0 , NULL , HFILL } } ,
{ & hf_snmp_decryptedPDU , {
2014-08-13 06:51:20 +00:00
" Decrypted ScopedPDU " , " snmp.decrypted_pdu " , FT_BYTES , BASE_NONE ,
2009-06-22 05:18:37 +00:00
NULL , 0 , " Decrypted PDU " , HFILL } } ,
2010-10-14 01:44:27 +00:00
{ & hf_snmp_noSuchObject , {
" noSuchObject " , " snmp.noSuchObject " , FT_NONE , BASE_NONE ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_noSuchInstance , {
" noSuchInstance " , " snmp.noSuchInstance " , FT_NONE , BASE_NONE ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_endOfMibView , {
" endOfMibView " , " snmp.endOfMibView " , FT_NONE , BASE_NONE ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_unSpecified , {
" unSpecified " , " snmp.unSpecified " , FT_NONE , BASE_NONE ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_integer32_value , {
" Value (Integer32) " , " snmp.value.int " , FT_INT64 , BASE_DEC ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_octetstring_value , {
2020-10-08 13:15:07 +00:00
" Value (OctetString) " , " snmp.value.octets " , FT_BYTES , BASE_SHOW_ASCII_PRINTABLE ,
2010-10-14 01:44:27 +00:00
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_oid_value , {
" Value (OID) " , " snmp.value.oid " , FT_OID , BASE_NONE ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_null_value , {
" Value (Null) " , " snmp.value.null " , FT_NONE , BASE_NONE ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_ipv4_value , {
" Value (IpAddress) " , " snmp.value.ipv4 " , FT_IPv4 , BASE_NONE ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_ipv6_value , {
" Value (IpAddress) " , " snmp.value.ipv6 " , FT_IPv6 , BASE_NONE ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_anyaddress_value , {
" Value (IpAddress) " , " snmp.value.addr " , FT_BYTES , BASE_NONE ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_unsigned32_value , {
" Value (Unsigned32) " , " snmp.value.u32 " , FT_INT64 , BASE_DEC ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_gauge32_value , {
" Value (Gauge32) " , " snmp.value.g32 " , FT_INT64 , BASE_DEC ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_unknown_value , {
" Value (Unknown) " , " snmp.value.unk " , FT_BYTES , BASE_NONE ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_counter_value , {
" Value (Counter32) " , " snmp.value.counter " , FT_UINT64 , BASE_DEC ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_big_counter_value , {
" Value (Counter64) " , " snmp.value.counter " , FT_UINT64 , BASE_DEC ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_nsap_value , {
" Value (NSAP) " , " snmp.value.nsap " , FT_UINT64 , BASE_DEC ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_timeticks_value , {
" Value (Timeticks) " , " snmp.value.timeticks " , FT_UINT64 , BASE_DEC ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_opaque_value , {
" Value (Opaque) " , " snmp.value.opaque " , FT_BYTES , BASE_NONE ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_objectname , {
" Object Name " , " snmp.name " , FT_OID , BASE_NONE ,
NULL , 0 , NULL , HFILL } } ,
{ & hf_snmp_scalar_instance_index , {
" Scalar Instance Index " , " snmp.name.index " , FT_UINT64 , BASE_DEC ,
NULL , 0 , NULL , HFILL } } ,
2013-06-04 20:05:16 +00:00
{ & hf_snmp_var_bind_str , {
" Variable-binding-string " , " snmp.var-bind_str " , FT_STRING , BASE_NONE ,
NULL , 0 , NULL , HFILL } } ,
2014-08-08 13:19:29 +00:00
{ & hf_snmp_agentid_trailer , {
" AgentID Trailer " , " snmp.agentid_trailer " , FT_BYTES , BASE_NONE ,
NULL , 0 , NULL , HFILL } } ,
2007-11-12 18:44:29 +00:00
2005-12-04 21:45:38 +00:00
# include "packet-snmp-hfarr.c"
2014-08-11 07:35:11 +00:00
} ;
/* List of subtrees */
static gint * ett [ ] = {
& ett_snmp ,
& ett_engineid ,
& ett_msgFlags ,
& ett_encryptedPDU ,
& ett_decrypted ,
& ett_authParameters ,
& ett_internet ,
& ett_varbind ,
& ett_name ,
& ett_value ,
& ett_decoding_error ,
2005-12-04 21:45:38 +00:00
# include "packet-snmp-ettarr.c"
2014-08-11 07:35:11 +00:00
} ;
static ei_register_info ei [ ] = {
{ & ei_snmp_failed_decrypted_data_pdu , { " snmp.failed_decrypted_data_pdu " , PI_MALFORMED , PI_WARN , " Failed to decrypt encryptedPDU " , EXPFILL } } ,
{ & ei_snmp_decrypted_data_bad_formatted , { " snmp.decrypted_data_bad_formatted " , PI_MALFORMED , PI_WARN , " Decrypted data not formatted as expected, wrong key? " , EXPFILL } } ,
{ & ei_snmp_verify_authentication_error , { " snmp.verify_authentication_error " , PI_MALFORMED , PI_ERROR , " Error while verifying Message authenticity " , EXPFILL } } ,
{ & ei_snmp_authentication_ok , { " snmp.authentication_ok " , PI_CHECKSUM , PI_CHAT , " SNMP Authentication OK " , EXPFILL } } ,
{ & ei_snmp_authentication_error , { " snmp.authentication_error " , PI_CHECKSUM , PI_WARN , " SNMP Authentication Error " , EXPFILL } } ,
{ & ei_snmp_varbind_not_uni_class_seq , { " snmp.varbind.not_uni_class_seq " , PI_MALFORMED , PI_WARN , " VarBind is not an universal class sequence " , EXPFILL } } ,
{ & ei_snmp_varbind_has_indicator , { " snmp.varbind.has_indicator " , PI_MALFORMED , PI_WARN , " VarBind has indicator set " , EXPFILL } } ,
{ & ei_snmp_objectname_not_oid , { " snmp.objectname_not_oid " , PI_MALFORMED , PI_WARN , " ObjectName not an OID " , EXPFILL } } ,
{ & ei_snmp_objectname_has_indicator , { " snmp.objectname_has_indicator " , PI_MALFORMED , PI_WARN , " ObjectName has indicator set " , EXPFILL } } ,
{ & ei_snmp_value_not_primitive_encoding , { " snmp.value_not_primitive_encoding " , PI_MALFORMED , PI_WARN , " value not in primitive encoding " , EXPFILL } } ,
{ & ei_snmp_invalid_oid , { " snmp.invalid_oid " , PI_MALFORMED , PI_WARN , " invalid oid " , EXPFILL } } ,
{ & ei_snmp_varbind_wrong_tag , { " snmp.varbind.wrong_tag " , PI_MALFORMED , PI_WARN , " Wrong tag for SNMP VarBind error value " , EXPFILL } } ,
{ & ei_snmp_varbind_response , { " snmp.varbind.response " , PI_RESPONSE_CODE , PI_NOTE , " Response " , EXPFILL } } ,
{ & ei_snmp_no_instance_subid , { " snmp.no_instance_subid " , PI_MALFORMED , PI_WARN , " No instance sub-id in scalar value " , EXPFILL } } ,
{ & ei_snmp_wrong_num_of_subids , { " snmp.wrong_num_of_subids " , PI_MALFORMED , PI_WARN , " Wrong number of instance sub-ids in scalar value " , EXPFILL } } ,
{ & ei_snmp_index_suboid_too_short , { " snmp.index_suboid_too_short " , PI_MALFORMED , PI_WARN , " index sub-oid shorter than expected " , EXPFILL } } ,
{ & ei_snmp_unimplemented_instance_index , { " snmp.unimplemented_instance_index " , PI_UNDECODED , PI_WARN , " OID instaces not handled, if you want this implemented please contact the wireshark developers " , EXPFILL } } ,
{ & ei_snmp_index_suboid_len0 , { " snmp.ndex_suboid_len0 " , PI_MALFORMED , PI_WARN , " an index sub-oid OID cannot be 0 bytes long! " , EXPFILL } } ,
{ & ei_snmp_index_suboid_too_long , { " snmp.index_suboid_too_long " , PI_MALFORMED , PI_WARN , " index sub-oid should not be longer than remaining oid size " , EXPFILL } } ,
{ & ei_snmp_index_string_too_long , { " snmp.index_string_too_long " , PI_MALFORMED , PI_WARN , " index string should not be longer than remaining oid size " , EXPFILL } } ,
2020-12-16 09:59:50 +00:00
{ & ei_snmp_column_parent_not_row , { " snmp.column_parent_not_row " , PI_MALFORMED , PI_ERROR , " COLUMNS's parent is not a ROW " , EXPFILL } } ,
2014-08-11 07:35:11 +00:00
{ & ei_snmp_uint_too_large , { " snmp.uint_too_large " , PI_UNDECODED , PI_NOTE , " Unsigned integer value > 2^64 - 1 " , EXPFILL } } ,
{ & ei_snmp_int_too_large , { " snmp.int_too_large " , PI_UNDECODED , PI_NOTE , " Signed integer value > 2^63 - 1 or <= -2^63 " , EXPFILL } } ,
{ & ei_snmp_integral_value0 , { " snmp.integral_value0 " , PI_UNDECODED , PI_NOTE , " Integral value is zero-length " , EXPFILL } } ,
{ & ei_snmp_missing_mib , { " snmp.missing_mib " , PI_UNDECODED , PI_NOTE , " Unresolved value, Missing MIB " , EXPFILL } } ,
{ & ei_snmp_varbind_wrong_length_value , { " snmp.varbind.wrong_length_value " , PI_MALFORMED , PI_WARN , " Wrong length for SNMP VarBind/value " , EXPFILL } } ,
{ & ei_snmp_varbind_wrong_class_tag , { " snmp.varbind.wrong_class_tag " , PI_MALFORMED , PI_WARN , " Wrong class/tag for SNMP VarBind/value " , EXPFILL } } ,
{ & ei_snmp_rfc1910_non_conformant , { " snmp.rfc1910_non_conformant " , PI_PROTOCOL , PI_WARN , " Data not conforming to RFC1910 " , EXPFILL } } ,
{ & ei_snmp_rfc3411_non_conformant , { " snmp.rfc3411_non_conformant " , PI_PROTOCOL , PI_WARN , " Data not conforming to RFC3411 " , EXPFILL } } ,
{ & ei_snmp_version_unknown , { " snmp.version.unknown " , PI_PROTOCOL , PI_WARN , " Unknown version " , EXPFILL } } ,
2014-08-29 17:36:59 +00:00
{ & ei_snmp_trap_pdu_obsolete , { " snmp.trap_pdu_obsolete " , PI_PROTOCOL , PI_WARN , " Trap-PDU is obsolete in this SNMP version " , EXPFILL } } ,
2014-08-11 07:35:11 +00:00
} ;
expert_module_t * expert_snmp ;
module_t * snmp_module ;
static uat_field_t users_fields [ ] = {
UAT_FLD_BUFFER ( snmp_users , engine_id , " Engine ID " , " Engine-id for this entry (empty = any) " ) ,
UAT_FLD_LSTRING ( snmp_users , userName , " Username " , " The username " ) ,
UAT_FLD_VS ( snmp_users , auth_model , " Authentication model " , auth_types , " Algorithm to be used for authentication. " ) ,
UAT_FLD_LSTRING ( snmp_users , authPassword , " Password " , " The password used for authenticating packets for this entry " ) ,
UAT_FLD_VS ( snmp_users , priv_proto , " Privacy protocol " , priv_types , " Algorithm to be used for privacy. " ) ,
UAT_FLD_LSTRING ( snmp_users , privPassword , " Privacy password " , " The password used for encrypting packets for this entry " ) ,
UAT_END_FIELDS
} ;
uat_t * assocs_uat = uat_new ( " SNMP Users " ,
sizeof ( snmp_ue_assoc_t ) ,
" snmp_users " ,
TRUE ,
& ueas ,
& num_ueas ,
UAT_AFFECTS_DISSECTION , /* affects dissection of packets, but not set of named fields */
" ChSNMPUsersSection " ,
snmp_users_copy_cb ,
snmp_users_update_cb ,
snmp_users_free_cb ,
renew_ue_cache ,
2016-12-21 10:50:47 +00:00
NULL ,
2014-08-11 07:35:11 +00:00
users_fields ) ;
static uat_field_t specific_traps_flds [ ] = {
UAT_FLD_CSTRING ( specific_traps , enterprise , " Enterprise OID " , " Enterprise Object Identifier " ) ,
UAT_FLD_DEC ( specific_traps , trap , " Trap Id " , " The specific-trap value " ) ,
UAT_FLD_CSTRING ( specific_traps , desc , " Description " , " Trap type description " ) ,
UAT_END_FIELDS
} ;
uat_t * specific_traps_uat = uat_new ( " SNMP Enterprise Specific Trap Types " ,
sizeof ( snmp_st_assoc_t ) ,
" snmp_specific_traps " ,
TRUE ,
& specific_traps ,
& num_specific_traps ,
UAT_AFFECTS_DISSECTION , /* affects dissection of packets, but not set of named fields */
" ChSNMPEnterpriseSpecificTrapTypes " ,
snmp_specific_trap_copy_cb ,
NULL ,
snmp_specific_trap_free_cb ,
NULL ,
2016-12-21 10:50:47 +00:00
NULL ,
2014-08-11 07:35:11 +00:00
specific_traps_flds ) ;
/* Register protocol */
proto_snmp = proto_register_protocol ( PNAME , PSNAME , PFNAME ) ;
2016-07-01 00:41:45 +00:00
snmp_handle = register_dissector ( " snmp " , dissect_snmp , proto_snmp ) ;
2014-08-11 07:35:11 +00:00
/* Register fields and subtrees */
proto_register_field_array ( proto_snmp , hf , array_length ( hf ) ) ;
proto_register_subtree_array ( ett , array_length ( ett ) ) ;
expert_snmp = expert_register_protocol ( proto_snmp ) ;
expert_register_field_array ( expert_snmp , ei , array_length ( ei ) ) ;
/* Register configuration preferences */
snmp_module = prefs_register_protocol ( proto_snmp , process_prefs ) ;
prefs_register_bool_preference ( snmp_module , " display_oid " ,
2010-10-14 01:44:27 +00:00
" Show SNMP OID in info column " ,
" Whether the SNMP OID should be shown in the info column " ,
& display_oid ) ;
2005-12-04 21:45:38 +00:00
2014-08-11 07:35:11 +00:00
prefs_register_obsolete_preference ( snmp_module , " mib_modules " ) ;
prefs_register_obsolete_preference ( snmp_module , " users_file " ) ;
2007-08-19 23:00:47 +00:00
2014-08-11 07:35:11 +00:00
prefs_register_bool_preference ( snmp_module , " desegment " ,
2016-09-20 21:11:29 +00:00
" Reassemble SNMP-over-TCP messages spanning multiple TCP segments " ,
2010-10-14 01:44:27 +00:00
" 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 ) ;
2005-12-04 21:45:38 +00:00
2014-08-11 07:35:11 +00:00
prefs_register_bool_preference ( snmp_module , " var_in_tree " ,
2010-10-14 01:44:27 +00:00
" Display dissected variables inside SNMP tree " ,
" ON - display dissected variables inside SNMP tree, OFF - display dissected variables in root tree after SNMP " ,
& snmp_var_in_tree ) ;
2007-01-12 00:33:32 +00:00
2014-08-11 07:35:11 +00:00
prefs_register_uat_preference ( snmp_module , " users_table " ,
2009-11-01 18:45:43 +00:00
" Users Table " ,
" Table of engine-user associations used for authentication and decryption " ,
assocs_uat ) ;
2014-08-11 07:35:11 +00:00
prefs_register_uat_preference ( snmp_module , " specific_traps_table " ,
2009-11-01 18:45:43 +00:00
" Enterprise Specific Trap Types " ,
" Table of enterprise specific-trap type descriptions " ,
specific_traps_uat ) ;
2007-11-12 18:44:29 +00:00
2009-07-08 21:04:53 +00:00
# ifdef HAVE_LIBSMI
2014-08-11 07:35:11 +00:00
prefs_register_static_text_preference ( snmp_module , " info_mibs " ,
" MIB settings can be changed in the Name Resolution preferences " ,
" MIB settings can be changed in the Name Resolution preferences " ) ;
2009-07-08 21:04:53 +00:00
# endif
2008-03-13 22:17:11 +00:00
2016-08-30 22:51:54 +00:00
value_sub_dissectors_table = register_dissector_table ( " snmp.variable_oid " , " SNMP Variable OID " , proto_snmp , FT_STRING , BASE_NONE ) ;
2007-11-12 18:44:29 +00:00
2015-06-27 22:33:42 +00:00
register_init_routine ( init_ue_cache ) ;
register_cleanup_routine ( cleanup_ue_cache ) ;
2010-03-02 05:44:04 +00:00
2015-12-10 02:50:10 +00:00
register_ber_syntax_dissector ( " SNMP " , proto_snmp , dissect_snmp_tcp ) ;
2019-11-05 22:32:50 +00:00
snmp_tap = register_tap ( " snmp " ) ;
register_srt_table ( proto_snmp , NULL , 1 , snmpstat_packet , snmpstat_init , NULL ) ;
2005-12-04 21:45:38 +00:00
}
/*--- proto_reg_handoff_snmp ---------------------------------------*/
void proto_reg_handoff_snmp ( void ) {
dissector_handle_t snmp_tcp_handle ;
2016-10-05 20:33:54 +00:00
dissector_add_uint_with_preference ( " udp.port " , UDP_PORT_SNMP , snmp_handle ) ;
2010-12-20 05:35:29 +00:00
dissector_add_uint ( " ethertype " , ETHERTYPE_SNMP , snmp_handle ) ;
dissector_add_uint ( " ipx.socket " , IPX_SOCKET_SNMP_AGENT , snmp_handle ) ;
dissector_add_uint ( " ipx.socket " , IPX_SOCKET_SNMP_SINK , snmp_handle ) ;
dissector_add_uint ( " hpext.dxsap " , HPEXT_SNMP , snmp_handle ) ;
2005-12-04 21:45:38 +00:00
2015-12-09 02:06:20 +00:00
snmp_tcp_handle = create_dissector_handle ( dissect_snmp_tcp , proto_snmp ) ;
2016-10-07 20:25:01 +00:00
dissector_add_uint_with_preference ( " tcp.port " , TCP_PORT_SNMP , snmp_tcp_handle ) ;
/* Since "regular" SNMP port and "trap" SNMP port use the same handler,
the " trap " port doesn ' t really need a separate preference . Just register
normally */
2010-12-20 05:35:29 +00:00
dissector_add_uint ( " tcp.port " , TCP_PORT_SNMP_TRAP , snmp_tcp_handle ) ;
2016-10-05 20:33:54 +00:00
dissector_add_uint ( " udp.port " , UDP_PORT_SNMP_TRAP , snmp_handle ) ;
dissector_add_uint ( " udp.port " , UDP_PORT_SNMP_PATROL , snmp_handle ) ;
2005-12-04 21:45:38 +00:00
data_handle = find_dissector ( " data " ) ;
2013-06-04 20:05:16 +00:00
/* SNMPv2-MIB sysDescr "1.3.6.1.2.1.1.1.0" */
2013-06-19 18:33:49 +00:00
dissector_add_string ( " snmp.variable_oid " , " 1.3.6.1.2.1.1.1.0 " ,
2015-12-09 02:06:20 +00:00
create_dissector_handle ( dissect_snmp_variable_string , proto_snmp ) ) ;
2013-06-04 20:05:16 +00:00
/* SNMPv2-MIB::sysName.0 (1.3.6.1.2.1.1.5.0) */
2013-06-19 18:33:49 +00:00
dissector_add_string ( " snmp.variable_oid " , " 1.3.6.1.2.1.1.5.0 " ,
2015-12-09 02:06:20 +00:00
create_dissector_handle ( dissect_snmp_variable_string , proto_snmp ) ) ;
2013-06-04 20:05:16 +00:00
2005-12-04 21:45:38 +00:00
/*
* 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 gint * ett [ ] = {
& ett_smux ,
} ;
proto_smux = proto_register_protocol ( " SNMP Multiplex Protocol " ,
" SMUX " , " smux " ) ;
2014-08-13 06:25:21 +00:00
2005-12-04 21:45:38 +00:00
proto_register_subtree_array ( ett , array_length ( ett ) ) ;
}
void
proto_reg_handoff_smux ( void )
{
dissector_handle_t smux_handle ;
2015-12-09 02:06:20 +00:00
smux_handle = create_dissector_handle ( dissect_smux , proto_smux ) ;
2016-10-07 20:25:01 +00:00
dissector_add_uint_with_preference ( " tcp.port " , TCP_PORT_SMUX , smux_handle ) ;
2005-12-04 21:45:38 +00:00
}
2014-06-15 16:40:42 +00:00
/*
2019-07-26 18:43:17 +00:00
* Editor modelines - https : //www.wireshark.org/tools/modelines.html
2014-06-15 16:40:42 +00:00
*
* Local variables :
* c - basic - offset : 8
* tab - width : 8
* indent - tabs - mode : t
* End :
*
* vi : set shiftwidth = 8 tabstop = 8 noexpandtab :
* : indentSize = 8 : tabSize = 8 : noTabs = false :
*/