/* Portions of this file are subject to the following copyright(s). See * the Net-SNMP's COPYING file for more details and other copyrights * that may apply: */ /* * Portions of this file are copyrighted by: * Copyright © 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms specified in the COPYING file * distributed with the Net-SNMP package. * * Portions of this file are copyrighted by: * Copyright (c) 2016 VMware, Inc. All rights reserved. * Use is subject to license terms specified in the COPYING file * distributed with the Net-SNMP package. */ #include #include #include #include #include #if HAVE_STRING_H #include #else #include #endif #include #include #include /** @defgroup scalar scalar * Process scalars easily. * @ingroup leaf * @{ */ /** * Creates a scalar handler calling netsnmp_create_handler with a * handler name defaulted to "scalar" and access method, * netsnmp_scalar_helper_handler. * * @return Returns a pointer to a netsnmp_mib_handler struct which contains * the handler's name and the access method * * @see netsnmp_get_scalar_handler * @see netsnmp_register_scalar */ netsnmp_mib_handler * netsnmp_get_scalar_handler(void) { return netsnmp_create_handler("scalar", netsnmp_scalar_helper_handler); } /** * This function registers a scalar helper handler. The registered OID, * reginfo->rootoid, space is extended for the instance subid using * realloc() but the reginfo->rootoid_len length is not extended just yet. * .This function subsequently injects the instance, scalar, and serialize * helper handlers before actually registering reginfo. * * Each handler is injected/pushed to the top of the handler chain list * and will be processed last in first out, LIFO. * * @param reginfo a handler registration structure which could get created * using netsnmp_create_handler_registration. Used to register * a scalar helper handler. * * @return MIB_REGISTERED_OK is returned if the registration was a success. * Failures are MIB_REGISTRATION_FAILURE and MIB_DUPLICATE_REGISTRATION. * * @see netsnmp_register_read_only_scalar * @see netsnmp_get_scalar_handler */ int netsnmp_register_scalar(netsnmp_handler_registration *reginfo) { netsnmp_mib_handler *h1, *h2; /* * Extend the registered OID with space for the instance subid * (but don't extend the length just yet!) */ reginfo->rootoid = (oid*)realloc(reginfo->rootoid, (reginfo->rootoid_len+1) * sizeof(oid) ); reginfo->rootoid[ reginfo->rootoid_len ] = 0; h1 = netsnmp_get_instance_handler(); h2 = netsnmp_get_scalar_handler(); if (h1 && h2) { if (netsnmp_inject_handler(reginfo, h1) == SNMPERR_SUCCESS) { h1 = NULL; if (netsnmp_inject_handler(reginfo, h2) == SNMPERR_SUCCESS) return netsnmp_register_serialize(reginfo); } } snmp_log(LOG_ERR, "register scalar failed\n"); netsnmp_handler_free(h1); netsnmp_handler_free(h2); netsnmp_handler_registration_free(reginfo); return MIB_REGISTRATION_FAILED; } /** * This function registers a read only scalar helper handler. This * function is very similar to netsnmp_register_scalar the only addition * is that the "read_only" handler is injected into the handler chain * prior to injecting the serialize handler and registering reginfo. * * @param reginfo a handler registration structure which could get created * using netsnmp_create_handler_registration. Used to register * a read only scalar helper handler. * * @return MIB_REGISTERED_OK is returned if the registration was a success. * Failures are MIB_REGISTRATION_FAILED and MIB_DUPLICATE_REGISTRATION. * * @see netsnmp_register_scalar * @see netsnmp_get_scalar_handler * */ int netsnmp_register_read_only_scalar(netsnmp_handler_registration *reginfo) { netsnmp_mib_handler *h1, *h2, *h3; /* * Extend the registered OID with space for the instance subid * (but don't extend the length just yet!) */ reginfo->rootoid = (oid*)realloc(reginfo->rootoid, (reginfo->rootoid_len+1) * sizeof(oid) ); reginfo->rootoid[ reginfo->rootoid_len ] = 0; h1 = netsnmp_get_instance_handler(); h2 = netsnmp_get_scalar_handler(); h3 = netsnmp_get_read_only_handler(); if (h1 && h2 && h3) { if (netsnmp_inject_handler(reginfo, h1) == SNMPERR_SUCCESS) { h1 = NULL; if (netsnmp_inject_handler(reginfo, h2) == SNMPERR_SUCCESS) { h2 = NULL; if (netsnmp_inject_handler(reginfo, h3) == SNMPERR_SUCCESS) return netsnmp_register_serialize(reginfo); } } } snmp_log(LOG_ERR, "register read only scalar failed\n"); netsnmp_handler_free(h1); netsnmp_handler_free(h2); netsnmp_handler_free(h3); netsnmp_handler_registration_free(reginfo); return MIB_REGISTRATION_FAILED; } int netsnmp_scalar_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; int ret, cmp; int namelen; DEBUGMSGTL(("helper:scalar", "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", " oid:")); DEBUGMSGOID(("helper:scalar", var->name, var->name_length)); DEBUGMSG(("helper:scalar", "\n")); switch (reqinfo->mode) { case MODE_GET: if (cmp != 0) { netsnmp_set_request_error(reqinfo, requests, SNMP_NOSUCHOBJECT); return SNMP_ERR_NOERROR; } else { reginfo->rootoid[reginfo->rootoid_len++] = 0; ret = netsnmp_call_next_handler(handler, reginfo, reqinfo, requests); reginfo->rootoid_len--; return ret; } break; #ifndef NETSNMP_NO_WRITE_SUPPORT 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) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_NOCREATION); return SNMP_ERR_NOERROR; } else { reginfo->rootoid[reginfo->rootoid_len++] = 0; ret = netsnmp_call_next_handler(handler, reginfo, reqinfo, requests); reginfo->rootoid_len--; return ret; } break; #endif /* NETSNMP_NO_WRITE_SUPPORT */ case MODE_GETNEXT: reginfo->rootoid[reginfo->rootoid_len++] = 0; ret = netsnmp_call_next_handler(handler, reginfo, reqinfo, requests); reginfo->rootoid_len--; return ret; } /* * got here only if illegal mode found */ return SNMP_ERR_GENERR; } /** @} */