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/instance.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/serialize.h> 00026 #include <net-snmp/agent/read_only.h> 00027 00028 typedef struct netsnmp_num_file_instance_s { 00029 char *file_name; 00030 FILE *filep; 00031 int type; 00032 int flags; 00033 } netsnmp_num_file_instance; 00034 00048 netsnmp_mib_handler * 00049 netsnmp_get_instance_handler(void) 00050 { 00051 return netsnmp_create_handler("instance", 00052 netsnmp_instance_helper_handler); 00053 } 00054 00073 int 00074 netsnmp_register_instance(netsnmp_handler_registration *reginfo) 00075 { 00076 netsnmp_mib_handler *handler = netsnmp_get_instance_handler(); 00077 handler->flags |= MIB_HANDLER_INSTANCE; 00078 netsnmp_inject_handler(reginfo, handler); 00079 return netsnmp_register_serialize(reginfo); 00080 } 00081 00100 int 00101 netsnmp_register_read_only_instance(netsnmp_handler_registration *reginfo) 00102 { 00103 netsnmp_inject_handler(reginfo, netsnmp_get_instance_handler()); 00104 netsnmp_inject_handler(reginfo, netsnmp_get_read_only_handler()); 00105 return netsnmp_register_serialize(reginfo); 00106 } 00107 00108 static 00109 netsnmp_handler_registration * 00110 get_reg(const char *name, 00111 const char *ourname, 00112 const oid * reg_oid, size_t reg_oid_len, 00113 void *it, 00114 int modes, 00115 Netsnmp_Node_Handler * scalarh, Netsnmp_Node_Handler * subhandler, 00116 const char *contextName) 00117 { 00118 netsnmp_handler_registration *myreg; 00119 netsnmp_mib_handler *myhandler; 00120 00121 if (subhandler) { 00122 myreg = 00123 netsnmp_create_handler_registration(name, 00124 subhandler, 00125 reg_oid, reg_oid_len, 00126 modes); 00127 myhandler = netsnmp_create_handler(ourname, scalarh); 00128 myhandler->myvoid = (void *) it; 00129 netsnmp_inject_handler(myreg, myhandler); 00130 } else { 00131 myreg = 00132 netsnmp_create_handler_registration(name, 00133 scalarh, 00134 reg_oid, reg_oid_len, 00135 modes); 00136 myreg->handler->myvoid = (void *) it; 00137 } 00138 if (contextName) 00139 myreg->contextName = strdup(contextName); 00140 return myreg; 00141 } 00142 00143 int 00144 netsnmp_register_read_only_ulong_instance(const char *name, 00145 const oid * reg_oid, 00146 size_t reg_oid_len, u_long * it, 00147 Netsnmp_Node_Handler * 00148 subhandler) 00149 { 00150 return netsnmp_register_watched_instance( 00151 netsnmp_create_handler_registration( 00152 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RONLY), 00153 netsnmp_create_watcher_info( 00154 (void *)it, sizeof(u_long), 00155 ASN_UNSIGNED, WATCHER_FIXED_SIZE)); 00156 } 00157 00158 int 00159 netsnmp_register_ulong_instance(const char *name, 00160 const oid * reg_oid, size_t reg_oid_len, 00161 u_long * it, 00162 Netsnmp_Node_Handler * subhandler) 00163 { 00164 return netsnmp_register_watched_instance( 00165 netsnmp_create_handler_registration( 00166 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RWRITE), 00167 netsnmp_create_watcher_info( 00168 (void *)it, sizeof(u_long), 00169 ASN_UNSIGNED, WATCHER_FIXED_SIZE)); 00170 } 00171 00172 int 00173 netsnmp_register_read_only_counter32_instance(const char *name, 00174 const oid * reg_oid, 00175 size_t reg_oid_len, 00176 u_long * it, 00177 Netsnmp_Node_Handler * 00178 subhandler) 00179 { 00180 return netsnmp_register_watched_instance( 00181 netsnmp_create_handler_registration( 00182 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RONLY), 00183 netsnmp_create_watcher_info( 00184 (void *)it, sizeof(u_long), 00185 ASN_COUNTER, WATCHER_FIXED_SIZE)); 00186 } 00187 00188 int 00189 netsnmp_register_read_only_long_instance(const char *name, 00190 const oid * reg_oid, 00191 size_t reg_oid_len, 00192 long *it, 00193 Netsnmp_Node_Handler * subhandler) 00194 { 00195 return netsnmp_register_watched_instance( 00196 netsnmp_create_handler_registration( 00197 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RONLY), 00198 netsnmp_create_watcher_info( 00199 (void *)it, sizeof(long), ASN_INTEGER, WATCHER_FIXED_SIZE)); 00200 } 00201 00202 int 00203 netsnmp_register_long_instance(const char *name, 00204 const oid * reg_oid, size_t reg_oid_len, 00205 long *it, Netsnmp_Node_Handler * subhandler) 00206 { 00207 return netsnmp_register_watched_instance( 00208 netsnmp_create_handler_registration( 00209 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RWRITE), 00210 netsnmp_create_watcher_info( 00211 (void *)it, sizeof(long), ASN_INTEGER, WATCHER_FIXED_SIZE)); 00212 } 00213 00214 00215 int 00216 netsnmp_register_read_only_uint_instance(const char *name, 00217 const oid * reg_oid, 00218 size_t reg_oid_len, 00219 unsigned int *it, 00220 Netsnmp_Node_Handler * subhandler) 00221 { 00222 return netsnmp_register_watched_instance( 00223 netsnmp_create_handler_registration( 00224 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RONLY), 00225 netsnmp_create_watcher_info( 00226 (void *)it, sizeof(unsigned int), 00227 ASN_UNSIGNED, WATCHER_FIXED_SIZE)); 00228 } 00229 00230 int 00231 netsnmp_register_uint_instance(const char *name, 00232 const oid * reg_oid, size_t reg_oid_len, 00233 unsigned int *it, Netsnmp_Node_Handler * subhandler) 00234 { 00235 return netsnmp_register_watched_instance( 00236 netsnmp_create_handler_registration( 00237 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RWRITE), 00238 netsnmp_create_watcher_info( 00239 (void *)it, sizeof(unsigned int), 00240 ASN_UNSIGNED, WATCHER_FIXED_SIZE)); 00241 } 00242 00243 int 00244 netsnmp_register_read_only_int_instance(const char *name, 00245 const oid * reg_oid, size_t reg_oid_len, 00246 int *it, Netsnmp_Node_Handler * subhandler) 00247 { 00248 return netsnmp_register_watched_instance( 00249 netsnmp_create_handler_registration( 00250 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RONLY), 00251 netsnmp_create_watcher_info( 00252 (void *)it, sizeof(int), ASN_INTEGER, WATCHER_FIXED_SIZE)); 00253 } 00254 00255 /* 00256 * Compatibility with earlier (inconsistently named) routine 00257 */ 00258 int 00259 register_read_only_int_instance(const char *name, 00260 const oid * reg_oid, size_t reg_oid_len, 00261 int *it, Netsnmp_Node_Handler * subhandler) 00262 { 00263 return netsnmp_register_read_only_int_instance(name, 00264 reg_oid, reg_oid_len, 00265 it, subhandler); 00266 } 00267 00268 /* 00269 * Context registrations 00270 */ 00271 00272 int 00273 netsnmp_register_read_only_ulong_instance_context(const char *name, 00274 const oid * reg_oid, 00275 size_t reg_oid_len, 00276 u_long * it, 00277 Netsnmp_Node_Handler * 00278 subhandler, 00279 const char *contextName) 00280 { 00281 netsnmp_handler_registration *myreg = 00282 netsnmp_create_handler_registration( 00283 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RONLY); 00284 if (myreg && contextName) 00285 myreg->contextName = strdup(contextName); 00286 return netsnmp_register_watched_instance( 00287 myreg, netsnmp_create_watcher_info( 00288 (void *)it, sizeof(u_long), ASN_UNSIGNED, WATCHER_FIXED_SIZE)); 00289 } 00290 00291 int 00292 netsnmp_register_ulong_instance_context(const char *name, 00293 const oid * reg_oid, size_t reg_oid_len, 00294 u_long * it, 00295 Netsnmp_Node_Handler * subhandler, 00296 const char *contextName) 00297 { 00298 netsnmp_handler_registration *myreg = 00299 netsnmp_create_handler_registration( 00300 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RWRITE); 00301 if (myreg && contextName) 00302 myreg->contextName = strdup(contextName); 00303 return netsnmp_register_watched_instance( 00304 myreg, netsnmp_create_watcher_info( 00305 (void *)it, sizeof(u_long), ASN_UNSIGNED, WATCHER_FIXED_SIZE)); 00306 } 00307 00308 int 00309 netsnmp_register_read_only_counter32_instance_context(const char *name, 00310 const oid * reg_oid, 00311 size_t reg_oid_len, 00312 u_long * it, 00313 Netsnmp_Node_Handler * 00314 subhandler, 00315 const char *contextName) 00316 { 00317 netsnmp_handler_registration *myreg = 00318 netsnmp_create_handler_registration( 00319 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RONLY); 00320 if (myreg && contextName) 00321 myreg->contextName = strdup(contextName); 00322 return netsnmp_register_watched_instance( 00323 myreg, netsnmp_create_watcher_info( 00324 (void *)it, sizeof(u_long), ASN_COUNTER, WATCHER_FIXED_SIZE)); 00325 } 00326 00327 int 00328 netsnmp_register_read_only_long_instance_context(const char *name, 00329 const oid * reg_oid, 00330 size_t reg_oid_len, 00331 long *it, 00332 Netsnmp_Node_Handler 00333 *subhandler, 00334 const char *contextName) 00335 { 00336 netsnmp_handler_registration *myreg = 00337 netsnmp_create_handler_registration( 00338 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RONLY); 00339 if (myreg && contextName) 00340 myreg->contextName = strdup(contextName); 00341 return netsnmp_register_watched_instance( 00342 myreg, netsnmp_create_watcher_info( 00343 (void *)it, sizeof(long), ASN_INTEGER, WATCHER_FIXED_SIZE)); 00344 } 00345 00346 int 00347 netsnmp_register_long_instance_context(const char *name, 00348 const oid * reg_oid, size_t reg_oid_len, 00349 long *it, 00350 Netsnmp_Node_Handler * subhandler, 00351 const char *contextName) 00352 { 00353 netsnmp_handler_registration *myreg = 00354 netsnmp_create_handler_registration( 00355 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RWRITE); 00356 if (myreg && contextName) 00357 myreg->contextName = strdup(contextName); 00358 return netsnmp_register_watched_instance( 00359 myreg, netsnmp_create_watcher_info( 00360 (void *)it, sizeof(long), ASN_INTEGER, WATCHER_FIXED_SIZE)); 00361 } 00362 00363 int 00364 netsnmp_register_int_instance_context(const char *name, 00365 const oid * reg_oid, 00366 size_t reg_oid_len, 00367 int *it, 00368 Netsnmp_Node_Handler * subhandler, 00369 const char *contextName) 00370 { 00371 netsnmp_handler_registration *myreg = 00372 netsnmp_create_handler_registration( 00373 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RWRITE); 00374 if (myreg && contextName) 00375 myreg->contextName = strdup(contextName); 00376 return netsnmp_register_watched_instance( 00377 myreg, netsnmp_create_watcher_info( 00378 (void *)it, sizeof(int), ASN_INTEGER, WATCHER_FIXED_SIZE)); 00379 } 00380 00381 int 00382 netsnmp_register_read_only_int_instance_context(const char *name, 00383 const oid * reg_oid, 00384 size_t reg_oid_len, 00385 int *it, 00386 Netsnmp_Node_Handler * subhandler, 00387 const char *contextName) 00388 { 00389 netsnmp_handler_registration *myreg = 00390 netsnmp_create_handler_registration( 00391 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RONLY); 00392 if (myreg && contextName) 00393 myreg->contextName = strdup(contextName); 00394 return netsnmp_register_watched_instance( 00395 myreg, netsnmp_create_watcher_info( 00396 (void *)it, sizeof(int), ASN_INTEGER, WATCHER_FIXED_SIZE)); 00397 } 00398 00399 /* 00400 * Compatibility with earlier (inconsistently named) routine 00401 */ 00402 int 00403 register_read_only_int_instance_context(const char *name, 00404 const oid * reg_oid, size_t reg_oid_len, 00405 int *it, 00406 Netsnmp_Node_Handler * subhandler, 00407 const char *contextName) 00408 { 00409 return netsnmp_register_read_only_int_instance_context(name, 00410 reg_oid, reg_oid_len, 00411 it, subhandler, 00412 contextName); 00413 } 00414 00415 int 00416 netsnmp_register_num_file_instance(const char *name, 00417 const oid * reg_oid, size_t reg_oid_len, 00418 const char *file_name, int asn_type, int mode, 00419 Netsnmp_Node_Handler * subhandler, 00420 const char *contextName) 00421 { 00422 netsnmp_handler_registration *myreg; 00423 netsnmp_num_file_instance *nfi; 00424 00425 if ((NULL == name) || (NULL == reg_oid) || (NULL == file_name)) { 00426 snmp_log(LOG_ERR, "bad parameter to netsnmp_register_num_file_instance\n"); 00427 return MIB_REGISTRATION_FAILED; 00428 } 00429 00430 nfi = SNMP_MALLOC_TYPEDEF(netsnmp_num_file_instance); 00431 if ((NULL == nfi) || 00432 (NULL == (nfi->file_name = strdup(file_name)))) { 00433 snmp_log(LOG_ERR, "could not not allocate memory\n"); 00434 if (NULL != nfi) 00435 free(nfi); /* SNMP_FREE overkill on local var */ 00436 return MIB_REGISTRATION_FAILED; 00437 } 00438 00439 myreg = get_reg(name, "file_num_handler", reg_oid, reg_oid_len, nfi, 00440 mode, netsnmp_instance_num_file_handler, 00441 subhandler, contextName); 00442 if (NULL == myreg) { 00443 free(nfi); /* SNMP_FREE overkill on local var */ 00444 return MIB_REGISTRATION_FAILED; 00445 } 00446 00447 nfi->type = asn_type; 00448 00449 if (HANDLER_CAN_RONLY == mode) 00450 return netsnmp_register_read_only_instance(myreg); 00451 00452 return netsnmp_register_instance(myreg); 00453 } 00454 00473 int 00474 netsnmp_register_int_instance(const char *name, 00475 const oid * reg_oid, size_t reg_oid_len, 00476 int *it, Netsnmp_Node_Handler * subhandler) 00477 { 00478 return netsnmp_register_watched_instance( 00479 netsnmp_create_handler_registration( 00480 name, subhandler, reg_oid, reg_oid_len, HANDLER_CAN_RWRITE), 00481 netsnmp_create_watcher_info( 00482 (void *)it, sizeof(int), ASN_INTEGER, WATCHER_FIXED_SIZE)); 00483 } 00484 00485 #ifndef NETSNMP_NO_DEPRECATED_FUNCTIONS 00486 00490 int 00491 netsnmp_instance_ulong_handler(netsnmp_mib_handler *handler, 00492 netsnmp_handler_registration *reginfo, 00493 netsnmp_agent_request_info *reqinfo, 00494 netsnmp_request_info *requests) 00495 { 00496 00497 u_long *it = (u_long *) handler->myvoid; 00498 u_long *it_save; 00499 00500 DEBUGMSGTL(("netsnmp_instance_ulong_handler", "Got request: %d\n", 00501 reqinfo->mode)); 00502 00503 switch (reqinfo->mode) { 00504 /* 00505 * data requests 00506 */ 00507 case MODE_GET: 00508 snmp_set_var_typed_value(requests->requestvb, ASN_UNSIGNED, 00509 (u_char *) it, sizeof(*it)); 00510 break; 00511 00512 /* 00513 * SET requests. Should only get here if registered RWRITE 00514 */ 00515 case MODE_SET_RESERVE1: 00516 if (requests->requestvb->type != ASN_UNSIGNED) 00517 netsnmp_set_request_error(reqinfo, requests, 00518 SNMP_ERR_WRONGTYPE); 00519 break; 00520 00521 case MODE_SET_RESERVE2: 00522 /* 00523 * store old info for undo later 00524 */ 00525 memdup((u_char **) & it_save, (u_char *) it, sizeof(u_long)); 00526 if (it_save == NULL) { 00527 netsnmp_set_request_error(reqinfo, requests, 00528 SNMP_ERR_RESOURCEUNAVAILABLE); 00529 return SNMP_ERR_NOERROR; 00530 } 00531 netsnmp_request_add_list_data(requests, 00532 netsnmp_create_data_list 00533 (INSTANCE_HANDLER_NAME, it_save, 00534 free)); 00535 break; 00536 00537 case MODE_SET_ACTION: 00538 /* 00539 * update current 00540 */ 00541 DEBUGMSGTL(("testhandler", "updated u_long %lu -> %lu\n", *it, 00542 *(requests->requestvb->val.integer))); 00543 *it = *(requests->requestvb->val.integer); 00544 break; 00545 00546 case MODE_SET_UNDO: 00547 *it = 00548 *((u_long *) netsnmp_request_get_list_data(requests, 00549 INSTANCE_HANDLER_NAME)); 00550 break; 00551 00552 case MODE_SET_COMMIT: 00553 case MODE_SET_FREE: 00554 /* 00555 * nothing to do 00556 */ 00557 break; 00558 } 00559 00560 if (handler->next && handler->next->access_method) 00561 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 00562 requests); 00563 00564 return SNMP_ERR_NOERROR; 00565 } 00566 00570 int 00571 netsnmp_instance_counter32_handler(netsnmp_mib_handler *handler, 00572 netsnmp_handler_registration *reginfo, 00573 netsnmp_agent_request_info *reqinfo, 00574 netsnmp_request_info *requests) 00575 { 00576 00577 u_long *it = (u_long *) handler->myvoid; 00578 00579 DEBUGMSGTL(("netsnmp_instance_counter32_handler", 00580 "Got request: %d\n", reqinfo->mode)); 00581 00582 switch (reqinfo->mode) { 00583 /* 00584 * data requests 00585 */ 00586 case MODE_GET: 00587 snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER, 00588 (u_char *) it, sizeof(*it)); 00589 break; 00590 00591 /* 00592 * SET requests. Should only get here if registered RWRITE 00593 */ 00594 default: 00595 snmp_log(LOG_ERR, 00596 "netsnmp_instance_counter32_handler: illegal mode\n"); 00597 netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR); 00598 return SNMP_ERR_NOERROR; 00599 } 00600 if (handler->next && handler->next->access_method) 00601 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 00602 requests); 00603 return SNMP_ERR_NOERROR; 00604 } 00605 00609 int 00610 netsnmp_instance_long_handler(netsnmp_mib_handler *handler, 00611 netsnmp_handler_registration *reginfo, 00612 netsnmp_agent_request_info *reqinfo, 00613 netsnmp_request_info *requests) 00614 { 00615 00616 long *it = (long *) handler->myvoid; 00617 long *it_save; 00618 00619 DEBUGMSGTL(("netsnmp_instance_long_handler", "Got request: %d\n", 00620 reqinfo->mode)); 00621 00622 switch (reqinfo->mode) { 00623 /* 00624 * data requests 00625 */ 00626 case MODE_GET: 00627 snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, 00628 (u_char *) it, sizeof(*it)); 00629 break; 00630 00631 /* 00632 * SET requests. Should only get here if registered RWRITE 00633 */ 00634 case MODE_SET_RESERVE1: 00635 if (requests->requestvb->type != ASN_INTEGER) 00636 netsnmp_set_request_error(reqinfo, requests, 00637 SNMP_ERR_WRONGTYPE); 00638 break; 00639 00640 case MODE_SET_RESERVE2: 00641 /* 00642 * store old info for undo later 00643 */ 00644 memdup((u_char **) & it_save, (u_char *) it, sizeof(long)); 00645 if (it_save == NULL) { 00646 netsnmp_set_request_error(reqinfo, requests, 00647 SNMP_ERR_RESOURCEUNAVAILABLE); 00648 return SNMP_ERR_NOERROR; 00649 } 00650 netsnmp_request_add_list_data(requests, 00651 netsnmp_create_data_list 00652 (INSTANCE_HANDLER_NAME, it_save, 00653 free)); 00654 break; 00655 00656 case MODE_SET_ACTION: 00657 /* 00658 * update current 00659 */ 00660 DEBUGMSGTL(("testhandler", "updated u_long %lu -> %lu\n", *it, 00661 *(requests->requestvb->val.integer))); 00662 *it = *(requests->requestvb->val.integer); 00663 break; 00664 00665 case MODE_SET_UNDO: 00666 *it = 00667 *((u_long *) netsnmp_request_get_list_data(requests, 00668 INSTANCE_HANDLER_NAME)); 00669 break; 00670 00671 case MODE_SET_COMMIT: 00672 case MODE_SET_FREE: 00673 /* 00674 * nothing to do 00675 */ 00676 break; 00677 } 00678 if (handler->next && handler->next->access_method) 00679 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 00680 requests); 00681 return SNMP_ERR_NOERROR; 00682 } 00683 00687 int 00688 netsnmp_instance_int_handler(netsnmp_mib_handler *handler, 00689 netsnmp_handler_registration *reginfo, 00690 netsnmp_agent_request_info *reqinfo, 00691 netsnmp_request_info *requests) 00692 { 00693 00694 int *it = (int *) handler->myvoid; 00695 int *it_save; 00696 long tmp_it; 00697 00698 DEBUGMSGTL(("netsnmp_instance_int_handler", "Got request: %d\n", 00699 reqinfo->mode)); 00700 00701 switch (reqinfo->mode) { 00702 /* 00703 * data requests 00704 */ 00705 case MODE_GET: 00706 /* 00707 * Use a long here, otherwise on 64 bit use of an int would fail 00708 */ 00709 tmp_it = *it; 00710 snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, 00711 (u_char *) &tmp_it, sizeof(tmp_it)); 00712 break; 00713 00714 /* 00715 * SET requests. Should only get here if registered RWRITE 00716 */ 00717 case MODE_SET_RESERVE1: 00718 if (requests->requestvb->type != ASN_INTEGER) 00719 netsnmp_set_request_error(reqinfo, requests, 00720 SNMP_ERR_WRONGTYPE); 00721 break; 00722 00723 case MODE_SET_RESERVE2: 00724 /* 00725 * store old info for undo later 00726 */ 00727 memdup((u_char **) & it_save, (u_char *) it, sizeof(int)); 00728 if (it_save == NULL) { 00729 netsnmp_set_request_error(reqinfo, requests, 00730 SNMP_ERR_RESOURCEUNAVAILABLE); 00731 return SNMP_ERR_NOERROR; 00732 } 00733 netsnmp_request_add_list_data(requests, 00734 netsnmp_create_data_list 00735 (INSTANCE_HANDLER_NAME, it_save, 00736 free)); 00737 break; 00738 00739 case MODE_SET_ACTION: 00740 /* 00741 * update current 00742 */ 00743 DEBUGMSGTL(("testhandler", "updated int %d -> %ld\n", *it, 00744 *(requests->requestvb->val.integer))); 00745 *it = (int) *(requests->requestvb->val.integer); 00746 break; 00747 00748 case MODE_SET_UNDO: 00749 *it = 00750 *((u_int *) netsnmp_request_get_list_data(requests, 00751 INSTANCE_HANDLER_NAME)); 00752 break; 00753 00754 case MODE_SET_COMMIT: 00755 case MODE_SET_FREE: 00756 /* 00757 * nothing to do 00758 */ 00759 break; 00760 } 00761 if (handler->next && handler->next->access_method) 00762 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 00763 requests); 00764 return SNMP_ERR_NOERROR; 00765 } 00766 00767 #endif /* NETSNMP_NO_DEPRECATED_FUNCTIONS */ 00768 00769 int 00770 netsnmp_instance_num_file_handler(netsnmp_mib_handler *handler, 00771 netsnmp_handler_registration *reginfo, 00772 netsnmp_agent_request_info *reqinfo, 00773 netsnmp_request_info *requests) 00774 { 00775 netsnmp_num_file_instance *nfi; 00776 u_long it, *it_save; 00777 int rc; 00778 00779 netsnmp_assert(NULL != handler); 00780 nfi = (netsnmp_num_file_instance *)handler->myvoid; 00781 netsnmp_assert(NULL != nfi); 00782 netsnmp_assert(NULL != nfi->file_name); 00783 00784 DEBUGMSGTL(("netsnmp_instance_int_handler", "Got request: %d\n", 00785 reqinfo->mode)); 00786 00787 switch (reqinfo->mode) { 00788 /* 00789 * data requests 00790 */ 00791 case MODE_GET: 00792 /* 00793 * Use a long here, otherwise on 64 bit use of an int would fail 00794 */ 00795 netsnmp_assert(NULL == nfi->filep); 00796 nfi->filep = fopen(nfi->file_name, "r"); 00797 if (NULL == nfi->filep) { 00798 netsnmp_set_request_error(reqinfo, requests, 00799 SNMP_NOSUCHINSTANCE); 00800 return SNMP_ERR_NOERROR; 00801 } 00802 rc = fscanf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu", 00803 &it); 00804 fclose(nfi->filep); 00805 nfi->filep = NULL; 00806 if (rc != 1) { 00807 netsnmp_set_request_error(reqinfo, requests, 00808 SNMP_NOSUCHINSTANCE); 00809 return SNMP_ERR_NOERROR; 00810 } 00811 snmp_set_var_typed_value(requests->requestvb, nfi->type, 00812 (u_char *) &it, sizeof(it)); 00813 break; 00814 00815 /* 00816 * SET requests. Should only get here if registered RWRITE 00817 */ 00818 case MODE_SET_RESERVE1: 00819 netsnmp_assert(NULL == nfi->filep); 00820 if (requests->requestvb->type != nfi->type) 00821 netsnmp_set_request_error(reqinfo, requests, 00822 SNMP_ERR_WRONGTYPE); 00823 break; 00824 00825 case MODE_SET_RESERVE2: 00826 netsnmp_assert(NULL == nfi->filep); 00827 nfi->filep = fopen(nfi->file_name, "w+"); 00828 if (NULL == nfi->filep) { 00829 netsnmp_set_request_error(reqinfo, requests, 00830 SNMP_ERR_NOTWRITABLE); 00831 return SNMP_ERR_NOERROR; 00832 } 00833 /* 00834 * store old info for undo later 00835 */ 00836 if (fscanf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu", 00837 &it) != 1) { 00838 netsnmp_set_request_error(reqinfo, requests, 00839 SNMP_ERR_RESOURCEUNAVAILABLE); 00840 return SNMP_ERR_NOERROR; 00841 } 00842 00843 memdup((u_char **) & it_save, (u_char *)&it, sizeof(u_long)); 00844 if (it_save == NULL) { 00845 netsnmp_set_request_error(reqinfo, requests, 00846 SNMP_ERR_RESOURCEUNAVAILABLE); 00847 return SNMP_ERR_NOERROR; 00848 } 00849 netsnmp_request_add_list_data(requests, 00850 netsnmp_create_data_list 00851 (INSTANCE_HANDLER_NAME, it_save, 00852 free)); 00853 break; 00854 00855 case MODE_SET_ACTION: 00856 /* 00857 * update current 00858 */ 00859 DEBUGMSGTL(("helper:instance", "updated %s -> %ld\n", nfi->file_name, 00860 *(requests->requestvb->val.integer))); 00861 it = *(requests->requestvb->val.integer); 00862 rewind(nfi->filep); /* rewind to make sure we are at the beginning */ 00863 rc = fprintf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu", 00864 it); 00865 if (rc < 0) { 00866 netsnmp_set_request_error(reqinfo, requests, 00867 SNMP_ERR_GENERR); 00868 return SNMP_ERR_NOERROR; 00869 } 00870 break; 00871 00872 case MODE_SET_UNDO: 00873 it = 00874 *((u_int *) netsnmp_request_get_list_data(requests, 00875 INSTANCE_HANDLER_NAME)); 00876 rc = fprintf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu", 00877 it); 00878 if (rc < 0) 00879 netsnmp_set_request_error(reqinfo, requests, 00880 SNMP_ERR_UNDOFAILED); 00883 case MODE_SET_COMMIT: 00884 case MODE_SET_FREE: 00885 if (NULL != nfi->filep) { 00886 fclose(nfi->filep); 00887 nfi->filep = NULL; 00888 } 00889 break; 00890 } 00891 00892 if (handler->next && handler->next->access_method) 00893 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 00894 requests); 00895 return SNMP_ERR_NOERROR; 00896 } 00897 00898 #ifndef NETSNMP_NO_DEPRECATED_FUNCTIONS 00899 00903 int 00904 netsnmp_instance_uint_handler(netsnmp_mib_handler *handler, 00905 netsnmp_handler_registration *reginfo, 00906 netsnmp_agent_request_info *reqinfo, 00907 netsnmp_request_info *requests) 00908 { 00909 00910 unsigned int *it = (unsigned int *) handler->myvoid; 00911 unsigned int *it_save; 00912 unsigned long tmp_it; 00913 00914 DEBUGMSGTL(("netsnmp_instance_uint_handler", "Got request: %d\n", 00915 reqinfo->mode)); 00916 00917 switch (reqinfo->mode) { 00918 /* 00919 * data requests 00920 */ 00921 case MODE_GET: 00922 /* 00923 * Use a long here, otherwise on 64 bit use of an int would fail 00924 */ 00925 tmp_it = *it; 00926 snmp_set_var_typed_value(requests->requestvb, ASN_UNSIGNED, 00927 (u_char *) &tmp_it, sizeof(unsigned long)); 00928 break; 00929 00930 /* 00931 * SET requests. Should only get here if registered RWRITE 00932 */ 00933 case MODE_SET_RESERVE1: 00934 if (requests->requestvb->type != ASN_UNSIGNED) 00935 netsnmp_set_request_error(reqinfo, requests, 00936 SNMP_ERR_WRONGTYPE); 00937 break; 00938 00939 case MODE_SET_RESERVE2: 00940 /* 00941 * store old info for undo later 00942 */ 00943 memdup((u_char **) & it_save, (u_char *) it, sizeof(u_int)); 00944 if (it_save == NULL) { 00945 netsnmp_set_request_error(reqinfo, requests, 00946 SNMP_ERR_RESOURCEUNAVAILABLE); 00947 return SNMP_ERR_NOERROR; 00948 } 00949 netsnmp_request_add_list_data(requests, 00950 netsnmp_create_data_list 00951 (INSTANCE_HANDLER_NAME, it_save, 00952 free)); 00953 break; 00954 00955 case MODE_SET_ACTION: 00956 /* 00957 * update current 00958 */ 00959 DEBUGMSGTL(("testhandler", "updated uint %d -> %ld\n", *it, 00960 *(requests->requestvb->val.integer))); 00961 *it = (unsigned int) *(requests->requestvb->val.integer); 00962 break; 00963 00964 case MODE_SET_UNDO: 00965 *it = 00966 *((u_int *) netsnmp_request_get_list_data(requests, 00967 INSTANCE_HANDLER_NAME)); 00968 break; 00969 00970 case MODE_SET_COMMIT: 00971 case MODE_SET_FREE: 00972 /* 00973 * nothing to do 00974 */ 00975 break; 00976 } 00977 if (handler->next && handler->next->access_method) 00978 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 00979 requests); 00980 return SNMP_ERR_NOERROR; 00981 } 00982 00983 #endif /* NETSNMP_NO_DEPRECATED_FUNCTIONS */ 00984 00985 int 00986 netsnmp_instance_helper_handler(netsnmp_mib_handler *handler, 00987 netsnmp_handler_registration *reginfo, 00988 netsnmp_agent_request_info *reqinfo, 00989 netsnmp_request_info *requests) 00990 { 00991 00992 netsnmp_variable_list *var = requests->requestvb; 00993 00994 int ret, cmp; 00995 00996 DEBUGMSGTL(("helper:instance", "Got request:\n")); 00997 cmp = snmp_oid_compare(requests->requestvb->name, 00998 requests->requestvb->name_length, 00999 reginfo->rootoid, reginfo->rootoid_len); 01000 01001 DEBUGMSGTL(("helper:instance", " oid:")); 01002 DEBUGMSGOID(("helper:instance", var->name, var->name_length)); 01003 DEBUGMSG(("helper:instance", "\n")); 01004 01005 switch (reqinfo->mode) { 01006 case MODE_GET: 01007 if (cmp != 0) { 01008 netsnmp_set_request_error(reqinfo, requests, 01009 SNMP_NOSUCHINSTANCE); 01010 return SNMP_ERR_NOERROR; 01011 } else { 01012 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 01013 requests); 01014 } 01015 break; 01016 01017 case MODE_SET_RESERVE1: 01018 case MODE_SET_RESERVE2: 01019 case MODE_SET_ACTION: 01020 case MODE_SET_COMMIT: 01021 case MODE_SET_UNDO: 01022 case MODE_SET_FREE: 01023 if (cmp != 0) { 01024 netsnmp_set_request_error(reqinfo, requests, 01025 SNMP_ERR_NOCREATION); 01026 return SNMP_ERR_NOERROR; 01027 } else { 01028 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 01029 requests); 01030 } 01031 break; 01032 01033 case MODE_GETNEXT: 01034 if (cmp < 0 || (cmp == 0 && requests->inclusive)) { 01035 reqinfo->mode = MODE_GET; 01036 snmp_set_var_objid(requests->requestvb, reginfo->rootoid, 01037 reginfo->rootoid_len); 01038 ret = 01039 netsnmp_call_next_handler(handler, reginfo, reqinfo, 01040 requests); 01041 reqinfo->mode = MODE_GETNEXT; 01042 /* 01043 * if the instance doesn't have data, set type to ASN_NULL 01044 * to move to the next sub-tree. Ignore delegated requests; they 01045 * might have data later on. 01046 */ 01047 if (!requests->delegated && 01048 (requests->requestvb->type == SNMP_NOSUCHINSTANCE || 01049 requests->requestvb->type == SNMP_NOSUCHOBJECT)) { 01050 requests->requestvb->type = ASN_NULL; 01051 } 01052 return ret; 01053 } else { 01054 return SNMP_ERR_NOERROR; 01055 } 01056 break; 01057 } 01058 /* 01059 * got here only if illegal mode found 01060 */ 01061 return SNMP_ERR_GENERR; 01062 } 01063
Last modified: Wednesday, 01-Aug-2018 04:41:28 UTC
For questions regarding web content and site functionality, please write to the net-snmp-users mail list.