基于visual c++之windows核心编程代码分析(31)SNMP协议编程
SNMP(Simple Network Management Protocol,簡(jiǎn)單網(wǎng)絡(luò)管理協(xié)議)的前身是簡(jiǎn)單網(wǎng)關(guān)監(jiān)控協(xié)議(SGMP),用來(lái)對(duì)通信線(xiàn)路進(jìn)行管理。隨后,人們對(duì)SGMP進(jìn)行了很大的修改,特別是加入了符合Internet定義的SMI和MIB:體系結(jié)構(gòu),改進(jìn)后的協(xié)議就是著名的SNMP。SNMP的目標(biāo)是管理互聯(lián)網(wǎng)Internet上眾多廠(chǎng)家生產(chǎn)的軟硬件平臺(tái),因此SNMP受Internet標(biāo)準(zhǔn)網(wǎng)絡(luò)管理框架的影響也很大。現(xiàn)在SNMP已經(jīng)出到第三個(gè)版本的協(xié)議,其功能較以前已經(jīng)大大地加強(qiáng)和改進(jìn)了.
MIB,Management Information Base:管理信息庫(kù),由網(wǎng)絡(luò)管理協(xié)議訪(fǎng)問(wèn)的管理對(duì)象數(shù)據(jù)庫(kù),它包括SNMP可以通過(guò)網(wǎng)絡(luò)設(shè)備的SNMP管理代理進(jìn)行設(shè)置的變量。SMI,Structure of Management Information:管理信息結(jié)構(gòu),用于定義通過(guò)網(wǎng)絡(luò)管理協(xié)議可訪(fǎng)問(wèn)的對(duì)象的規(guī)則。
SMI定義在MIB中使用的數(shù)據(jù)類(lèi)型及網(wǎng)絡(luò)資源在MIB中的名稱(chēng)或表示。
使用SNMP進(jìn)行網(wǎng)絡(luò)管理需要下面幾個(gè)重要部分:管理基站,管理代理,管理信息庫(kù)和網(wǎng)絡(luò)管理工具。管理基站通常是一個(gè)獨(dú)立的設(shè)備,它用作網(wǎng)絡(luò)管理者進(jìn)行網(wǎng)絡(luò)管理的用戶(hù)接口。基站上必須裝備有管理軟件,管理員可以使用的用戶(hù)接口和從MIB取得信息的數(shù)據(jù)庫(kù),同時(shí)為了進(jìn)行網(wǎng)絡(luò)管理它應(yīng)該具備將管理命令發(fā)出基站的能力。
管理代理是一種網(wǎng)絡(luò)設(shè)備,如主機(jī),網(wǎng)橋,路由器和集線(xiàn)器等,這些設(shè)備都必須能夠接收管理基站發(fā)來(lái)的信息,它們的狀態(tài)也必須可以由管理基站監(jiān)視。管理代理響應(yīng)基站的請(qǐng)求進(jìn)行相應(yīng)的操作,也可以在沒(méi)有請(qǐng)求的情況下向基站發(fā)送信息。
MIB是對(duì)象的集合,它代表網(wǎng)絡(luò)中可以管理的資源和設(shè)備。每個(gè)對(duì)象基本上是一個(gè)數(shù)據(jù)變量,它代表被管理的對(duì)象的一方面的信息。
最后一個(gè)方面是管理協(xié)議,也就是SNMP,SNMP的基本功能是:取得,設(shè)置和接收代理發(fā)送的意外信息。取得指的是基站發(fā)送請(qǐng)求,代理根據(jù)這個(gè)請(qǐng)求回送相應(yīng)的數(shù)據(jù),設(shè)置是基站設(shè)置管理對(duì)象(也就是代理)的值,接收代理發(fā)送的意外信息是指代理可以在基站未請(qǐng)求的狀態(tài)下向基站報(bào)告發(fā)生的意外情況。
SNMP為應(yīng)用層協(xié)議,是TCP/IP協(xié)議族的一部分。它通過(guò)用戶(hù)數(shù)據(jù)報(bào)協(xié)議(UDP)來(lái)操作。在分立的管理站中,管理者進(jìn)程對(duì)位于管理站中心的MIB的訪(fǎng)問(wèn)進(jìn)行控制,并提供網(wǎng)絡(luò)管理員接口。管理者進(jìn)程通過(guò)SNMP完成網(wǎng)絡(luò)管理。SNMP在UDP、IP及有關(guān)的特殊網(wǎng)絡(luò)協(xié)議(如,Ethernet, FDDI, X.25)之上實(shí)現(xiàn)。
SNMPv2標(biāo)準(zhǔn)的核心就是通信協(xié)議———它是一個(gè)請(qǐng)求/應(yīng)答式的協(xié)議。
這個(gè)協(xié)議提供了在manager與agent、manager與manager之間交換管理信息的直觀(guān)、基本的方法。
每條SNMPv2的報(bào)文都由一些域構(gòu)成:
如果發(fā)送方、接收方的兩個(gè)Party都采用了驗(yàn)證(authentication)機(jī)制,它就包含與驗(yàn)證有關(guān)的信息;否則它為空(取NULL)。
驗(yàn)證的過(guò)程如下:發(fā)送方和接收方的Party都分別有一個(gè)驗(yàn)證用的密鑰(secretkey)和一個(gè)驗(yàn)證用的算法。
報(bào)文發(fā)送前,發(fā)送方先將密鑰值填入圖中digest域,作為報(bào)文的前綴。然后根據(jù)驗(yàn)證算法,對(duì)報(bào)文中digest域以后(包括digest域)的報(bào)文數(shù)據(jù)進(jìn)行計(jì)算,計(jì)算出一個(gè)摘要值(digest),再用摘要值取代密鑰,填入報(bào)文中的digest域。接收方收到報(bào)文后,先將報(bào)文中的摘要值取出來(lái),暫存在一個(gè)位置,然后用發(fā)送方的密鑰放入報(bào)文中的digest。將這兩個(gè)摘要值進(jìn)行比較,如果一樣,就證明發(fā)送方確實(shí)是srcParty域中所指明的那個(gè)Party,報(bào)文是合法的;如果不一樣,接收方斷定發(fā)送方非法。驗(yàn)證機(jī)制可以防止非法用戶(hù)"冒充"某個(gè)合法Party來(lái)進(jìn)行破壞。
authInfo域中還包含兩個(gè)時(shí)間戳(timestamp),用于發(fā)送方與接收方之間的同步,以防止報(bào)文被截獲和重發(fā)。
SNMPv2的另一大改進(jìn)是可以對(duì)通信報(bào)文進(jìn)行加密,以防止監(jiān)聽(tīng)者竊取報(bào)文內(nèi)容。除了privDst域外,報(bào)文的其余部分可以被加密。發(fā)送方與接收方采用同樣的加密算法(如DES)。 通信報(bào)文可以不加任何安全保護(hù),或只進(jìn)行驗(yàn)證,也可以二者都進(jìn)行。
我們下面來(lái)實(shí)現(xiàn)SNMP的編程實(shí)現(xiàn)網(wǎng)絡(luò)數(shù)據(jù)的抓取
#include <stdio.h> #include <malloc.h> #include <snmp.h> #include <mgmtapi.h> #pragma comment(lib,"Mgmtapi.lib") #pragma comment(lib,"Snmpapi.lib") //利用 SNMP API時(shí)需要以上頭文件和庫(kù)文件 #define GET 1 //get,就理解成獲取一個(gè)信息。 #define GETNEXT 2 //getnext,就理解成獲取下一個(gè)信息。 #define WALK 3 //walk,就理解成獲取一堆信息,即所有數(shù)據(jù)庫(kù)子樹(shù)/子目錄的信息#define TIMEOUT 6000 /* milliseconds */ #define RETRIES 3//一些有用的oid char *SnmpOid[5]={".1.3.6.1.2.1.25.4.2.1.2",//進(jìn)程列表".1.3.6.1.4.1.77.1.2.25.1.1",//系統(tǒng)用戶(hù)".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"};// 列出系統(tǒng)信息 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; //這個(gè)程序使用WALK來(lái)獲取信息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";//設(shè)置查詢(xún)密碼variableBindings.list = NULL;variableBindings.len = 0;// 設(shè)置 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]);// 把字符串轉(zhuǎn)換成標(biāo)準(zhǔn)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{// 打印查詢(xún)的結(jié)果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() // 準(zhǔn)備下一次查詢(xún)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); }// 關(guān)閉 SNMP session if (!SnmpMgrClose(session))//清理退出{printf("error on SnmpMgrClose %d\n", GetLastError());return 1;}return 0;}
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/niulanshan/archive/2012/01/22/6175584.html
總結(jié)
以上是生活随笔為你收集整理的基于visual c++之windows核心编程代码分析(31)SNMP协议编程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C语言关键字 - 铁布衫:const
- 下一篇: css3之border-image