net-snmp 5.7
scalar.c
00001 /* Portions of this file are subject to the following copyright(s).  See
00002  * the Net-SNMP's COPYING file for more details and other copyrights
00003  * that may apply:
00004  */
00005 /*
00006  * Portions of this file are copyrighted by:
00007  * Copyright © 2003 Sun Microsystems, Inc. All rights reserved.
00008  * Use is subject to license terms specified in the COPYING file
00009  * distributed with the Net-SNMP package.
00010  */
00011 #include <net-snmp/net-snmp-config.h>
00012 
00013 #include <net-snmp/net-snmp-includes.h>
00014 #include <net-snmp/agent/net-snmp-agent-includes.h>
00015 
00016 #include <net-snmp/agent/scalar.h>
00017 
00018 #include <stdlib.h>
00019 #if HAVE_STRING_H
00020 #include <string.h>
00021 #else
00022 #include <strings.h>
00023 #endif
00024 
00025 #include <net-snmp/agent/instance.h>
00026 #include <net-snmp/agent/serialize.h>
00027 #include <net-snmp/agent/read_only.h>
00028 
00046 netsnmp_mib_handler *
00047 netsnmp_get_scalar_handler(void)
00048 {
00049     return netsnmp_create_handler("scalar",
00050                                   netsnmp_scalar_helper_handler);
00051 }
00052 
00074 int
00075 netsnmp_register_scalar(netsnmp_handler_registration *reginfo)
00076 {
00077     /*
00078      * Extend the registered OID with space for the instance subid
00079      * (but don't extend the length just yet!)
00080      */
00081     reginfo->rootoid = (oid*)realloc(reginfo->rootoid,
00082                                     (reginfo->rootoid_len+1) * sizeof(oid) );
00083     reginfo->rootoid[ reginfo->rootoid_len ] = 0;
00084 
00085     netsnmp_inject_handler(reginfo, netsnmp_get_instance_handler());
00086     netsnmp_inject_handler(reginfo, netsnmp_get_scalar_handler());
00087     return netsnmp_register_serialize(reginfo);
00088 }
00089 
00090 
00109 int
00110 netsnmp_register_read_only_scalar(netsnmp_handler_registration *reginfo)
00111 {
00112     /*
00113      * Extend the registered OID with space for the instance subid
00114      * (but don't extend the length just yet!)
00115      */
00116     reginfo->rootoid = (oid*)realloc(reginfo->rootoid,
00117                                     (reginfo->rootoid_len+1) * sizeof(oid) );
00118     reginfo->rootoid[ reginfo->rootoid_len ] = 0;
00119 
00120     netsnmp_inject_handler(reginfo, netsnmp_get_instance_handler());
00121     netsnmp_inject_handler(reginfo, netsnmp_get_scalar_handler());
00122     netsnmp_inject_handler(reginfo, netsnmp_get_read_only_handler());
00123     return netsnmp_register_serialize(reginfo);
00124 }
00125 
00126 
00127 
00128 int
00129 netsnmp_scalar_helper_handler(netsnmp_mib_handler *handler,
00130                                 netsnmp_handler_registration *reginfo,
00131                                 netsnmp_agent_request_info *reqinfo,
00132                                 netsnmp_request_info *requests)
00133 {
00134 
00135     netsnmp_variable_list *var = requests->requestvb;
00136 
00137     int             ret, cmp;
00138     int             namelen;
00139 
00140     DEBUGMSGTL(("helper:scalar", "Got request:\n"));
00141     namelen = SNMP_MIN(requests->requestvb->name_length,
00142                        reginfo->rootoid_len);
00143     cmp = snmp_oid_compare(requests->requestvb->name, namelen,
00144                            reginfo->rootoid, reginfo->rootoid_len);
00145 
00146     DEBUGMSGTL(("helper:scalar", "  oid:"));
00147     DEBUGMSGOID(("helper:scalar", var->name, var->name_length));
00148     DEBUGMSG(("helper:scalar", "\n"));
00149 
00150     switch (reqinfo->mode) {
00151     case MODE_GET:
00152         if (cmp != 0) {
00153             netsnmp_set_request_error(reqinfo, requests,
00154                                       SNMP_NOSUCHOBJECT);
00155             return SNMP_ERR_NOERROR;
00156         } else {
00157             reginfo->rootoid[reginfo->rootoid_len++] = 0;
00158             ret = netsnmp_call_next_handler(handler, reginfo, reqinfo,
00159                                              requests);
00160             reginfo->rootoid_len--;
00161             return ret;
00162         }
00163         break;
00164 
00165 #ifndef NETSNMP_NO_WRITE_SUPPORT
00166     case MODE_SET_RESERVE1:
00167     case MODE_SET_RESERVE2:
00168     case MODE_SET_ACTION:
00169     case MODE_SET_COMMIT:
00170     case MODE_SET_UNDO:
00171     case MODE_SET_FREE:
00172         if (cmp != 0) {
00173             netsnmp_set_request_error(reqinfo, requests,
00174                                       SNMP_ERR_NOCREATION);
00175             return SNMP_ERR_NOERROR;
00176         } else {
00177             reginfo->rootoid[reginfo->rootoid_len++] = 0;
00178             ret = netsnmp_call_next_handler(handler, reginfo, reqinfo,
00179                                              requests);
00180             reginfo->rootoid_len--;
00181             return ret;
00182         }
00183         break;
00184 #endif /* NETSNMP_NO_WRITE_SUPPORT */
00185 
00186     case MODE_GETNEXT:
00187         reginfo->rootoid[reginfo->rootoid_len++] = 0;
00188         ret = netsnmp_call_next_handler(handler, reginfo, reqinfo, requests);
00189         reginfo->rootoid_len--;
00190         return ret;
00191     }
00192     /*
00193      * got here only if illegal mode found 
00194      */
00195     return SNMP_ERR_GENERR;
00196 }
00197