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
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
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
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;
00127 }
00128 r = SNMP_MALLOC_TYPEDEF(netsnmp_handler_registration);
00129
00130 if (r == NULL) {
00131
00132
00133
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;
00183 r->range_ubound = 0;
00184 r->timeout = timeout;
00185 r->modes = HANDLER_CAN_RWRITE;
00186
00187
00188
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, ®_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
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
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;
00294 }
00295 #endif
00296
00297
00298
00299
00300 if (access) {
00301
00302
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
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
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
00344
00345
00346 default:
00347
00348
00349
00350
00351
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
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
00385
00386
00387
00388 break;
00389 }
00390 }
00391 return SNMP_ERR_NOERROR;
00392 }
00393
00396
00397
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
00408
00409 void
00410 set_current_agent_session(netsnmp_agent_session *asp)
00411 {
00412 current_agent_session = asp;
00413 }