1. 程式人生 > >【NetSNMP##】 C語言傳送SNMP Trap訊息

【NetSNMP##】 C語言傳送SNMP Trap訊息

專案需求系統利用SNMP Trap訊息上報狀態給NMS,考慮使用net-snmp提供的SNMP庫函式實現該功能,且需要根據不同埠使用不同的session。

1)標頭檔案

為了使用 netsnmp 的 API,必須 include 以下這些標頭檔案:

#include <net-snmp/net-snmp-config.h>

#include <net-snmp/net-snmp-includes.h>

2)snmp初始化

在使用 netsnmp 庫之前,先要做一些必要的初始化工作。 函式 init_snmp 初始化 SNMP Library。 假如在呼叫 init_snmp 函式時指定了檔名,init_snmp 函式將讀取配置檔案,設定諸如 Access Control 等具體配置。否則會使用預設的 /etc 下面的配置檔案。

初始化 SNMP 庫之後,我們就可以開啟一個會話 session。此後所有和 NMS 的資訊互動都在該 session 內進行,因為可能在同一臺機器上執行多個 SNMP 程序,每個程序都需要自己獨立的 session 來和 NMS 進行資訊互動。

呼叫函式 snmp_sess_init 成功後將返回一個 session 資料結構。我們用該資料結構來設定 session 的屬性,比如 peer 的 IP 資訊。在下面的程式碼中,我將 peername 設定為 16.157.76.227。

還可以設定其它的必要資訊,比如 Community,即用於 SNMP 安全的社群設定,前面 snmptrapd 設定為 public,因此這裡也設定為 public。這類似於通行密碼,不過安全性的確比較弱。

Session 屬性設定好之後便可以使用函式 snmp_open 開啟 session。示例程式碼如下。

 程式碼最大長度示例

init_snmp("myexample");

struct snmp_session session;

snmp_sess_init(&session);

session.version = SNMP_VERSION_2c;

strcpy(peername,"16.157.76.227:1622");

strcpy(commu,"public");

session.peername = peername;

session.community = (unsigned char*)commu;

session.community_len = strlen(commu);

ss = snmp_open(&session);

開啟一個會話之後,程式可以通過該會話傳送 Trap 給 NMS,也可以從 NMS 接受 SNMP get/set 操作。

3)建立pdu報文,傳送trap

每個 Trap 都由 PDU 承載,PDU 有固定的格式。 為了簡化描述,本文只描述 SNMPv2 的 Trap 傳送方法。SNMP v2c 和 v1 的 Trap 有所不同。請閱讀參考文獻瞭解這些不同的細節,此外本文的附件程式碼中也實現了 v1 的支援程式碼。SNMPv2 的 Trap PDU 定義如下:

圖 3. SNMP Trap PDU 格式

å¾ 3. SNMP Trap PDU æ ¼å¼

其中各個組成部分的解釋如下: sysUpTime– 被管理裝置上一次初始化網路到本 Trap 傳送以來的累積時間。 snmpTrapOID– 表示本 PDU 是一個 Trap,有固定的值。對於一般的 Trap,RFC1907 給出了通用的定義。使用者自定義的 Trap 通常是由以下幾個部分連線而成:SNMPv1 Enterprise parameter + '0' + SNMPv1 Specific trap code。 VarBindList– 變數列表,所謂變數就是 Trap 訊息中所攜帶的資訊單元。

下面的程式碼片斷用來填充如圖三所示的一個 PDU。

oid objid_sysuptime[] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };

 oid objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };

 netsnmp_pdu * pdu = NULL;

 oid tmpOID[MAX_OID_LEN];

 size_t tmpOID_len;

 in_addr_t addr;

 

 pdu = snmp_pdu_create(SNMP_MSG_TRAP2);

 long sysuptime;

 char tempbuf[128];

 memset(tempbuf,128,0);

 sprintf(tempbuf,"%ld",sysuptime);

 sysuptime = get_uptime();

 oid tmpOID[MAX_OID_LEN];

 size_t tmpOID_len;

 tmpOID_len = MAX_OID_LEN;

 if(!snmp_parse_oid(TRAP_NAME_1, tmpOID, &tmpOID_len))

