學習NET-SNMP之一 ---------編譯NET-SNMP程序。

該程序摘自《深入理解NET-SNMP實戰》第8章的示例程序,編譯本書代碼的前提是已經從NET-SNMP源碼編譯出lib文件。

同事有完整的源代碼文件。

一、程序源代碼

#include<net-snmp/net-snmp-config.h>
#include<net-snmp/includes.h>
#include<string.h>
int main(int argc,char *argv)
{
	/*
	結構體netsnmp_session中記錄了SNMP會話信息;
	第一個變量需要填充準備會話的信息,
	第二個爲一指針用於記錄返回的會話信息;
	*/
	netsnmp_session session,*ss;
	netsnmp_pdu *pdu;//該結構體中記錄了遠程主機所有的信息。
	netsnmp_pdu *response;//該結構體中記錄了遠程主機返回的PDU信息。
	//記錄OID節點位置信息
	oid anOID[MAX_OID_LEN];
	size_t anOID_len;
	//變量綁定列表(爲list數據結構),也就是需要操作的數據。
	netsnmp_variable_list *vars;
	int status;
	int count=1;
	/*
	初始化SNMP庫;
	初始化互斥量、MIB解析、傳輸層、
	調試信息的初始化、解析配置文件的初始化(netsnmp_ds_register_config),各種句柄的初始化。
	定時器的初始化、讀取配置文件
	*/
	init_snmp("snmpdemoapp");
	/*
		session的初始化:包括初始化目的地,SNMP協議版本、認證機制、初始化會話結構體(爲默認值),不是及任何的MIB文件處理。
	*/
	snmp_sess_init(&session);
	//設置會話結構體:目標地址;可以爲其他有效的網絡地址
	session.peername=strdup("localhost");
	//使用SNMPv1版本
	session.version=SNMP_VERSION_1;
	//設置共同體
	session.community="public";
	session.community_len=strlen(session.community);
	/*
		開啓和綁定底層的傳輸層(TCP/UDP),建立會話,返回會話句柄,每個會話對應一個socket
	*/
	ss=snmp_open(&session);
	if(!ss){
		snmp_sess_perror("snmpdemoapp",&session);
		exit(1);
	}
	/* 會話創建完成後,接下來是創建指定類型(命令類型)的PDU,作爲本次會話的實例執行操作的準備,
	這就包括綁定準備通信的OID
	*/
	pdu=snmp_pdu_create(SNMP_MSG_GET);
	anOID_len=MAX_OID_LEN;//該宏值爲128,正如RFC建議所述“節點下子OID數量不超過128個”。
	/*
		此處read_objid / snmp_parse_oid的作用是檢查OID的正確性,
		兵賦予anOID正確的值,也就是最終請求的OID
	*/
	//read_objid("system.sysDescr.0", anOID, &anOID_len);
	//if ( !snmp_parse_oid(".1.3.6.1.2.1.1.1.0",anOID, &anO_len)){
	if(!snmp_parse_oid("system.sysDescr.0",anOID,&anOID_len)){
		snmp_perror(".1.3.6.1.2.1.1.1.0");
		exit(1);
	}
	/*
		按照協議PDU格式的要求,將該OID加入到PDU報文中,
		同時賦予一個NULL值作爲變量的綁定;
		當然對於SET命令的PDU來說就是賦予待設置的值。
	*/
	snmp_add_null_var(pdu,anOID,anOID_len);
	//同步發送報文。
	status = snmp_synch_response(ss,pdu,&response);
	/*
		下面的代碼是處理返回的PDU報文,需要根據返回的信息作出合理的後續處理:
		報文的返回和執行狀態都正確,讀取返回的值。
	*/
	if( status == STAT_SUCCESS && response->errstat ==SNMP_ERR_NOERROR){
		//將讀取的返回值打印到標準輸出(stdout)出來。
		for(vars=response->variables;vars;vars=vars->next_variable)
			print_variable( vars->name, vars->name_length,vars );//處理(打印)接收到的信息;
		for(vars=response->variables;vars;vars=vars->next_variable)
		{
			if(vars->type==ASN_OCTET_STR){
				char *sp = (char *)malloc(1 + vars->val_len);
				memcpy(sp,vars->val.string,vars->val_len);
				sp[vars->val_len]='\0';
				printf("value #%d is a string :%s\n", count++,sp);
				free(sp);
			}else{
				//如果返回值有錯誤:打印其錯誤信息
				printf("value #%d is NOT a string! Ack\n",count++);
			}
		}
	}else{
		if(status == STAT_SUCCESS)
			fprintf(stderr,"Error in packet\nReason: %s\n",snmp_errstring(response->errstat));
		else if(status == STAT_TIMEOUT)
			fprintf(stderr,"Timeout: No response from %s. \n",session.peername);
		else
			snmp_sess_perror("snmpdemoapp",ss);
	}
	//釋放分配的空間:關閉會話,關閉socket,釋放資源。
	if(response)
		snmp_free_pdu(response);
	snmp_close(ss);
	return(0);
}


二、程序編譯的環境

1.IDE: VisualStudio2010

2. SNMP庫版本:net-snmp 5.7.3

3.新建Win32控制檯空項目(選擇預先編譯頭文件)

4.新建CPP源文件並拷貝以上源文件。

三、編譯過程產生的問題。

問題一:找不到頭文件和netsnmp_session。

解決方法:

1.添加頭文件目錄(C/C++  |  常規  |   附加包含目錄

net-snmp-5.7.3 \ win32

net-snmp-5.7.3 \ include

2.修改原本包含的頭文件(因爲對應的版本文件名改變了)

將#include <net-snmp/ includes.h >修改爲 #include< net-snmp / net-snmp-includes.h >

問題二:error C2440: “=”: 無法從“const char [7]”轉換爲“u_char *”

解決方法:

session.community="public";

session.community_len=strlen(session.community);

修改爲:

session.community=(u_char *)"public";

session.community_len=strlen( (char*) session.community);

問題三:fatal error LNK1120: 13 個無法解析的外部命令

fatal error LNK1120: 26 個無法解析的外部命令

解決方法:

1.添加庫目錄(鏈接器 |   常規  |   附加庫目錄

目錄選擇生成的鏈接庫所在的目錄。

2.添加鏈接庫文件(以下使用宏處理命令方式添加)

#pragma comment (lib,"netsnmp.lib")
#pragma comment (lib, "ws2_32.lib")

第一個庫針對13個無法解析的命令。

第二個庫針對26個無法解析的命令。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章