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