欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

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

发布时间:2025/3/15 33 豆豆
生活随笔 收集整理的这篇文章主要介绍了 windows下使用net-snmp实现agent扩展(三) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

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

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

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

[cpp] view plaincopy print?
  • typedef enum tagALARMITEM  
  • {  
  • CPU_USAGE = 1, //在这里需要以1开始,和后面用到的结构结合  
  • MEMORY_USAGE,  
  • DISK_USAGE,  
  • CLIENT_NUM  
  • }ALARMITEM;  
  • 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中,在前面先声明两个函数:

    [cpp] view plaincopy print?
  • //这个函数很重要,是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);  
  • //这个函数很重要,是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库中的各点与程序中要获取的各项:

    [cpp] view plaincopy print?
  • 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}},  
  • };  
  • 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.

    [cpp] view plaincopy print?
  • //把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);  
  • }  
  • //把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); }

    核心的代码就是上面的这些了。通过这几个函数,能够实现对多个字符串变量的get和set,set命令实现的时候,要注意制作MIB库时,把节点设置为可读写权限。

    总结

    以上是生活随笔为你收集整理的windows下使用net-snmp实现agent扩展(三)的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。