/** creates a new row from an existing defined default set */ netsnmp_table_row * netsnmp_table_data_set_create_row_from_defaults (netsnmp_table_data_set_storage *defrow) { netsnmp_table_row *row; row = netsnmp_create_table_data_row(); if (!row) return NULL; for (; defrow; defrow = defrow->next) { netsnmp_set_row_column(row, defrow->column, defrow->type, defrow->data.voidp, defrow->data_len); if (defrow->writable) netsnmp_mark_row_column_writable(row, defrow->column, 1); } return row; }
/** creates a new row from an existing defined default set */ netsnmp_table_row * netsnmp_table_data_set_create_row_from_defaults (netsnmp_table_data_set_storage *defrow) { netsnmp_table_row *row; row = netsnmp_create_table_data_row(); if (!row) return NULL; for (; defrow; defrow = defrow->next) { netsnmp_set_row_column(row, defrow->column, defrow->type, defrow->data.voidp, defrow->data_len); #ifndef NETSNMP_NO_WRITE_SUPPORT if (defrow->writable) netsnmp_mark_row_column_writable(row, defrow->column, 1); #endif /* !NETSNMP_NO_WRITE_SUPPORT */ } return row; }
/* Handles creation of new rows for the table */ static int sipOtherStatsTable_newRow(struct sip_snmp_handler *h) { netsnmp_table_row *row; /* XXX: make sure applIndex is an index for your table */ static int applIndex = -1; const char *func = "snmp_mod"; register struct sip_snmp_handler *c; struct sip_snmp_obj *o; int i, col; /* get applIndex first */ if(applIndex == -1) { applIndex = ser_getApplIndex(); if(applIndex == -1) { LOG(L_ERR,"%s: Couldn't get application index, cannot create " "new row\n", func); return -1; } } /* create the row */ row = netsnmp_create_table_data_row(); if(!row) { LOG(L_ERR, "%s: Couldn't create new row, out of memory?\n", func); return -1; } /* add indexes */ netsnmp_table_row_add_index(row, ASN_INTEGER, &applIndex, sizeof(applIndex)); c = h; for(i=1; i<SIPOTHERSTATSTABLE_INDEXES; i++) { if(!c) { LOG(L_ERR, "%s: Not enought indexes passed, need %d\n", func, SIPOTHERSTATSTABLE_INDEXES); netsnmp_table_data_delete_row(row); return -1; } if(!c->sip_obj || !c->sip_obj->value.voidp) { LOG(L_ERR, "%s: Invalid index passed\n", func); netsnmp_table_data_delete_row(row); return -1; } if(!netsnmp_table_row_add_index(row, ser_types[c->sip_obj->type], c->sip_obj->value.voidp, c->sip_obj->val_len)) { LOG(L_ERR, "%s: Error adding index to row\n", func); netsnmp_table_data_delete_row(row); return -1; } c = c->next; } /* add the data. We start from the last index, all the way to the * end of the linked list */ c = h; for(i=2; i<SIPOTHERSTATSTABLE_INDEXES; i++) c = c->next; col = 1; while(c) { if(col > SIPOTHERSTATSTABLE_COLUMNS) { LOG(L_ERR, "%s: Too many columns for new row\n", func); netsnmp_table_data_delete_row(row); return -1; } o = c->sip_obj; if(!o || !o->value.voidp) { LOG(L_ERR, "%s: Invalid object to add to new row\n", func); netsnmp_table_data_delete_row(row); return -1; } if(netsnmp_set_row_column(row, col, ser_types[o->type], o->value.voidp, o->val_len) != SNMPERR_SUCCESS) { LOG(L_ERR, "%s: Error adding object to row\n", func); netsnmp_table_data_delete_row(row); return -1; } if(c->on_set) netsnmp_mark_row_column_writable(row, col, 1); /* next, please... */ c = c->next; col++; } /* add the row to the table */ if(netsnmp_table_data_add_row(sipOtherStatsTable->table, row) != SNMPERR_SUCCESS) { LOG(L_ERR, "%s: Error adding new row to table\n", func); netsnmp_table_data_delete_row(row); return -1; } return 0; }
/* Adds a new object to the table. If the row doesn't exist is created. * Assumes all objects go to the same row, and all the objects are * new (replacing is done silently) */ static int sipOtherStatsTable_addObj(struct sip_snmp_handler *h, int col) { static netsnmp_table_row *row = NULL; int applIndex; /* Default index for most tables */ int first = 0; const char *func = "snmp_mod"; if(!row) { /* First time. Create row and add indexes */ /* Get index (applIndex). First since we don't need to undo it * but it's still possible that it fails (e.g. if we get called * at the wrong time) */ applIndex = ser_getApplIndex(); if(applIndex == -1) { LOG(L_ERR, "%s: Failed getting table index\n", func); return -1; } /* XXX: If table has more indexes init them here and add * a similar call to row_add_index() as below */ /* Create the row */ row = netsnmp_create_table_data_row(); if(!row) { LOG(L_ERR, "%s: failed creating table row\n", func); return -1; } /* add the index(es) to the table */ if(!netsnmp_table_row_add_index(row, ASN_INTEGER, &applIndex, sizeof(applIndex))) { LOG(L_ERR, "%s: Error adding index to row\n", func); netsnmp_table_data_delete_row(row); row = NULL; return -1; } first = 1; } /* sanity checks */ if(col < 1 || col > SIPOTHERSTATSTABLE_COLUMNS) { LOG(L_ERR, "%s: Invalid column %d to add new object\n", func, col); return -1; } if(!h || !h->sip_obj || !h->sip_obj->value.voidp) { LOG(L_ERR, "%s: Invalid object to add\n", func); return -1; } /* add object to row */ if(netsnmp_set_row_column(row, col, ser_types[h->sip_obj->type], h->sip_obj->value.voidp, h->sip_obj->val_len) != SNMPERR_SUCCESS) { LOG(L_ERR, "%s: Error adding new object to table\n", func); return -1; } /* is it writable? */ if(h->on_set) netsnmp_mark_row_column_writable(row, col, 1); /* If first time, add the row. Subsequent times don't need to do * anything since the table just has a pointer to our local row. * However, if indexes were to change then the row needs to be * replaced */ if(first) { if(netsnmp_table_data_add_row(sipOtherStatsTable->table, row) != SNMPERR_SUCCESS) { LOG(L_ERR, "%s: Error adding new row to table\n",func); return -1; } } /* Fin */ return 0; }
/** @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"); } }
/* * (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")); }
/** Initialize the lightingTable table by defining its contents and how it's structured */ void initialize_table_lightingTable(void) { const oid lightingTable_oid[] = {1,3,6,1,4,1,12620,5,2}; netsnmp_table_data_set *table_set; /* create the table structure itself */ table_set = netsnmp_create_table_data_set("lightingTable"); /* comment this out or delete if you don't support creation of new rows */ table_set->allow_creation = 1; /*************************************************** * Adding indexes */ DEBUGMSGTL(("initialize_table_lightingTable", "adding indexes to table lightingTable\n")); //netsnmp_table_set_add_indexes(table_set, // ASN_INTEGER, /* index: lightIndex */ // 0); //DEBUGMSGTL(("gpDroneMIB","pt-1\n")); netsnmp_table_dataset_add_index(table_set, ASN_INTEGER); /* index: lightIndex */ DEBUGMSGTL(("initialize_table_lightingTable", "adding column types to table lightingTable\n")); //DEBUGMSGTL(("gpDroneMIB","pt1\n")); /*netsnmp_table_set_multi_add_default_row(table_set, COLUMN_LIGHTDESCRIPTION, ASN_OCTET_STR, 0, NULL, 0, COLUMN_LIGHTTOGGLE, ASN_INTEGER, 1, NULL, 0, COLUMN_LIGHTINDEX, ASN_INTEGER, 0, NULL, 0, 0); */ netsnmp_table_set_multi_add_default_row(table_set, COLUMN_LIGHTINDEX, ASN_INTEGER, 0, NULL, 0, COLUMN_LIGHTDESCRIPTION, ASN_OCTET_STR, 0, NULL, 0, COLUMN_LIGHTTOGGLE, ASN_INTEGER, 1, NULL, 0, 0); //DEBUGMSGTL(("gpDroneMIB","pt2\n")); /* registering the table with the master agent */ /* note: if you don't need a subhandler to deal with any aspects of the request, change lightingTable_handler to "NULL" */ netsnmp_register_table_data_set(netsnmp_create_handler_registration("lightingTable", lightingTable_handler, lightingTable_oid, OID_LENGTH(lightingTable_oid), HANDLER_CAN_RWRITE), table_set, NULL); my_table = (struct tb_entry*)malloc(sizeof(struct tb_entry)*5); int i; for(i = 1; i <= 5; i++){ my_table[i-1].index = (long)i; strncpy(my_table[i-1].descr,l_table[i-1].descr,256); my_table[i-1].toggle = 0;//TODO: initialize int index = i; netsnmp_table_row *row = netsnmp_create_table_data_row(); netsnmp_table_row_add_index(row,ASN_INTEGER,&index,sizeof(index)); netsnmp_set_row_column(row,1,ASN_INTEGER,&index,sizeof(index)); netsnmp_mark_row_column_writable(row,1,0); netsnmp_set_row_column(row,2,ASN_OCTET_STR,l_table[i-1].descr,strlen(l_table[i-1].descr)); netsnmp_mark_row_column_writable(row,2,0); netsnmp_set_row_column(row,3,ASN_INTEGER,&index,sizeof(index)); netsnmp_mark_row_column_writable(row,3,1); netsnmp_table_dataset_add_row(table_set,row); } /*FILE *f = fopen("result.txt","w"); fprintf(f,"Index\t\tDescr\t\tToggle\n"); for(i = 1; i <= 5; i++){ fprintf(f,"%d\t\t%s\t\t%d\n",my_table[i-1].index,my_table[i-1].descr,my_table[i-1].toggle); } fclose(f); */ }