VC天下 » C/C++Windows

windows下使用net-snmp实现agent扩展(三)

时间隔得太长了,我都快忘了什么是snmp了,知识啊知识,很容易在不用的时候忘却,也可能是自己脑袋不好使了吧?翻了翻代码,赶紧总结下,不然真不会了……

在上篇博客中,实现了get/set一个字符串型变量,现在来实现对多个字符串变量的get/set。假设要实现获取CPU利用率、内存占用率和磁盘占用率的的功能,建立两个文件:alarmInfo.h和alarmInfo.c。

在alarmInfo.h中,定义一个枚举:

typedef enum tagALARMITEM
{
CPU_USAGE = 1, //在这里需要以1开始,和后面用到的结构结合
MEMORY_USAGE,
DISK_USAGE,
CLIENT_NUM
}ALARMITEM;
声明一个被main中调用的函数:void init_GeneralInfo(void); //get/set命令实现
声明获取三个值的函数:
int GetUsedCPU(); //获得cpu利用率
int GetUsedMemory(); //获得内存利用率
int GetUsedDisk(); //获得C盘可用空间

alarmInfo.c中,在前面先声明两个函数:

//这个函数很重要,是snmp内部处理用的函数,用于验证oid的合法性,传递函数指针等操作
int header_hrproc(struct variable *vp,
oid * name,
size_t * length,
int exact, size_t * var_len, WriteMethod ** write_method);
//把变量和值映射到snmp能调用的内部结构中
u_char *var_general_info(struct variable *vp,
oid * name,
size_t * length,
int exact, size_t * var_len, WriteMethod ** write_method);

一个MIB库中的企业根节点:static oid dcs_variables_oid[] = {1,3,6,1,4,1,9000,1 }; //企业根节点

一个variable2类型的结构体,用于对应MIB库中的各点与程序中要获取的各项:

struct variable2 dcs_variables[] =
{
{CPU_USAGE, ASN_OCTET_STR, RONLY, var_general_info, 1, {1}}, //1,3,6,1,4,1,9000,1,1
{MEMORY_USAGE, ASN_OCTET_STR, RONLY, var_general_info, 1, {2}},
{DISK_USAGE, ASN_OCTET_STR, RONLY, var_general_info, 1, {3}},
};

注意这里的第一项要以1开始,也就是CPU_USAGE不能为0.

//把init_GeneralInfo这个函数在main.c中替换init_nstAgentSubagentObject();
void init_GeneralInfo(void)
{
REGISTER_MIB(“vcsky”, dcs_variables, variable2, dcs_variables_oid);
}
//实现get/set命令,在这个函数中增加各个报警点的处理,获取值
u_char *var_general_info(struct variable *vp,
oid * name,
size_t * length,
int exact, size_t * var_len, WriteMethod ** write_method)
{
DEBUGMSGTL((“vcsky”, “var_general_info entered\n”));
if (header_hrproc(vp, name, length, exact, var_len, write_method) ==
MATCH_FAILED)
return NULL;
switch (vp->magic)
{
case CPU_USAGE:
{
/*
* Note that the assumption that the answer will be an
* integer does not hold true in this case, so the length
* of the answer needs to be set explicitly.
*/
int usedCpu = GetUsedCPU();
char Str_usedCpu[32];
sprintf(Str_usedCpu,”%d”,usedCpu);
*var_len = strlen(Str_usedCpu); //很重要,长度一定要对应上,否则会出错!
return (u_char *) Str_usedCpu;
}
case MEMORY_USAGE:
{
int usedMemory = GetUsedMemory();
char Str_usedMem[32];
sprintf(Str_usedMem,”%d”,usedMemory);
*var_len = strlen(Str_usedMem);
return (u_char *) Str_usedMem;
}
case DISK_USAGE:
{
int usedDisk = GetUsedDisk();
char Str_usedDisk[32];
sprintf(Str_usedDisk,”%d”,usedDisk);
*var_len = strlen(Str_usedDisk);
return (u_char *) Str_usedDisk;
}
default:
DEBUGMSGTL((“snmpd”, “unknown sub-id %d in dcs-mib\n”, vp->magic));
}
return NULL;
}
int header_hrproc(struct variable *vp, oid * name, size_t * length,int exact, size_t * var_len, WriteMethod ** write_method)
{
oid newname[MAX_OID_LEN];
int result;
memcpy((char *) newname, (char *) vp->name,
(int) vp->namelen * sizeof(oid));
//newname[vp->namelen] = 0; //不需要在已注册节点后加“0”,这里和net-snmp源码不同
result = snmp_oid_compare(name, *length, newname, vp->namelen);
if ((exact && (result != 0)) || (!exact && (result >= 0)))
return (MATCH_FAILED);
memcpy((char *) name, (char *) newname,
((int) vp->namelen) * sizeof(oid));
*length = vp->namelen;
*write_method = 0;
*var_len = sizeof(long); /* default to ‘long’ results */
return (MATCH_SUCCEEDED);
}

评论关闭