/** intended to be registerd as a .conf parser * It should be registered using: * * register_app_config_handler("token", netsnmp_read_data_callback, XXX) * * where INFO_POINTER is a pointer to a netsnmp_data_list_saveinfo object * containing apporpriate registration information * @todo make netsnmp_read_data_callback deal with a free routine */ void netsnmp_read_data_callback(const char *token, char *line) { netsnmp_data_list_saveinfo *info; char *dataname = NULL; size_t dataname_len; void *data = NULL; /* find the stashed information about what we're parsing */ info = (netsnmp_data_list_saveinfo *) netsnmp_get_list_data(saveHead, token); if (!info) { snmp_log(LOG_WARNING, "netsnmp_read_data_callback called without previously registered subparser"); return; } /* read in the token */ line = read_config_read_data(ASN_OCTET_STR, line, &dataname, &dataname_len); if (!line || !dataname) return; /* call the sub-parser to read the rest */ data = (info->data_list_read_ptr)(line, strlen(line)); if (!data) { free(dataname); return; } /* add to the datalist */ netsnmp_add_list_data(info->datalist, netsnmp_create_data_list(dataname, data, info->data_list_free_ptr)); return; }
/** @internal */ void netsnmp_config_parse_add_row(const char *token, char *line) { char buf[SNMP_MAXBUF_MEDIUM]; char tname[SNMP_MAXBUF_MEDIUM]; size_t buf_size; int rc; data_set_tables *tables; netsnmp_variable_list *vb; /* containing only types */ netsnmp_table_row *row; netsnmp_table_data_set_storage *dr; line = copy_nword(line, tname, SNMP_MAXBUF_MEDIUM); tables = (data_set_tables *) netsnmp_get_list_data(auto_tables, tname); if (!tables) { config_pwarn("Unknown table trying to add a row"); return; } /* * do the indexes first */ row = netsnmp_create_table_data_row(); for (vb = tables->table_set->table->indexes_template; vb; vb = vb->next_variable) { if (!line) { config_pwarn("missing an index value"); return; } DEBUGMSGTL(("table_set_add_row", "adding index of type %d\n", vb->type)); buf_size = SNMP_MAXBUF_MEDIUM; line = read_config_read_memory(vb->type, line, buf, &buf_size); netsnmp_table_row_add_index(row, vb->type, buf, buf_size); } /* * then do the data */ for (dr = tables->table_set->default_row; dr; dr = dr->next) { if (!line) { config_pwarn("missing a data value. " "All columns must be specified."); snmp_log(LOG_WARNING," can't find value for column %d\n", dr->column - 1); return; } buf_size = SNMP_MAXBUF_MEDIUM; line = read_config_read_memory(dr->type, line, buf, &buf_size); DEBUGMSGTL(("table_set_add_row", "adding data at column %d of type %d\n", dr->column, dr->type)); netsnmp_set_row_column(row, dr->column, dr->type, buf, buf_size); if (dr->writable) netsnmp_mark_row_column_writable(row, dr->column, 1); /* make writable */ } rc = netsnmp_table_data_add_row(tables->table_set->table, row); if (SNMPERR_SUCCESS != rc) { config_pwarn("error adding table row"); } }
/** @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); }