snmp_error(“snmp_parse_oid”);

 snmp_add_var(pdu, objid_sysuptime, sizeof(objid_sysuptime)/sizeof(oid), 't', tempbuf);

 snmp_add_var(pdu, objid_snmptrap, sizeof(objid_snmptrap)/sizeof(oid),'o',

              “IBM-DW-SAMPLE::nodeDown”);

首先呼叫函式 snmp_pdu_create 建立一個 SNMPv2 的 Trap PDU然後呼叫 snmp_add_var 向該 PDU 中新增圖三所示的三個部分。 sysUpTime 在 SNMPv2-MIB 中定義,其 OID 為”1.3.6.1.2.1.1.3.0”。我們只需要通過 get_uptime() 函式獲得該值,然後呼叫 snmp_add_var 將該變數加入剛才建立的 PDU 中。

同理,snmpTrapOID 也是固定的 :” 1.3.6.1.6.3.1.1.4.1.0”。同樣利用 snmp_add_var 函式將我們定義的 OID 為“IBM-DW-SAMPLE::nodeDown”的 Trap 加入該 PDU。 稍稍留意一下,您應該可以發現,sysUpTime 的型別為't',即 timestamp;而 snmpTrapOID 的型別為’ o ’,即 OID 型別。PDU 內的每一個元素都擁有自己的型別。 在該 Trap 中,我們還打算攜帶兩個變數:IBM-DW-SAMPLE::host 和 IBM-DW-SAMPLE::ip。表示一些真正有趣的資訊。 新增這兩個變數的程式碼如下所示:

HP-DW-SAMPLE::ip",varId,&varIdLen))

    {

      snmp_perror("ip");

    }

    else

    {

       printf("Success snmp_parse_oid\n");

       snmp_add_var(pdu, varId, sizeof(varId)/sizeof(oid),'s',"2.2.2.2");

    }

    if(!snmp_parse_oid("HP-DW-SAMPLE::host",varId,&varIdLen))

    {

      snmp_perror("host");

    }

    else

    {

       retv =  snmp_add_var(pdu, varId, sizeof(varId)/sizeof(oid),'s',”M1”);

 }

用 snmp_parse_oid 解析相應變數的 OID,然後就可以呼叫 snmp_add_var 將您想設定的值加入 PDU 中了。假如您直接在程式碼中使用”HP-DW-SAMPLE::ip”的 OID,(即 1.3.6.1.4.1.10234.10.2),那麼可以不需要呼叫 snmp_parse_oid。該函式只是把一個好記的字串翻譯為一串數字的 OID。不過這就好比用 16.157.1.2 而不使用 www.ibm.com 一樣。

至此,一個 SNMP Trap PDU 就建立成功了。將該 PDU 傳送出去即可:

if( !snmp_send(sptr, pdu) )

{

  snmp_error("Send pdu error \n");

}

3)傳送結束,清理工作

程式結束之前需要做清理工作,程式碼如下:

snmp_close(sptr);

snmp_shutdown( "myexample" );

SOCK_CLEANUP;

相關推薦

NetSNMP## C語言傳送SNMP Trap訊息

專案需求系統利用SNMP Trap訊息上報狀態給NMS,考慮使用net-snmp提供的SNMP庫函式實現該功能,且需要根據不同埠使用不同的session。 1)標頭檔案 為了使用 netsnmp 的 API,必須 include 以下這些標頭檔案: #include &

C語言之變量存儲類型

art 技術分享 .net ont alt enter fill img 分享 【精】C語言之變量存儲類型

C語言文件操作詳解

pri void rfi 識別 archive format 隨機 stat 文本文 轉自:http://www.cnblogs.com/likebeta/archive/2012/06/16/2551780.html C語言中沒有輸入輸出語句,所有的輸入輸出功能都用

C語言 printf格式控制符 完全解析

china int 數字 大於 轉換 OS 組成 字符數 無符號 printf的格式控制的完整格式:% - 0 m.n l或h 格式字符下面對組成格式說明的各項加以說明:①%:表示格式說明的起始符號,不可缺少。②-:

STLHDU2024C語言合法標識符水題

AI info targe == () 簡潔 技術分享 type #define 鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=2024 既然要求了全體同學都要刷完杭電100題,那我還是以身作則,也都給刷完吧~~~ 這些水題真的是

