我认为在net-snmp方面最大的痛点就是谷歌索引的所有Doxygen页面,但它们提供的可用内容几乎为零。对于大多数开发人员来说,阅读.h文件已经很明显了,事实上,net-snmp提供了许多不同层次的API,但很少有有用的文档。我们需要的不是几十个相同的托管Doxygen的网站副本,而是一些好的示例。
最终,mib2c工具是我获得足够示例代码使整个过程工作的方式。我想我尝试使用每个net-snmp.conf文件运行mib2c,并花了很多时间阅读生成的代码以更好地理解。以下是我发现给我最好提示的内容:
- mib2c -c mib2c.create-dataset.conf MyMib
- mib2c -c mib2c.table_data.conf MyMib
.conf文件在这里:/etc/snmp/mib2c.*
以下页面也很有用:
据我所知,net-snmp API 中有许多辅助/层可用。因此,此示例伪代码可能并不适用于每个人,但这是我个人使用 net-snmp v5.4 使我的表格工作的方式:
需要跨多个函数使用的变量(将其设置为全局变量或结构体的成员?)
netsnmp_tdata *table = NULL;
表示表中一行的结构(必须匹配MIB定义)
struct MyTable_entry
{
long myTableIndex;
...insert one line here for each column of the table...
int valid;
}
使用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 );
处理请求的处理程序
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 )
{
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;
}
Building/adding rows to the table(构建/添加表格行)
if ( table == NULL ) return;
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;
entry->blah = 456;
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 );
}
组合
在我的情况下,最后一个构建行的函数是由系统中的其他事件周期性触发的。因此,每当有新的统计数据可用时,表格就会重新构建,删除所有旧行,并插入新行。我没有尝试修改现有行。相反,我发现从头开始重建表格更容易。
mib2c
?mib2c
可以为您生成整个框架。之后,将其转换为子代理很容易。您是否已经查看了“http://net-snmp.sourceforge.net/wiki/index.php/TUT:Writing_a_Subagent”? - j4x