/** @internal */ void netsnmp_config_parse_table_set(const char *token, char *line) { oid name[MAX_OID_LEN], table_name[MAX_OID_LEN]; size_t name_length = MAX_OID_LEN, table_name_length = MAX_OID_LEN; struct tree *tp, *indexnode; netsnmp_table_data_set *table_set; data_set_tables *tables; struct index_list *index; unsigned int mincol = 0xffffff, maxcol = 0; u_char type; char *pos; /* * instatiate a fake table based on MIB information */ DEBUGMSGTL(("9:table_set_add_table", "processing '%s'\n", line)); if (NULL != (pos = strchr(line,' '))) { config_pwarn("ignoring extra tokens on line"); snmp_log(LOG_WARNING," ignoring '%s'\n", pos); *pos = '\0'; } /* * check for duplicate table */ tables = (data_set_tables *) netsnmp_get_list_data(auto_tables, line); if (NULL != tables) { config_pwarn("duplicate table definition"); return; } /* * parse oid and find tree structure */ if (!snmp_parse_oid(line, table_name, &table_name_length)) { config_pwarn ("can't instatiate table since I can't parse the table name"); return; } if(NULL == (tp = get_tree(table_name, table_name_length, get_tree_head()))) { config_pwarn("can't instatiate table since " "I can't find mib information about it"); return; } if (NULL == (tp = tp->child_list) || NULL == tp->child_list) { config_pwarn("can't instatiate table since it doesn't appear to be " "a proper table (no children)"); return; } /* * check for augments indexes */ if (NULL != tp->augments) { if (!snmp_parse_oid(tp->augments, table_name, &table_name_length)) { config_pwarn("I can't parse the augment tabel name"); snmp_log(LOG_WARNING, " can't parse %s\n", tp->augments); return; } if(NULL == (tp = get_tree(table_name, table_name_length, get_tree_head()))) { config_pwarn("can't instatiate table since " "I can't find mib information about augment table"); snmp_log(LOG_WARNING, " table %s not found in tree\n", tp->augments); return; } table_set = netsnmp_create_table_data_set(line); /* * loop through indexes and add types */ for (index = tp->indexes; index; index = index->next) { if (!snmp_parse_oid(index->ilabel, name, &name_length) || (NULL == (indexnode = get_tree(name, name_length, get_tree_head())))) { config_pwarn("can't instatiate table since " "I don't know anything about one index"); snmp_log(LOG_WARNING, " index %s not found in tree\n", index->ilabel); return; /* xxx mem leak */ } type = mib_to_asn_type(indexnode->type); if (type == (u_char) - 1) { config_pwarn("unknown index type"); return; /* xxx mem leak */ } if (index->isimplied) /* if implied, mark it as such */ type |= ASN_PRIVATE; DEBUGMSGTL(("table_set_add_row", "adding default index of type %d\n", type)); netsnmp_table_dataset_add_index(table_set, type); } } else table_set = netsnmp_create_table_data_set(line); /* * loop through indexes and add types */ for (index = tp->indexes; index; index = index->next) { if (!snmp_parse_oid(index->ilabel, name, &name_length) || (NULL == (indexnode = get_tree(name, name_length, get_tree_head())))) { config_pwarn("can't instatiate table since " "I don't know anything about one index"); snmp_log(LOG_WARNING, " index %s not found in tree\n", index->ilabel); return; /* xxx mem leak */ } type = mib_to_asn_type(indexnode->type); if (type == (u_char) - 1) { config_pwarn("unknown index type"); return; /* xxx mem leak */ } if (index->isimplied) /* if implied, mark it as such */ type |= ASN_PRIVATE; DEBUGMSGTL(("table_set_add_row", "adding default index of type %d\n", type)); netsnmp_table_dataset_add_index(table_set, type); } /* * loop through children and add each column info */ for (tp = tp->child_list; tp; tp = tp->next_peer) { int canwrite = 0; type = mib_to_asn_type(tp->type); if (type == (u_char) - 1) { config_pwarn("unknown column type"); return; /* xxx mem leak */ } DEBUGMSGTL(("table_set_add_row", "adding column %s(%d) of type %d (access %d)\n", tp->label, tp->subid, type, tp->access)); switch (tp->access) { case MIB_ACCESS_CREATE: table_set->allow_creation = 1; case MIB_ACCESS_READWRITE: case MIB_ACCESS_WRITEONLY: canwrite = 1; case MIB_ACCESS_READONLY: DEBUGMSGTL(("table_set_add_row", "adding column %d of type %d\n", tp->subid, type)); netsnmp_table_set_add_default_row(table_set, tp->subid, type, canwrite, NULL, 0); mincol = SNMP_MIN(mincol, tp->subid); maxcol = SNMP_MAX(maxcol, tp->subid); break; case MIB_ACCESS_NOACCESS: case MIB_ACCESS_NOTIFY: break; default: config_pwarn("unknown column access type"); break; } } /* * register the table */ netsnmp_register_table_data_set(netsnmp_create_handler_registration (line, NULL, table_name, table_name_length, HANDLER_CAN_RWRITE), table_set, NULL); netsnmp_register_auto_data_table(table_set, NULL); }
/* * (to get called, the function name must match init_FILENAME() */ void init_data_set (void) { netsnmp_table_row *row; /* * the OID we want to register our integer at. This should be the * * OID node for the entire table. In our case this is the * * netSnmpIETFWGTable oid definition */ oid my_registration_oid[] = { 1, 3, 6, 1, 4, 1, 8072, 2, 2, 1 }; /* * a debugging statement. Run the agent with -Dexample_data_set to see * * the output of this debugging statement. */ DEBUGMSGTL (("example_data_set", "Initalizing example dataset table\n")); /* * 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 = netsnmp_create_table_data_set ("netSnmpIETFWGTable"); /* * allow the creation of new rows via SNMP SETs */ table_set->allow_creation = 1; /* * set up what a row "should" look like, starting with the index */ netsnmp_table_dataset_add_index (table_set, ASN_OCTET_STR); /* * define what the columns should look like. both are octet strings here */ netsnmp_table_set_multi_add_default_row (table_set, /* * column 2 = OCTET STRING, * writable = 1, * default value = NULL, * default value len = 0 */ 2, ASN_OCTET_STR, 1, NULL, 0, /* * similar */ 3, ASN_OCTET_STR, 1, NULL, 0, 0 /* done */ ); /* * register the table */ /* * if we wanted to handle specific data in a specific way, or note * * when requests came in we could change the NULL below to a valid * * handler method in which we could over ride the default * * behaviour of the table_dataset helper */ netsnmp_register_table_data_set (netsnmp_create_handler_registration ("netSnmpIETFWGTable", NULL, my_registration_oid, OID_LENGTH (my_registration_oid), HANDLER_CAN_RWRITE), table_set, NULL); /* * create the a row for the table, and add the data */ row = netsnmp_create_table_data_row (); /* * set the index to the IETF WG name "snmpv3" */ netsnmp_table_row_add_index (row, ASN_OCTET_STR, "snmpv3", strlen ("snmpv3")); /* * set column 2 to be the WG chair name "Russ Mundy" */ netsnmp_set_row_column (row, 2, ASN_OCTET_STR, "Russ Mundy", strlen ("Russ Mundy")); netsnmp_mark_row_column_writable (row, 2, 1); /* make writable via SETs */ /* * set column 3 to be the WG chair name "David Harrington" */ netsnmp_set_row_column (row, 3, ASN_OCTET_STR, "David Harrington", strlen ("David Harrington")); netsnmp_mark_row_column_writable (row, 3, 1); /* make writable via SETs */ /* * add the row to the table */ netsnmp_table_dataset_add_row (table_set, row); #ifdef ADD_MORE_DATA /* * add the data, for the second row */ row = netsnmp_create_table_data_row (); netsnmp_table_row_add_index (row, ASN_OCTET_STR, "snmpconf", strlen ("snmpconf")); netsnmp_set_row_column (row, 2, ASN_OCTET_STR, "David Partain", strlen ("David Partain")); netsnmp_mark_row_column_writable (row, 2, 1); /* make writable */ netsnmp_set_row_column (row, 3, ASN_OCTET_STR, "Jon Saperia", strlen ("Jon Saperia")); netsnmp_mark_row_column_writable (row, 3, 1); /* make writable */ netsnmp_table_dataset_add_row (table_set, row); #endif /* * Finally, this actually allows the "add_row" token it the * * snmpd.conf file to add rows to this table. * * Example snmpd.conf line: * * add_row netSnmpIETFWGTable eos "Glenn Waters" "Dale Francisco" */ netsnmp_register_auto_data_table (table_set, NULL); DEBUGMSGTL (("example_data_set", "Done initializing.\n")); }