| #include <net-snmp/net-snmp-config.h> |
| |
| #if HAVE_STRING_H |
| #include <string.h> |
| #else |
| #include <strings.h> |
| #endif |
| |
| #include "mibincl.h" |
| #include "testhandler.h" |
| #include "snmp_agent.h" |
| |
| #include "snmp_api.h" |
| #include "snmp_client.h" |
| #include <net-snmp/agent/table.h> |
| #include <net-snmp/agent/instance.h> |
| #include <net-snmp/agent/table_data.h> |
| #include <net-snmp/agent/table_dataset.h> |
| |
| static oid my_test_oid[4] = {1,2,3,4}; |
| static oid my_table_oid[4] = {1,2,3,5}; |
| static oid my_instance_oid[5] = {1,2,3,6,1}; |
| static oid my_data_table_oid[4] = {1,2,3,7}; |
| static oid my_data_table_set_oid[4] = {1,2,3,8}; |
| static oid my_data_ulong_instance[4] = {1,2,3,9}; |
| |
| u_long my_ulong=0; |
| |
| void |
| init_testhandler(void) { |
| /* we're registering at .1.2.3.4 */ |
| handler_registration *my_test; |
| table_registration_info *table_info; |
| u_long ind1; |
| table_data *table; |
| table_data_set *table_set; |
| table_row *row; |
| |
| DEBUGMSGTL(("testhandler", "initializing\n")); |
| |
| /* |
| * basic handler test |
| */ |
| register_handler(create_handler_registration("myTest", my_test_handler, |
| my_test_oid, 4, |
| HANDLER_CAN_RONLY)); |
| |
| /* |
| * instance handler test |
| */ |
| |
| register_instance(create_handler_registration("myInstance", |
| my_test_instance_handler, |
| my_instance_oid, 5, |
| HANDLER_CAN_RWRITE)); |
| |
| register_ulong_instance("myulong", |
| my_data_ulong_instance, 4, |
| &my_ulong); |
| |
| /* |
| * table helper test |
| */ |
| |
| my_test = create_handler_registration("myTable", |
| my_test_table_handler, |
| my_table_oid, 4, |
| HANDLER_CAN_RONLY); |
| if (!my_test) |
| return; |
| |
| table_info = SNMP_MALLOC_TYPEDEF(table_registration_info); |
| |
| table_helper_add_indexes(table_info, ASN_INTEGER, ASN_INTEGER, 0); |
| table_info->min_column = 3; |
| table_info->max_column = 3; |
| register_table(my_test, table_info); |
| |
| /* |
| * data table helper test |
| */ |
| /* we'll construct a simple table here with two indexes: an |
| integer and a string (why not). It'll contain only one |
| column so the data pointer is merely the data in that |
| column. */ |
| |
| table = create_table_data("data_table_test"); |
| |
| table_data_add_index(table, ASN_INTEGER); |
| table_data_add_index(table, ASN_OCTET_STR); |
| |
| /* 1 partridge in a pear tree */ |
| row = create_table_data_row(); |
| ind1 = 1; |
| table_row_add_index(row, ASN_INTEGER, &ind1, sizeof(ind1)); |
| table_row_add_index(row, ASN_OCTET_STR, "partridge",\ |
| strlen("partridge")); |
| row->data = (void *) "pear tree"; |
| table_data_add_row(table, row); |
| |
| /* 2 turtle doves */ |
| row = create_table_data_row(); |
| ind1 = 2; |
| table_row_add_index(row, ASN_INTEGER, &ind1, sizeof(ind1)); |
| table_row_add_index(row, ASN_OCTET_STR, "turtle",\ |
| strlen("turtle")); |
| row->data = (void *) "doves"; |
| table_data_add_row(table, row); |
| |
| /* we're going to register it as a normal table too, so we get the |
| automatically parsed column and index information */ |
| table_info = SNMP_MALLOC_TYPEDEF(table_registration_info); |
| |
| table_helper_add_indexes(table_info, ASN_INTEGER, ASN_OCTET_STR, 0); |
| table_info->min_column = 3; |
| table_info->max_column = 3; |
| |
| register_read_only_table_data( |
| create_handler_registration("12days", |
| my_data_table_handler, |
| my_data_table_oid, |
| 4, HANDLER_CAN_RONLY), |
| table, |
| table_info); |
| |
| /* |
| * register a full featured, I don't care about the data afterwards table. |
| */ |
| /* It's going to be the "working group chairs" table, since I'm |
| sitting at an IETF convention while I'm writing this. |
| |
| column 1 = index = string = WG name |
| column 2 = string = chair #1 |
| column 3 = string = chair #2 (most WGs have 2 chairs now) |
| */ |
| table_set = create_table_data_set("chairs"); |
| |
| /* set up what a row "should" look like */ |
| table_dataset_add_index(table_set, ASN_OCTET_STR); |
| table_set_multi_add_default_row(table_set, |
| 2, ASN_OCTET_STR, 1, |
| 3, ASN_OCTET_STR, 1); |
| |
| /* register the table */ |
| register_table_data_set(create_handler_registration("chairs", |
| NULL, |
| my_data_table_set_oid, |
| 4, HANDLER_CAN_RWRITE), |
| table_set, NULL); |
| |
| /* add the data, for the first row */ |
| row = create_table_data_row(); |
| table_row_add_index(row, ASN_OCTET_STR, "snmpv3",\ |
| strlen("snmpv3")); |
| set_row_column(row, 2, ASN_OCTET_STR, "Russ Mundy", strlen("Russ Mundy")); |
| mark_row_column_writable(row, 2, 1); /* make writable */ |
| set_row_column(row, 3, ASN_OCTET_STR, "David Harrington", |
| strlen("David Harrington")); |
| mark_row_column_writable(row, 3, 1); /* make writable */ |
| table_dataset_add_row(table_set, row); |
| |
| /* add the data, for the second row */ |
| row = create_table_data_row(); |
| table_row_add_index(row, ASN_OCTET_STR, "snmpconf",\ |
| strlen("snmpconf")); |
| set_row_column(row, 2, ASN_OCTET_STR, "David Partain", |
| strlen("David Partain")); |
| mark_row_column_writable(row, 2, 1); /* make writable */ |
| set_row_column(row, 3, ASN_OCTET_STR, "Jon Saperia", |
| strlen("Jon Saperia")); |
| mark_row_column_writable(row, 3, 1); /* make writable */ |
| table_dataset_add_row(table_set, row); |
| } |
| |
| int |
| my_test_handler( |
| mib_handler *handler, |
| handler_registration *reginfo, |
| agent_request_info *reqinfo, |
| request_info *requests) { |
| |
| oid myoid1[] = {1,2,3,4,5,6}; |
| static u_long accesses = 0; |
| |
| DEBUGMSGTL(("testhandler", "Got request:\n")); |
| /* loop through requests */ |
| while(requests) { |
| struct variable_list *var = requests->requestvb; |
| |
| DEBUGMSGTL(("testhandler", " oid:")); |
| DEBUGMSGOID(("testhandler", var->name, |
| var->name_length)); |
| DEBUGMSG(("testhandler", "\n")); |
| |
| switch(reqinfo->mode) { |
| case MODE_GET: |
| if (snmp_oid_compare(var->name, var->name_length, myoid1, 6) |
| == 0) { |
| snmp_set_var_typed_value(var, ASN_INTEGER, |
| (u_char *) &accesses, |
| sizeof(accesses)); |
| return SNMP_ERR_NOERROR; |
| } |
| break; |
| |
| case MODE_GETNEXT: |
| if (snmp_oid_compare(var->name, var->name_length, myoid1, 6) |
| < 0) { |
| snmp_set_var_objid(var, myoid1, 6); |
| snmp_set_var_typed_value(var, ASN_INTEGER, |
| (u_char *) &accesses, |
| sizeof(accesses)); |
| return SNMP_ERR_NOERROR; |
| } |
| break; |
| |
| default: |
| set_request_error(reqinfo, requests, SNMP_ERR_GENERR); |
| break; |
| } |
| |
| requests = requests->next; |
| } |
| return SNMP_ERR_NOERROR; |
| } |
| |
| /* |
| * functionally this is a simply a multiplication table for 12x12 |
| */ |
| |
| #define MAX_COLONE 12 |
| #define MAX_COLTWO 12 |
| #define RESULT_COLUMN 3 |
| int |
| my_test_table_handler(mib_handler *handler, |
| handler_registration *reginfo, |
| agent_request_info *reqinfo, |
| request_info *requests) { |
| |
| table_registration_info |
| *handler_reg_info = (table_registration_info *) handler->prev->myvoid; |
| table_request_info *table_info; |
| u_long result; |
| int x, y; |
| |
| |
| while(requests) { |
| struct variable_list *var = requests->requestvb; |
| |
| if (requests->processed != 0) |
| continue; |
| |
| DEBUGMSGTL(("testhandler_table", "Got request:\n")); |
| DEBUGMSGTL(("testhandler_table", " oid:")); |
| DEBUGMSGOID(("testhandler_table", var->name, var->name_length)); |
| DEBUGMSG(("testhandler_table", "\n")); |
| |
| table_info = extract_table_info(requests); |
| if (table_info==NULL) { |
| requests = requests->next; |
| continue; |
| } |
| |
| switch(reqinfo->mode) { |
| case MODE_GETNEXT: |
| /* beyond our search range? */ |
| if (table_info->colnum > RESULT_COLUMN) |
| break; |
| |
| /* below our minimum column? */ |
| if (table_info->colnum < RESULT_COLUMN || |
| /* or no index specified */ |
| table_info->indexes->val.integer == 0) { |
| table_info->colnum = RESULT_COLUMN; |
| x = 0; |
| y = 0; |
| } else { |
| x = *(table_info->indexes->val.integer); |
| y = *(table_info->indexes->next_variable->val.integer); |
| } |
| |
| if (table_info->number_indexes == handler_reg_info->number_indexes) { |
| y++; /* GETNEXT is basically just y+1 for this table */ |
| if (y > MAX_COLTWO) { /* (with wrapping) */ |
| y = 0; |
| x++; |
| } |
| } |
| if (x <= MAX_COLONE) { |
| result = x * y; |
| |
| *(table_info->indexes->val.integer) = x; |
| *(table_info->indexes->next_variable->val.integer) = y; |
| table_build_result(reginfo, requests, |
| table_info, ASN_INTEGER, |
| (u_char *) &result, |
| sizeof(result)); |
| } |
| |
| break; |
| |
| case MODE_GET: |
| if (var->type == ASN_NULL) { /* valid request if ASN_NULL */ |
| /* is it the right column? */ |
| if (table_info->colnum == RESULT_COLUMN && |
| /* and within the max boundries? */ |
| *(table_info->indexes->val.integer) <= MAX_COLONE && |
| *(table_info->indexes->next_variable->val.integer) |
| <= MAX_COLTWO) { |
| |
| /* then, the result is column1 * column2 */ |
| result = *(table_info->indexes->val.integer) * |
| *(table_info->indexes->next_variable->val.integer); |
| snmp_set_var_typed_value(var, ASN_INTEGER, |
| (u_char *) &result, |
| sizeof(result)); |
| } |
| } |
| break; |
| |
| } |
| |
| requests = requests->next; |
| } |
| |
| return SNMP_ERR_NOERROR; |
| } |
| |
| #define TESTHANDLER_SET_NAME "my_test" |
| int |
| my_test_instance_handler( |
| mib_handler *handler, |
| handler_registration *reginfo, |
| agent_request_info *reqinfo, |
| request_info *requests) { |
| |
| static u_long accesses = 0; |
| u_long *accesses_cache = NULL; |
| |
| DEBUGMSGTL(("testhandler", "Got instance request:\n")); |
| |
| switch(reqinfo->mode) { |
| case MODE_GET: |
| accesses++; |
| snmp_set_var_typed_value(requests->requestvb, ASN_UNSIGNED, |
| (u_char *) &accesses, |
| sizeof(accesses)); |
| break; |
| |
| 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 **) &accesses_cache, |
| (u_char *) &accesses, sizeof(accesses)); |
| if (accesses_cache == NULL) { |
| set_request_error(reqinfo, requests, |
| SNMP_ERR_RESOURCEUNAVAILABLE); |
| return SNMP_ERR_NOERROR; |
| } |
| request_add_list_data(requests, |
| create_data_list(TESTHANDLER_SET_NAME, |
| accesses_cache, free)); |
| break; |
| |
| case MODE_SET_ACTION: |
| /* update current */ |
| accesses = *(requests->requestvb->val.integer); |
| DEBUGMSGTL(("testhandler","updated accesses -> %d\n", accesses)); |
| break; |
| |
| case MODE_SET_UNDO: |
| accesses = |
| *((u_long *) request_get_list_data(requests, |
| TESTHANDLER_SET_NAME)); |
| break; |
| |
| case MODE_SET_COMMIT: |
| case MODE_SET_FREE: |
| /* nothing to do */ |
| break; |
| } |
| |
| return SNMP_ERR_NOERROR; |
| } |
| |
| int |
| my_data_table_handler( |
| mib_handler *handler, |
| handler_registration *reginfo, |
| agent_request_info *reqinfo, |
| request_info *requests) { |
| |
| char *column3; |
| table_request_info *table_info; |
| table_row *row; |
| |
| while(requests) { |
| if (requests->processed) |
| continue; |
| |
| /* extract our stored data and table info */ |
| row = extract_table_row(requests); |
| table_info = extract_table_info(requests); |
| if (row) |
| column3 = (char *) row->data; |
| if (!row || !table_info || !column3) |
| continue; |
| |
| /* there's only one column, we don't need to check if it's right */ |
| table_data_build_result(reginfo, reqinfo, requests, row, |
| table_info->colnum, |
| ASN_OCTET_STR, column3, strlen(column3)); |
| requests = requests->next; |
| } |
| return SNMP_ERR_NOERROR; |
| } |