📄 snmpv3.c
字号:
/* * snmpv3.c */#include <net-snmp/net-snmp-config.h>#include <stdio.h>#include <sys/types.h>#if TIME_WITH_SYS_TIME# ifdef WIN32# include <sys/timeb.h># else# include <sys/time.h># endif# include <time.h>#else# if HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#include <ctype.h>#if HAVE_NETINET_IN_H#include <netinet/in.h>#endif#if HAVE_UNISTD_H#include <unistd.h>#endif#if HAVE_WINSOCK_H#include <winsock.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/* * Stuff needed for getHwAddress(...) */#ifdef HAVE_SYS_IOCTL_H# include <sys/ioctl.h>#endif#ifdef HAVE_NET_IF_H# include <net/if.h>#endif#if HAVE_DMALLOC_H#include <dmalloc.h>#endif#include <net-snmp/types.h>#include <net-snmp/output_api.h>#include <net-snmp/config_api.h>#include <net-snmp/utilities.h>#include <net-snmp/library/snmpv3.h>#include <net-snmp/library/callback.h>#include <net-snmp/library/snmp_api.h>#include <net-snmp/library/lcd_time.h>#include <net-snmp/library/scapi.h>#include <net-snmp/library/keytools.h>#include <net-snmp/library/lcd_time.h>#include <net-snmp/library/snmp_secmod.h>#include <net-snmp/library/snmpusm.h>#include <net-snmp/library/transform_oids.h>static u_long engineBoots = 1;static unsigned int engineIDType = ENGINEID_TYPE_UCD_RND;static unsigned char *engineID = NULL;static size_t engineIDLength = 0;static unsigned char *engineIDNic = NULL;static unsigned int engineIDIsSet = 0; /* flag if ID set by config */static unsigned char *oldEngineID = NULL;static size_t oldEngineIDLength = 0;static struct timeval snmpv3starttime;/* * Set up default snmpv3 parameter value storage. */static const oid *defaultAuthType = NULL;static size_t defaultAuthTypeLen = 0;static const oid *defaultPrivType = NULL;static size_t defaultPrivTypeLen = 0;#if defined(IFHWADDRLEN) && defined(SIOCGIFHWADDR)static int getHwAddress(const char *networkDevice, char *addressOut);#endifvoidsnmpv3_authtype_conf(const char *word, char *cptr){ if (strcasecmp(cptr, "MD5") == 0) defaultAuthType = usmHMACMD5AuthProtocol; else if (strcasecmp(cptr, "SHA") == 0) defaultAuthType = usmHMACSHA1AuthProtocol; else config_perror("Unknown authentication type"); defaultAuthTypeLen = USM_LENGTH_OID_TRANSFORM; DEBUGMSGTL(("snmpv3", "set default authentication type: %s\n", cptr));}const 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;}voidsnmpv3_privtype_conf(const char *word, char *cptr){ if (strcasecmp(cptr, "DES") == 0) defaultPrivType = usmDESPrivProtocol;#if HAVE_AES /* XXX AES: assumes oid length == des oid length */ else if (strcasecmp(cptr, "AES128") == 0) defaultPrivType = usmAES128PrivProtocol; else if (strcasecmp(cptr, "AES192") == 0) defaultPrivType = usmAES192PrivProtocol; else if (strcasecmp(cptr, "AES256") == 0) defaultPrivType = usmAES256PrivProtocol;#endif else config_perror("Unknown privacy type"); defaultPrivTypeLen = SNMP_DEFAULT_PRIV_PROTOLEN; DEBUGMSGTL(("snmpv3", "set default privacy type: %s\n", cptr));}const oid *get_default_privtype(size_t * len){ if (defaultPrivType == NULL) { defaultPrivType = 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" */voidsnmpv3_secLevel_conf(const char *word, char *cptr){ char buf[1024]; if (strcasecmp(cptr, "noAuthNoPriv") == 0 || strcmp(cptr, "1") == 0 || strcasecmp(cptr, "nanp") == 0) { netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SECLEVEL, SNMP_SEC_LEVEL_NOAUTH); } else if (strcasecmp(cptr, "authNoPriv") == 0 || strcmp(cptr, "2") == 0 || strcasecmp(cptr, "anp") == 0) { netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SECLEVEL, SNMP_SEC_LEVEL_AUTHNOPRIV); } else if (strcasecmp(cptr, "authPriv") == 0 || strcmp(cptr, "3") == 0 || strcasecmp(cptr, "ap") == 0) { netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SECLEVEL, SNMP_SEC_LEVEL_AUTHPRIV); } else { snprintf(buf, sizeof(buf), "Unknown security level: %s", cptr); buf[ sizeof(buf)-1 ] = 0; config_perror(buf); } DEBUGMSGTL(("snmpv3", "default secLevel set to: %s = %d\n", cptr, netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SECLEVEL)));}intsnmpv3_options(char *optarg, netsnmp_session * session, char **Apsz, char **Xpsz, int argc, char *const *argv){ char *cp = optarg; optarg++; /* * Support '... -3x=value ....' syntax */ if (*optarg == '=') { optarg++; } /* * and '.... "-3x value" ....' (*with* the quotes) */ while (*optarg && isspace(*optarg)) { optarg++; } /* * Finally, handle ".... -3x value ...." syntax * (*without* surrounding quotes) */ if (!*optarg) { /* * We've run off the end of the argument * so move on the the next. */ optarg = argv[optind++]; if (optind > argc) { fprintf(stderr, "Missing argument after SNMPv3 '-3%c' option.\n", *cp); return (-1); } } switch (*cp) { case 'Z': session->engineBoots = strtoul(optarg, NULL, 10); if (session->engineBoots == 0 || !isdigit(optarg[0])) { fprintf(stderr, "Need engine boots value after -3Z flag.\n"); return (-1); } cp = strchr(optarg, ','); if (cp && *(++cp) && isdigit(*cp)) session->engineTime = strtoul(cp, NULL, 10); else { fprintf(stderr, "Need engine time value after -3Z flag.\n"); return (-1); } break; case 'e':{ size_t ebuf_len = 32, eout_len = 0; u_char *ebuf = (u_char *) malloc(ebuf_len); if (ebuf == NULL) { fprintf(stderr, "malloc failure processing -3e flag.\n"); return (-1); } if (!snmp_hex_to_binary (&ebuf, &ebuf_len, &eout_len, 1, optarg)) { fprintf(stderr, "Bad engine ID value after -3e flag.\n"); free(ebuf); return (-1); } session->securityEngineID = ebuf; session->securityEngineIDLen = eout_len; break; } case 'E':{ size_t ebuf_len = 32, eout_len = 0; u_char *ebuf = (u_char *) malloc(ebuf_len); if (ebuf == NULL) { fprintf(stderr, "malloc failure processing -3E flag.\n"); return (-1); } if (!snmp_hex_to_binary (&ebuf, &ebuf_len, &eout_len, 1, optarg)) { fprintf(stderr, "Bad engine ID value after -3E flag.\n"); free(ebuf); return (-1); } session->contextEngineID = ebuf; session->contextEngineIDLen = eout_len; break; } case 'n': session->contextName = optarg; session->contextNameLen = strlen(optarg); break; case 'u': session->securityName = optarg; session->securityNameLen = strlen(optarg); break; case 'l': if (!strcasecmp(optarg, "noAuthNoPriv") || !strcmp(optarg, "1") || !strcasecmp(optarg, "nanp")) { session->securityLevel = SNMP_SEC_LEVEL_NOAUTH; } else if (!strcasecmp(optarg, "authNoPriv") || !strcmp(optarg, "2") || !strcasecmp(optarg, "anp")) { session->securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV; } else if (!strcasecmp(optarg, "authPriv") || !strcmp(optarg, "3") || !strcasecmp(optarg, "ap")) { session->securityLevel = SNMP_SEC_LEVEL_AUTHPRIV; } else { fprintf(stderr, "Invalid security level specified after -3l flag: %s\n", optarg); return (-1); } break; case 'a': if (!strcasecmp(optarg, "MD5")) { session->securityAuthProto = usmHMACMD5AuthProtocol; session->securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN; } else if (!strcasecmp(optarg, "SHA")) { session->securityAuthProto = usmHMACSHA1AuthProtocol; session->securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN; } else { fprintf(stderr, "Invalid authentication protocol specified after -3a flag: %s\n", optarg); return (-1); } break; case 'x': if (!strcasecmp(optarg, "DES")) { session->securityPrivProto = usmDESPrivProtocol; session->securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN;#ifdef HAVE_AES } else if (!strcasecmp(optarg, "AES128")) { session->securityPrivProto = usmAES128PrivProtocol; session->securityPrivProtoLen = USM_PRIV_PROTO_AES128_LEN; } else if (!strcasecmp(optarg, "AES192")) { session->securityPrivProto = usmAES192PrivProtocol; session->securityPrivProtoLen = USM_PRIV_PROTO_AES192_LEN; } else if (!strcasecmp(optarg, "AES256")) { session->securityPrivProto = usmAES256PrivProtocol; session->securityPrivProtoLen = USM_PRIV_PROTO_AES256_LEN;#endif } else { fprintf(stderr, "Invalid privacy protocol specified after -3x flag: %s\n", optarg); return (-1); } break; case 'A': *Apsz = optarg; break; case 'X': *Xpsz = optarg; break; default: fprintf(stderr, "Unknown SNMPv3 option passed to -3: %c.\n", *cp); return -1; } return 0;}/*******************************************************************-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). */intsetup_engineID(u_char ** eidp, const char *text){ int enterpriseid = htonl(ENTERPRISE_OID), ucdavisid = htonl(UCDAVIS_OID), 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; int localEngineIDType = engineIDType; int tmpint; time_t tmptime; engineIDIsSet = 1; /* * get the host name and save the information */#ifdef HAVE_GETHOSTNAME gethostname((char *) buf, sizeof(buf)); hent = gethostbyname((char *) buf); /* * Determine if we are using IPV6 */#ifdef AF_INET6 /* * see if they selected IPV4 or IPV6 support */ if ((ENGINEID_TYPE_IPV6 == localEngineIDType) || (ENGINEID_TYPE_IPV4 == localEngineIDType)) { if (hent && hent->h_addrtype == AF_INET6) { localEngineIDType = ENGINEID_TYPE_IPV6; } else { /* * Not IPV6 so we go with default */ localEngineIDType = ENGINEID_TYPE_IPV4; } }#else /* * No IPV6 support. Check if they selected IPV6 engineID type. If so * * make it IPV4 for them */ if (ENGINEID_TYPE_IPV6 == localEngineIDType) { localEngineIDType = ENGINEID_TYPE_IPV4; }#endif#endif /* HAVE_GETHOSTNAME */ /* * Determine if we have text and if so setup our localEngineIDType * * appropriately. */ if (NULL != text) { engineIDType = localEngineIDType = ENGINEID_TYPE_TEXT; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -