| #include <net-snmp/net-snmp-config.h> |
| |
| #if HAVE_STRING_H |
| #include <string.h> |
| #else |
| #include <strings.h> |
| #endif |
| |
| #include "mibincl.h" |
| #include "tools.h" |
| #include "snmp_agent.h" |
| #include <net-snmp/agent/instance.h> |
| #include <net-snmp/agent/serialize.h> |
| #include <net-snmp/agent/read_only.h> |
| |
| #if HAVE_DMALLOC_H |
| #include <dmalloc.h> |
| #endif |
| |
| /** @defgroup instance instance: process scalars and other instances easily. |
| * @ingroup handler |
| * @{ |
| */ |
| mib_handler * |
| get_instance_handler(void) { |
| return create_handler("instance", instance_helper_handler); |
| } |
| |
| int |
| register_instance(handler_registration *reginfo) { |
| inject_handler(reginfo, get_instance_handler()); |
| return register_serialize(reginfo); |
| } |
| |
| int |
| register_read_only_instance(handler_registration *reginfo) { |
| inject_handler(reginfo, get_instance_handler()); |
| inject_handler(reginfo, get_read_only_handler()); |
| return register_serialize(reginfo); |
| } |
| |
| int |
| register_read_only_ulong_instance(const char *name, |
| oid *reg_oid, size_t reg_oid_len, |
| u_long *it) |
| { |
| handler_registration *myreg = |
| create_handler_registration(name, |
| instance_ulong_handler, |
| reg_oid, reg_oid_len, |
| HANDLER_CAN_RONLY); |
| myreg->handler->myvoid = (void *) it; |
| return register_read_only_instance(myreg); |
| } |
| |
| int |
| register_ulong_instance(const char *name, |
| oid *reg_oid, size_t reg_oid_len, |
| u_long *it) |
| { |
| handler_registration *myreg = |
| create_handler_registration(name, |
| instance_ulong_handler, |
| reg_oid, reg_oid_len, |
| HANDLER_CAN_RWRITE); |
| myreg->handler->myvoid = (void *) it; |
| return register_instance(myreg); |
| } |
| |
| int |
| register_read_only_counter32_instance(const char *name, |
| oid *reg_oid, size_t reg_oid_len, |
| u_long *it) |
| { |
| handler_registration *myreg = |
| create_handler_registration(name, |
| instance_counter32_handler, |
| reg_oid, reg_oid_len, |
| HANDLER_CAN_RONLY); |
| myreg->handler->myvoid = (void *) it; |
| return register_read_only_instance(myreg); |
| } |
| |
| int |
| register_read_only_long_instance(const char *name, |
| oid *reg_oid, size_t reg_oid_len, |
| long *it) |
| { |
| handler_registration *myreg = |
| create_handler_registration(name, |
| instance_long_handler, |
| reg_oid, reg_oid_len, |
| HANDLER_CAN_RONLY); |
| myreg->handler->myvoid = (void *) it; |
| return register_read_only_instance(myreg); |
| } |
| |
| int |
| register_long_instance(const char *name, |
| oid *reg_oid, size_t reg_oid_len, |
| long *it) |
| { |
| handler_registration *myreg = |
| create_handler_registration(name, |
| instance_long_handler, |
| reg_oid, reg_oid_len, |
| HANDLER_CAN_RWRITE); |
| myreg->handler->myvoid = (void *) it; |
| return register_instance(myreg); |
| } |
| |
| int |
| instance_ulong_handler( |
| mib_handler *handler, |
| handler_registration *reginfo, |
| agent_request_info *reqinfo, |
| request_info *requests) { |
| |
| u_long *it = (u_long *) handler->myvoid; |
| u_long *it_save; |
| |
| DEBUGMSGTL(("instance_ulong_handler", "Got request: %d\n", reqinfo->mode)); |
| |
| switch(reqinfo->mode) { |
| /* data requests */ |
| case MODE_GET: |
| snmp_set_var_typed_value(requests->requestvb, ASN_UNSIGNED, |
| (u_char *) it, |
| sizeof(*it)); |
| break; |
| |
| /* SET requests. Should only get here if registered RWRITE */ |
| case MODE_SET_RESERVE1: |
| if (requests->requestvb->type != ASN_UNSIGNED) |
| set_request_error(reqinfo, requests, SNMP_ERR_WRONGTYPE); |
| break; |
| |
| case MODE_SET_RESERVE2: |
| /* store old info for undo later */ |
| memdup((u_char **) &it_save, |
| (u_char *) it, sizeof(u_long)); |
| if (it_save == NULL) { |
| set_request_error(reqinfo, requests, |
| SNMP_ERR_RESOURCEUNAVAILABLE); |
| return SNMP_ERR_NOERROR; |
| } |
| request_add_list_data(requests, |
| create_data_list(INSTANCE_HANDLER_NAME, |
| it_save, free)); |
| break; |
| |
| case MODE_SET_ACTION: |
| /* update current */ |
| DEBUGMSGTL(("testhandler","updated u_long %ul -> %ul\n", *it, |
| *(requests->requestvb->val.integer))); |
| *it = *(requests->requestvb->val.integer); |
| break; |
| |
| case MODE_SET_UNDO: |
| *it = |
| *((u_long *) request_get_list_data(requests, |
| INSTANCE_HANDLER_NAME)); |
| break; |
| |
| case MODE_SET_COMMIT: |
| case MODE_SET_FREE: |
| /* nothing to do */ |
| break; |
| } |
| return SNMP_ERR_NOERROR; |
| } |
| |
| int |
| instance_counter32_handler( |
| mib_handler *handler, |
| handler_registration *reginfo, |
| agent_request_info *reqinfo, |
| request_info *requests) { |
| |
| u_long *it = (u_long *) handler->myvoid; |
| u_long *it_save; |
| |
| DEBUGMSGTL(("instance_ulong_handler", "Got request: %d\n", reqinfo->mode)); |
| |
| switch(reqinfo->mode) { |
| /* data requests */ |
| case MODE_GET: |
| snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER, |
| (u_char *) it, |
| sizeof(*it)); |
| break; |
| |
| /* SET requests. Should only get here if registered RWRITE */ |
| default: |
| snmp_log(LOG_ERR,"instance_counter32_handler: illegal mode\n"); |
| set_request_error(reqinfo, requests, SNMP_ERR_GENERR); |
| return SNMP_ERR_NOERROR; |
| } |
| return SNMP_ERR_NOERROR; |
| } |
| |
| int |
| instance_long_handler( |
| mib_handler *handler, |
| handler_registration *reginfo, |
| agent_request_info *reqinfo, |
| request_info *requests) { |
| |
| long *it = (u_long *) handler->myvoid; |
| long *it_save; |
| |
| DEBUGMSGTL(("instance_ulong_handler", "Got request: %d\n", reqinfo->mode)); |
| |
| switch(reqinfo->mode) { |
| /* data requests */ |
| case MODE_GET: |
| snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, |
| (u_char *) it, |
| sizeof(*it)); |
| break; |
| |
| /* SET requests. Should only get here if registered RWRITE */ |
| case MODE_SET_RESERVE1: |
| if (requests->requestvb->type != ASN_UNSIGNED) |
| set_request_error(reqinfo, requests, SNMP_ERR_WRONGTYPE); |
| break; |
| |
| case MODE_SET_RESERVE2: |
| /* store old info for undo later */ |
| memdup((u_char **) &it_save, |
| (u_char *) it, sizeof(u_long)); |
| if (it_save == NULL) { |
| set_request_error(reqinfo, requests, |
| SNMP_ERR_RESOURCEUNAVAILABLE); |
| return SNMP_ERR_NOERROR; |
| } |
| request_add_list_data(requests, |
| create_data_list(INSTANCE_HANDLER_NAME, |
| it_save, free)); |
| break; |
| |
| case MODE_SET_ACTION: |
| /* update current */ |
| DEBUGMSGTL(("testhandler","updated u_long %ul -> %ul\n", *it, |
| *(requests->requestvb->val.integer))); |
| *it = *(requests->requestvb->val.integer); |
| break; |
| |
| case MODE_SET_UNDO: |
| *it = |
| *((u_long *) request_get_list_data(requests, |
| INSTANCE_HANDLER_NAME)); |
| break; |
| |
| case MODE_SET_COMMIT: |
| case MODE_SET_FREE: |
| /* nothing to do */ |
| break; |
| } |
| return SNMP_ERR_NOERROR; |
| } |
| |
| int |
| instance_helper_handler( |
| mib_handler *handler, |
| handler_registration *reginfo, |
| agent_request_info *reqinfo, |
| request_info *requests) { |
| |
| struct variable_list *var = requests->requestvb; |
| |
| int ret, cmp; |
| |
| DEBUGMSGTL(("helper:instance", "Got request:\n")); |
| cmp = snmp_oid_compare(requests->requestvb->name, |
| requests->requestvb->name_length, |
| reginfo->rootoid, |
| reginfo->rootoid_len); |
| |
| DEBUGMSGTL(("helper:instance", " oid:", cmp)); |
| DEBUGMSGOID(("helper:instance", var->name, var->name_length)); |
| DEBUGMSG(("helper:instance", "\n")); |
| |
| switch(reqinfo->mode) { |
| case MODE_GET: |
| if (cmp != 0) { |
| var->type = SNMP_NOSUCHOBJECT; |
| return SNMP_ERR_NOERROR; |
| } else { |
| return call_next_handler(handler, reginfo, reqinfo, requests); |
| } |
| break; |
| |
| case MODE_SET_RESERVE1: |
| case MODE_SET_RESERVE2: |
| case MODE_SET_ACTION: |
| case MODE_SET_COMMIT: |
| case MODE_SET_UNDO: |
| case MODE_SET_FREE: |
| if (cmp != 0) { |
| set_request_error(reqinfo, requests, SNMP_ERR_NOSUCHNAME); |
| return SNMP_ERR_NOERROR; |
| } else { |
| return call_next_handler(handler, reginfo, reqinfo, requests); |
| } |
| break; |
| |
| case MODE_GETNEXT: |
| if (cmp < 0) { |
| reqinfo->mode = MODE_GET; |
| snmp_set_var_objid(requests->requestvb, reginfo->rootoid, |
| reginfo->rootoid_len); |
| ret = call_next_handler(handler, reginfo, reqinfo, requests); |
| reqinfo->mode = MODE_GETNEXT; |
| return ret; |
| } else { |
| return SNMP_ERR_NOERROR; |
| } |
| break; |
| } |
| /* got here only if illegal mode found */ |
| return SNMP_ERR_GENERR; |
| } |
| |
| /* @} */ |