1. 程式人生 > >使用Snmp++獲取MIB表

使用Snmp++獲取MIB表


        Snmp++
是一套強大的網路管理應用開發包。它提供了Snmp網管協議所描述的所有命令,並且提供SMI資料型別的解析。MIB資料包含普通資料和表資料。在提取表資料時,由於表項的數量和Oid都不確定,所以不能通過某個特定的Oid直接獲得取值。通常,關於Snmp的書上都會介紹使用GetNext命令來實現表的遍歷,這種方法比較簡單,這裡主要討論該演算法的原理和如何用Snmp++實現。

MIB表是通過行和列來描述的。其中列表頭是各個表項的原始Oid,而行表頭則是index。這樣以來一個Oid和一個index就唯一地確定了表中的一項。比如在介面表中,ifDescrOid1.3.6.1.2.1.2.2.1.2

)為一列,而具體對於某一個介面則為一行。這樣,某一具體表項的Oid就表示為:列Oid+index的形式。下圖形象地描述了一張表的格式。

ifIndex

1.3.6.1.2.1.2.2.1.1

ifDescr

1.3.6.1.2.1.2.2.1.2

ifType

1.3.6.1.2.1.2.2.1.3

ifMtu

1.3.6.1.2.1.2.2.1.4

Ifspeed

1.3.6.1.2.1.2.2.1.5

Index0

xxx

xxx

xxx

xxx

xxx

Index1

xxx

xxx

xxx

xxx

xxx

Index2

xxx

xxx

xxx

xxx

xxx

按照協議描述,最基本的方法是通過index來獲取某一表項。但事實上,index本身也是一個表項,再加之有些表需要多個index,並且各種index的資料型別不同,比如要手工處理ip地址型別的index就比較困難,所以這種方法具有很難的操作性。因此,在實際程式設計時,可以採取一些比較技巧化的方法。

Snmp中對於GetNext命令的描述可知,如果GetNext的引數為一個表中某一列的表頭Oid,比如前面的ifDescr1.3.6.1.2.1.2.2.1.2),則得到的值為該列第一行元素值,並可得到該值的Oid。再對取得的Oid使用GetNext就可獲得該列第二行的值。如此下去,如果到了該列的最後一行,那麼用

GetNext將得到下一列的第一行。如果到了該表的最後一個元素,那麼用GetNext將得到按MIB樹所得的下一個元素值。顯然,在越界的情況下,其Oid的前部分已不同於本列表頭的Oid,所以,可以通過得到的Oid值來判斷是否越界。

以下為其主要的程式碼:

/*從代理提取某一特定表項,即表中的一列*/

void get_Table(Oid *item_oid, CTarget *target)

{

GenAddress address;

target->get_address( address);
            
Oid full_oids[MAX_INDEX];//用來儲存得到的所有oid

int index_count=0;//該列的行數

bool tag=true;//標誌迴圈是否結束

for(;tag==true;)

{

Pdu pdu;

Vb vb;

vb.set_oid(item_oid);

pdu += vb;

int status;

if ((status=snmp->get_next( pdu, *target))== SNMP_CLASS_SUCCESS)

{

pdu.get_vb( vb,0);

Oid full_oid;//該表項的Oid

vb.get_oid(full_oid);

//判斷是否已越界,如果是則結束迴圈

if(item_oid ->nCompare(item_oid ->len(), full_oid)==0)

{

vb.get_oid(full_oids[index_count]);

index_count++;

/*

在這裡進行資料處理

*/

}

else

{

tag=false;

}

}

else

{

tag=false;

}

}

}

以上的演算法是從表中提取一列,那麼如何提取一行呢?對於上述演算法可以加以改進以適應我們的需要。但是,GetNext命令是按列遍歷的,當我們要用它獲得一行的時候還是必須先至少獲得一列的資訊,也就是說,在行遍歷演算法中還是要包含上述程式碼。這種方法經過實踐是成功的,在這裡僅對演算法進行一下描述。

首先還是要執行上述程式碼,但是,在資料處理的時候必須儲存所得到的完整Oid。我們知道,得到的Oid實際上是由列Oid+index構成,而列Oid是已知的,那麼如果我們將得到的Oid前面的列Oid部分替換為另外的列Oid就可以獲得該行另一列的完整Oid。在多數情況下,同一表中不同的列Oid僅相差一個數字,所以,替換方法也比較簡單。這裡假設我們只需替換一位(其它情況下只需做修改即可),演算法如下:

//按行提取表資料

Oid row_oid[MAX_OID_NUM];

/*

首先在此處包含前面按列提取的程式碼,

並在資料處理處將full_oid儲存在陣列row_oid

*/

//假設前面已經將第一列的所有表項Oid儲存在陣列row_oid中了

//按行迴圈

for(int i=0; i<index_count; i++)

