net-snmp 5.7
|
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 #include <net-snmp/net-snmp-features.h> 00013 00014 #include <net-snmp/net-snmp-includes.h> 00015 #include <net-snmp/agent/net-snmp-agent-includes.h> 00016 00017 #include <net-snmp/agent/instance.h> 00018 00019 #include <stdlib.h> 00020 #if HAVE_STRING_H 00021 #include <string.h> 00022 #else 00023 #include <strings.h> 00024 #endif 00025 00026 #include <net-snmp/net-snmp-includes.h> 00027 #include <net-snmp/agent/serialize.h> 00028 #include <net-snmp/agent/read_only.h> 00029 00030 netsnmp_feature_provide(instance) 00031 netsnmp_feature_child_of(instance, mib_helpers) 00032 00033 typedef struct netsnmp_num_file_instance_s { 00034 int refcnt; 00035 char *file_name; 00036 FILE *filep; 00037 u_char type; 00038 int flags; 00039 } netsnmp_num_file_instance; 00040 00047 static netsnmp_num_file_instance * 00048 netsnmp_num_file_instance_ref(netsnmp_num_file_instance *nfi) 00049 { 00050 nfi->refcnt++; 00051 return nfi; 00052 } 00053 00054 static void 00055 netsnmp_num_file_instance_deref(netsnmp_num_file_instance *nfi) 00056 { 00057 if (--nfi->refcnt == 0) { 00058 free(nfi->file_name); 00059 free(nfi); 00060 } 00061 } 00062 00070 netsnmp_mib_handler * 00071 netsnmp_get_instance_handler(void) 00072 { 00073 return netsnmp_create_handler("instance", 00074 netsnmp_instance_helper_handler); 00075 } 00076 00095 int 00096 netsnmp_register_instance(netsnmp_handler_registration *reginfo) 00097 { 00098 netsnmp_mib_handler *handler = netsnmp_get_instance_handler(); 00099 handler->flags |= MIB_HANDLER_INSTANCE; 00100 netsnmp_inject_handler(reginfo, handler); 00101 return netsnmp_register_serialize(reginfo); 00102 } 00103 00122 int 00123 netsnmp_register_read_only_instance(netsnmp_handler_registration *reginfo) 00124 { 00125 netsnmp_inject_handler(reginfo, netsnmp_get_instance_handler()); 00126 netsnmp_inject_handler(reginfo, netsnmp_get_read_only_handler()); 00127 return netsnmp_register_serialize(reginfo); 00128 } 00129 00130 static 00131 netsnmp_handler_registration * 00132 get_reg(const char *name, 00133 const char *ourname, 00134 const oid * reg_oid, size_t reg_oid_len, 00135 netsnmp_num_file_instance *it, 00136 int modes, 00137 Netsnmp_Node_Handler * scalarh, Netsnmp_Node_Handler * subhandler, 00138 const char *contextName) 00139 { 00140 netsnmp_handler_registration *myreg; 00141 netsnmp_mib_handler *myhandler; 00142 00143 if (subhandler) { 00144 myreg = 00145 netsnmp_create_handler_registration(name, 00146 subhandler, 00147 reg_oid, reg_oid_len, 00148 modes); 00149 myhandler = netsnmp_create_handler(ourname, scalarh); 00150 myhandler->myvoid = it; 00151 myhandler->data_clone = (void*(*)(void*))netsnmp_num_file_instance_ref; 00152 myhandler->data_free = (void(*)(void*))netsnmp_num_file_instance_deref; 00153 netsnmp_inject_handler(myreg, myhandler); 00154 } else { 00155 myreg = 00156 netsnmp_create_handler_registration(name, 00157 scalarh, 00158 reg_oid, reg_oid_len, 00159 modes); 00160 myreg->handler->myvoid = it; 00161 myreg->handler->data_clone 00162 = (void *(*)(void *))netsnmp_num_file_instance_ref; 00163 myreg->handler->data_free 00164 = (void (*)(void *))netsnmp_num_file_instance_deref; 00165 } 00166 if (contextName) 00167 myreg->contextName = strdup(contextName); 00168 return myreg; 00169 } 00170 00171 /* Watched 'long' instances are writable on both 32-bit and 64-bit systems */ 00172 netsnmp_feature_child_of(read_only_ulong_instance,instance) 00173 #ifndef NETSNMP_FEATURE_REMOVE_READ_ONLY_ULONG_INSTANCE 00174 int 00175 netsnmp_register_read_only_ulong_instance(const char *name, 00176 const oid * reg_oid, 00177 size_t reg_oid_len, u_long * it, 00178 Netsnmp_Node_Handler * 00179 subhandler) 00180 { 00181 return netsnmp_register_watched_instance2( 00182 netsnmp_create_handler_registration( 00183 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RONLY), 00184 netsnmp_create_watcher_info( 00185 (void *)it, sizeof(u_long), 00186 ASN_UNSIGNED, WATCHER_FIXED_SIZE)); 00187 } 00188 #endif /* NETSNMP_FEATURE_REMOVE_READ_ONLY_ULONG_INSTANCE */ 00189 00190 netsnmp_feature_child_of(ulong_instance,instance) 00191 #ifndef NETSNMP_FEATURE_REMOVE_ULONG_INSTANCE 00192 int 00193 netsnmp_register_ulong_instance(const char *name, 00194 const oid * reg_oid, size_t reg_oid_len, 00195 u_long * it, 00196 Netsnmp_Node_Handler * subhandler) 00197 { 00198 return netsnmp_register_watched_instance2( 00199 netsnmp_create_handler_registration( 00200 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RWRITE), 00201 netsnmp_create_watcher_info( 00202 (void *)it, sizeof(u_long), 00203 ASN_UNSIGNED, WATCHER_FIXED_SIZE)); 00204 } 00205 #endif /* NETSNMP_FEATURE_REMOVE_ULONG_INSTANCE */ 00206 00207 netsnmp_feature_child_of(read_only_counter32_instance,instance) 00208 #ifndef NETSNMP_FEATURE_REMOVE_READ_ONLY_COUNTER32_INSTANCE 00209 int 00210 netsnmp_register_read_only_counter32_instance(const char *name, 00211 const oid * reg_oid, 00212 size_t reg_oid_len, 00213 u_long * it, 00214 Netsnmp_Node_Handler * 00215 subhandler) 00216 { 00217 return netsnmp_register_watched_instance2( 00218 netsnmp_create_handler_registration( 00219 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RONLY), 00220 netsnmp_create_watcher_info( 00221 (void *)it, sizeof(u_long), 00222 ASN_COUNTER, WATCHER_FIXED_SIZE)); 00223 } 00224 #endif /* NETSNMP_FEATURE_REMOVE_READ_ONLY_COUNTER32_INSTANCE */ 00225 00226 netsnmp_feature_child_of(read_only_long_instance,instance) 00227 #ifndef NETSNMP_FEATURE_REMOVE_READ_ONLY_LONG_INSTANCE 00228 int 00229 netsnmp_register_read_only_long_instance(const char *name, 00230 const oid * reg_oid, 00231 size_t reg_oid_len, 00232 long *it, 00233 Netsnmp_Node_Handler * subhandler) 00234 { 00235 return netsnmp_register_watched_instance2( 00236 netsnmp_create_handler_registration( 00237 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RONLY), 00238 netsnmp_create_watcher_info( 00239 (void *)it, sizeof(long), ASN_INTEGER, WATCHER_FIXED_SIZE)); 00240 } 00241 #endif /* NETSNMP_FEATURE_REMOVE_READ_ONLY_LONG_INSTANCE */ 00242 00243 netsnmp_feature_child_of(long_instance,instance) 00244 #ifndef NETSNMP_FEATURE_REMOVE_LONG_INSTANCE 00245 int 00246 netsnmp_register_long_instance(const char *name, 00247 const oid * reg_oid, size_t reg_oid_len, 00248 long *it, Netsnmp_Node_Handler * subhandler) 00249 { 00250 return netsnmp_register_watched_instance2( 00251 netsnmp_create_handler_registration( 00252 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RWRITE), 00253 netsnmp_create_watcher_info( 00254 (void *)it, sizeof(long), ASN_INTEGER, WATCHER_FIXED_SIZE)); 00255 } 00256 #endif /* NETSNMP_FEATURE_REMOVE_LONG_INSTANCE */ 00257 00258 /* Watched 'int' instances are only writable on 32-bit systems */ 00259 netsnmp_feature_child_of(read_only_uint_instance,instance) 00260 #ifndef NETSNMP_FEATURE_REMOVE_READ_ONLY_UINT_INSTANCE 00261 int 00262 netsnmp_register_read_only_uint_instance(const char *name, 00263 const oid * reg_oid, 00264 size_t reg_oid_len, 00265 unsigned int *it, 00266 Netsnmp_Node_Handler * subhandler) 00267 { 00268 return netsnmp_register_watched_instance2( 00269 netsnmp_create_handler_registration( 00270 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RONLY), 00271 netsnmp_create_watcher_info( 00272 (void *)it, sizeof(unsigned int), 00273 ASN_UNSIGNED, WATCHER_FIXED_SIZE)); 00274 } 00275 #endif /* NETSNMP_FEATURE_REMOVE_READ_ONLY_UINT_INSTANCE */ 00276 00277 netsnmp_feature_child_of(uint_instance,instance) 00278 #ifndef NETSNMP_FEATURE_REMOVE_UINT_INSTANCE 00279 int 00280 netsnmp_register_uint_instance(const char *name, 00281 const oid * reg_oid, size_t reg_oid_len, 00282 unsigned int *it, Netsnmp_Node_Handler * subhandler) 00283 { 00284 return netsnmp_register_watched_instance2( 00285 netsnmp_create_handler_registration( 00286 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RWRITE), 00287 netsnmp_create_watcher_info( 00288 (void *)it, sizeof(unsigned int), 00289 ASN_UNSIGNED, WATCHER_FIXED_SIZE)); 00290 } 00291 #endif /* NETSNMP_FEATURE_REMOVE_UINT_INSTANCE */ 00292 00293 netsnmp_feature_child_of(read_only_int_instance,instance) 00294 #ifndef NETSNMP_FEATURE_REMOVE_READ_ONLY_INT_INSTANCE 00295 int 00296 netsnmp_register_read_only_int_instance(const char *name, 00297 const oid * reg_oid, size_t reg_oid_len, 00298 int *it, Netsnmp_Node_Handler * subhandler) 00299 { 00300 return netsnmp_register_watched_instance2( 00301 netsnmp_create_handler_registration( 00302 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RONLY), 00303 netsnmp_create_watcher_info( 00304 (void *)it, sizeof(int), ASN_INTEGER, WATCHER_FIXED_SIZE)); 00305 } 00306 #endif /* NETSNMP_FEATURE_REMOVE_READ_ONLY_INT_INSTANCE */ 00307 00308 /* 00309 * Compatibility with earlier (inconsistently named) routine 00310 */ 00311 netsnmp_feature_child_of(register_read_only_int_instance,netsnmp_unused) 00312 #ifndef NETSNMP_FEATURE_REMOVE_REGISTER_READ_ONLY_INT_INSTANCE 00313 int 00314 register_read_only_int_instance(const char *name, 00315 const oid * reg_oid, size_t reg_oid_len, 00316 int *it, Netsnmp_Node_Handler * subhandler) 00317 { 00318 return netsnmp_register_read_only_int_instance(name, 00319 reg_oid, reg_oid_len, 00320 it, subhandler); 00321 } 00322 #endif /* NETSNMP_FEATURE_REMOVE_REGISTER_READ_ONLY_INT_INSTANCE */ 00323 00324 /* 00325 * Context registrations 00326 */ 00327 00328 netsnmp_feature_child_of(register_read_only_ulong_instance_context,instance) 00329 #ifndef NETSNMP_FEATURE_REMOVE_REGISTER_READ_ONLY_ULONG_INSTANCE_CONTEXT 00330 int 00331 netsnmp_register_read_only_ulong_instance_context(const char *name, 00332 const oid * reg_oid, 00333 size_t reg_oid_len, 00334 u_long * it, 00335 Netsnmp_Node_Handler * 00336 subhandler, 00337 const char *contextName) 00338 { 00339 netsnmp_handler_registration *myreg = 00340 netsnmp_create_handler_registration( 00341 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RONLY); 00342 if (myreg && contextName) 00343 myreg->contextName = strdup(contextName); 00344 return netsnmp_register_watched_instance2( 00345 myreg, netsnmp_create_watcher_info( 00346 (void *)it, sizeof(u_long), ASN_UNSIGNED, WATCHER_FIXED_SIZE)); 00347 } 00348 #endif /* NETSNMP_FEATURE_REMOVE_REGISTER_READ_ONLY_ULONG_INSTANCE_CONTEXT */ 00349 00350 netsnmp_feature_child_of(register_ulong_instance_context,instance) 00351 #ifndef NETSNMP_FEATURE_REMOVE_REGISTER_ULONG_INSTANCE_CONTEXT 00352 int 00353 netsnmp_register_ulong_instance_context(const char *name, 00354 const oid * reg_oid, size_t reg_oid_len, 00355 u_long * it, 00356 Netsnmp_Node_Handler * subhandler, 00357 const char *contextName) 00358 { 00359 netsnmp_handler_registration *myreg = 00360 netsnmp_create_handler_registration( 00361 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RWRITE); 00362 if (myreg && contextName) 00363 myreg->contextName = strdup(contextName); 00364 return netsnmp_register_watched_instance2( 00365 myreg, netsnmp_create_watcher_info( 00366 (void *)it, sizeof(u_long), ASN_UNSIGNED, WATCHER_FIXED_SIZE)); 00367 } 00368 #endif /* NETSNMP_FEATURE_REMOVE_REGISTER_ULONG_INSTANCE_CONTEXT */ 00369 00370 netsnmp_feature_child_of(register_read_only_counter32_instance_context,instance) 00371 #ifndef NETSNMP_FEATURE_REMOVE_REGISTER_READ_ONLY_COUNTER32_INSTANCE_CONTEXT 00372 int 00373 netsnmp_register_read_only_counter32_instance_context(const char *name, 00374 const oid * reg_oid, 00375 size_t reg_oid_len, 00376 u_long * it, 00377 Netsnmp_Node_Handler * 00378 subhandler, 00379 const char *contextName) 00380 { 00381 netsnmp_handler_registration *myreg = 00382 netsnmp_create_handler_registration( 00383 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RONLY); 00384 if (myreg && contextName) 00385 myreg->contextName = strdup(contextName); 00386 return netsnmp_register_watched_instance2( 00387 myreg, netsnmp_create_watcher_info( 00388 (void *)it, sizeof(u_long), ASN_COUNTER, WATCHER_FIXED_SIZE)); 00389 } 00390 #endif /* NETSNMP_FEATURE_REMOVE_REGISTER_READ_ONLY_COUNTER32_INSTANCE_CONTEXT */ 00391 00392 netsnmp_feature_child_of(register_read_only_long_instance_context,instance) 00393 #ifndef NETSNMP_FEATURE_REMOVE_REGISTER_READ_ONLY_LONG_INSTANCE_CONTEXT 00394 int 00395 netsnmp_register_read_only_long_instance_context(const char *name, 00396 const oid * reg_oid, 00397 size_t reg_oid_len, 00398 long *it, 00399 Netsnmp_Node_Handler 00400 *subhandler, 00401 const char *contextName) 00402 { 00403 netsnmp_handler_registration *myreg = 00404 netsnmp_create_handler_registration( 00405 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RONLY); 00406 if (myreg && contextName) 00407 myreg->contextName = strdup(contextName); 00408 return netsnmp_register_watched_instance2( 00409 myreg, netsnmp_create_watcher_info( 00410 (void *)it, sizeof(long), ASN_INTEGER, WATCHER_FIXED_SIZE)); 00411 } 00412 #endif /* NETSNMP_FEATURE_REMOVE_REGISTER_READ_ONLY_LONG_INSTANCE_CONTEXT */ 00413 00414 netsnmp_feature_child_of(register_long_instance_context,instance) 00415 #ifndef NETSNMP_FEATURE_REMOVE_REGISTER_LONG_INSTANCE_CONTEXT 00416 int 00417 netsnmp_register_long_instance_context(const char *name, 00418 const oid * reg_oid, size_t reg_oid_len, 00419 long *it, 00420 Netsnmp_Node_Handler * subhandler, 00421 const char *contextName) 00422 { 00423 netsnmp_handler_registration *myreg = 00424 netsnmp_create_handler_registration( 00425 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RWRITE); 00426 if (myreg && contextName) 00427 myreg->contextName = strdup(contextName); 00428 return netsnmp_register_watched_instance2( 00429 myreg, netsnmp_create_watcher_info( 00430 (void *)it, sizeof(long), ASN_INTEGER, WATCHER_FIXED_SIZE)); 00431 } 00432 #endif /* NETSNMP_FEATURE_REMOVE_REGISTER_LONG_INSTANCE_CONTEXT */ 00433 00434 netsnmp_feature_child_of(register_int_instance_context,instance) 00435 #ifndef NETSNMP_FEATURE_REMOVE_REGISTER_INT_INSTANCE_CONTEXT 00436 int 00437 netsnmp_register_int_instance_context(const char *name, 00438 const oid * reg_oid, 00439 size_t reg_oid_len, 00440 int *it, 00441 Netsnmp_Node_Handler * subhandler, 00442 const char *contextName) 00443 { 00444 netsnmp_handler_registration *myreg = 00445 netsnmp_create_handler_registration( 00446 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RWRITE); 00447 if (myreg && contextName) 00448 myreg->contextName = strdup(contextName); 00449 return netsnmp_register_watched_instance2( 00450 myreg, netsnmp_create_watcher_info( 00451 (void *)it, sizeof(int), ASN_INTEGER, WATCHER_FIXED_SIZE)); 00452 } 00453 #endif /* NETSNMP_FEATURE_REMOVE_REGISTER_INT_INSTANCE_CONTEXT */ 00454 00455 netsnmp_feature_child_of(register_read_only_int_instance_context,instance) 00456 #ifndef NETSNMP_FEATURE_REMOVE_REGISTER_READ_ONLY_INT_INSTANCE_CONTEXT 00457 int 00458 netsnmp_register_read_only_int_instance_context(const char *name, 00459 const oid * reg_oid, 00460 size_t reg_oid_len, 00461 int *it, 00462 Netsnmp_Node_Handler * subhandler, 00463 const char *contextName) 00464 { 00465 netsnmp_handler_registration *myreg = 00466 netsnmp_create_handler_registration( 00467 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RONLY); 00468 if (myreg && contextName) 00469 myreg->contextName = strdup(contextName); 00470 return netsnmp_register_watched_instance2( 00471 myreg, netsnmp_create_watcher_info( 00472 (void *)it, sizeof(int), ASN_INTEGER, WATCHER_FIXED_SIZE)); 00473 } 00474 #endif /* NETSNMP_FEATURE_REMOVE_REGISTER_READ_ONLY_INT_INSTANCE_CONTEXT */ 00475 00476 /* 00477 * Compatibility with earlier (inconsistently named) routine 00478 */ 00479 netsnmp_feature_child_of(read_only_int_instance_context,instance) 00480 #ifndef NETSNMP_FEATURE_REMOVE_READ_ONLY_INT_INSTANCE_CONTEXT 00481 int 00482 register_read_only_int_instance_context(const char *name, 00483 const oid * reg_oid, size_t reg_oid_len, 00484 int *it, 00485 Netsnmp_Node_Handler * subhandler, 00486 const char *contextName) 00487 { 00488 return netsnmp_register_read_only_int_instance_context(name, 00489 reg_oid, reg_oid_len, 00490 it, subhandler, 00491 contextName); 00492 } 00493 #endif /* NETSNMP_FEATURE_REMOVE_READ_ONLY_INT_INSTANCE_CONTEXT */ 00494 00495 netsnmp_feature_child_of(register_num_file_instance,instance) 00496 #ifndef NETSNMP_FEATURE_REMOVE_REGISTER_NUM_FILE_INSTANCE 00497 int 00498 netsnmp_register_num_file_instance(const char *name, 00499 const oid * reg_oid, size_t reg_oid_len, 00500 const char *file_name, int asn_type, int mode, 00501 Netsnmp_Node_Handler * subhandler, 00502 const char *contextName) 00503 { 00504 netsnmp_handler_registration *myreg; 00505 netsnmp_num_file_instance *nfi; 00506 00507 if ((NULL == name) || (NULL == reg_oid) || (NULL == file_name)) { 00508 snmp_log(LOG_ERR, "bad parameter to netsnmp_register_num_file_instance\n"); 00509 return MIB_REGISTRATION_FAILED; 00510 } 00511 00512 nfi = SNMP_MALLOC_TYPEDEF(netsnmp_num_file_instance); 00513 if ((NULL == nfi) || 00514 (NULL == (nfi->file_name = strdup(file_name)))) { 00515 snmp_log(LOG_ERR, "could not not allocate memory\n"); 00516 if (NULL != nfi) 00517 free(nfi); /* SNMP_FREE overkill on local var */ 00518 return MIB_REGISTRATION_FAILED; 00519 } 00520 00521 nfi->refcnt = 1; 00522 myreg = get_reg(name, "file_num_handler", reg_oid, reg_oid_len, nfi, 00523 mode, netsnmp_instance_num_file_handler, 00524 subhandler, contextName); 00525 if (NULL == myreg) { 00526 netsnmp_num_file_instance_deref(nfi); 00527 return MIB_REGISTRATION_FAILED; 00528 } 00529 00530 nfi->type = asn_type; 00531 00532 if (HANDLER_CAN_RONLY == mode) 00533 return netsnmp_register_read_only_instance(myreg); 00534 00535 return netsnmp_register_instance(myreg); 00536 } 00537 #endif /* NETSNMP_FEATURE_REMOVE_REGISTER_NUM_FILE_INSTANCE */ 00538 00557 netsnmp_feature_child_of(register_int_instance,instance) 00558 #ifndef NETSNMP_FEATURE_REMOVE_REGISTER_INT_INSTANCE 00559 int 00560 netsnmp_register_int_instance(const char *name, 00561 const oid * reg_oid, size_t reg_oid_len, 00562 int *it, Netsnmp_Node_Handler * subhandler) 00563 { 00564 return netsnmp_register_watched_instance2( 00565 netsnmp_create_handler_registration( 00566 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RWRITE), 00567 netsnmp_create_watcher_info( 00568 (void *)it, sizeof(int), ASN_INTEGER, WATCHER_FIXED_SIZE)); 00569 } 00570 #endif /* NETSNMP_FEATURE_REMOVE_REGISTER_INT_INSTANCE */ 00571 00572 #ifdef HAVE_DMALLOC_H 00573 static void free_wrapper(void * p) 00574 { 00575 free(p); 00576 } 00577 #else 00578 #define free_wrapper free 00579 #endif 00580 00581 int 00582 netsnmp_instance_num_file_handler(netsnmp_mib_handler *handler, 00583 netsnmp_handler_registration *reginfo, 00584 netsnmp_agent_request_info *reqinfo, 00585 netsnmp_request_info *requests) 00586 { 00587 netsnmp_num_file_instance *nfi; 00588 u_long it; 00589 #ifndef NETSNMP_NO_WRITE_SUPPORT 00590 u_long *it_save; 00591 #endif /* NETSNMP_NO_WRITE_SUPPORT */ 00592 int rc; 00593 00594 netsnmp_assert(NULL != handler); 00595 nfi = (netsnmp_num_file_instance *)handler->myvoid; 00596 netsnmp_assert(NULL != nfi); 00597 netsnmp_assert(NULL != nfi->file_name); 00598 00599 DEBUGMSGTL(("netsnmp_instance_int_handler", "Got request: %d\n", 00600 reqinfo->mode)); 00601 00602 switch (reqinfo->mode) { 00603 /* 00604 * data requests 00605 */ 00606 case MODE_GET: 00607 /* 00608 * Use a long here, otherwise on 64 bit use of an int would fail 00609 */ 00610 netsnmp_assert(NULL == nfi->filep); 00611 nfi->filep = fopen(nfi->file_name, "r"); 00612 if (NULL == nfi->filep) { 00613 netsnmp_set_request_error(reqinfo, requests, 00614 SNMP_NOSUCHINSTANCE); 00615 return SNMP_ERR_NOERROR; 00616 } 00617 rc = fscanf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu", 00618 &it); 00619 fclose(nfi->filep); 00620 nfi->filep = NULL; 00621 if (rc != 1) { 00622 netsnmp_set_request_error(reqinfo, requests, 00623 SNMP_NOSUCHINSTANCE); 00624 return SNMP_ERR_NOERROR; 00625 } 00626 snmp_set_var_typed_value(requests->requestvb, nfi->type, 00627 (u_char *) &it, sizeof(it)); 00628 break; 00629 00630 /* 00631 * SET requests. Should only get here if registered RWRITE 00632 */ 00633 #ifndef NETSNMP_NO_WRITE_SUPPORT 00634 case MODE_SET_RESERVE1: 00635 netsnmp_assert(NULL == nfi->filep); 00636 if (requests->requestvb->type != nfi->type) 00637 netsnmp_set_request_error(reqinfo, requests, 00638 SNMP_ERR_WRONGTYPE); 00639 break; 00640 00641 case MODE_SET_RESERVE2: 00642 netsnmp_assert(NULL == nfi->filep); 00643 nfi->filep = fopen(nfi->file_name, "w+"); 00644 if (NULL == nfi->filep) { 00645 netsnmp_set_request_error(reqinfo, requests, 00646 SNMP_ERR_NOTWRITABLE); 00647 return SNMP_ERR_NOERROR; 00648 } 00649 /* 00650 * store old info for undo later 00651 */ 00652 if (fscanf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu", 00653 &it) != 1) { 00654 netsnmp_set_request_error(reqinfo, requests, 00655 SNMP_ERR_RESOURCEUNAVAILABLE); 00656 return SNMP_ERR_NOERROR; 00657 } 00658 00659 memdup((u_char **) & it_save, (u_char *)&it, sizeof(u_long)); 00660 if (it_save == NULL) { 00661 netsnmp_set_request_error(reqinfo, requests, 00662 SNMP_ERR_RESOURCEUNAVAILABLE); 00663 return SNMP_ERR_NOERROR; 00664 } 00665 netsnmp_request_add_list_data(requests, 00666 netsnmp_create_data_list 00667 (INSTANCE_HANDLER_NAME, it_save, 00668 &free_wrapper)); 00669 break; 00670 00671 case MODE_SET_ACTION: 00672 /* 00673 * update current 00674 */ 00675 DEBUGMSGTL(("helper:instance", "updated %s -> %ld\n", nfi->file_name, 00676 *(requests->requestvb->val.integer))); 00677 it = *(requests->requestvb->val.integer); 00678 rewind(nfi->filep); /* rewind to make sure we are at the beginning */ 00679 rc = fprintf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu", 00680 it); 00681 if (rc < 0) { 00682 netsnmp_set_request_error(reqinfo, requests, 00683 SNMP_ERR_GENERR); 00684 return SNMP_ERR_NOERROR; 00685 } 00686 break; 00687 00688 case MODE_SET_UNDO: 00689 it = 00690 *((u_int *) netsnmp_request_get_list_data(requests, 00691 INSTANCE_HANDLER_NAME)); 00692 rc = fprintf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu", 00693 it); 00694 if (rc < 0) 00695 netsnmp_set_request_error(reqinfo, requests, 00696 SNMP_ERR_UNDOFAILED); 00699 case MODE_SET_COMMIT: 00700 case MODE_SET_FREE: 00701 if (NULL != nfi->filep) { 00702 fclose(nfi->filep); 00703 nfi->filep = NULL; 00704 } 00705 break; 00706 #endif /* NETSNMP_NO_WRITE_SUPPORT */ 00707 default: 00708 snmp_log(LOG_ERR, 00709 "netsnmp_instance_num_file_handler: illegal mode\n"); 00710 netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR); 00711 return SNMP_ERR_NOERROR; 00712 } 00713 00714 if (handler->next && handler->next->access_method) 00715 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 00716 requests); 00717 return SNMP_ERR_NOERROR; 00718 } 00719 00720 int 00721 netsnmp_instance_helper_handler(netsnmp_mib_handler *handler, 00722 netsnmp_handler_registration *reginfo, 00723 netsnmp_agent_request_info *reqinfo, 00724 netsnmp_request_info *requests) 00725 { 00726 00727 netsnmp_variable_list *var = requests->requestvb; 00728 00729 int ret, cmp; 00730 00731 DEBUGMSGTL(("helper:instance", "Got request:\n")); 00732 cmp = snmp_oid_compare(requests->requestvb->name, 00733 requests->requestvb->name_length, 00734 reginfo->rootoid, reginfo->rootoid_len); 00735 00736 DEBUGMSGTL(("helper:instance", " oid:")); 00737 DEBUGMSGOID(("helper:instance", var->name, var->name_length)); 00738 DEBUGMSG(("helper:instance", "\n")); 00739 00740 switch (reqinfo->mode) { 00741 case MODE_GET: 00742 if (cmp != 0) { 00743 netsnmp_set_request_error(reqinfo, requests, 00744 SNMP_NOSUCHINSTANCE); 00745 return SNMP_ERR_NOERROR; 00746 } else { 00747 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 00748 requests); 00749 } 00750 break; 00751 00752 #ifndef NETSNMP_NO_WRITE_SUPPORT 00753 case MODE_SET_RESERVE1: 00754 case MODE_SET_RESERVE2: 00755 case MODE_SET_ACTION: 00756 case MODE_SET_COMMIT: 00757 case MODE_SET_UNDO: 00758 case MODE_SET_FREE: 00759 if (cmp != 0) { 00760 netsnmp_set_request_error(reqinfo, requests, 00761 SNMP_ERR_NOCREATION); 00762 return SNMP_ERR_NOERROR; 00763 } else { 00764 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 00765 requests); 00766 } 00767 break; 00768 #endif /* NETSNMP_NO_WRITE_SUPPORT */ 00769 00770 case MODE_GETNEXT: 00771 if (cmp < 0 || (cmp == 0 && requests->inclusive)) { 00772 reqinfo->mode = MODE_GET; 00773 snmp_set_var_objid(requests->requestvb, reginfo->rootoid, 00774 reginfo->rootoid_len); 00775 ret = 00776 netsnmp_call_next_handler(handler, reginfo, reqinfo, 00777 requests); 00778 reqinfo->mode = MODE_GETNEXT; 00779 /* 00780 * if the instance doesn't have data, set type to ASN_NULL 00781 * to move to the next sub-tree. Ignore delegated requests; they 00782 * might have data later on. 00783 */ 00784 if (!requests->delegated && 00785 (requests->requestvb->type == SNMP_NOSUCHINSTANCE || 00786 requests->requestvb->type == SNMP_NOSUCHOBJECT)) { 00787 requests->requestvb->type = ASN_NULL; 00788 } 00789 return ret; 00790 } else { 00791 return SNMP_ERR_NOERROR; 00792 } 00793 break; 00794 default: 00795 snmp_log(LOG_ERR, 00796 "netsnmp_instance_helper_handler: illegal mode\n"); 00797 netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR); 00798 return SNMP_ERR_NOERROR; 00799 } 00800 /* 00801 * got here only if illegal mode found 00802 */ 00803 return SNMP_ERR_GENERR; 00804 } 00805