ixp425上SNMP代理开发

1SNMP代理需求

(1) 提供设备相关的信息节点,供SNMP管理端查询,可支持getget nextwalk查询命令。提供SNWANIPCPU占用率、内存使用率、进程个数、网络接口状态、网络接口当前流量、软件版本信息等节点信息。

(2) 提供对特俗事件到来时的发往SNMP管理端得TRAP告警功能。包括CPU使用率超阈值、内存超阈值、网口流量超阈值、WANIP改变、设备重启等告警功能(暂未做)。

提供对snmp v1v2版本的支持(V3版本将在后面实现)

 

2、总体设计思想

(1) 开发环境:基于开源软件net-snmp-5.4.2

(2) MIB库来源:根据功能和节点的定义自行开发。

(3) 程序实现:利用mib2c工具将MIB库转化为代理程序框架,然后基于此框架进行进一步开发。最后将开发的代理程序静态编译进net-snmp框架中,它将注册到net-snmp框架中。注册的方法是分别建立一个文件和头文件,名称明别取为bamboobamboo.h,在bamboo中存放自己开发的所有c程序和头文件(xxx.cxxx.h),然后在bamboo.h中添加module_require(xxx),并在configure时跟上:—with-mib_modules=”bamboo”来配置Makefile,使之在编译时加载bamboo文件下面的xxx文件(可以有多个xxx文件)。

 

3get信息节点的实现,以cpu占用率信息节点为例

(1) 自己编写该节点MIB库,由于eX110只有一个CPU,所以编写一个节点即可:

          hr_proc  OBJECT-TYPE

          SYNTAX      Integer32

              MAX-ACCESS  read-only

              STATUS      current

              DESCRIPTION "cpu usage"           

              ::= { my_cpu 2 }

(2) 利用mib2c工具mib2c_old-api.conf将该mib库转化为get信息节点的程序框架,然后基于该框架,添加需要实现的功能,部分代码如下:

 

/*由系统基于MIB库生成的与节点相关的信息的结构体*/

#define    HRPROC_LOAD           2

struct variable4 hrproc_variables[] = {

    {HRPROC_LOAD, ASN_INTEGER, RONLY, var_hrproc, 3, {1, 2, 768}}

};

oid             hrproc_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 3, 3 };

 

 

/*由系统生成的该节点初始化函数,在该初始化函数中注册了针对该节点的处理函数*/

void init_hr_proc(void)

{

    REGISTER_MIB("bamboo/hr_proc", hrproc_variables, variable4,

                 hrproc_variables_oid);

}

 

 

/*

 * header_hrproc:自己编写实现的函数,该函数将已注册到net-snmp的节点信息和管理端与访问的节点信息作比较。由于规定第一个CPU是用节点编号768开始,并且eX110只有一个CPU即要求该节点为1.3.6.1.2.1.25.3.3.1.2.768 ,所以将netsnmp 中提供head_generic()函数中将已注册节点最后加“o”这步去掉, 直接将注册的该节点和跟管理端欲访问的节点作对比。

 * vp     IN      - 指向已注册节点数组的指针

 * name    IN/OUT  - 指向管理端欲访问节点的指针

 * length  IN/OUT  - length of IN/OUT oid's

 * exact   IN      - TRUE if an exact match was requested

 * var_len OUT     - length of variable or 0 if function returned

 * write_method

 */

 

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.

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

}

 

 /* System specific implementation functions 注册的处理函数*/

u_char   *var_hrproc(struct variable * vp,

           oid * name,

           size_t * length,

           int exact, size_t * var_len, WriteMethod ** write_method)

{

    int             proc_idx;

    static unsigned char string[SPRINT_MAX_LEN];

       FILE *file;

 

    proc_idx =

        header_hrproc(vp, name, length, exact, var_len, write_method);

    if (proc_idx == MATCH_FAILED)

        return NULL;

 

    switch (vp->magic) {

    case HRPROC_LOAD:

              get_cpu_usage(cpu_usage);   //获取CPU使用率

        snprintf(string, sizeof(string), cpu_usage);            /* ++by Bamboo */

              long_return = atoi(string);

              if ((file = fopen("/var/run/snmp.log", "w")) == NULL)

              return;

              fprintf(file, "string is:%s , value is :%d/n", string, long_return);

              fclose(file);

             

        return (u_char *) &long_return;  //返回long_return

    default:

        DEBUGMSGTL(("host/hr_proc", "unknown sub-id %d in var_hrproc/n",

                    vp->magic));

    }

    return NULL;

}

 

/*get cpu usage information for file loadavg5 and save it in string[] */

void

get_cpu_usage(char *string)

{

       FILE *file;

       char *str;

       int i = 0;

       char tmp[16];

      

       if ((file = fopen("/proc/loadavg5", "r")) == NULL)

              return;

       fread(tmp, 1, sizeof(tmp), file);

       fclose(file);

      

       str = tmp;

       while (*str != '/n') {

              if (*str == '.') {

                     str++;

              }

              else

                     *(string + i++) = *str++;

       }

       *(string + i) = '/0';

      

       return;

}

 

