diff options
Diffstat (limited to 'agent/mibgroup/target/target.c')
-rw-r--r-- | agent/mibgroup/target/target.c | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/agent/mibgroup/target/target.c b/agent/mibgroup/target/target.c new file mode 100644 index 0000000..901e99f --- /dev/null +++ b/agent/mibgroup/target/target.c @@ -0,0 +1,220 @@ +#include <net-snmp/net-snmp-config.h> + +#if HAVE_WINSOCK_H +#include <winsock.h> +#endif +#if HAVE_STRING_H +#include <string.h> +#else +#include <strings.h> +#endif + +#include <net-snmp/net-snmp-includes.h> +#include <net-snmp/agent/net-snmp-agent-includes.h> + +#include "snmpTargetAddrEntry.h" +#include "snmpTargetParamsEntry.h" +#include "target.h" + +#define MAX_TAGS 128 + +netsnmp_session * +get_target_sessions(char *taglist, TargetFilterFunction * filterfunct, + void *filterArg) +{ + netsnmp_session *ret = NULL, thissess; + struct targetAddrTable_struct *targaddrs; + char buf[SPRINT_MAX_LEN]; + char tags[MAX_TAGS][SPRINT_MAX_LEN], *cp; + int numtags = 0, i; + static struct targetParamTable_struct *param; + + DEBUGMSGTL(("target_sessions", "looking for: %s\n", taglist)); + for (cp = taglist; cp && numtags < MAX_TAGS;) { + cp = copy_nword(cp, tags[numtags], sizeof(tags[numtags])); + DEBUGMSGTL(("target_sessions", " for: %d=%s\n", numtags, + tags[numtags])); + numtags++; + } + + for (targaddrs = get_addrTable(); targaddrs; + targaddrs = targaddrs->next) { + + /* + * legal row? + */ + if (targaddrs->tDomain == NULL || + targaddrs->tAddress == NULL || + targaddrs->rowStatus != SNMP_ROW_ACTIVE) { + DEBUGMSGTL(("target_sessions", " which is not ready yet\n")); + continue; + } + + if (netsnmp_tdomain_support + (targaddrs->tDomain, targaddrs->tDomainLen, NULL, NULL) == 0) { + snmp_log(LOG_ERR, + "unsupported domain for target address table entry %s\n", + targaddrs->name); + } + + /* + * check tag list to see if we match + */ + if (targaddrs->tagList) { + int matched = 0; + + /* + * loop through tag list looking for requested tags + */ + for (cp = targaddrs->tagList; cp && !matched;) { + cp = copy_nword(cp, buf, sizeof(buf)); + for (i = 0; i < numtags && !matched; i++) { + if (strcmp(buf, tags[i]) == 0) { + /* + * found a valid target table entry + */ + DEBUGMSGTL(("target_sessions", "found one: %s\n", + tags[i])); + + if (targaddrs->params) { + param = get_paramEntry(targaddrs->params); + if (!param + || param->rowStatus != SNMP_ROW_ACTIVE) { + /* + * parameter entry must exist and be active + */ + continue; + } + } else { + /* + * parameter entry must be specified + */ + continue; + } + + /* + * last chance for caller to opt-out. Call + * filtering function + */ + if (filterfunct && + (*(filterfunct)) (targaddrs, param, + filterArg)) { + continue; + } + + /* + * Only one notification per TargetAddrEntry, + * rather than one per tag + */ + matched = 1; + + if (targaddrs->storageType != ST_READONLY && + targaddrs->sess && + param->updateTime >= + targaddrs->sessionCreationTime) { + /* + * parameters have changed, nuke the old session + */ + snmp_close(targaddrs->sess); + targaddrs->sess = NULL; + } + + /* + * target session already exists? + */ + if (targaddrs->sess == NULL) { + /* + * create an appropriate snmp session and add + * it to our return list + */ + netsnmp_transport *t = NULL; + + t = netsnmp_tdomain_transport_oid(targaddrs-> + tDomain, + targaddrs-> + tDomainLen, + targaddrs-> + tAddress, + targaddrs-> + tAddressLen, + 0); + if (t == NULL) { + DEBUGMSGTL(("target_sessions", + "bad dest \"")); + DEBUGMSGOID(("target_sessions", + targaddrs->tDomain, + targaddrs->tDomainLen)); + DEBUGMSG(("target_sessions", "\", \"")); + DEBUGMSGHEX(("target_sessions", + targaddrs->tAddress, + targaddrs->tAddressLen)); + DEBUGMSG(("target_sessions", "\n")); + continue; + } else { + char *dst_str = + t->f_fmtaddr(t, NULL, 0); + if (dst_str != NULL) { + DEBUGMSGTL(("target_sessions", + " to: %s\n", dst_str)); + free(dst_str); + } + } + memset(&thissess, 0, sizeof(thissess)); + thissess.timeout = (targaddrs->timeout) * 1000; + thissess.retries = targaddrs->retryCount; + DEBUGMSGTL(("target_sessions", + "timeout: %d -> %d\n", + targaddrs->timeout, + thissess.timeout)); + + if (param->mpModel == SNMP_VERSION_3 && + param->secModel != 3) { + snmp_log(LOG_ERR, + "unsupported model/secmodel combo for target %s\n", + targaddrs->name); + /* + * XXX: memleak + */ + netsnmp_transport_free(t); + continue; + } + thissess.paramName = strdup(param->paramName); + thissess.version = param->mpModel; + if (param->mpModel == SNMP_VERSION_3) { + thissess.securityName = strdup(param->secName); + thissess.securityNameLen = + strlen(thissess.securityName); + thissess.securityLevel = param->secLevel; + thissess.securityModel = param->secModel; +#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C) + } else { + thissess.community = + (u_char *) strdup(param->secName); + thissess.community_len = + strlen((char *) thissess.community); +#endif + } + + thissess.flags |= SNMP_FLAGS_DONT_PROBE; + targaddrs->sess = snmp_add(&thissess, t, + NULL, NULL); + thissess.flags &= ~SNMP_FLAGS_DONT_PROBE; + targaddrs->sessionCreationTime = time(NULL); + } + if (targaddrs->sess) { + if (NULL == targaddrs->sess->paramName) + targaddrs->sess->paramName = + strdup(param->paramName); + + targaddrs->sess->next = ret; + ret = targaddrs->sess; + } else { + snmp_sess_perror("target session", &thissess); + } + } + } + } + } + } + return ret; +} |