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 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_inject_handler(reginfo, netsnmp_get_instance_handler()); 00077 return netsnmp_register_serialize(reginfo); 00078 } 00079 00098 int 00099 netsnmp_register_read_only_instance(netsnmp_handler_registration *reginfo) 00100 { 00101 netsnmp_inject_handler(reginfo, netsnmp_get_instance_handler()); 00102 netsnmp_inject_handler(reginfo, netsnmp_get_read_only_handler()); 00103 return netsnmp_register_serialize(reginfo); 00104 } 00105 00106 static 00107 netsnmp_handler_registration * 00108 get_reg(const char *name, 00109 const char *ourname, 00110 oid * reg_oid, size_t reg_oid_len, 00111 void *it, 00112 int modes, 00113 Netsnmp_Node_Handler * scalarh, Netsnmp_Node_Handler * subhandler, 00114 const char *contextName) 00115 { 00116 netsnmp_handler_registration *myreg; 00117 netsnmp_mib_handler *myhandler; 00118 00119 if (subhandler) { 00120 myreg = 00121 netsnmp_create_handler_registration(name, 00122 subhandler, 00123 reg_oid, reg_oid_len, 00124 modes); 00125 myhandler = netsnmp_create_handler(ourname, scalarh); 00126 myhandler->myvoid = (void *) it; 00127 netsnmp_inject_handler(myreg, myhandler); 00128 } else { 00129 myreg = 00130 netsnmp_create_handler_registration(name, 00131 scalarh, 00132 reg_oid, reg_oid_len, 00133 modes); 00134 myreg->handler->myvoid = (void *) it; 00135 } 00136 if (contextName) 00137 myreg->contextName = strdup(contextName); 00138 return myreg; 00139 } 00140 00141 int 00142 netsnmp_register_read_only_ulong_instance(const char *name, 00143 oid * reg_oid, 00144 size_t reg_oid_len, u_long * it, 00145 Netsnmp_Node_Handler * 00146 subhandler) 00147 { 00148 netsnmp_handler_registration *myreg; 00149 00150 myreg = get_reg(name, "ulong_handler", reg_oid, reg_oid_len, it, 00151 HANDLER_CAN_RONLY, netsnmp_instance_ulong_handler, 00152 subhandler, NULL); 00153 return netsnmp_register_read_only_instance(myreg); 00154 } 00155 00156 int 00157 netsnmp_register_ulong_instance(const char *name, 00158 oid * reg_oid, size_t reg_oid_len, 00159 u_long * it, 00160 Netsnmp_Node_Handler * subhandler) 00161 { 00162 netsnmp_handler_registration *myreg; 00163 00164 myreg = get_reg(name, "ulong_handler", reg_oid, reg_oid_len, it, 00165 HANDLER_CAN_RWRITE, netsnmp_instance_ulong_handler, 00166 subhandler, NULL); 00167 return netsnmp_register_instance(myreg); 00168 } 00169 00170 int 00171 netsnmp_register_read_only_counter32_instance(const char *name, 00172 oid * reg_oid, 00173 size_t reg_oid_len, 00174 u_long * it, 00175 Netsnmp_Node_Handler * 00176 subhandler) 00177 { 00178 netsnmp_handler_registration *myreg; 00179 00180 myreg = get_reg(name, "counter32_handler", reg_oid, reg_oid_len, it, 00181 HANDLER_CAN_RONLY, netsnmp_instance_counter32_handler, 00182 subhandler, NULL); 00183 return netsnmp_register_read_only_instance(myreg); 00184 } 00185 00186 int 00187 netsnmp_register_read_only_long_instance(const char *name, 00188 oid * reg_oid, size_t reg_oid_len, 00189 long *it, 00190 Netsnmp_Node_Handler * subhandler) 00191 { 00192 netsnmp_handler_registration *myreg; 00193 00194 myreg = get_reg(name, "long_handler", reg_oid, reg_oid_len, it, 00195 HANDLER_CAN_RONLY, netsnmp_instance_long_handler, 00196 subhandler, NULL); 00197 return netsnmp_register_read_only_instance(myreg); 00198 } 00199 00200 int 00201 netsnmp_register_long_instance(const char *name, 00202 oid * reg_oid, size_t reg_oid_len, 00203 long *it, Netsnmp_Node_Handler * subhandler) 00204 { 00205 netsnmp_handler_registration *myreg; 00206 00207 myreg = get_reg(name, "long_handler", reg_oid, reg_oid_len, it, 00208 HANDLER_CAN_RWRITE, netsnmp_instance_long_handler, 00209 subhandler, NULL); 00210 return netsnmp_register_instance(myreg); 00211 } 00212 00213 int 00214 netsnmp_register_read_only_int_instance(const char *name, 00215 oid * reg_oid, size_t reg_oid_len, 00216 int *it, Netsnmp_Node_Handler * subhandler) 00217 { 00218 netsnmp_handler_registration *myreg; 00219 00220 myreg = get_reg(name, "int_handler", reg_oid, reg_oid_len, it, 00221 HANDLER_CAN_RONLY, netsnmp_instance_int_handler, 00222 subhandler, NULL); 00223 return netsnmp_register_read_only_instance(myreg); 00224 } 00225 00226 /* 00227 * Compatibility with earlier (inconsistently named) routine 00228 */ 00229 int 00230 register_read_only_int_instance(const char *name, 00231 oid * reg_oid, size_t reg_oid_len, 00232 int *it, Netsnmp_Node_Handler * subhandler) 00233 { 00234 return netsnmp_register_read_only_int_instance(name, 00235 reg_oid, reg_oid_len, 00236 it, subhandler); 00237 } 00238 00239 /* 00240 * Context registrations 00241 */ 00242 00243 int 00244 netsnmp_register_read_only_ulong_instance_context(const char *name, 00245 oid * reg_oid, 00246 size_t reg_oid_len, 00247 u_long * it, 00248 Netsnmp_Node_Handler * 00249 subhandler, 00250 const char *contextName) 00251 { 00252 netsnmp_handler_registration *myreg; 00253 00254 myreg = get_reg(name, "ulong_handler", reg_oid, reg_oid_len, it, 00255 HANDLER_CAN_RONLY, netsnmp_instance_ulong_handler, 00256 subhandler, contextName); 00257 return netsnmp_register_read_only_instance(myreg); 00258 } 00259 00260 int 00261 netsnmp_register_ulong_instance_context(const char *name, 00262 oid * reg_oid, size_t reg_oid_len, 00263 u_long * it, 00264 Netsnmp_Node_Handler * subhandler, 00265 const char *contextName) 00266 { 00267 netsnmp_handler_registration *myreg; 00268 00269 myreg = get_reg(name, "ulong_handler", reg_oid, reg_oid_len, it, 00270 HANDLER_CAN_RWRITE, netsnmp_instance_ulong_handler, 00271 subhandler, contextName); 00272 return netsnmp_register_instance(myreg); 00273 } 00274 00275 int 00276 netsnmp_register_read_only_counter32_instance_context(const char *name, 00277 oid * reg_oid, 00278 size_t reg_oid_len, 00279 u_long * it, 00280 Netsnmp_Node_Handler * 00281 subhandler, 00282 const char *contextName) 00283 { 00284 netsnmp_handler_registration *myreg; 00285 00286 myreg = get_reg(name, "counter32_handler", reg_oid, reg_oid_len, it, 00287 HANDLER_CAN_RONLY, netsnmp_instance_counter32_handler, 00288 subhandler, contextName); 00289 return netsnmp_register_read_only_instance(myreg); 00290 } 00291 00292 int 00293 netsnmp_register_read_only_long_instance_context(const char *name, 00294 oid * reg_oid, 00295 size_t reg_oid_len, 00296 long *it, 00297 Netsnmp_Node_Handler 00298 *subhandler, 00299 const char *contextName) 00300 { 00301 netsnmp_handler_registration *myreg; 00302 00303 myreg = get_reg(name, "long_handler", reg_oid, reg_oid_len, it, 00304 HANDLER_CAN_RONLY, netsnmp_instance_long_handler, 00305 subhandler, contextName); 00306 return netsnmp_register_read_only_instance(myreg); 00307 } 00308 00309 int 00310 netsnmp_register_long_instance_context(const char *name, 00311 oid * reg_oid, size_t reg_oid_len, 00312 long *it, 00313 Netsnmp_Node_Handler * subhandler, 00314 const char *contextName) 00315 { 00316 netsnmp_handler_registration *myreg; 00317 00318 myreg = get_reg(name, "long_handler", reg_oid, reg_oid_len, it, 00319 HANDLER_CAN_RWRITE, netsnmp_instance_long_handler, 00320 subhandler, contextName); 00321 return netsnmp_register_instance(myreg); 00322 } 00323 00324 int 00325 netsnmp_register_int_instance_context(const char *name, 00326 oid * reg_oid, 00327 size_t reg_oid_len, 00328 int *it, 00329 Netsnmp_Node_Handler * subhandler, 00330 const char *contextName) 00331 { 00332 netsnmp_handler_registration *myreg; 00333 00334 myreg = get_reg(name, "int_handler", reg_oid, reg_oid_len, it, 00335 HANDLER_CAN_RWRITE, netsnmp_instance_int_handler, 00336 subhandler, contextName); 00337 return netsnmp_register_read_only_instance(myreg); 00338 } 00339 00340 int 00341 netsnmp_register_read_only_int_instance_context(const char *name, 00342 oid * reg_oid, 00343 size_t reg_oid_len, 00344 int *it, 00345 Netsnmp_Node_Handler * subhandler, 00346 const char *contextName) 00347 { 00348 netsnmp_handler_registration *myreg; 00349 00350 myreg = get_reg(name, "int_handler", reg_oid, reg_oid_len, it, 00351 HANDLER_CAN_RONLY, netsnmp_instance_int_handler, 00352 subhandler, contextName); 00353 return netsnmp_register_read_only_instance(myreg); 00354 } 00355 00356 /* 00357 * Compatibility with earlier (inconsistently named) routine 00358 */ 00359 int 00360 register_read_only_int_instance_context(const char *name, 00361 oid * reg_oid, size_t reg_oid_len, 00362 int *it, 00363 Netsnmp_Node_Handler * subhandler, 00364 const char *contextName) 00365 { 00366 return netsnmp_register_read_only_int_instance_context(name, 00367 reg_oid, reg_oid_len, 00368 it, subhandler, 00369 contextName); 00370 } 00371 00372 int 00373 netsnmp_register_num_file_instance(const char *name, 00374 oid * reg_oid, size_t reg_oid_len, 00375 char *file_name, int asn_type, int mode, 00376 Netsnmp_Node_Handler * subhandler, 00377 const char *contextName) 00378 { 00379 netsnmp_handler_registration *myreg; 00380 netsnmp_num_file_instance *nfi; 00381 00382 if ((NULL == name) || (NULL == reg_oid) || (NULL == file_name)) { 00383 snmp_log(LOG_ERR, "bad parameter to netsnmp_register_num_file_instance\n"); 00384 return MIB_REGISTRATION_FAILED; 00385 } 00386 00387 nfi = SNMP_MALLOC_TYPEDEF(netsnmp_num_file_instance); 00388 if ((NULL == nfi) || 00389 (NULL == (nfi->file_name = strdup(file_name)))) { 00390 snmp_log(LOG_ERR, "could not not allocate memory\n"); 00391 return MIB_REGISTRATION_FAILED; 00392 } 00393 00394 myreg = get_reg(name, "file_num_handler", reg_oid, reg_oid_len, nfi, 00395 mode, netsnmp_instance_num_file_handler, 00396 subhandler, contextName); 00397 if (NULL == myreg) 00398 return MIB_REGISTRATION_FAILED; 00399 00400 nfi->type = asn_type; 00401 00402 if (HANDLER_CAN_RONLY == mode) 00403 return netsnmp_register_read_only_instance(myreg); 00404 00405 return netsnmp_register_instance(myreg); 00406 } 00407 00426 int 00427 netsnmp_register_int_instance(const char *name, 00428 oid * reg_oid, size_t reg_oid_len, 00429 int *it, Netsnmp_Node_Handler * subhandler) 00430 { 00431 netsnmp_handler_registration *myreg; 00432 00433 myreg = get_reg(name, "int_handler", reg_oid, reg_oid_len, it, 00434 HANDLER_CAN_RWRITE, netsnmp_instance_int_handler, 00435 subhandler, NULL); 00436 return netsnmp_register_instance(myreg); 00437 } 00438 00439 int 00440 netsnmp_instance_ulong_handler(netsnmp_mib_handler *handler, 00441 netsnmp_handler_registration *reginfo, 00442 netsnmp_agent_request_info *reqinfo, 00443 netsnmp_request_info *requests) 00444 { 00445 00446 u_long *it = (u_long *) handler->myvoid; 00447 u_long *it_save; 00448 00449 DEBUGMSGTL(("netsnmp_instance_ulong_handler", "Got request: %d\n", 00450 reqinfo->mode)); 00451 00452 switch (reqinfo->mode) { 00453 /* 00454 * data requests 00455 */ 00456 case MODE_GET: 00457 snmp_set_var_typed_value(requests->requestvb, ASN_UNSIGNED, 00458 (u_char *) it, sizeof(*it)); 00459 break; 00460 00461 /* 00462 * SET requests. Should only get here if registered RWRITE 00463 */ 00464 case MODE_SET_RESERVE1: 00465 if (requests->requestvb->type != ASN_UNSIGNED) 00466 netsnmp_set_request_error(reqinfo, requests, 00467 SNMP_ERR_WRONGTYPE); 00468 break; 00469 00470 case MODE_SET_RESERVE2: 00471 /* 00472 * store old info for undo later 00473 */ 00474 memdup((u_char **) & it_save, (u_char *) it, sizeof(u_long)); 00475 if (it_save == NULL) { 00476 netsnmp_set_request_error(reqinfo, requests, 00477 SNMP_ERR_RESOURCEUNAVAILABLE); 00478 return SNMP_ERR_NOERROR; 00479 } 00480 netsnmp_request_add_list_data(requests, 00481 netsnmp_create_data_list 00482 (INSTANCE_HANDLER_NAME, it_save, 00483 free)); 00484 break; 00485 00486 case MODE_SET_ACTION: 00487 /* 00488 * update current 00489 */ 00490 DEBUGMSGTL(("testhandler", "updated u_long %ul -> %ul\n", *it, 00491 *(requests->requestvb->val.integer))); 00492 *it = *(requests->requestvb->val.integer); 00493 break; 00494 00495 case MODE_SET_UNDO: 00496 *it = 00497 *((u_long *) netsnmp_request_get_list_data(requests, 00498 INSTANCE_HANDLER_NAME)); 00499 break; 00500 00501 case MODE_SET_COMMIT: 00502 case MODE_SET_FREE: 00503 /* 00504 * nothing to do 00505 */ 00506 break; 00507 } 00508 00509 if (handler->next && handler->next->access_method) 00510 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 00511 requests); 00512 00513 return SNMP_ERR_NOERROR; 00514 } 00515 00516 int 00517 netsnmp_instance_counter32_handler(netsnmp_mib_handler *handler, 00518 netsnmp_handler_registration *reginfo, 00519 netsnmp_agent_request_info *reqinfo, 00520 netsnmp_request_info *requests) 00521 { 00522 00523 u_long *it = (u_long *) handler->myvoid; 00524 00525 DEBUGMSGTL(("netsnmp_instance_counter32_handler", 00526 "Got request: %d\n", reqinfo->mode)); 00527 00528 switch (reqinfo->mode) { 00529 /* 00530 * data requests 00531 */ 00532 case MODE_GET: 00533 snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER, 00534 (u_char *) it, sizeof(*it)); 00535 break; 00536 00537 /* 00538 * SET requests. Should only get here if registered RWRITE 00539 */ 00540 default: 00541 snmp_log(LOG_ERR, 00542 "netsnmp_instance_counter32_handler: illegal mode\n"); 00543 netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR); 00544 return SNMP_ERR_NOERROR; 00545 } 00546 if (handler->next && handler->next->access_method) 00547 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 00548 requests); 00549 return SNMP_ERR_NOERROR; 00550 } 00551 00552 int 00553 netsnmp_instance_long_handler(netsnmp_mib_handler *handler, 00554 netsnmp_handler_registration *reginfo, 00555 netsnmp_agent_request_info *reqinfo, 00556 netsnmp_request_info *requests) 00557 { 00558 00559 long *it = (u_long *) handler->myvoid; 00560 long *it_save; 00561 00562 DEBUGMSGTL(("netsnmp_instance_long_handler", "Got request: %d\n", 00563 reqinfo->mode)); 00564 00565 switch (reqinfo->mode) { 00566 /* 00567 * data requests 00568 */ 00569 case MODE_GET: 00570 snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, 00571 (u_char *) it, sizeof(*it)); 00572 break; 00573 00574 /* 00575 * SET requests. Should only get here if registered RWRITE 00576 */ 00577 case MODE_SET_RESERVE1: 00578 if (requests->requestvb->type != ASN_INTEGER) 00579 netsnmp_set_request_error(reqinfo, requests, 00580 SNMP_ERR_WRONGTYPE); 00581 break; 00582 00583 case MODE_SET_RESERVE2: 00584 /* 00585 * store old info for undo later 00586 */ 00587 memdup((u_char **) & it_save, (u_char *) it, sizeof(u_long)); 00588 if (it_save == NULL) { 00589 netsnmp_set_request_error(reqinfo, requests, 00590 SNMP_ERR_RESOURCEUNAVAILABLE); 00591 return SNMP_ERR_NOERROR; 00592 } 00593 netsnmp_request_add_list_data(requests, 00594 netsnmp_create_data_list 00595 (INSTANCE_HANDLER_NAME, it_save, 00596 free)); 00597 break; 00598 00599 case MODE_SET_ACTION: 00600 /* 00601 * update current 00602 */ 00603 DEBUGMSGTL(("testhandler", "updated u_long %ul -> %ul\n", *it, 00604 *(requests->requestvb->val.integer))); 00605 *it = *(requests->requestvb->val.integer); 00606 break; 00607 00608 case MODE_SET_UNDO: 00609 *it = 00610 *((u_long *) netsnmp_request_get_list_data(requests, 00611 INSTANCE_HANDLER_NAME)); 00612 break; 00613 00614 case MODE_SET_COMMIT: 00615 case MODE_SET_FREE: 00616 /* 00617 * nothing to do 00618 */ 00619 break; 00620 } 00621 if (handler->next && handler->next->access_method) 00622 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 00623 requests); 00624 return SNMP_ERR_NOERROR; 00625 } 00626 00627 int 00628 netsnmp_instance_int_handler(netsnmp_mib_handler *handler, 00629 netsnmp_handler_registration *reginfo, 00630 netsnmp_agent_request_info *reqinfo, 00631 netsnmp_request_info *requests) 00632 { 00633 00634 int *it = (int *) handler->myvoid; 00635 int *it_save; 00636 long tmp_it; 00637 00638 DEBUGMSGTL(("netsnmp_instance_int_handler", "Got request: %d\n", 00639 reqinfo->mode)); 00640 00641 switch (reqinfo->mode) { 00642 /* 00643 * data requests 00644 */ 00645 case MODE_GET: 00646 /* 00647 * Use a long here, otherwise on 64 bit use of an int would fail 00648 */ 00649 tmp_it = *it; 00650 snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, 00651 (u_char *) &tmp_it, sizeof(tmp_it)); 00652 break; 00653 00654 /* 00655 * SET requests. Should only get here if registered RWRITE 00656 */ 00657 case MODE_SET_RESERVE1: 00658 if (requests->requestvb->type != ASN_INTEGER) 00659 netsnmp_set_request_error(reqinfo, requests, 00660 SNMP_ERR_WRONGTYPE); 00661 break; 00662 00663 case MODE_SET_RESERVE2: 00664 /* 00665 * store old info for undo later 00666 */ 00667 memdup((u_char **) & it_save, (u_char *) it, sizeof(u_long)); 00668 if (it_save == NULL) { 00669 netsnmp_set_request_error(reqinfo, requests, 00670 SNMP_ERR_RESOURCEUNAVAILABLE); 00671 return SNMP_ERR_NOERROR; 00672 } 00673 netsnmp_request_add_list_data(requests, 00674 netsnmp_create_data_list 00675 (INSTANCE_HANDLER_NAME, it_save, 00676 free)); 00677 break; 00678 00679 case MODE_SET_ACTION: 00680 /* 00681 * update current 00682 */ 00683 DEBUGMSGTL(("testhandler", "updated int %d -> %l\n", *it, 00684 *(requests->requestvb->val.integer))); 00685 *it = (int) *(requests->requestvb->val.integer); 00686 break; 00687 00688 case MODE_SET_UNDO: 00689 *it = 00690 *((u_int *) netsnmp_request_get_list_data(requests, 00691 INSTANCE_HANDLER_NAME)); 00692 break; 00693 00694 case MODE_SET_COMMIT: 00695 case MODE_SET_FREE: 00696 /* 00697 * nothing to do 00698 */ 00699 break; 00700 } 00701 if (handler->next && handler->next->access_method) 00702 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 00703 requests); 00704 return SNMP_ERR_NOERROR; 00705 } 00706 00707 int 00708 netsnmp_instance_num_file_handler(netsnmp_mib_handler *handler, 00709 netsnmp_handler_registration *reginfo, 00710 netsnmp_agent_request_info *reqinfo, 00711 netsnmp_request_info *requests) 00712 { 00713 netsnmp_num_file_instance *nfi; 00714 u_long it, *it_save; 00715 int rc; 00716 00717 netsnmp_assert(NULL != handler); 00718 nfi = (netsnmp_num_file_instance *)handler->myvoid; 00719 netsnmp_assert(NULL != nfi); 00720 netsnmp_assert(NULL != nfi->file_name); 00721 00722 DEBUGMSGTL(("netsnmp_instance_int_handler", "Got request: %d\n", 00723 reqinfo->mode)); 00724 00725 switch (reqinfo->mode) { 00726 /* 00727 * data requests 00728 */ 00729 case MODE_GET: 00730 /* 00731 * Use a long here, otherwise on 64 bit use of an int would fail 00732 */ 00733 netsnmp_assert(NULL == nfi->filep); 00734 nfi->filep = fopen(nfi->file_name, "r"); 00735 if (NULL == nfi->filep) { 00736 netsnmp_set_request_error(reqinfo, requests, 00737 SNMP_NOSUCHINSTANCE); 00738 return SNMP_ERR_NOERROR; 00739 } 00740 rc = fscanf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu", 00741 &it); 00742 fclose(nfi->filep); 00743 nfi->filep = NULL; 00744 if (rc != 1) { 00745 netsnmp_set_request_error(reqinfo, requests, 00746 SNMP_NOSUCHINSTANCE); 00747 return SNMP_ERR_NOERROR; 00748 } 00749 snmp_set_var_typed_value(requests->requestvb, nfi->type, 00750 (u_char *) &it, sizeof(it)); 00751 break; 00752 00753 /* 00754 * SET requests. Should only get here if registered RWRITE 00755 */ 00756 case MODE_SET_RESERVE1: 00757 netsnmp_assert(NULL == nfi->filep); 00758 if (requests->requestvb->type != nfi->type) 00759 netsnmp_set_request_error(reqinfo, requests, 00760 SNMP_ERR_WRONGTYPE); 00761 break; 00762 00763 case MODE_SET_RESERVE2: 00764 netsnmp_assert(NULL == nfi->filep); 00765 nfi->filep = fopen(nfi->file_name, "w+"); 00766 if (NULL == nfi->filep) { 00767 netsnmp_set_request_error(reqinfo, requests, 00768 SNMP_ERR_NOTWRITABLE); 00769 return SNMP_ERR_NOERROR; 00770 } 00771 /* 00772 * store old info for undo later 00773 */ 00774 if (fscanf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu", 00775 &it) != 1) { 00776 netsnmp_set_request_error(reqinfo, requests, 00777 SNMP_ERR_RESOURCEUNAVAILABLE); 00778 return SNMP_ERR_NOERROR; 00779 } 00780 00781 memdup((u_char **) & it_save, (u_char *)&it, sizeof(u_long)); 00782 if (it_save == NULL) { 00783 netsnmp_set_request_error(reqinfo, requests, 00784 SNMP_ERR_RESOURCEUNAVAILABLE); 00785 return SNMP_ERR_NOERROR; 00786 } 00787 netsnmp_request_add_list_data(requests, 00788 netsnmp_create_data_list 00789 (INSTANCE_HANDLER_NAME, it_save, 00790 free)); 00791 break; 00792 00793 case MODE_SET_ACTION: 00794 /* 00795 * update current 00796 */ 00797 DEBUGMSGTL(("helper:instance", "updated %s -> %l\n", nfi->file_name, 00798 *(requests->requestvb->val.integer))); 00799 it = *(requests->requestvb->val.integer); 00800 rewind(nfi->filep); /* rewind to make sure we are at the beginning */ 00801 rc = fprintf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu", 00802 it); 00803 if (rc < 0) { 00804 netsnmp_set_request_error(reqinfo, requests, 00805 SNMP_ERR_GENERR); 00806 return SNMP_ERR_NOERROR; 00807 } 00808 break; 00809 00810 case MODE_SET_UNDO: 00811 it = 00812 *((u_int *) netsnmp_request_get_list_data(requests, 00813 INSTANCE_HANDLER_NAME)); 00814 rc = fprintf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu", 00815 it); 00816 if (rc < 0) 00817 netsnmp_set_request_error(reqinfo, requests, 00818 SNMP_ERR_UNDOFAILED); 00821 case MODE_SET_COMMIT: 00822 case MODE_SET_FREE: 00823 if (NULL != nfi->filep) { 00824 fclose(nfi->filep); 00825 nfi->filep = NULL; 00826 } 00827 break; 00828 } 00829 00830 if (handler->next && handler->next->access_method) 00831 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 00832 requests); 00833 return SNMP_ERR_NOERROR; 00834 } 00835 00836 int 00837 netsnmp_instance_helper_handler(netsnmp_mib_handler *handler, 00838 netsnmp_handler_registration *reginfo, 00839 netsnmp_agent_request_info *reqinfo, 00840 netsnmp_request_info *requests) 00841 { 00842 00843 netsnmp_variable_list *var = requests->requestvb; 00844 00845 int ret, cmp; 00846 00847 DEBUGMSGTL(("helper:instance", "Got request:\n")); 00848 cmp = snmp_oid_compare(requests->requestvb->name, 00849 requests->requestvb->name_length, 00850 reginfo->rootoid, reginfo->rootoid_len); 00851 00852 DEBUGMSGTL(("helper:instance", " oid:", cmp)); 00853 DEBUGMSGOID(("helper:instance", var->name, var->name_length)); 00854 DEBUGMSG(("helper:instance", "\n")); 00855 00856 switch (reqinfo->mode) { 00857 case MODE_GET: 00858 if (cmp != 0) { 00859 netsnmp_set_request_error(reqinfo, requests, 00860 SNMP_NOSUCHINSTANCE); 00861 return SNMP_ERR_NOERROR; 00862 } else { 00863 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 00864 requests); 00865 } 00866 break; 00867 00868 case MODE_SET_RESERVE1: 00869 case MODE_SET_RESERVE2: 00870 case MODE_SET_ACTION: 00871 case MODE_SET_COMMIT: 00872 case MODE_SET_UNDO: 00873 case MODE_SET_FREE: 00874 if (cmp != 0) { 00875 netsnmp_set_request_error(reqinfo, requests, 00876 SNMP_ERR_NOCREATION); 00877 return SNMP_ERR_NOERROR; 00878 } else { 00879 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 00880 requests); 00881 } 00882 break; 00883 00884 case MODE_GETNEXT: 00885 if (cmp < 0 || (cmp == 0 && requests->inclusive)) { 00886 reqinfo->mode = MODE_GET; 00887 snmp_set_var_objid(requests->requestvb, reginfo->rootoid, 00888 reginfo->rootoid_len); 00889 ret = 00890 netsnmp_call_next_handler(handler, reginfo, reqinfo, 00891 requests); 00892 reqinfo->mode = MODE_GETNEXT; 00893 if (!requests->delegated && 00894 (requests->requestvb->type == ASN_NULL || 00895 requests->requestvb->type == SNMP_NOSUCHINSTANCE || 00896 requests->requestvb->type == SNMP_NOSUCHOBJECT)) { 00897 requests->requestvb->type = ASN_PRIV_RETRY; 00898 } 00899 return ret; 00900 } else { 00901 return SNMP_ERR_NOERROR; 00902 } 00903 break; 00904 } 00905 /* 00906 * got here only if illegal mode found 00907 */ 00908 return SNMP_ERR_GENERR; 00909 } 00910 00911 /* 00912 * @} 00913 */
1.3.9.1
Last modified: Thursday, 01-Mar-2007 16:20:14 PST
For questions regarding web content and site functionality, please write to the net-snmp-users mail list.