Creo que el mayor dolor cuando se trata de net-snmp es todas aquellas páginas de Doxygen en los índices de Google, pero que proporcionan contenido útil cercano a cero. La lectura de los archivos .h
probablemente ya sea obvia para la mayoría de los desarrolladores, y la verdad es que net-snmp proporciona muchas capas diferentes de API con muy poca documentación que encontré útil. Lo que necesitamos no son varias docenas de copias idénticas de sitios web que alojan Doxygen, sino algunos buenos ejemplos.
Al final, la herramienta mib2c es cómo obtuve suficiente código de ejemplo para que todo funcione. Creo que traté de ejecutar mib2c con cada archivo net-snmp .conf
, y dediqué mucho tiempo a leer el código que generaba para comprenderlo mejor. Aquí están los que encontré me dieron los mejores consejos:
- mib2c -c-mib2c.create dataset.conf MyMib
- mib2c -c mib2c.table_data.conf MyMib
Los archivos .conf
Estás aquí: /etc/snmp/mib2c.*
también Han sido útiles las siguientes páginas:
Por lo que entiendo, hay muchos ayudantes/capas disponibles en la API de red SNMP. Así que este ejemplo pseudocódigo puede no funcionar para todos, pero así es como yo personalmente tengo mis tablas para trabajar de uso de red SNMP v5.4:
variable necesaria la mayoría de las funciones (que sea global o un miembro de una struct?)
netsnmp_tdata *table = NULL;
estructura para representar una fila de la tabla (debe coincidir con la definición MIB)
struct MyTable_entry
{
long myTableIndex;
...insert one line here for each column of the table...
int valid; // add this one to the end
}
inicializar la tabla con 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 para procesar las solicitudes
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;
}
Construcción/añadir filas a la tabla
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);
}
Juntando todo
En mi caso, esa última función que crea las filas se activa periódicamente por algunos otros eventos en el sistema. Entonces, de vez en cuando, cuando hay nuevas estadísticas disponibles, la tabla se reconstruye, todas las filas antiguas se eliminan y las nuevas se insertan. No me molesté en tratar de modificar las filas existentes. En cambio, descubrí que era más fácil reconstruir la tabla desde cero.
¿Está escribiendo su agente desde cero o utilizando 'mib2c'? 'mib2c' puede generar todo el esqueleto para usted. Después de eso, convertirlo en un subagente es fácil. ¿Ya ha mirado "http://net-snmp.sourceforge.net/wiki/index.php/TUT:Writing_a_Subagent"? – j4x