Uważam, że największym zagrożeniem dla net-snmp są wszystkie strony Doxygen indeksowane przez Google, ale zapewniające prawie zero użytecznej zawartości. Czytanie plików .h
jest prawdopodobnie już oczywiste dla większości programistów, a prawda jest taka, że net-snmp oferuje wiele różnych warstw interfejsów API z bardzo małą ilością użytecznych dokumentów. To, czego potrzebujemy, to nie kilkadziesiąt identycznych kopii witryn internetowych obsługujących Doxygen, ale kilka dobrych przykładów.
W końcu narzędzie mib2c jest tym, jak mam wystarczający kod przykładowy, aby wszystko działało. Myślę, że próbowałem uruchomić mib2c z każdym pojedynczym plikiem net-snmp .conf
i spędziłem dużo czasu czytając wygenerowany kod, aby uzyskać lepsze zrozumienie. Oto te, znalazłem dał mi najlepsze wskazówki:
- mib2c -c mib2c.create-dataset.conf MyMib
- mib2c -c mib2c.table_data.conf MyMib
W .conf
pliki Jesteś tutaj: /etc/snmp/mib2c.*
także użyteczne były następujące strony:
Z tego co rozumiem, istnieje wiele pomocników/warstwy dostępne w API net-snmp. Więc ten przykład pseudokod może nie działać dla wszystkich, ale to jest jak ja osobiście mam moje stoły do pracy przy użyciu net-snmp V5.4:
zmiennej potrzebne w kilku funkcji (uczynić go globalny, lub członkiem struct?)
netsnmp_tdata *table = NULL;
struktury do reprezentowania jednego wiersza w tabeli (musi być zgodny z definicją MIB)
struct MyTable_entry
{
long myTableIndex;
...insert one line here for each column of the table...
int valid; // add this one to the end
}
inicjalizację stół snmpd
std::string name("name_of_the_table_from_mib");
table = netsnmp_tdata_create_table(name.c_str(), 0);
netsnmp_table_registration_info *table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, 0); // index: myTableIndex
// specify the number of columns in the table (exclude the index which was already added)
table_info->min_column = COLUMN_BLAH;
table_info->max_column = MAX_COLUMN_INDEX;
netsnmp_handler_registration *reg = netsnmp_create_handler_registration(name.c_str(), MyTable_handler, oid, oid.size(), HANDLER_CAN_RONLY);
netsnmp_tdata_register(reg, table, table_info);
Handler przetwarzanie żądań
int myTable_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests)
{
if (reqInfo->mode != MODE_GET) return SNMP_ERR_NOERROR;
for (netsnmp_request_info *request = requests; request; request = request->next)
{
MyTable_entry *table_entry = (MyTable_entry*)netsnmp_tdata_extract_entry(request);
netsnmp_table_request_info *table_info = netsnmp_extract_table_info(request);
if (table_entry == NULL) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; }
switch (table_info->colnum)
{
// ...this is similar to non-table situations, eg:
case COLUMN_BLAH:
snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, table_entry->blah); break;
// ...
default: netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
}
}
return SNMP_ERR_NOERROR;
}
Budownictwo/dodawanie wierszy do tabeli
if (table == NULL) return; // remember our "global" variable named "table"?
// start by deleting all of the existing rows
while (netsnmp_tdata_row_count(table) > 0)
{
netsnmp_tdata_row *row = netsnmp_tdata_row_first(table);
netsnmp_tdata_remove_and_delete_row(table, row);
}
for (...loop through all the data you want to add as rows into the table...)
{
MyTable_entry *entry = SNMP_MALLOC_TYPEDEF(MyTable_entry);
if (entry == NULL) ... return;
netsnmp_tdata_row *row = netsnmp_tdata_create_row();
if (row == NULL) SNMP_FREE(entry); .... return;
entry->myTableIndex = 123; // the row index number
// populate the table the way you need
entry->blah = 456;
// ...
// add the data into the row, then add the row to the table
entry->valid = 1;
row->data = entry;
netsnmp_tdata_row_add_index(row, ASN_INTEGER, &(entry->myTableIndex), sizeof(entry->myTableIndex));
netsnmp_tdata_add_row(table, row);
}
wprowadzenie go razem
W moim przypadku ta ostatnia funkcja budująca wiersze jest wyzwalana okresowo przez inne zdarzenia w systemie. Tak więc od czasu do czasu, gdy dostępne są nowe statystyki, tabela jest przebudowywana, wszystkie stare wiersze są usuwane, a nowe są wstawiane. Nie próbowałem modyfikować istniejących wierszy. Zamiast tego okazało się, że łatwiej jest odbudować stół od zera.
Czy piszesz swojego agenta od zera lub używając 'mib2c'? 'mib2c' może wygenerować dla ciebie cały szkielet. Potem przekształcenie go w subagenta jest łatwe. Czy jesteś w stanie spojrzeć na "http://net-snmp.sourceforge.net/wiki/index.php/TUT:Writing_a_Subagent"? – j4x