基於W5500的嵌入式SNMP代理端實現
最近一個做焊接裝置的朋友想在焊機上新增監控的新功能,實時獲取焊機的溫度、功耗等引數,還可簡單控制,實現對叢集焊接裝置的網路化管理。而這個朋友不想在開發管理系統上花太多精力,想找一個開源的管理軟體來實現他的需求。這讓我想到了簡單郵件管理協議SNMP,它生來就是為搞網路管理服務的。能廣泛相容各網路裝置,一經推出就得到了廣泛的應用和支援,幾乎所有的網路裝置生產廠家都實現了對SNMP的支援,大多數網路管理系統和平臺也都是基於SNMP的。事實上,目前SNMP已成為網路管理領域中的工業標準,我國國家廣電總局就要求通訊領域的標準網路裝置都必須支援SNMP協議。SNMP代理端實際佔用系統資源少,在微控制器上執行是沒有問題的。於是我想到用手頭的WIZnet-W5500評估板實現了SNMP代理端,給他提供一個參考。
二 SNMP基礎普及
在實現SNMP代理端之前,我們先了解一下SNMP的基本知識。管理系統中就要有管理者和被管理者,網管協議定義它為管理站和代理端,它們通過管理資訊庫MIB進行介面統一,實現資料的通訊。
MIB可以認為是一個被管理物件的集合,每個物件規定了能夠被管理程式查詢和設定的資訊,同時都有自己的名字我們稱之為物件識別符號,簡稱OID,它的命名方法跟DNS樹形結構命名類似,通過OID就能知道這個裝置所屬的領域和廠家,如MIB中有一個節點{1.3.6.1.4.1},即enterprises,代表企業,它以下的節點都為企業型的。如IBM為{1.3.6.1.4.1.2},Cisco為{1.3.6.1.4.1.9}等。任何一個公司、學校只要用電子郵件發往iana-mib@isi.edu進行申請即可獲得一個結點名。這樣就可以定義自己的產品的OID,使它能用SNMP進行管理。
為了操作管理資料庫MIB,如圖1所示:SNMP規定了5種協議SNMP報文,用來在管理程式和代理之間的交換。1 get-request;2 get-next-request;3 set-request;4 get-response;5trap。前面的3種操作是由管理程式向代理程式發出的get/set操作,雙方都使用UDP161埠。第4個是對前三種操作的迴應,用UDP161埠,第5個代理程式主動發出的報文,通知管理程式有某些事情發生,使用UDP162埠。
圖1 SNMP的5種報文操作
圖2是封裝成UDP資料包的5種操作的SNMP報文格式。可見一個SNMP報文共有三個部分組成,即公共SNMP首部、get/set首部或trap首部、變數繫結。
圖2 SNMP報文格式
三 SNMP嵌入式系統實現方法
瞭解了SNMP協議之後,下面就讓我們通過WIZnet W5500EVB做一個嵌入式SNMP代理端的簡單實驗。
1.實驗目的:建立一個SNMP代理端
2.硬體環境
微控制器:STM32F103RC,256K位元組Flash,48K位元組SRAM
乙太網控制器:W5500,SPI介面與微控制器相連
電源:USB供電
硬體外設:板載LED
3.開發工具: IAR V5.14(版本不一樣,需要稍加改動)
4.測試軟體:串列埠除錯助手,Net-SNMP(可從網路下載)
軟體部分是實現簡單網路管理協議SNMP的關鍵,下面就以程式流程圖的形式看看我們是如何實現的。
圖3為主程式流程圖,我們可以看出程式首先進行微控制器系統軟硬體初始化,然後初始化W5500,配置了IP地址、MAC地址、和閘道器。
圖3主程式流程圖
配置完畢後就是代理端主動傳送SNMP Trap報文了,傳送SNMP Trap報文的過程比較簡單,主要就是安裝Trap報文格式對傳送資料進行打包即可,需要注意的是資料包要根據ASN.1中的BER編碼方式(格式型別/長度/值)進行編碼。打包完畢後,開啟UDP Socket,本地埠為162,然後向管理的162埠傳送Trap包。接下來就進入一個迴圈,等待解析SNMP管理站發來Request資料包,邊解析,邊準備要回復的資料包,下圖為代理端解析管理站發來的GET/SET請求,並準備Response資料包的流程圖。
圖4代理端解析Request程式流程圖
通過圖4流程圖我們可以看到,整個過程是嚴格按照SNMP協議一步步進行解析判斷的。需要說明的是,也是先根據SNMP編碼方式進行解碼,再進行比較和判斷。我們知道SNMP中MIB聯絡管理站和代理端的關鍵,解析程式到最後查詢的便是MIB中的物件,在此我們給出定義MIB物件的結構體:
typedef struct {
uint8 oidlen;
uint8 oid[MAX_OID];
uint8 dataType;
uint8 dataLen;
union {
uint8octetstring[MAX_STRING];
uint32 intval;
} u;
void(*getfunction)(void *, uint8 *);
void(*setfunction)(int32);
} dataEntryType;
通過該結構體的定義我們可以知道MIB物件的幾個部分:OID ,資料型別,資料長度,資料,get函式,set函式,本方案MIB中定義的一個控制LED動作的一個物件:{8, {0x2b, 6, 1, 4, 1, 0, 2, 0},SNMPDTYPE_INTEGER, 4,{""}, NULL, setWIZnetLed}
其中8為OID長度,0x2b是ASN.1中“1.3”的縮寫,即:1*40+3=0x2b。整個OID其實為1.3.6.1.4.1.0.2.0。該物件的set函式為setWIZnetLed:
void setWIZnetLed(int32 val){
wiznetLedStatus =val;// W5500-EVB
if (wiznetLedStatus==0 )GPIO_SetBits(GPIOA, LED3); // STM32
elseGPIO_ResetBits(GPIOA, LED3);
}
此為函式名,同樣也為函式的指標,在解析SET函式過程中有一句程式碼:snmpData[id].setfunction(snmpData[id].u.intval);就是執行了該函式,其中snmpData[id].u.intval為從set Request當中解析到的繫結變數值。
整個MIB就是由上述格式的物件組成,讓可以自己定義物件的OID變數及物件的函式,當管理站向該物件傳送請求時,就可以執行相應函式,從而完成你所需要讓SNMP完成的管理和控制。
完整源程式下載:http://pan.baidu.com/s/1qWmHpTE
四測試SNMP代理端
下面以PC機為SNMP管理站,講述如何測試我們實現的SNMP代理端。
1.在電腦中安裝Net-SNMP軟體。Net-SNMP是一個免費的、開放原始碼的SNMP實現方式。按預設選型安裝軟體後,點選Windows開始——>執行 輸入“ CMD ”,點選確認,進入DC命令環境,輸入“ cd \usr\bin”,此路徑即安裝的Net—SNMP預設路徑,在此路徑下可執行SNMP命令。
2.修改PC本地連線IP地址。控制皮膚——>網路和Internet——>網路連線,點選本地連線選擇屬性,設定PC為靜態IP(與W5500在同一網段),設定完成後點選確定,本例中我們設定PC機ip為192.168.1.110,SNMP代理端IP為192.168.1.111,預設閘道器都為192.168.1.1。
3.接著用網線把PC和W5500EVB連線,開啟串列埠軟體,選擇正確的COM口並開啟串列埠,以獲取除錯資訊。
4.下載編譯好的程式碼並復位W5500EVB,我們發現板子上有一排LED,最右邊這個LED就是我們要查詢並且控制的。如圖5所示,現在這個LED是亮的。
圖5最右邊LED亮
5.在剛才開啟的Net—SNMP預設路徑下可以輸入指令,如圖所示輸入“snmpget -v 1 -cpublic 192.168.1.111 .1.3.6.1.4.1.0.1.0 ”回車,查詢到“LED On”,符合板子現在亮的情況。
6.再輸入“snmpset -v 1 -cpublic 192.168.1.111 .1.3.6.1.4.1.0.2.0 i 0”回車,結合這個OID物件的set函式分析可知,該條命令是置STM32的LED3對應引腳為高,即關閉LED。如圖6觀察板子上的LED3,可見已滅。
圖6最右邊LED滅
7.如圖7再次輸入第5步的snmpget指令,可以查詢到狀態為“LED Off”。
圖7 Net-SNMP工具測試SNMP協議
通過以上步驟可以看出SNMP Agent已經執行,當然要實現一個複雜的網路管理功能還需要Net—SNMP中很多其他指令在此不一一列舉。
五總結
本文給出了基於W5500的嵌入式系統SNMP的設計與實現方案,並展示瞭如何用Net-SNMP除錯工具進行簡單控制的方法。隨著物聯網事業的發展,越來越多的嵌入式裝置都將擁有聯網功能,相信SNMP協議的作用將越來越重要。除了智慧家居,在當下物聯網時代,想必還有其他應用也會遇到類似問題,希望本文能對做網路裝置開發的朋友有所幫助。
相關文章
- 基於snmp的反射攻擊的理論及其實現反射
- 服務端SSE資料代理與基於fetch的EventSource實現服務端
- 基於嵌入式板卡實現的藍芽AOA基站藍芽
- frp實現基於反向代理的內網穿透FRP內網穿透
- 實現基於React的移動端Swiper元件React元件
- 基於Retrofit2實現的LycheeHttp-使用動態代理實現上傳HTTP
- .NET 下基於動態代理的 AOP 框架實現揭祕框架
- 基於Chrome外掛實現支援CORS的本地開發代理ChromeCORS
- React服務端渲染實現(基於Dva)React服務端
- 基於使用者認證的前後端實現後端
- SNMP用VC++6.0實現的方法 (轉)C++
- 基於 WebSocket 的 PPT 遠端控制器簡單實現Web
- 基於 Agora SDK 實現 iOS 端的多人視訊互動GoiOS
- Go基於gRPC實現客戶端連入服務端GoRPC客戶端服務端
- 基於 Agora SDK 實現 Windows 端的多人視訊互動(基於3.6.2版本)GoWindows
- 基於W5500+STM32的SNMP協議應用協議
- 基於vue實現web端超大資料量表格VueWeb大資料
- 基於Web實現遠端與硬體互動Web
- 基於Bmob在小程式端實現一鍵支付
- 基於jquery實現的ExceljQueryExcel
- 基於JVMTI的Agent實現JVM
- APP功能模組實現之思路歷程(基於iOS端)APPiOS
- 基於快照實現遠端資料只讀複製
- 基於 Agora SDK 實現 Windows 端的一對一視訊通話(基於3.6.2版本)GoWindows
- 通過 ProxyChains-NG 實現終端代理AI
- SNMP 實戰1
- Qt實現基於多執行緒的檔案傳輸(服務端,客戶端)QT執行緒服務端客戶端
- 基於Masstransit實現Eventbus的功能
- 基於 SplPriorityQueue 實現的排序方法排序
- 基於Python的Akka實現Python
- 實現基於角色的授權
- 圖解基於 Node.js 實現前後端分離圖解Node.js後端
- mybatis原始碼學習:基於動態代理實現查詢全過程MyBatis原始碼
- 基於XMPP實現android客戶端與伺服器的互動Android客戶端伺服器
- W5500通過上位機控制實現調節LED燈帶的亮度
- 基於 Nginx&Lua 實現自建服務端埋點系統Nginx服務端
- ISAServer中基於L2TP實現遠端撥入VPNServer
- 移動端基於LBS實現簽到功能可行性分析