2012-03-23 17 views
7

Napisałem aplikację AgentX (Linux, gcc, g ++), która działa dobrze w przypadku wysyłania skalerów. Oto, co robię teraz:Poszukaj przykładowego kodu do implementacji tabeli SNMP przy użyciu agentaX

init_agent("blah"); 
netsnmp_register_read_only_scalar(netsnmp_create_handler_registration("foo1", handle_foo1, oid, oid.size(), HANDLER_CAN_RONLY)); 
init_snmp("blah"); 
while (true) 
{ 
    // internal stuff 
    agent_check_and_process(1); // where 1==block 
} 

Funkcje jak handle_foo1(...) rozmowy snmp_set_var_typed_value(...) do zwrotu wartości, które są buforowane w globalnym C struct w aplikacji.

Próbuję teraz zmodyfikować ten kod, aby obsługiwał również tabelę SNMP. Zawartość tabeli jest przechowywana/buforowana jako kontener STL w aplikacji. Jest to względnie prosta tabela SNMP z kolejnymi wierszami, a wszystkie kolumny składają się z typów takich jak Integer32, Gauge32, InetAddress i TruthValue. Problem polega na tym, że nie widzę wspaniałych przykładów kodu na stronie internetowej net-snmp, tylko wiele stron doxygen.

Moje pytanie:

Co API powinien być patrzysz? Czy są to prawidłowe połączenia:

netsnmp_register_read_only_table_data(); 
netsnmp_create_table_data(); 
netsnmp_create_table_data_row(); 
netsnmp_table_data_add_row(); 

... czy jest coś prostszego, czego powinienem używać?

+0

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

Odpowiedz

15

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.

Powiązane problemy