snmpv3.c
资源名称:snmp.src.rar [点击查看]
上传用户:cxs890
上传日期:2021-05-22
资源大小:347k
文件大小:29k
源码类别:
SNMP编程
开发平台:
C/C++
- /*
- * snmpv3.c
- */
- #include <config.h>
- #include <assert.h>
- #include <stdio.h>
- #include <sys/types.h>
- #if TIME_WITH_SYS_TIME
- # ifdef WIN32
- # include <sys/timeb.h>
- # else
- # include <time.h>
- # endif
- # include <time.h>
- #else
- # if HAVE_SYS_TIME_H
- # include <sys/time.h>
- # else
- # include <time.h>
- # endif
- #endif
- #ifdef OS_VXWORKS
- #include <sys/times.h>
- #endif
- #if HAVE_STRING_H
- #include <string.h>
- #else
- #include <strings.h>
- #endif
- #if HAVE_NETINET_IN_H
- #include <netinet/in.h>
- #endif
- #if HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #if HAVE_WINSOCK_H
- #include <ip/socket.h>
- #endif
- #if HAVE_SYS_SOCKET_H
- #include <sys/socket.h>
- #endif
- #if HAVE_NETDB_H
- #include <netdb.h>
- #endif
- #if HAVE_STDLIB_H
- # include <stdlib.h>
- #endif
- #if HAVE_DMALLOC_H
- #include <dmalloc.h>
- #endif
- #include "system.h"
- #include "asn1.h"
- #include "snmpv3.h"
- #include "callback.h"
- #include "snmpusm.h"
- #include "snmp.h"
- #include "parse.h"
- #include "snmp_api.h"
- #include "snmp_impl.h"
- #include "read_config.h"
- #include "lcd_time.h"
- #include "scapi.h"
- #include "tools.h"
- #include "keytools.h"
- #include "lcd_time.h"
- #include "snmp_debug.h"
- #include "snmp_logging.h"
- #include "default_store.h"
- #include <ip/netdb.h>
- #include "transform_oids.h"
- #include <snmp/agent_trap.h>
- #include <snmp/snmp_command.h>
- #include <boot/convert.h>
- #include <libvty/log.h>
- static u_long engineBoots = 1;
- static unsigned char *engineID = NULL;
- static size_t engineIDLength = 0;
- static unsigned char *oldEngineID = NULL;
- static size_t oldEngineIDLength = 0;
- static struct timeval snmpv3starttime;
- extern char *strdup (char*);
- extern int strcasecmp(const char*, const char*);
- /*
- * Set up default snmpv3 parameter value storage.
- */
- static oid *defaultAuthType = NULL;
- static size_t defaultAuthTypeLen = 0;
- static oid *defaultPrivType = NULL;
- static size_t defaultPrivTypeLen = 0;
- void
- snmpv3_authtype_conf(const char *word, char *cptr)
- {
- if (strcasecmp(cptr,"MD5") == 0)
- defaultAuthType = usmHMACMD5AuthProtocol;
- else if (strcasecmp(cptr,"SHA") == 0)
- defaultAuthType = usmHMACMD5AuthProtocol;
- else
- config_perror("Unknown authentication type");
- defaultAuthTypeLen = USM_LENGTH_OID_TRANSFORM;
- DEBUGMSGTL(("snmpv3","set default authentication type: %sn", cptr));
- }
- oid *
- get_default_authtype(size_t *len)
- {
- if (defaultAuthType == NULL) {
- defaultAuthType = SNMP_DEFAULT_AUTH_PROTO;
- defaultAuthTypeLen = SNMP_DEFAULT_AUTH_PROTOLEN;
- }
- if (len)
- *len = defaultAuthTypeLen;
- return defaultAuthType;
- }
- void
- snmpv3_privtype_conf(const char *word, char *cptr)
- {
- if (strcasecmp(cptr,"DES") == 0)
- defaultPrivType = SNMP_DEFAULT_PRIV_PROTO;
- else
- config_perror("Unknown privacy type");
- defaultPrivTypeLen = SNMP_DEFAULT_PRIV_PROTOLEN;
- DEBUGMSGTL(("snmpv3","set default privacy type: %sn", cptr));
- }
- oid *
- get_default_privtype(size_t *len)
- {
- if (defaultAuthType == NULL) {
- defaultAuthType = usmDESPrivProtocol;
- defaultPrivTypeLen = USM_LENGTH_OID_TRANSFORM;
- }
- if (len)
- *len = defaultPrivTypeLen;
- return defaultPrivType;
- }
- /*******************************************************************-o-******
- * snmpv3_secLevel_conf
- *
- * Parameters:
- * *word
- * *cptr
- *
- * Line syntax:
- * defSecurityLevel "noAuthNoPriv" | "authNoPriv" | "authPriv"
- */
- void
- snmpv3_secLevel_conf(const char *word, char *cptr)
- {
- char buf[1024];
- if (strcasecmp(cptr,"noAuthNoPriv") == 0 || strcmp(cptr, "1") == 0
- || strcasecmp(cptr, "nanp") == 0)
- ds_set_int(DS_LIBRARY_ID, DS_LIB_SECLEVEL, SNMP_SEC_LEVEL_NOAUTH);
- else if (strcasecmp(cptr,"authNoPriv") == 0 || strcmp(cptr, "2") == 0
- || strcasecmp(cptr, "anp") == 0)
- ds_set_int(DS_LIBRARY_ID, DS_LIB_SECLEVEL, SNMP_SEC_LEVEL_AUTHNOPRIV);
- else if (strcasecmp(cptr,"authPriv") == 0 || strcmp(cptr, "3") == 0
- || strcasecmp(cptr, "ap") == 0)
- ds_set_int(DS_LIBRARY_ID, DS_LIB_SECLEVEL, SNMP_SEC_LEVEL_AUTHPRIV);
- else {
- sprintf(buf,"Unknown security level: %s", cptr);
- config_perror(buf);
- }
- DEBUGMSGTL(("snmpv3","default secLevel set to: %s = %dn", cptr,
- ds_get_int(DS_LIBRARY_ID, DS_LIB_SECLEVEL)));
- }
- /*******************************************************************-o-******
- * setup_engineID
- *
- * Parameters:
- * **eidp
- * *text Printable (?) text to be plugged into the snmpEngineID.
- *
- * Return:
- * Length of allocated engineID string in bytes, -OR-
- * -1 on error.
- *
- *
- * Create an snmpEngineID using text and the local IP address. If eidp
- * is defined, use it to return a pointer to the newly allocated data.
- * Otherwise, use the result to define engineID defined in this module.
- *
- * Line syntax:
- * engineID <text> | NULL
- *
- * XXX What if a node has multiple interfaces?
- * XXX What if multiple engines all choose the same address?
- * (answer: You're screwed, because you might need a kul database
- * which is dependant on the current engineID. Enumeration and other
- * tricks won't work).
- */
- int
- setup_engineID(u_char **eidp, const char *text)
- {
- int enterpriseid = htonl(default_enterprise[6]),
- localsetup = (eidp) ? 0 : 1;
- /* Use local engineID if *eidp == NULL. */
- #ifdef HAVE_GETHOSTNAME
- u_char buf[SNMP_MAXBUF_SMALL];
- struct hostent *hent;
- #endif
- u_char *bufp = NULL;
- size_t len;
- #if 0
- if (eprom_extend()&&eprom_oem())
- {
- char company_name[100];
- if (!get_extend_info_string(INFO_COMPANY_NAME,company_name))
- {
- if (!strcasecmp(company_name,DIGITAL_CHINA_VENDOR_NAME))
- {
- enterpriseid = htonl(DIGITAL_CHINA_ENTERPRISE_NUMBER);
- default_enterprise[6]=DIGITAL_CHINA_ENTERPRISE_NUMBER;
- }
- if (!strcasecmp(company_name,DLINK_VENDOR_NAME))
- {
- enterpriseid = htonl(DLINK_ENTERPRISE_NUMBER);
- default_enterprise[6]=DLINK_ENTERPRISE_NUMBER;
- }
- }
- }
- #endif
- /*
- * Determine length of the engineID string.
- */
- if (text) {
- len = 5+strlen(text); /* 5 leading bytes+text. */
- } else {
- len = 5 + 4; /* 5 leading bytes + four byte IPv4 address */
- #ifdef HAVE_GETHOSTNAME
- gethostname((char *)buf, sizeof(buf));
- hent = gethostbyname((char *)buf);
- #ifdef AF_INET6
- if (hent && hent->h_addrtype == AF_INET6)
- len += 12; /* 16 bytes total for IPv6 address. */
- #endif
- #endif /* HAVE_GETHOSTNAME */
- } /* endif -- text (1) */
- /*
- * Allocate memory and store enterprise ID.
- */
- if ((bufp = (u_char *) malloc(len)) == NULL) {
- snmp_log_perror("setup_engineID malloc");
- return -1;
- }
- memcpy(bufp, &enterpriseid, sizeof(enterpriseid)); /* XXX Must be 4 bytes! */
- bufp[0] |= 0x80;
- /*
- * Store the given text -OR- the first found IP address.
- */
- if (text) {
- bufp[4] = 4;
- memcpy((char *)bufp+5, text, strlen(text));
- } else {
- bufp[4] = 1;
- #ifdef HAVE_GETHOSTNAME
- gethostname((char *)buf, sizeof(buf));
- hent = gethostbyname((char *)buf);
- if (hent && hent->h_addrtype == AF_INET) {
- memcpy(bufp+5, hent->h_addr_list[0], hent->h_length);
- #ifdef AF_INET6
- } else if (hent && hent->h_addrtype == AF_INET6) {
- bufp[4] = 2;
- memcpy(bufp+5, hent->h_addr_list[0], hent->h_length);
- #endif
- } else { /* Unknown address type. Default to 127.0.0.1. */
- bufp[5] = 127;
- bufp[6] = 0;
- bufp[7] = 0;
- bufp[8] = 1;
- }
- #else /* HAVE_GETHOSTNAME */
- /* Unknown address type. Default to 127.0.0.1. */
- bufp[5] = 127;
- bufp[6] = 0;
- bufp[7] = 0;
- bufp[8] = 1;
- #endif /* HAVE_GETHOSTNAME */
- } /* endif -- text (2) */
- /*
- * Pass the string back to the calling environment, or use it for
- * our local engineID.
- */
- if (localsetup) {
- SNMP_FREE(engineID);
- engineID = bufp;
- engineIDLength = len;
- } else {
- *eidp = bufp;
- }
- return len;
- } /* end setup_engineID() */
- void
- usm_parse_create_usmUser(const char *token, char *line) {
- char *cp;
- char buf[SNMP_MAXBUF_MEDIUM];
- struct usmUser *newuser;
- u_char userKey[SNMP_MAXBUF_SMALL];
- size_t userKeyLen = SNMP_MAXBUF_SMALL;
- size_t ret;
- newuser = usm_create_user();
- /* READ: Security Name */
- cp = copy_word(line, buf);
- newuser->secName = strdup(buf);
- newuser->name = strdup(buf);
- newuser->engineID = snmpv3_generate_engineID(&ret);
- if ( ret < 0 ) {
- usm_free_user(newuser);
- return;
- }
- newuser->engineIDLen = ret;
- if (!cp)
- goto add; /* no authentication or privacy type */
- /* READ: Authentication Type */
- if (strncmp(cp, "MD5", 3) == 0) {
- memcpy(newuser->authProtocol, usmHMACMD5AuthProtocol,
- sizeof(usmHMACMD5AuthProtocol));
- } else if (strncmp(cp, "SHA", 3) == 0) {
- memcpy(newuser->authProtocol, usmHMACSHA1AuthProtocol,
- sizeof(usmHMACSHA1AuthProtocol));
- } else {
- config_perror("Unknown authentication protocol");
- usm_free_user(newuser);
- return;
- }
- cp = skip_token(cp);
- /* READ: Authentication Pass Phrase */
- if (!cp) {
- config_perror("no authentication pass phrase");
- usm_free_user(newuser);
- return;
- }
- cp = copy_word(cp, buf);
- /* And turn it into a localized key */
- ret = generate_Ku(newuser->authProtocol, newuser->authProtocolLen,
- (u_char *)buf, strlen(buf),
- userKey, &userKeyLen );
- if (ret != SNMPERR_SUCCESS) {
- config_perror("Error generating auth key from pass phrase.");
- usm_free_user(newuser);
- return;
- }
- newuser->authKeyLen =
- sc_get_properlength(newuser->authProtocol, newuser->authProtocolLen);
- newuser->authKey = (u_char *) malloc(newuser->authKeyLen);
- ret = generate_kul(newuser->authProtocol, newuser->authProtocolLen,
- newuser->engineID, newuser->engineIDLen,
- userKey, userKeyLen,
- newuser->authKey, &newuser->authKeyLen );
- if (ret != SNMPERR_SUCCESS) {
- config_perror("Error generating localized auth key (Kul) from Ku.");
- usm_free_user(newuser);
- return;
- }
- if (!cp)
- goto add; /* no privacy type (which is legal) */
- /* READ: Privacy Type */
- if (strncmp(cp, "DES", 3) == 0) {
- memcpy(newuser->privProtocol, usmDESPrivProtocol,
- sizeof(usmDESPrivProtocol));
- } else {
- config_perror("Unknown privacy protocol");
- usm_free_user(newuser);
- return;
- }
- cp = skip_token(cp);
- /* READ: Authentication Pass Phrase */
- if (!cp) {
- /* assume the same as the authentication key */
- snmp_memdup(&newuser->privKey, newuser->authKey, newuser->authKeyLen);
- } else {
- cp = copy_word(cp, buf);
- /* And turn it into a localized key */
- ret = generate_Ku(newuser->authProtocol, newuser->authProtocolLen,
- (u_char *)buf, strlen(buf),
- userKey, &userKeyLen );
- if (ret != SNMPERR_SUCCESS) {
- config_perror("Error generating priv key from pass phrase.");
- usm_free_user(newuser);
- return;
- }
- ret = sc_get_properlength(newuser->authProtocol, newuser->authProtocolLen);
- if (ret < 0) {
- config_perror("Error getting proper key length for priv algorithm.");
- usm_free_user(newuser);
- return;
- }
- newuser->privKeyLen = ret;
- newuser->privKey = (u_char *) malloc(newuser->privKeyLen);
- ret = generate_kul(newuser->authProtocol, newuser->authProtocolLen,
- newuser->engineID, newuser->engineIDLen,
- userKey, userKeyLen,
- newuser->privKey, &newuser->privKeyLen );
- if (ret != SNMPERR_SUCCESS) {
- config_perror("Error generating localized priv key (Kul) from Ku.");
- usm_free_user(newuser);
- return;
- }
- }
- add:
- usm_add_user(newuser);
- DEBUGMSGTL(("usmUser","created a new user %sn", newuser->secName));
- }
- /*******************************************************************-o-******
- * engineBoots_conf
- *
- * Parameters:
- * *word
- * *cptr
- *
- * Line syntax:
- * engineBoots <num_boots>
- */
- void
- engineBoots_conf(const char *word, char *cptr)
- {
- engineBoots = atoi(cptr)+1;
- DEBUGMSGTL(("snmpv3","engineBoots: %dn",engineBoots));
- }
- /*******************************************************************-o-******
- * engineID_conf
- *
- * Parameters:
- * *word
- * *cptr
- *
- * This function reads a string from the configuration file and uses that
- * string to initialize the engineID. It's assumed to be human readable.
- */
- void
- engineID_conf(const char *word, char *cptr)
- {
- setup_engineID(NULL, cptr);
- DEBUGMSGTL(("snmpv3","initialized engineID with: %sn",cptr));
- }
- void
- version_conf(const char *word, char *cptr)
- {
- if (strcmp(cptr,"1") == 0) {
- ds_set_int(DS_LIBRARY_ID, DS_LIB_SNMPVERSION, SNMP_VERSION_1);
- } else if (strcasecmp(cptr,"2c") == 0) {
- ds_set_int(DS_LIBRARY_ID, DS_LIB_SNMPVERSION, SNMP_VERSION_2c);
- } else if (strcmp(cptr,"3") == 0) {
- ds_set_int(DS_LIBRARY_ID, DS_LIB_SNMPVERSION, SNMP_VERSION_3);
- } else {
- config_perror("Unknown version specification");
- return;
- }
- DEBUGMSGTL(("snmpv3","set default version to %dn",
- ds_get_int(DS_LIBRARY_ID, DS_LIB_SNMPVERSION)));
- }
- /* engineID_old_conf(const char *, char *):
- Reads a octet string encoded engineID into the oldEngineID and
- oldEngineIDLen pointers.
- */
- void
- oldengineID_conf(const char *word, char *cptr)
- {
- read_config_read_octet_string(cptr, &oldEngineID, &oldEngineIDLength);
- }
- /*******************************************************************-o-******
- * init_snmpv3
- *
- * Parameters:
- * *type Label for the config file "type" used by calling entity.
- *
- * Set time and engineID.
- * Set parsing functions for config file tokens.
- * Initialize SNMP Crypto API (SCAPI).
- */
- void
- init_snmpv3(const char *type) {
- gettimeofday(&snmpv3starttime, NULL);
- if (type == NULL)
- type = "snmpapp";
- if (type && !strcmp(type,"snmpapp")) {
- setup_engineID(NULL,"__snmpapp__");
- } else {
- setup_engineID(NULL, NULL);
- }
- /* initialize submodules */
- init_usm();
- /* we need to be called back later */
- snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_POST_READ_CONFIG,
- init_snmpv3_post_config, NULL);
- /* we need to be called back later */
- snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
- snmpv3_store, (void *) type);
- #if !defined(USE_INTERNAL_MD5)
- /* doesn't belong here at all */
- sc_init();
- #endif /* !USE_INTERNAL_MD5 */
- /* register all our configuration handlers (ack, there's a lot) */
- /* handle engineID setup before everything else which may depend on it */
- register_premib_handler(type,"engineID", engineID_conf, NULL, "string");
- register_premib_handler(type,"oldEngineID", oldengineID_conf, NULL, NULL);
- register_config_handler(type,"engineBoots", engineBoots_conf, NULL, NULL);
- /* default store config entries */
- ds_register_config(ASN_OCTET_STR, "snmp", "defSecurityName", DS_LIBRARY_ID,
- DS_LIB_SECNAME);
- ds_register_config(ASN_OCTET_STR, "snmp", "defContext", DS_LIBRARY_ID,
- DS_LIB_CONTEXT);
- ds_register_config(ASN_OCTET_STR, "snmp", "defPassphrase", DS_LIBRARY_ID,
- DS_LIB_PASSPHRASE);
- ds_register_config(ASN_OCTET_STR, "snmp", "defAuthPassphrase", DS_LIBRARY_ID,
- DS_LIB_AUTHPASSPHRASE);
- ds_register_config(ASN_OCTET_STR, "snmp", "defPrivPassphrase", DS_LIBRARY_ID,
- DS_LIB_PRIVPASSPHRASE);
- register_config_handler("snmp","defVersion", version_conf, NULL, "1|2c|3");
- register_config_handler("snmp","defAuthType", snmpv3_authtype_conf, NULL,
- "MD5|SHA");
- register_config_handler("snmp","defPrivType", snmpv3_privtype_conf, NULL,
- "DES (currently the only possible value)");
- register_config_handler("snmp","defSecurityLevel", snmpv3_secLevel_conf,
- NULL, "noAuthNoPriv|authNoPriv|authPriv");
- register_config_handler(type,"userSetAuthPass", usm_set_password, NULL,
- "secname engineIDLen engineID pass");
- register_config_handler(type,"userSetPrivPass", usm_set_password, NULL,
- "secname engineIDLen engineID pass");
- register_config_handler(type,"userSetAuthKey", usm_set_password, NULL,
- "secname engineIDLen engineID KuLen Ku");
- register_config_handler(type,"userSetPrivKey", usm_set_password, NULL,
- "secname engineIDLen engineID KuLen Ku");
- register_config_handler(type,"userSetAuthLocalKey", usm_set_password, NULL,
- "secname engineIDLen engineID KulLen Kul");
- register_config_handler(type,"userSetPrivLocalKey", usm_set_password, NULL,
- "secname engineIDLen engineID KulLen Kul");
- }
- /*
- * initializations for SNMPv3 to be called after the configuration files
- * have been read.
- */
- int
- init_snmpv3_post_config(int majorid, int minorid, void *serverarg,
- void *clientarg) {
- size_t engineIDLen;
- u_char *c_engineID;
- c_engineID = snmpv3_generate_engineID(&engineIDLen);
- if ( engineIDLen < 0 ) {
- /* Somethine went wrong - help! */
- return SNMPERR_GENERR;
- }
- /* if our engineID has changed at all, the boots record must be set to 1 */
- if (engineIDLen != (int)oldEngineIDLength ||
- oldEngineID == NULL || c_engineID == NULL ||
- memcmp(oldEngineID, c_engineID, engineIDLen) != 0) {
- engineBoots = 1;
- }
- /* set our local engineTime in the LCD timing cache */
- set_enginetime(c_engineID, engineIDLen,
- snmpv3_local_snmpEngineBoots(),
- snmpv3_local_snmpEngineTime(),
- TRUE);
- free(c_engineID);
- return SNMPERR_SUCCESS;
- }
- /*******************************************************************-o-******
- * store_snmpv3
- *
- * Parameters:
- * *type
- */
- int
- snmpv3_store(int majorID, int minorID, void *serverarg, void *clientarg) {
- char line[SNMP_MAXBUF_SMALL];
- u_char c_engineID[SNMP_MAXBUF_SMALL];
- int engineIDLen;
- const char *type = (const char *) clientarg;
- if (type == NULL) /* should never happen, since the arg is ours */
- type = "unknown";
- sprintf(line, "engineBoots %ld", engineBoots);
- read_config_store(type, line);
- engineIDLen = snmpv3_get_engineID(c_engineID, SNMP_MAXBUF_SMALL);
- if (engineIDLen) {
- /* store the engineID used for this run */
- sprintf(line, "oldEngineID ");
- read_config_save_octet_string(line+strlen(line), c_engineID,
- engineIDLen);
- read_config_store(type, line);
- }
- return SNMPERR_SUCCESS;
- } /* snmpv3_store() */
- u_long
- snmpv3_local_snmpEngineBoots(void)
- {
- return engineBoots;
- }
- /*******************************************************************-o-******
- * snmpv3_get_engineID
- *
- * Parameters:
- * *buf
- * buflen
- *
- * Returns:
- * Length of engineID On Success
- * SNMPERR_GENERR Otherwise.
- *
- *
- * Store engineID in buf; return the length.
- *
- */
- int
- snmpv3_get_engineID(u_char *buf, size_t buflen)
- {
- /*
- * Sanity check.
- */
- if ( !buf || (buflen < engineIDLength) ) {
- return SNMPERR_GENERR;
- }
- memcpy(buf,engineID,engineIDLength);
- return engineIDLength;
- } /* end snmpv3_get_engineID() */
- /*******************************************************************-o-******
- * snmpv3_clone_engineID
- *
- * Parameters:
- * **dest
- * *dest_len
- * src
- * srclen
- *
- * Returns:
- * Length of engineID On Success
- * 0 Otherwise.
- *
- *
- * Clones engineID, creates memory
- *
- */
- int
- snmpv3_clone_engineID(u_char **dest, size_t* destlen, u_char*src, size_t srclen)
- {
- if ( !dest || !destlen ) return 0;
- *dest = NULL; *destlen = 0;
- if (srclen && src) {
- *dest = (u_char*)malloc((unsigned)srclen * sizeof(u_char));
- if (*dest == NULL) return 0;
- memmove(*dest, src, srclen * sizeof(u_char));
- *destlen = srclen;
- }
- return *destlen;
- } /* end snmpv3_clone_engineID() */
- /*******************************************************************-o-******
- * snmpv3_generate_engineID
- *
- * Parameters:
- * *length
- *
- * Returns:
- * Pointer to copy of engineID On Success.
- * NULL If malloc() or snmpv3_get_engineID()
- * fail.
- *
- * Generates a malloced copy of our engineID.
- *
- * 'length' is set to the length of engineID -OR- < 0 on failure.
- */
- u_char *
- snmpv3_generate_engineID(size_t *length)
- {
- u_char *newID;
- newID = (u_char *) malloc(engineIDLength);
- if (newID) {
- *length = snmpv3_get_engineID(newID, engineIDLength);
- }
- if (*length < 0) {
- SNMP_FREE(newID);
- newID = NULL;
- }
- return newID;
- } /* end snmpv3_generate_engineID() */
- /* snmpv3_local_snmpEngineTime(): return the number of seconds since the
- snmpv3 engine last incremented engine_boots */
- u_long
- snmpv3_local_snmpEngineTime(void)
- {
- struct timeval now;
- gettimeofday(&now, NULL);
- return calculate_time_diff(&now, &snmpv3starttime)/100;
- }
- #ifdef SNMP_TESTING_CODE
- /* snmpv3_set_engineBootsAndTime(): this function does not exist. Go away. */
- /* It certainly should never be used, unless in a testing scenero,
- which is why it was created */
- void
- snmpv3_set_engineBootsAndTime(int boots, int ttime) {
- engineBoots = boots;
- gettimeofday(&snmpv3starttime, NULL);
- snmpv3starttime.tv_sec -= ttime;
- }
- #endif
- #ifdef INCLUDE_SNMPV3
- /*Sunxi, 26, Feb 2004 */
- /*the flowing code is to manage snmpEngineIDs on remote hosts*/
- struct snmp_remote_engineID{
- u_char remote_addr[16];/*SNMP engine on which host*/
- u_short remote_port;/*on which port received SNMP messages(specially notification messages)*/
- u_char remote_engineID[SNMP_MAX_ENG_SIZE];/*snmpEngineID*/
- u_int reference_count;
- struct snmp_remote_engineID *next;
- };
- struct snmp_remote_engineID *snmp_remote_engineID_list = NULL;
- #define FOREACH_ENGINE(pe)
- for(pe = snmp_remote_engineID_list; pe != NULL; pe = pe->next)
- /*is engineID Greater/Equal*/
- #define COMPARE_EID(eid1, eid2, op)
- (strcmp(eid1->remote_addr, eid2->remote_addr) op 0)
- void snmpv3_add_remote_engineID(u_char* ipaddr, u_short port, u_char *engineID, size_t engineIDLen)
- {
- struct snmp_remote_engineID *eID = malloc(sizeof(struct snmp_remote_engineID)), *ptr, *prev = NULL;
- if (eID == NULL)
- return;
- memset((void *)eID, 0, sizeof(struct snmp_remote_engineID));
- strncpy(eID->remote_addr, ipaddr, sizeof(eID->remote_addr));
- eID->remote_port = port;
- memcpy(eID->remote_engineID, engineID, engineIDLen);
- if (snmp_remote_engineID_list == NULL) {
- snmp_remote_engineID_list = eID;
- return;
- }
- FOREACH_ENGINE(ptr) {
- if (COMPARE_EID(ptr, eID, >)) {
- prev = ptr;
- continue;
- }
- if (COMPARE_EID(ptr, eID, ==)) {
- if (ptr->remote_port == eID->remote_port) {
- /*duplicate remote engine ID*/
- /*update remote user list and host list*/
- refreshV3TrapSession(ipaddr, engineID, engineIDLen);
- refresh_snmp_user_engineID(ptr->remote_engineID, SNMP_MAX_ENG_SIZE, engineID, engineIDLen);
- /*replace the old one*/
- memset((void*)ptr->remote_engineID, 0, sizeof(ptr->remote_engineID));
- memcpy(ptr->remote_engineID, engineID, engineIDLen);
- free(eID);
- return;
- }
- } else /*ptr < eID*/
- break;
- }
- if (ptr == NULL) {
- /*add to tail*/
- prev->next = eID;
- } else if (prev == NULL) {
- /*add to head*/
- eID->next = snmp_remote_engineID_list;
- snmp_remote_engineID_list = eID;
- } else {
- eID->next = prev->next;
- prev->next = eID;
- }
- }
- void snmpv3_delete_remote_engineID(u_char *ipaddr, u_short port)
- {
- struct snmp_remote_engineID *ptr, *prev = NULL, temp;
- strncpy(temp.remote_addr, ipaddr, sizeof(temp.remote_addr));
- temp.remote_port = port;
- FOREACH_ENGINE(ptr) {
- if (COMPARE_EID(ptr, (&temp), >)) {
- prev = ptr;
- continue;
- }
- if (COMPARE_EID(ptr, (&temp), ==)) {
- if (ptr->remote_port == port) {
- /*found it!!!*/
- if (ptr->reference_count != 0) {
- syslog(LOG_WARNING, "%%SNMP-%d-ENGINEID: The engineID is used by SNMP-hosts or SNMP users. It can't be deletedn", LOG_WARNING);
- return;
- }
- if (prev == NULL) {
- /*first remote engine ID to be removed*/
- snmp_remote_engineID_list = ptr->next;
- } else
- prev->next = ptr->next;
- free(ptr);
- return;
- }
- } else /*not found*/
- return;
- }
- }
- char *snmpv3_get_remote_engineID(u_char *ipaddr, u_short port)
- {
- struct snmp_remote_engineID *ptr, temp;
- strncpy(temp.remote_addr, ipaddr, sizeof(temp.remote_addr));
- temp.remote_port = port;
- FOREACH_ENGINE(ptr) {
- if (COMPARE_EID(ptr, (&temp), >))
- continue;
- if (COMPARE_EID(ptr, (&temp), ==)) {
- if (ptr->remote_port == port) {
- /*found it!!!*/
- return ptr->remote_engineID;
- }
- } else /*not found*/
- return NULL;
- }
- return NULL;
- }
- void snmpv3_get_remote_host_info_by_engineID(u_char *snmpEngineID, u_char **addr, u_short *port)
- {
- struct snmp_remote_engineID *ptr;
- assert(snmpEngineID && addr && port);
- *addr = NULL;
- *port = 0;
- FOREACH_ENGINE(ptr) {
- if (memcmp(snmpEngineID, ptr->remote_engineID, sizeof(ptr->remote_engineID)) == 0) {
- *addr = ptr->remote_addr;
- *port = ptr->remote_port;
- return;
- }
- }
- }
- void snmpv3_inc_remote_engineID_reference(u_char *ipaddr, u_short port)
- {
- struct snmp_remote_engineID *ptr, temp;
- strncpy(temp.remote_addr, ipaddr, sizeof(temp.remote_addr));
- temp.remote_port = port;
- FOREACH_ENGINE(ptr) {
- if (COMPARE_EID(ptr, (&temp), >))
- continue;
- if (COMPARE_EID(ptr, (&temp), ==)) {
- if (ptr->remote_port == port) {
- /*found it!!!*/
- ptr->reference_count++;
- return;
- }
- } else /*not found*/
- return;
- }
- return ;
- }
- void snmpv3_dec_remote_engineID_reference(u_char *ipaddr, u_short port)
- {
- struct snmp_remote_engineID *ptr, temp;
- strncpy(temp.remote_addr, ipaddr, sizeof(temp.remote_addr));
- temp.remote_port = port;
- FOREACH_ENGINE(ptr) {
- if (COMPARE_EID(ptr, (&temp), >))
- continue;
- if (COMPARE_EID(ptr, (&temp), ==)) {
- if (ptr->remote_port == port) {
- /*found it!!!*/
- ptr->reference_count--;
- return;
- }
- } else /*not found*/
- return;
- }
- return ;
- }
- void snmpv3_engineID2str(char *engineID, size_t engineIDLen, char *dest)
- {
- int i;
- assert(engineID && dest);
- for(i=0;i<engineIDLen;i++)
- sprintf(dest + i * 2, "%02x", (int)(engineID[i]));
- /*trunc endding zeros'*/
- for(i=engineIDLen * 2 - 1;i>=0;i--)
- if (dest[i] == '0')
- dest[i] = 0;
- else
- return;
- }
- void do_show_snmpv3_remote_engineID()
- {
- struct snmp_remote_engineID *ptr;
- char engineIDstr[SNMP_MAX_ENG_SIZE * 2 + 1];
- vty_printf("Remote Engine ID IP-addr Portn");
- FOREACH_ENGINE(ptr) {
- memset((void *)engineIDstr, 0, sizeof(engineIDstr));
- snmpv3_engineID2str(ptr->remote_engineID, SNMP_MAX_ENG_SIZE, engineIDstr);
- if (strlen(engineIDstr) <= 32)
- vty_printf("%.32s %.16s %dn",
- engineIDstr, ptr->remote_addr, ptr->remote_port);
- else
- vty_printf("%s n %.16s %dn",
- engineIDstr, ptr->remote_addr, ptr->remote_port);
- }
- }
- BOOL do_showrunning_snmpv3_remote_engineID()
- {
- struct snmp_remote_engineID *ptr;
- char engineIDstr[SNMP_MAX_ENG_SIZE * 2 + 1];
- if (snmp_remote_engineID_list == NULL)
- return FALSE;
- FOREACH_ENGINE(ptr) {
- memset((void *)engineIDstr, 0, sizeof(engineIDstr));
- snmpv3_engineID2str(ptr->remote_engineID, SNMP_MAX_ENG_SIZE, engineIDstr);
- vty_printf("snmp-server engineID remote %s ", ptr->remote_addr);
- if (ptr->remote_port != SNMP_TRAP_PORT)
- vty_printf("udp-port %d ", ptr->remote_port);
- vty_printf("%sn", engineIDstr);
- }
- return TRUE;
- }
- /*end add*/
- #endif /*INCLUDE_SNMPV3*/