old_api.c

00001 #include <net-snmp/net-snmp-config.h>
00002 
00003 #if HAVE_STRING_H
00004 #include <string.h>
00005 #else
00006 #include <strings.h>
00007 #endif
00008 
00009 #include <net-snmp/net-snmp-includes.h>
00010 #include <net-snmp/agent/net-snmp-agent-includes.h>
00011 
00012 #include <net-snmp/agent/old_api.h>
00013 #include <net-snmp/agent/agent_callbacks.h>
00014 
00015 #define MIB_CLIENTS_ARE_EVIL 1
00016 
00017 /*
00018  * don't use these! 
00019  */
00020 void            set_current_agent_session(netsnmp_agent_session *asp);
00021 netsnmp_agent_session *netsnmp_get_current_agent_session(void);
00022 
00036 netsnmp_mib_handler *
00037 get_old_api_handler(void)
00038 {
00039     return netsnmp_create_handler("old_api", netsnmp_old_api_helper);
00040 }
00041 
00042 
00047 int
00048 netsnmp_register_old_api(const char *moduleName,
00049                          struct variable *var,
00050                          size_t varsize,
00051                          size_t numvars,
00052                          oid * mibloc,
00053                          size_t mibloclen,
00054                          int priority,
00055                          int range_subid,
00056                          oid range_ubound,
00057                          netsnmp_session * ss,
00058                          const char *context, int timeout, int flags)
00059 {
00060 
00061     unsigned int    i;
00062 
00063     /*
00064      * register all subtree nodes 
00065      */
00066     for (i = 0; i < numvars; i++) {
00067         struct variable *vp;
00068         netsnmp_handler_registration *reginfo =
00069             SNMP_MALLOC_TYPEDEF(netsnmp_handler_registration);
00070 
00071         memdup((void *) &vp,
00072                (void *) (struct variable *) ((char *) var + varsize * i),
00073                varsize);
00074 
00075         reginfo->handler = get_old_api_handler();
00076         reginfo->handlerName = strdup(moduleName);
00077         reginfo->rootoid_len = (mibloclen + vp->namelen);
00078         reginfo->rootoid =
00079             (oid *) malloc(reginfo->rootoid_len * sizeof(oid));
00080 
00081         memcpy(reginfo->rootoid, mibloc, mibloclen * sizeof(oid));
00082         memcpy(reginfo->rootoid + mibloclen, vp->name, vp->namelen
00083                * sizeof(oid));
00084         reginfo->handler->myvoid = (void *) vp;
00085 
00086         reginfo->priority = priority;
00087         reginfo->range_subid = range_subid;
00088 
00089         reginfo->range_ubound = range_ubound;
00090         reginfo->timeout = timeout;
00091         reginfo->contextName = (context) ? strdup(context) : NULL;
00092         reginfo->modes = HANDLER_CAN_RWRITE;
00093 
00094         /*
00095          * register ourselves in the mib tree 
00096          */
00097         if (netsnmp_register_handler(reginfo) != MIB_REGISTERED_OK) {
00099             SNMP_FREE(vp);
00100         }
00101     }
00102     return SNMPERR_SUCCESS;
00103 }
00104 
00106 int
00107 netsnmp_register_mib_table_row(const char *moduleName,
00108                                struct variable *var,
00109                                size_t varsize,
00110                                size_t numvars,
00111                                oid * mibloc,
00112                                size_t mibloclen,
00113                                int priority,
00114                                int var_subid,
00115                                netsnmp_session * ss,
00116                                const char *context, int timeout, int flags)
00117 {
00118     unsigned int    i = 0, rc = 0;
00119     oid             ubound = 0;
00120 
00121     for (i = 0; i < numvars; i++) {
00122         struct variable *vr =
00123             (struct variable *) ((char *) var + (i * varsize));
00124         netsnmp_handler_registration *r;
00125         if ( var_subid > (int)mibloclen ) {
00126             break;    /* doesn't make sense */
00127         }
00128         r = SNMP_MALLOC_TYPEDEF(netsnmp_handler_registration);
00129 
00130         if (r == NULL) {
00131             /*
00132              * Unregister whatever we have registered so far, and
00133              * return an error.  
00134              */
00135             rc = MIB_REGISTRATION_FAILED;
00136             break;
00137         }
00138         memset(r, 0, sizeof(netsnmp_handler_registration));
00139 
00140         r->handler = get_old_api_handler();
00141         r->handlerName = strdup(moduleName);
00142 
00143         if (r->handlerName == NULL) {
00144             netsnmp_handler_registration_free(r);
00145             break;
00146         }
00147 
00148         r->rootoid_len = mibloclen;
00149         r->rootoid = (oid *) malloc(r->rootoid_len * sizeof(oid));
00150 
00151         if (r->rootoid == NULL) {
00152             netsnmp_handler_registration_free(r);
00153             rc = MIB_REGISTRATION_FAILED;
00154             break;
00155         }
00156         memcpy(r->rootoid, mibloc, mibloclen * sizeof(oid));
00157         memcpy((u_char *) (r->rootoid + (var_subid - vr->namelen)), vr->name,
00158                vr->namelen * sizeof(oid));
00159         DEBUGMSGTL(("netsnmp_register_mib_table_row", "rootoid "));
00160         DEBUGMSGOID(("netsnmp_register_mib_table_row", r->rootoid,
00161                      r->rootoid_len));
00162         DEBUGMSG(("netsnmp_register_mib_table_row", "(%d)\n",
00163                      (var_subid - vr->namelen)));
00164         r->handler->myvoid = (void *) malloc(varsize);
00165 
00166         if (r->handler->myvoid == NULL) {
00167             netsnmp_handler_registration_free(r);
00168             rc = MIB_REGISTRATION_FAILED;
00169             break;
00170         }
00171         memcpy((char *) r->handler->myvoid, vr, varsize);
00172 
00173         r->contextName = (context) ? strdup(context) : NULL;
00174 
00175         if (context != NULL && r->contextName == NULL) {
00176             netsnmp_handler_registration_free(r);
00177             rc = MIB_REGISTRATION_FAILED;
00178             break;
00179         }
00180 
00181         r->priority = priority;
00182         r->range_subid = 0;     /* var_subid; */
00183         r->range_ubound = 0;    /* range_ubound; */
00184         r->timeout = timeout;
00185         r->modes = HANDLER_CAN_RWRITE;
00186 
00187         /*
00188          * Register this column and row  
00189          */
00190         if ((rc =
00191              netsnmp_register_handler_nocallback(r)) !=
00192             MIB_REGISTERED_OK) {
00193             DEBUGMSGTL(("netsnmp_register_mib_table_row",
00194                         "register failed %d\n", rc));
00195             netsnmp_handler_registration_free(r);
00196             break;
00197         }
00198 
00199         if (vr->namelen > 0) {
00200             if (vr->name[vr->namelen - 1] > ubound) {
00201                 ubound = vr->name[vr->namelen - 1];
00202             }
00203         }
00204     }
00205 
00206     if (rc == MIB_REGISTERED_OK) {
00207         struct register_parameters reg_parms;
00208 
00209         reg_parms.name = mibloc;
00210         reg_parms.namelen = mibloclen;
00211         reg_parms.priority = priority;
00212         reg_parms.flags = (u_char) flags;
00213         reg_parms.range_subid = var_subid;
00214         reg_parms.range_ubound = ubound;
00215         reg_parms.timeout = timeout;
00216         reg_parms.contextName = context;
00217         rc = snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
00218                                  SNMPD_CALLBACK_REGISTER_OID, &reg_parms);
00219     }
00220 
00221     return rc;
00222 }
00223 
00225 int
00226 netsnmp_old_api_helper(netsnmp_mib_handler *handler,
00227                        netsnmp_handler_registration *reginfo,
00228                        netsnmp_agent_request_info *reqinfo,
00229                        netsnmp_request_info *requests)
00230 {
00231 
00232 #if MIB_CLIENTS_ARE_EVIL
00233     oid             save[MAX_OID_LEN];
00234     size_t          savelen = 0;
00235 #endif
00236     struct variable compat_var, *cvp = &compat_var;
00237     int             exact = 1;
00238     int             status;
00239 
00240     struct variable *vp;
00241     WriteMethod    *write_method = NULL;
00242     size_t          len;
00243     u_char         *access = NULL;
00244     netsnmp_old_api_cache *cacheptr;
00245     netsnmp_agent_session *oldasp = NULL;
00246 
00247     vp = (struct variable *) handler->myvoid;
00248 
00249     /*
00250      * create old variable structure with right information 
00251      */
00252     memcpy(cvp->name, reginfo->rootoid,
00253            reginfo->rootoid_len * sizeof(oid));
00254     cvp->namelen = reginfo->rootoid_len;
00255     cvp->type = vp->type;
00256     cvp->magic = vp->magic;
00257     cvp->acl = vp->acl;
00258     cvp->findVar = vp->findVar;
00259 
00260     switch (reqinfo->mode) {
00261     case MODE_GETNEXT:
00262     case MODE_GETBULK:
00263         exact = 0;
00264     }
00265 
00266     for (; requests; requests = requests->next) {
00267 
00268 #if MIB_CLIENTS_ARE_EVIL
00269         savelen = requests->requestvb->name_length;
00270         memcpy(save, requests->requestvb->name, savelen * sizeof(oid));
00271 #endif
00272 
00273         switch (reqinfo->mode) {
00274         case MODE_GET:
00275         case MODE_GETNEXT:
00276         case MODE_SET_RESERVE1:
00277             /*
00278              * Actually call the old mib-module function 
00279              */
00280             if (vp && vp->findVar)
00281                 access = (*(vp->findVar)) (cvp, requests->requestvb->name,
00282                                            &(requests->requestvb->
00283                                              name_length), exact, &len,
00284                                            &write_method);
00285             else
00286                 access = NULL;
00287 
00288 #ifdef WWW_FIX
00289             if (IS_DELEGATED(cvp->type)) {
00290                 add_method = (AddVarMethod *) statP;
00291                 requests->delayed = 1;
00292                 have_delegated = 1;
00293                 continue;       /* WWW: This may not get to the right place */
00294             }
00295 #endif
00296 
00297             /*
00298              * WWW: end range checking 
00299              */
00300             if (access) {
00301                 /*
00302                  * result returned 
00303                  */
00304                 if (reqinfo->mode != MODE_SET_RESERVE1)
00305                     snmp_set_var_typed_value(requests->requestvb,
00306                                              cvp->type, access, len);
00307             } else {
00308                 /*
00309                  * no result returned 
00310                  */
00311 #if MIB_CLIENTS_ARE_EVIL
00312                 if (access == NULL) {
00313                     if (netsnmp_oid_equals(requests->requestvb->name,
00314                                          requests->requestvb->name_length,
00315                                          save, savelen) != 0) {
00316                         DEBUGMSGTL(("old_api", "evil_client: %s\n",
00317                                     reginfo->handlerName));
00318                         memcpy(requests->requestvb->name, save,
00319                                savelen * sizeof(oid));
00320                         requests->requestvb->name_length = savelen;
00321                     }
00322                 }
00323 #endif
00324             }
00325 
00326             /*
00327              * AAA: fall through for everything that is a set (see BBB) 
00328              */
00329             if (reqinfo->mode != MODE_SET_RESERVE1)
00330                 break;
00331 
00332             cacheptr = SNMP_MALLOC_TYPEDEF(netsnmp_old_api_cache);
00333             if (!cacheptr)
00334                 return netsnmp_set_request_error(reqinfo, requests,
00335                                                  SNMP_ERR_RESOURCEUNAVAILABLE);
00336             cacheptr->data = access;
00337             cacheptr->write_method = write_method;
00338             write_method = NULL;
00339             netsnmp_request_add_list_data(requests,
00340                                           netsnmp_create_data_list
00341                                           (OLD_API_NAME, cacheptr, free));
00342             /*
00343              * BBB: fall through for everything that is a set (see AAA) 
00344              */
00345 
00346         default:
00347             /*
00348              * WWW: explicitly list the SET conditions 
00349              */
00350             /*
00351              * (the rest of the) SET contions 
00352              */
00353             cacheptr =
00354                 (netsnmp_old_api_cache *)
00355                 netsnmp_request_get_list_data(requests, OLD_API_NAME);
00356 
00357             if (cacheptr == NULL || cacheptr->write_method == NULL) {
00358                 /*
00359                  * WWW: try to set ourselves if possible? 
00360                  */
00361                 return netsnmp_set_request_error(reqinfo, requests,
00362                                                  SNMP_ERR_NOTWRITABLE);
00363             }
00364 
00365             oldasp = netsnmp_get_current_agent_session();
00366             set_current_agent_session(reqinfo->asp);
00367             status =
00368                 (*(cacheptr->write_method)) (reqinfo->mode,
00369                                              requests->requestvb->val.
00370                                              string,
00371                                              requests->requestvb->type,
00372                                              requests->requestvb->val_len,
00373                                              cacheptr->data,
00374                                              requests->requestvb->name,
00375                                              requests->requestvb->
00376                                              name_length);
00377             set_current_agent_session(oldasp);
00378 
00379             if (status != SNMP_ERR_NOERROR) {
00380                 netsnmp_set_request_error(reqinfo, requests, status);
00381             }
00382 
00383             /*
00384              * clean up is done by the automatic freeing of the
00385              * cache stored in the request. 
00386              */
00387 
00388             break;
00389         }
00390     }
00391     return SNMP_ERR_NOERROR;
00392 }
00393 
00396 /*
00397  * don't use this! 
00398  */
00399 static netsnmp_agent_session *current_agent_session = NULL;
00400 netsnmp_agent_session *
00401 netsnmp_get_current_agent_session()
00402 {
00403     return current_agent_session;
00404 }
00405 
00406 /*
00407  * don't use this! 
00408  */
00409 void
00410 set_current_agent_session(netsnmp_agent_session *asp)
00411 {
00412     current_agent_session = asp;
00413 }

net-snmpに対してSat Sep 5 13:14:22 2009に生成されました。  doxygen 1.4.7