您好,欢迎访问三七文档
#includenet-snmp/net-snmp-config.h#includenet-snmp/net-snmp-includes.h#includenet-snmp/agent/net-snmp-agent-includes.h#ifHAVE_STDLIB_H#includestdlib.h#endif#ifTIME_WITH_SYS_TIME#ifdefWIN32#includesys/timeb.h#else#includesys/time.h#endif#includetime.h#else#ifHAVE_SYS_TIME_H#includesys/time.h#else#includetime.h#endif#endif#includeutil_funcs.h包含自己的头文件#includeDisplay_time.h#defineEXAMPLE_STR_LEN300#defineEXAMPLE_STR_DEFAULTlifetheuniverseandeverythingintexample_int=42;charexample_str[EXAMPLE_STR_LEN];voidexample_parse_config_exampleint(constchar*token,char*cptr);voidexample_parse_config_examplestr(constchar*token,char*cptr);voidexample_free_config_exampleint(void);voidexample_free_config_examplestr(void);这个数组的类型是structvariableN,其中N是这个数组中OID号的最长的数,即:结构体最后一个成员(这个成员是个数组)定义了MIBTreeOID的底层数字。N定义了MIBTreeOID的底层的层数(也就是这个数组的长度)。所有有效的N数字都定义在了agent/var_struct.h文件中。structvariableN类型成员的说明:1):FoxmailINT:这个magicnumber是在自己的头文件Display_time.h中宏定义,这个参数被用来传递给CallBack例程,用来决定那个object被查询。2):ASN_INTEGER:这个参数说明了object的类型,所有有效的类型在snmp_impl.h文件中列表说明。3):RONLY:这个参数说明了object是否能够被set。4):var_foxmail:当有object被查询时,这个CallBack例程被调用。一般的情况下,同一个文件中的所有的object使用相同的allBack例程。5):1:MIBTreeOID的底层数字的层数。(这个数字决定了structvariableN中的N)6):{1}:MIBTreeOID的底层数字。structvariable2example_variables[]={{EXAMPLESTRING,ASN_OCTET_STR,RONLY,var_example,1,{1}},{EXAMPLEINTEGER,ASN_INTEGER,RWRITE,var_example,2,{2,1}},{EXAMPLEOBJECTID,ASN_OBJECT_ID,RONLY,var_example,2,{2,2}},{EXAMPLETIMETICKS,ASN_TIMETICKS,RONLY,var_example,1,{3}},{EXAMPLEIPADDRESS,ASN_IPADDRESS,RONLY,var_example,1,{4}},{EXAMPLECOUNTER,ASN_COUNTER,RONLY,var_example,1,{5}},{EXAMPLEGAUGE,ASN_GAUGE,RONLY,var_example,1,{6}},{EXAMPLETRIGGERTRAP,ASN_INTEGER,RWRITE,var_example,1,{7}},{EXAMPLETRIGGERTRAP2,ASN_INTEGER,RWRITE,var_example,1,{8}}};下面这个数组定义了MIBTreeOID的顶层数字。oidexample_variables_oid[]={1,3,6,1,4,1,2021,254};这个例程在Agent程序开始的时候被调用,用来初始化可能被查询的Object。voidinit_example(void){注册我们自己的MIBTree,以便Agent查询的时候能够处理。参数:1)descr:描述这个MIBTree2)var:变量结构体,类型structvariableN。3)vartype:类型structvariableN4)theoid:MIBTree的顶层数字REGISTER_MIB(example,example_variables,variable2,example_variables_oid);把example_str变量设上默认字符串。example_int已经在上面初始化了。strncpy(example_str,EXAMPLE_STR_DEFAULT,EXAMPLE_STR_LEN);*Registerconfighandlersforthetwoobjectsthatcanbeset*viaconfigurationfiledirectivesnmpd_register_config_handler(exampleint,example_parse_config_exampleint,example_free_config_exampleint,exampleintvalue);snmpd_register_config_handler(examplestr,example_parse_config_examplestr,example_free_config_examplestr,examplestrvalue);snmpd_register_config_handler(examplestring,example_parse_config_examplestr,example_free_config_examplestr,examplestringvalue);我们经常需要读取内核中的数据,我们需要在这里进行一些必要的初始化。以加快我们读取这些内核信息的速度,快速反应查询请求。}配置文件处理函数voidexample_parse_config_exampleint(constchar*token,char*cptr){example_int=atoi(cptr);}voidexample_parse_config_examplestr(constchar*token,char*cptr){必须确保字符串长度小于分配的空间。if(strlen(cptr)EXAMPLE_STR_LEN)strcpy(example_str,cptr);else{如果需要的话,截断这个字符串。strncpy(example_str,cptr,EXAMPLE_STR_LEN-4);example_str[EXAMPLE_STR_LEN-4]=0;strcat(example_str,...);example_str[EXAMPLE_STR_LEN-1]=0;}}当关闭Agent时需要的清除工作。voidexample_free_config_exampleint(void){}voidexample_free_config_examplestr(void){}当有请求访问这个MIBTree的object时,就会调用这个处理函数。参数:1)vp被请求访问的object的example_variables的入口地址2)name被请求访问的object的OID3)lengthOID的长度4)exact指示这个request是“exact”(GET/SET)请求,还是“inexact”(GETNEXT/GETBULK)请求四个参数被用来返回信息:1)name被请求访问的object的OID2)lengthOID的长度3)var_len返回应答的长度4)write_method被请求访问的object的SET函数的指针u_char*var_example(structvariable*vp,oid*name,size_t*length,intexact,size_t*var_len,WriteMethod**write_method){从这个函数返回的值必须是一个staticdata的指针,这样才能够从函数外来访问。staticcharstring[EXAMPLE_STR_LEN];staticoidoid_ret[8];staticlonglong_ret;在进行应答请求之前,需要检查这个请求objectOID是否是一个有效的OID。header_generic()函数能够用来检查scalarobjects。header_simple_table()函数能够用来检查simpletable。这些函数也当检查正确时,设置默认的返回值。*Thenameandlengtharesetsuitablyforthecurrentobject,*var_lenassumesthattheresultisanintegerofsomeform,*andwrite_methodassumesthattheobjectcannotbeset.DEBUGMSGTL((example,var_exampleentered\n));if(header_generic(vp,name,length,exact,var_len,write_method)==MATCH_FAILED)returnNULL;我们使用structvariableN结构体中的magicnumber来决定那个object被请求。switch(vp-magic){caseEXAMPLESTRING:sprintf(string,example_str);在上面时假设返回值是integer,但是并不是,所以需要重新设置var_len。*var_len=strlen(string);return(u_char*)string;caseEXAMPLEINTEGER:这种情况,上面的假设的长度是正确的,但是这个object是可以写的,所以需要设置write_method。long_ret=example_int;*write_method=write_exampleint;return(u_char*)&long_ret;caseEXAMPLEOBJECTID:oid_ret[0]=1;oid_ret[1]=3;oid_ret[2]=6;oid_ret[3]=1;oid_ret[4]=4;oid_ret[5]=oid_ret[6]=oid_ret[7]=42;这种情况,上面的假设的长度是错误的。*var_len=8*sizeof(oid);return(u_char*)oid_ret;caseEXAMPLETIMETICKS:这种情况,上面的假设的长度是正确的,直接返回。long_ret=363136200;return(u_char*)&long_ret;caseEXAMPLEIPADDRESS:long_ret=ntohl(INADDR_LOOPBACK);return(u_char*)&long_ret;caseEXAMPLECOUNTER:long_ret=42;return(u_char*)&long_ret;caseEXAMPLEGAUGE:long_ret=42;return(u_char*)&long_ret;caseEXAMPLETRIGGERTRAP:这个object是只能够写的“write-only”
本文标题:snmp源码分析
链接地址:https://www.777doc.com/doc-1346982 .html