基于visual c++之windows核心编程代码分析(31)SNMP协议编程
SNMP(Simple Network Management Protocol,簡單網絡管理協議)的前身是簡單網關監控協議(SGMP),用來對通信線路進行管理。隨后,人們對SGMP進行了很大的修改,特別是加入了符合Internet定義的SMI和MIB:體系結構,改進后的協議就是著名的SNMP。SNMP的目標是管理互聯網Internet上眾多廠家生產的軟硬件平臺,因此SNMP受Internet標準網絡管理框架的影響也很大。現在SNMP已經出到第三個版本的協議,其功能較以前已經大大地加強和改進了.
MIB,Management Information Base:管理信息庫,由網絡管理協議訪問的管理對象數據庫,它包括SNMP可以通過網絡設備的SNMP管理代理進行設置的變量。SMI,Structure of Management Information:管理信息結構,用于定義通過網絡管理協議可訪問的對象的規則。
SMI定義在MIB中使用的數據類型及網絡資源在MIB中的名稱或表示。
使用SNMP進行網絡管理需要下面幾個重要部分:管理基站,管理代理,管理信息庫和網絡管理工具。管理基站通常是一個獨立的設備,它用作網絡管理者進行網絡管理的用戶接口。基站上必須裝備有管理軟件,管理員可以使用的用戶接口和從MIB取得信息的數據庫,同時為了進行網絡管理它應該具備將管理命令發出基站的能力。
管理代理是一種網絡設備,如主機,網橋,路由器和集線器等,這些設備都必須能夠接收管理基站發來的信息,它們的狀態也必須可以由管理基站監視。管理代理響應基站的請求進行相應的操作,也可以在沒有請求的情況下向基站發送信息。
MIB是對象的集合,它代表網絡中可以管理的資源和設備。每個對象基本上是一個數據變量,它代表被管理的對象的一方面的信息。
最后一個方面是管理協議,也就是SNMP,SNMP的基本功能是:取得,設置和接收代理發送的意外信息。取得指的是基站發送請求,代理根據這個請求回送相應的數據,設置是基站設置管理對象(也就是代理)的值,接收代理發送的意外信息是指代理可以在基站未請求的狀態下向基站報告發生的意外情況。
SNMP為應用層協議,是TCP/IP協議族的一部分。它通過用戶數據報協議(UDP)來操作。在分立的管理站中,管理者進程對位于管理站中心的MIB的訪問進行控制,并提供網絡管理員接口。管理者進程通過SNMP完成網絡管理。SNMP在UDP、IP及有關的特殊網絡協議(如,Ethernet, FDDI, X.25)之上實現。
SNMPv2標準的核心就是通信協議———它是一個請求/應答式的協議。
這個協議提供了在manager與agent、manager與manager之間交換管理信息的直觀、基本的方法。
每條SNMPv2的報文都由一些域構成:
如果發送方、接收方的兩個Party都采用了驗證(authentication)機制,它就包含與驗證有關的信息;否則它為空(取NULL)。
驗證的過程如下:發送方和接收方的Party都分別有一個驗證用的密鑰(secretkey)和一個驗證用的算法。
報文發送前,發送方先將密鑰值填入圖中digest域,作為報文的前綴。然后根據驗證算法,對報文中digest域以后(包括digest域)的報文數據進行計算,計算出一個摘要值(digest),再用摘要值取代密鑰,填入報文中的digest域。接收方收到報文后,先將報文中的摘要值取出來,暫存在一個位置,然后用發送方的密鑰放入報文中的digest。將這兩個摘要值進行比較,如果一樣,就證明發送方確實是srcParty域中所指明的那個Party,報文是合法的;如果不一樣,接收方斷定發送方非法。驗證機制可以防止非法用戶"冒充"某個合法Party來進行破壞。
authInfo域中還包含兩個時間戳(timestamp),用于發送方與接收方之間的同步,以防止報文被截獲和重發。
SNMPv2的另一大改進是可以對通信報文進行加密,以防止監聽者竊取報文內容。除了privDst域外,報文的其余部分可以被加密。發送方與接收方采用同樣的加密算法(如DES)。 通信報文可以不加任何安全保護,或只進行驗證,也可以二者都進行。
我們下面來實現SNMP的編程實現網絡數據的抓取
#include <stdio.h> #include <malloc.h> #include <snmp.h> #include <mgmtapi.h> #pragma comment(lib,"Mgmtapi.lib") #pragma comment(lib,"Snmpapi.lib") //利用 SNMP API時需要以上頭文件和庫文件 #define GET 1 //get,就理解成獲取一個信息。 #define GETNEXT 2 //getnext,就理解成獲取下一個信息。 #define WALK 3 //walk,就理解成獲取一堆信息,即所有數據庫子樹/子目錄的信息#define TIMEOUT 6000 /* milliseconds */ #define RETRIES 3//一些有用的oid char *SnmpOid[5]={".1.3.6.1.2.1.25.4.2.1.2",//進程列表".1.3.6.1.4.1.77.1.2.25.1.1",//系統用戶".1.3.6.1.4.1.77.1.4.1.0",//域名".1.3.6.1.2.1.25.6.3.1.2",//列出安裝的軟件".1.3.6.1.2.1.1"};// 列出系統信息 void usage(char *name) { printf("=================SNMP tool================\n"); printf("=======gxisone@hotmail.com 2004/8/10====\n"); printf("\nusage: %s [remoteip] [sysprocess|sysuser|domainname|sysinf|software]\n",name); printf("Exameple: %s 192.168.1.1 sysuser\n",name);}int main(int argc,char *argv[]){int operation;LPSTR agent;LPSTR community;RFC1157VarBindList variableBindings;LPSNMP_MGR_SESSION session;int timeout = TIMEOUT;int retries = RETRIES;int i;BYTE requestType;AsnInteger errorStatus;AsnInteger errorIndex;char *chkPtr = NULL;operation = WALK; //這個程序使用WALK來獲取信息if (argc != 3){usage(argv[0]);return 0;}else{AsnObjectIdentifier reqObject;// 取得IP地址agent = (LPSTR)SNMP_malloc(strlen(*argv) + 1);strcpy(agent, argv[1]);community="public";//設置查詢密碼variableBindings.list = NULL;variableBindings.len = 0;// 設置 oidif(!strcmp(argv[2],"sysprocess"))i=0;else if(!strcmp(argv[2],"sysuser"))i=1;else if(!strcmp(argv[2],"domainname"))i=2;else if(!strcmp(argv[2],"software"))i=3;else if(!strcmp(argv[2],"sysinf"))i=4;else{usage(argv[0]);return 0;} printf("%s\n",SnmpOid[i]);// 把字符串轉換成標準oidif (!SnmpMgrStrToOid(SnmpOid[i], &reqObject)){printf("Error: Invalid oid, %s, specified.\n", *argv);return 1;}else{variableBindings.len++;if ((variableBindings.list = (RFC1157VarBind *)SNMP_realloc(variableBindings.list, sizeof(RFC1157VarBind) *variableBindings.len)) == NULL){printf("Error: Error allocating oid, %s.\n",*argv);return 1;}variableBindings.list[variableBindings.len - 1].name=reqObject; variableBindings.list[variableBindings.len - 1].value.asnType=ASN_NULL;}// Make sure only one variable binding was specified if operation// is WALK.if (operation == WALK && variableBindings.len != 1){printf("Error: Multiple oids specified for WALK.\n");return 1;}// Establish a SNMP session to communicate with the remote agent. The// community, communications timeout, and communications retry count// for the session are also required.if ((session = SnmpMgrOpen(agent, community, timeout, retries)) == NULL){printf("error on SnmpMgrOpen %d\n", GetLastError());return 1;}} // end if{AsnObjectIdentifier root;AsnObjectIdentifier tempOid;SnmpUtilOidCpy(&root, &variableBindings.list[0].name);requestType = ASN_RFC1157_GETNEXTREQUEST;for(;;){if (!SnmpMgrRequest(session, requestType, &variableBindings,&errorStatus, &errorIndex)){printf("error on SnmpMgrRequest %d\n", GetLastError());break;}else{if (errorStatus == SNMP_ERRORSTATUS_NOSUCHNAME ||SnmpUtilOidNCmp(&variableBindings.list[0].name,&root, root.idLength)){printf("End of MIB subtree.\n\n");break;}if (errorStatus > 0){printf("Error: errorStatus=%d, errorIndex=%d \n", errorStatus, errorIndex);break;}else{// 打印查詢的結果char *string = NULL;SnmpMgrOidToStr(&variableBindings.list[0].name, &string);printf("Variable = %s\n", string);if (string) SNMP_free(string);printf("Value = ");SnmpUtilPrintAsnAny(&variableBindings.list[0].value);printf("\n");} } // end if() // 準備下一次查詢SnmpUtilOidCpy(&tempOid, &variableBindings.list[0].name);SnmpUtilVarBindFree(&variableBindings.list[0]);SnmpUtilOidCpy(&variableBindings.list[0].name, &tempOid);variableBindings.list[0].value.asnType = ASN_NULL;SnmpUtilOidFree(&tempOid); } // end while()// 釋放資源SnmpUtilVarBindListFree(&variableBindings);SnmpUtilOidFree(&root); }// 關閉 SNMP session if (!SnmpMgrClose(session))//清理退出{printf("error on SnmpMgrClose %d\n", GetLastError());return 1;}return 0;}
?
?
轉載于:https://www.cnblogs.com/niulanshan/archive/2012/01/22/6175584.html
總結
以上是生活随笔為你收集整理的基于visual c++之windows核心编程代码分析(31)SNMP协议编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言关键字 - 铁布衫:const
- 下一篇: VC++控制台程序中使用定时器