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

来源:互联网 发布:淘宝耐克正品店铺 贴吧 编辑:程序博客网 时间:2024/06/01 22:53

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

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

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

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

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

[cpp] view plain copy
print?
  1. //这个函数很重要,是snmp内部处理用的函数,用于验证oid的合法性,传递函数指针等操作  
  2. int header_hrproc(struct variable *vp,  
  3. oid * name,  
  4. size_t * length,  
  5. int exact, size_t * var_len, WriteMethod ** write_method);  
  6. //把变量和值映射到snmp能调用的内部结构中  
  7. u_char *var_general_info(struct variable *vp,  
  8. oid * name,  
  9. size_t * length,  
  10. 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 plain copy
print?
  1. struct variable2 dcs_variables[] =  
  2. {  
  3. {CPU_USAGE, ASN_OCTET_STR, RONLY, var_general_info, 1, {1}}, //1,3,6,1,4,1,9000,1,1  
  4. {MEMORY_USAGE, ASN_OCTET_STR, RONLY, var_general_info, 1, {2}},  
  5. {DISK_USAGE, ASN_OCTET_STR, RONLY, var_general_info, 1, {3}},  
  6. };  

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

[cpp] view plain copy
print?
  1. //把init_GeneralInfo这个函数在main.c中替换init_nstAgentSubagentObject();  
  2. void init_GeneralInfo(void)  
  3. {  
  4. REGISTER_MIB(“vcsky”, dcs_variables, variable2, dcs_variables_oid);  
  5. }  
  6. //实现get/set命令,在这个函数中增加各个报警点的处理,获取值  
  7. u_char *var_general_info(struct variable *vp,  
  8. oid * name,  
  9. size_t * length,  
  10. int exact, size_t * var_len, WriteMethod ** write_method)  
  11. {  
  12. DEBUGMSGTL((“vcsky”, “var_general_info entered\n”));  
  13. if (header_hrproc(vp, name, length, exact, var_len, write_method) ==  
  14. MATCH_FAILED)  
  15. return NULL;  
  16. switch (vp->magic)  
  17. {  
  18. case CPU_USAGE:  
  19. {  
  20. /* 
  21. * Note that the assumption that the answer will be an 
  22. * integer does not hold true in this case, so the length 
  23. * of the answer needs to be set explicitly. 
  24. */  
  25. int usedCpu = GetUsedCPU();  
  26. char Str_usedCpu[32];  
  27. sprintf(Str_usedCpu,”%d”,usedCpu);  
  28. *var_len = strlen(Str_usedCpu); //很重要,长度一定要对应上,否则会出错!  
  29. return (u_char *) Str_usedCpu;  
  30. }  
  31. case MEMORY_USAGE:  
  32. {  
  33. int usedMemory = GetUsedMemory();  
  34. char Str_usedMem[32];  
  35. sprintf(Str_usedMem,”%d”,usedMemory);  
  36. *var_len = strlen(Str_usedMem);  
  37. return (u_char *) Str_usedMem;  
  38. }  
  39. case DISK_USAGE:  
  40. {  
  41. int usedDisk = GetUsedDisk();  
  42. char Str_usedDisk[32];  
  43. sprintf(Str_usedDisk,”%d”,usedDisk);  
  44. *var_len = strlen(Str_usedDisk);  
  45. return (u_char *) Str_usedDisk;  
  46. }  
  47. default:  
  48. DEBUGMSGTL((“snmpd”, “unknown sub-id %d in dcs-mib\n”, vp->magic));  
  49. }  
  50. return NULL;  
  51. }  
  52. int header_hrproc(struct variable *vp, oid * name, size_t * length,int exact, size_t * var_len, WriteMethod ** write_method)  
  53. {  
  54. oid newname[MAX_OID_LEN];  
  55. int result;  
  56. memcpy((char *) newname, (char *) vp->name,  
  57. (int) vp->namelen * sizeof(oid));  
  58. //newname[vp->namelen] = 0; //不需要在已注册节点后加“0”,这里和net-snmp源码不同  
  59. result = snmp_oid_compare(name, *length, newname, vp->namelen);  
  60. if ((exact && (result != 0)) || (!exact && (result >= 0)))  
  61. return (MATCH_FAILED);  
  62. memcpy((char *) name, (char *) newname,  
  63. ((int) vp->namelen) * sizeof(oid));  
  64. *length = vp->namelen;  
  65. *write_method = 0;  
  66. *var_len = sizeof(long); /* default to ‘long’ results */  
  67. return (MATCH_SUCCEEDED);  
  68. }  


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

原创粉丝点击