scalar_group.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:6k
- #include <net-snmp/net-snmp-config.h>
- #include <stdlib.h>
- #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 <net-snmp/agent/scalar_group.h>
- #include <net-snmp/agent/scalar.h>
- #include <net-snmp/agent/serialize.h>
- #include <net-snmp/agent/read_only.h>
- #if HAVE_DMALLOC_H
- #include <dmalloc.h>
- #endif
- /** @defgroup scalar_group_group scalar_group: process groups of scalars.
- * @ingroup leaf
- * @{
- */
- netsnmp_mib_handler *
- netsnmp_get_scalar_group_handler(oid first, oid last)
- {
- netsnmp_mib_handler *ret = NULL;
- netsnmp_scalar_group *sgroup = NULL;
- ret = netsnmp_create_handler("scalar_group",
- netsnmp_scalar_group_helper_handler);
- if (ret) {
- sgroup = SNMP_MALLOC_TYPEDEF(netsnmp_scalar_group);
- if (NULL == sgroup) {
- netsnmp_handler_free(ret);
- ret = NULL;
- }
- else {
- sgroup->lbound = first;
- sgroup->ubound = last;
- ret->myvoid = (void *)sgroup;
- }
- }
- return ret;
- }
- int
- netsnmp_register_scalar_group(netsnmp_handler_registration *reginfo,
- oid first, oid last)
- {
- netsnmp_inject_handler(reginfo, netsnmp_get_instance_handler());
- netsnmp_inject_handler(reginfo, netsnmp_get_scalar_handler());
- netsnmp_inject_handler(reginfo, netsnmp_get_scalar_group_handler(first, last));
- return netsnmp_register_serialize(reginfo);
- }
- int
- netsnmp_scalar_group_helper_handler(netsnmp_mib_handler *handler,
- netsnmp_handler_registration *reginfo,
- netsnmp_agent_request_info *reqinfo,
- netsnmp_request_info *requests)
- {
- netsnmp_variable_list *var = requests->requestvb;
- netsnmp_scalar_group *sgroup = (netsnmp_scalar_group *)handler->myvoid;
- int ret, cmp;
- int namelen;
- oid subid, root_tmp[MAX_OID_LEN], *root_save;
- DEBUGMSGTL(("helper:scalar_group", "Got request:n"));
- namelen = SNMP_MIN(requests->requestvb->name_length,
- reginfo->rootoid_len);
- cmp = snmp_oid_compare(requests->requestvb->name, namelen,
- reginfo->rootoid, reginfo->rootoid_len);
- DEBUGMSGTL(( "helper:scalar_group", " cmp=%d, oid:", cmp));
- DEBUGMSGOID(("helper:scalar_group", var->name, var->name_length));
- DEBUGMSG(( "helper:scalar_group", "n"));
- /*
- * copy root oid to root_tmp, set instance to 0. (subid set later on)
- * save rootoid, since we'll replace it before calling next handler,
- * and need to restore it afterwards.
- */
- memcpy(root_tmp, reginfo->rootoid, reginfo->rootoid_len * sizeof(oid));
- root_tmp[reginfo->rootoid_len + 1] = 0;
- root_save = reginfo->rootoid;
- ret = SNMP_ERR_NOCREATION;
- switch (reqinfo->mode) {
- /*
- * The handling of "exact" requests is basically the same.
- * The only difference between GET and SET requests is the
- * error/exception to return on failure.
- */
- case MODE_GET:
- ret = SNMP_NOSUCHOBJECT;
- /* Fallthrough */
- case MODE_SET_RESERVE1:
- case MODE_SET_RESERVE2:
- case MODE_SET_ACTION:
- case MODE_SET_COMMIT:
- case MODE_SET_UNDO:
- case MODE_SET_FREE:
- if (cmp != 0 ||
- requests->requestvb->name_length <= reginfo->rootoid_len) {
- /*
- * Common prefix doesn't match, or only *just* matches
- * the registered root (so can't possibly match a scalar)
- */
- netsnmp_set_request_error(reqinfo, requests, ret);
- return SNMP_ERR_NOERROR;
- } else {
- /*
- * Otherwise,
- * extract the object subidentifier from the request,
- * check this is (probably) valid, and then fudge the
- * registered 'rootoid' to match, before passing the
- * request off to the next handler ('scalar').
- *
- * Note that we don't bother checking instance subidentifiers
- * here. That's left to the scalar helper.
- */
- subid = requests->requestvb->name[reginfo->rootoid_len];
- if (subid < sgroup->lbound ||
- subid > sgroup->ubound) {
- netsnmp_set_request_error(reqinfo, requests, ret);
- return SNMP_ERR_NOERROR;
- }
- root_tmp[reginfo->rootoid_len++] = subid;
- reginfo->rootoid = root_tmp;
- ret = netsnmp_call_next_handler(handler, reginfo, reqinfo,
- requests);
- reginfo->rootoid = root_save;
- reginfo->rootoid_len--;
- return ret;
- }
- break;
- case MODE_GETNEXT:
- /*
- * If we're being asked for something before (or exactly matches)
- * the registered root OID, then start with the first object.
- * If we're being asked for something that exactly matches an object
- * OID, then that's what we pass down.
- * Otherwise, we pass down the OID of the *next* object....
- */
- if (cmp < 0 ||
- requests->requestvb->name_length <= reginfo->rootoid_len) {
- subid = sgroup->lbound;
- } else if (requests->requestvb->name_length == reginfo->rootoid_len+1)
- subid = requests->requestvb->name[reginfo->rootoid_len];
- else
- subid = requests->requestvb->name[reginfo->rootoid_len]+1;
- /*
- * ... always assuming this is (potentially) valid, of course.
- */
- if (subid > sgroup->ubound)
- return SNMP_ERR_NOERROR;
-
- root_tmp[reginfo->rootoid_len++] = subid;
- reginfo->rootoid = root_tmp;
- ret = netsnmp_call_next_handler(handler, reginfo, reqinfo,
- requests);
- /*
- * If we didn't get an answer (due to holes in the group)
- * set things up to retry again.
- */
- if (!requests->delegated &&
- (requests->requestvb->type == ASN_NULL ||
- requests->requestvb->type == SNMP_NOSUCHOBJECT ||
- requests->requestvb->type == SNMP_NOSUCHINSTANCE)) {
- snmp_set_var_objid(requests->requestvb,
- reginfo->rootoid, reginfo->rootoid_len);
- requests->requestvb->name[reginfo->rootoid_len-1] = ++subid;
- requests->requestvb->type = ASN_PRIV_RETRY;
- }
- reginfo->rootoid = root_save;
- reginfo->rootoid_len--;
- return ret;
- }
- /*
- * got here only if illegal mode found
- */
- return SNMP_ERR_GENERR;
- }
- /*
- * @}
- */