前段時間一直在做snmp代理。從一無所知到把項目做完。一些總結寫在這裏,分享給需要的人。
1. 開發mib文件
mib文件的格式是:起始行;import;從根節點開始,一層層往下,每一層都可在上層找到依賴關係。具體實現可參考安裝包內mibs/ NET-SNMP-EXAMPLES-MIB.txt
注:對於可添加刪除的表格,則table必須額外添加一項Row Status。用於標識行的添加刪除修改。
將設計好的mib文件拷到/usr/local/share/snmp/mibs/
2. 用mib2c工具生成*.c *.h文件
設置環境變量,用對應配置文件生成代碼。注意要用root權限。
export MIBS=ALL;
mib2c –c configure mibnode
configure選擇:
表格用mib2c.iterate_access.conf或mib2c.iterate.conf
節點用mib2c.scalar.conf
Trap用mib2c.notify.conf
(如果沒有生成文件,檢查前幾步是否正確完成)
(參考安裝包內agent/mibgroup/example/ 下的文件完成開發)
3. 修改添加生成的.c文件,完成源代碼的編寫。
a) 節點方式函數
handle_XXX(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
MODE_GET用於get操作;
MODE_SET_COMMIT用於寫操作。從requests->requestvb->val.integer/string獲取節點數據。
b) table方式函數說明(mib2c.iterate_access.conf):
initialize_table_xxxTable(void)
模塊初始化
xxxTable_handler
表格處理函數句柄
xxxTable_createEntry
傳入表格參數,新建一個結構,將各參數依次賦給結構內各項。最後將結構添加在xxxTable_head的前面作爲首節點。
xxxTable_removeEntry
此函數可借用mib2c.iterate.conf文件生成的函數。
entry的意思表示是表格的入口,是在mib文件中設置的(index項)。可查看netsnmp_table_helper_add_indexes函數的第二個參數註釋。
xxxTable_get_first_data_point
手動創建鏈表,每個節點包含一行table內容,頭結點賦給xxxTable_head。
將xxxTable_head賦給 *my_loop_context。
xxxTable_get_next_data_point
需要填寫snmp_set_var_value(idx, (u_char *)xxx, sizeof(xxx))的後兩個參數,xxx爲index項。
xxxTable_create_data_context(netsnmp_variable_list * index_data, int column)
創建一個結構模板,entry項由index_data傳入,如下例:
entry->IPLineID = *(index_data->val.integer); 其他的項隨便填。如有RowStatus項,則RowStatus初始化爲0。
將創建的結構體添加到xxxTable_head的頭結點前面。
本函數在在xxxTable_handler函數中調用,默認生成的模板裏第二個參數爲空,編譯會出錯,填入1。
xxxTable_commit_row(void **my_data_context, int new_or_del)
具體的添加修改刪除行的操作在這個函數裏進行。例:
struct IPLineTable_entry *entry = (IPL_t *)*my_data_context;
switch (entry->RowStatus)
根據entry->RowStatus的不同類型區分不同的操作。
Get_xxx (void *data_context, size_t *ret_len)
獲取節點數據內容
Set_xxx (void *data_context, long *val, size_t val_len)
設置節點內容
c) trap函數
發送trap有兩種方式,一種是腳本中用snmptrap發送,一種是在程序內用函數發送。發送函數:send_xxxTrap_trap()。
需要填寫兩個snmp_varlist_add_variable函數。
snmp_varlist_add_variable(&var_list, snmptrap_oid, OID_LENGTH(snmptrap_oid),
ASN_OBJECT_ID, (u_char *)xxxTrap_oid, sizeof(xxxTrap_oid));
snmp_varlist_add_variable(&var_list, yyy_oid, OID_LENGTH(yyy_oid),
ASN_OCTET_STR, string, strlen(string));
xxxTrap_oid是trap節點號,yyy_oid是關聯節點號,string即爲要發送的字符串。
4. 編譯
添加擴展采用動態庫方式
生成動態庫:
gcc -g -I/root/net-snmp-5.2.2/include/ -c -o example.o example.c
gcc -g -fPIC -shared -o example.so example.o
裝載動態庫到程序節點
需要配置文件:/etc/snmp/snmpd.conf 中添加
dlmod example /root/snmpdll/ example.so
然後重新啓動snmpd程序。