1. 程式人生 > >windows下使用net-snmp實現agent擴充套件(三)

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); }