複習c語言幾道簡單程式設計題

最近在複習c語言的一些知識點,以下是整理的幾道比較重要的程式設計題: 1.列印100-200之間的素數 為了統計素數的個數,可設定一個計數器count; 方法1: #include<stdio.h> int main() { int i = 0; int count =

C語言鄰接表的實現

原文連結:C語言鄰接表的實現 這篇博文的程式碼寫的很好,我就直接合並在一起貼出來了,方便自己使用,至於文章內容有需要可以看上述原文   #define OK 1 #define ERROR 0 #define MVNum 100 #include<stdio.h> #in

函式C語言(三)

函式是一組一起執行一個任務的語句。每個 C 程式都至少有一個函式,即主函式 main() ,所有簡單的程式都可以定義其他額外的函式。  定義函式 return_type function_name( parameter list ) { body of the

良心C語言零基礎學習,C語言初學者入門基礎知識講解

C++ 其實是一種中級語言,它是 Bjarne Stroustrup 於 1979 年和以往的積累在貝爾實驗室開始設計開發的一種計算機語言。C++ 進一步擴充和完善了 C 語言,不僅是一種面向物件的程式設計語言,還要提到的C++ 可運行於多種平臺上,比如Windows還有

作業系統C語言模擬作業系統實現磁碟排程演算法——電梯排程演算法

#include<stdio.h> #include<stdlib.h> #include<time.h> int *Init(int arr[]) { int

分類 - C語言再學習

專欄達人 授予成功建立個人部落格專欄

OpenJudgec語言_A*B問題

描述 輸入兩個正整數A和B,求A*B。 輸入一行,包含兩個正整數A和B,中間用單個空格隔開。1 <= A,B <= 50000。 輸出一個整數,即A*B的值。 樣例輸入 3 4 樣例輸出 12 提示注意乘積的範圍和資料型別的選擇

演算法C語言實現陣列的動態分配

作者:白寧超 2016年10月27日20:13:13 摘要:資料結構和演算法對於程式設計的意義不言而喻,具有指導意義的。無論從事演算法優化方向研究,還是大資料處理,亦或者網站開發APP開發云云。在求職過程中資料結構必然也是筆試的重點,面試的常客。基於此,系統梳理複習下資料結構和演算法相關知識,其實核心

LinuxC語言實現資料夾拷貝

在《【Linux】利用C語言檔案流複製單一檔案》(點選開啟連結)講述瞭如何用C語言拷貝檔案,但是這隻能拷貝單一檔案。如果你要用LinuxC拷貝整個資料夾,同樣要像《【Java】利用檔案輸入輸出流完成把一個資料夾內的所有檔案拷貝的另一的資料夾的操作》(點選開啟連結)一樣,先用

筆記c語言學習筆記part1

最近學習oc,把之前學得很水的c語言重新過了一遍,打算整理一些基礎的東西,方便以後回顧 1.c程式編譯的過程 /* 1.預處理(Preprocessing):對源程式進行“替代”工作,生成一個沒有巨集定義、沒有條件編譯指令、沒有特殊

作業系統C語言模擬作業系統實現動態分割槽分配演算法

#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #defi

續集 C語言圖形和函式影象的繪製其他部分 第二章

           第二章【續集】 圖形和函式影象的繪製       圓形和拋物線的繪製 繪製函式影象的第二種方法 同一座標系下繪製多個函式影象(交叉影象) 4、圓形和拋物線的繪製    有了

20150127 ARM C語言+位域聯合體

結構體位域struct Fpga{unsigned int a:1;unsigned int b:1;unsigned int c:1;}; 聯合體:多個成員共用一塊儲存空間(佔最大資料型別空間)同一時刻只能用一個成員union FPH{unsigned int p;unsigned char ch;};un

轉載c語言結構體指標初始化

轉載來自:http://www.cnblogs.com/losesea/archive/2012/11/15/2772526.html   今天來討論一下C中的記憶體管理。 記得上週在飯桌上和同事討論C語言的崛起時,講到了記憶體管理方面 我說所有指標使用前都必須初始化

STLC++語言cstring庫之memcpy與memcpy_s

// void *memcpy(void *dest, const void *src, size_t count); // errno_t memcpy_s(void *dest, size_t numberOfElements, const void *src, siz