時間隔得太長了,我都快忘了什么是snmp了,知識啊知識,很容易在不用的時候忘卻,也可能是自己腦袋不好使了吧?翻了翻代碼,趕緊總結下,不然真不會了……
在上篇博客中,實現了get/set一個字符串型變量,現在來實現對多個字符串變量的get/set。假設要實現獲取CPU利用率、內存占用率和磁盤占用率的的功能,建立兩個文件:alarmInfo.h和alarmInfo.c。
在alarmInfo.h中,定義一個枚舉:
[cpp] view plaincopy print?
typedef?enum?tagALARMITEM??{??CPU_USAGE?=?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?
??int?header_hrproc(struct?variable?*vp,??oid?*?name,??size_t?*?length,??int?exact,?size_t?*?var_len,?WriteMethod?**?write_method);????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}},???{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?
??void?init_GeneralInfo(void)??{??REGISTER_MIB(“vcsky”,?dcs_variables,?variable2,?dcs_variables_oid);??}????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:??{????????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));????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);???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扩展(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。