{

Oid oid;

//獲取該行中每一列的資料

for(oid=第一列oid; oid<最後一列oid; oid=下一列的oid)

{

Pdu pdu;

Vb vb;

//替換,如有需要,可以採用其它方法,這裡選取最簡單的情況只替換一位

row_oid[i][oid.len()-1]=oid[oid.len()-1];

vb.set_oid(row_oid[i]);

pdu += vb;

int status;

if ((status=snmp->get( pdu, *target))== SNMP_CLASS_SUCCESS)

{

pdu.get_vb( vb,0);

/*

在這裡進行資料處理

*/

}

else

{

cout << snmp->error_msg( status) << "/n";

}

}

實際上,Snmp提取表資料的方法有很多,這裡介紹的是最簡單最基礎的一種方法。而且對於不同的開發包,還有更好的對錶支援的方法,比如AdventSnmp開發包就有直接的表操作函式。無論採用何種方法,瞭解最基本的工作原理都非常有幫助。

相關推薦

使用Snmp++獲取MIB

        Snmp++是一套強大的網路管理應用開發包。它提供了Snmp網管協議所描述的所有命令,並且提供SMI資料型別的解析。MIB資料包含普通資料和表資料。在提取表資料時,由於表項的數量和Oid都不確定,所以不能通過某個特定的Oid直接獲得取值。通常,關於Snmp的書

使用snmp協議獲取MIB的資料

公司最近的需求是獲取印表機的配件資訊,常規的TCP/IP協議獲取不到資料,機器資訊存放在MIB資料庫中,需要用snmp協議讀取機器中的資訊,網路上查詢了幾天終於有點頭緒了 廢話不多說,直接貼程式碼 public class MainActivity extends A

serialize可以獲取form單裏面的數值

col user ext pan har nbsp utf-8 div meta serialize屬性 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta

ASP.Net 獲取Form單值

eve length ted bsp pre html .net protect all 新建一HtmlPage1.html,如下post發送() <body> <form enctype="multipart/form-data" actio

下拉框獲取關聯的信息

tro () base 返回 自己的 option func tip ron 用jq和ajax實現 1.在jsp頁面上 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><

sqlite3獲取所有信息

-1 alt 所有 技術分享 .cn sqlite str 分享 .com SELECT * FROM sqlite_master sqlite3獲取所有表信息

js獲取詳情頁面多個模塊相同的project_id

click border cti delete ear table region RM edi js頁面 $(function(){ 1. $(‘#project_id‘).val(project_id); --》此行代碼是前端傳過來獲取多個模塊的相同id,必不可少

js獲取form單數據和form單賦值

input orm htm for 獲取 pro 多行文本框 serialize PE $.fn.extend({// 調用方式:$("xxxxx").getform(); getform: function () {

postgresql 獲取所有名、字段名、字段類型、註釋

where class a format sql TTT desc elf tno null 獲取表名及註釋: select relname as tabname,cast(obj_description(relfilenode,‘pg_class‘) as varchar

實訓任務05 MapReduce獲取成績的最高分記錄

image 有用 分享圖片 core 文本 sdn info 流程 acc 實訓任務05 MapReduce獲取成績表的最高分記錄 實訓1:統計用戶紡問次數 任務描述: 統計用戶在2016年度每個自然日的總訪問次數。原始數據文件中提供了用戶名稱與訪問日期。這個任務

JavaWeb:Controller中獲取Form單提交的資料的方式

Controller中獲取Form表單提交的資料的方式 新增HttpServletRequst型別入參,通過HttpServletRequst.getParameter()獲取請求資料 @RequestMapping(value="/user/save", meth

SQL Server 2008獲取一個的欄位,型別,長度,是否主鍵,是否為空,註釋等資訊

SELECT [表名]= case when a.colorder=1 then d. name else '' end , [表說明]= case when

sqlserver 獲取所有的欄位型別等資訊

USE [MultipleAnalysisDataFY] GO /****** Object: View [dbo].[selectfieldtype] Script Date: 2018/11/7 星期三 12:02:27 ******/ SET ANSI_NULLS ON GO SET

SQL語句正則表示式 匹配(獲取) 所有

寫出匹配SQL語句中的所有表名,備忘記錄 折磨了好久,正則表示式如下: *\s+from\s+[\w ]*.?[\w ]*.? ?(\b\w+) ?(\b\w+) ?[\r\n\s]* 支援各種表示式 SELECT * FROM Config SELE

layui之獲取form單的radio

form表單是這樣的: <div class="layui-form-item"> <label class="layui-form-label">單選框</label> <div class="layui-input-bloc

執行指令碼獲取mysql中的資料,報1044錯誤

  mysql>use mysql;mysql>grant all on *.* to 資料庫登入名字@"%" identified by "資料庫的密碼";mysql>FLUSH&nb

從頁面獲取form單提交的資料

  1 使用HttpServletRequest,方便靈活 頁面程式碼,使用action提交一個表單,裡邊有球的id,球的主人,球的顏色,所在省份,區域 <form action="balls/addball_form" method="post">

直接獲取form單所有資料傳送到後臺

form表單程式碼  <form action="${pageContext.request.contextPath}/user/updateUser" method="post" id="updateForm"> <p>使用者名稱:<in

struts 獲取form單中的資料

一、通過action獲取表單提交的資料:ActionContext         // action中的內容 public String form1(){ System.out.println("通過action獲取表單提交的資料:Ac

jquery-獲取form單中的所有資料列表

<script> $(function() { $('#submit').click(function() { var d = {}; var t = $('form').serializeArray(); $.each(t, function() {