3trap告警的实现,以cpu使用率超标Trap的实现为例

(1) Trap包需包含信息:acpuoverflow trap节点1.3.6.1.4.1.3902.151.11.10.3.5.1(自己定义)

       b、携带的其他信息携带变量:

SN oid 1.3.6.1.2.1.47.1.1.1.1.11,和对应的值

CPU使用率oid1.3.6.1.2.1.25.3.3.1.2,和其对应的值

阈值oid: 1.3.6.1.4.1.3902.151.11.10.3.3.9.1,和其对应的值

(2) 实现方法:参考示例notfication.c,并进行信号注册函数的修改,最终实现自己的功能。

(3) 程序实现:

/*cpu超阈值告警初始化,即注册新号处理函数,每30秒执行一次*/

Void init_cpuoverflow(void)

{

    snmp_alarm_register(30,     /* seconds */

                        SA_REPEAT,      /* repeat (every 30 seconds). */

                        send_cpuoverflow,      /* our callback */

                        NULL    /* no callback data needed */

        );

}

 

/*要调用的回调函数的实现*/

Void send_cpuoverflow(unsigned int clientreg, void *clientarg)

{

    /*

     * define the OID for the cpuoverflow we're going to send

     * NET-SNMP-EXAMPLES-MIB::netSnmpExampleHeartbeatNotification

     */

       FILE *file;

    oid             cpuoverflow_oid[] =

        { 1, 3, 6, 1, 4, 1, 3902, 151, 11, 10, 3, 5, 1};

    size_t          cpuoverflow_oid_len = OID_LENGTH(cpuoverflow_oid);

    static u_long count = 0;

       u_char sn[64];

       u_char cpu_usage_str[8];

       unsigned cpu_usage;

       u_char cpu_threshold_str[8];

      

      

       get_cpu_usage(cpu_usage_str);

       cpu_usage = atoi(cpu_usage_str);

      

       snprintf(cpu_threshold_str, sizeof(cpu_threshold_str), nvram_safe_get("cpu_threshold"));

      

       /*if cpu percentage is small than threshold, do not trap*/

       if (cpu_usage < atoi(cpu_threshold_str))     //CPU没超阈值,则返回。

              return;

      

       snprintf(sn, sizeof(sn), nvram_safe_get("dev_sn"));

      

    /*

     * In the cpuoverflow, we have to assign our cpuoverflow OID to

     * the snmpTrapOID.0 object. Here is it's definition.

     */

    oid             objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };

    size_t          objid_snmptrap_len = OID_LENGTH(objid_snmptrap);

 

    oid      devicesn_oid[]   = { 1, 3, 6, 1, 2, 1, 47, 1, 1, 1, 1, 11, 1 };

    size_t   devicesn_oid_len = OID_LENGTH(devicesn_oid);

      

    oid      hrproc_load_oid[]   = { 1, 3, 6, 1, 2, 1, 25, 3, 3, 1, 2, 768 };

    size_t   hrproc_load_oid_len = OID_LENGTH(hrproc_load_oid);

 

       oid      cpu_threshold_oid[]   = { 1, 3, 6, 1, 4, 1, 3902, 151, 11, 10, 3, 3, 9, 1, 0 };

    size_t   cpu_threshold_oid_len = OID_LENGTH(cpu_threshold_oid);

      

    /* here is where we store the variables to be sent in the trap */

netsnmp_variable_list *cpuoverflow_vars = NULL;  //所有的绑定变量都将保存在该链表中

 

    /*add in the trap definition object 依次手动加载要绑定的变量到链表中*/

    snmp_varlist_add_variable(&cpuoverflow_vars,

                              objid_snmptrap, objid_snmptrap_len,

                              ASN_OBJECT_ID,

                              (u_char *) cpuoverflow_oid,

                              cpuoverflow_oid_len * sizeof(oid));

 

    snmp_varlist_add_variable(&cpuoverflow_vars,

                               devicesn_oid, devicesn_oid_len,

                              ASN_OCTET_STR,

                              sn,

                              strlen(sn));

 

    snmp_varlist_add_variable(&cpuoverflow_vars,

                               hrproc_load_oid, hrproc_load_oid_len,

                               ASN_INTEGER,

                               (u_char *)&cpu_usage,

                                                    sizeof(cpu_usage));

                                                   

       snmp_varlist_add_variable(&cpuoverflow_vars,

                               cpu_threshold_oid, cpu_threshold_oid_len,

                               ASN_OCTET_STR,

                               cpu_threshold_str,

                                                    strlen(cpu_threshold_str));

 

    ++count;  //trap每执行一次,计数器加1

    send_v2trap(cpuoverflow_vars);    //发送snmpv2 trap

      

    /* free the created cpuoverflow variable list */

    snmp_free_varbind(cpuoverflow_vars);

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值