SNMP 的table 变量测试

  1. 设计MIB文件mytableTest-MIB.txt:

    myTestTable DEFINITIONS ::= BEGIN

    IMPORTS
        OBJECT-GROUP, MODULE-COMPLIANCE, NOTIFICATION-GROUP
            FROM SNMPv2-CONF
        enterprises, Integer32, Unsigned32, OBJECT-TYPE, MODULE-IDENTITY,
        NOTIFICATION-TYPE
            FROM SNMPv2-SMI
        DisplayString
            FROM SNMPv2-TC
        dell-OID-three
        FROM dellRX-MIB;

    -- 1.3.6.1.4.1.10000
        myTable-MIB MODULE-IDENTITY
        LAST-UPDATED "201412151450Z"
        ORGANIZATION
            "Actiontec Shenzhen team Surpas"
        CONTACT-INFO
            "Surpas HC(editor)
            Email: "
        DESCRIPTION
            "For Dell project MIB pdmGeneral."
        ::= { enterprises 10000 }

    --testID OBJECT IDENTIFIER ::= { pdmGeneral 2 }

    --1.3.6.1.4.1.10000.1
    testTableRoot OBJECT IDENTIFIER ::= { myTable-MIB 1 }

    --1.3.6.1.4.1.10000.1.1
    tcTable OBJECT-TYPE
        SYNTAX SEQUENCE OF TcEntry
        MAX-ACCESS not-accessible
        STATUS current
        ::= { testTableRoot 1 }

    --1.3.6.1.4.1.10000.1.1.1
    tcEntry OBJECT-TYPE
        SYNTAX     TcEntry
        MAX-ACCESS not-accessible
        STATUS     current
        DESCRIPTION
           "Information about a particular current UDP endpoint."
        INDEX   { tcIndex }--很重要,snmpwalk时的节点号。
        ::= { tcTable 1 }

    TcEntry ::= SEQUENCE {
        tcIndex        Interger32
        tcString    DisplayString (SIZE (0..100)),
        tcinteger    Integer32
        }

    --1.3.6.1.4.1.10000.1.1.1.1
    tcIndex OBJECT-TYPE
        SYNTAX     Integer32 
        MAX-ACCESS not-accessible
        STATUS     current
        DESCRIPTION
               "The address type of accepted."
        DEFVAL { "xxx table Index xxx!" }
        ::= { tcEntry 1 }

    --1.3.6.1.4.1.10000.1.1.1.2
    tcString OBJECT-TYPE
        SYNTAX     DisplayString (SIZE (0..100))
        MAX-ACCESS read-write
        STATUS     current
        DESCRIPTION
               "The address type of accepted."
        DEFVAL { "xxx table row string1 xxx!" }
        ::= { tcEntry 2 }

    --1.3.6.1.4.1.10000.1.1.1.3
    tcInteger OBJECT-TYPE
        SYNTAX     Integer32
        MAX-ACCESS read-write
        STATUS     current
        DESCRIPTION
               "The address type of accepted."
        DEFVAL { 6543 }
        ::= { tcEntry 3 }
    END

  2. 将MIB文件mytableTest-MIB.txt放到MIB search path: /home/actiontec/.snmp/mibs:/usr/local/share/snmp/mibs并且在目录/usr/local/etc/snmp:/usr/local/share/snmp:/usr/local/lib/snmp:/home/actiontec/.snmp:/var/net-snmp添加snmp.conf文件,添加内容:

    #mibs +/home/actiontec/.snmp/mibs/xxx.txt
    mibs +/home/actiontec/.snmp/mibs/mytableTest-MIB.txt

  3. 使用snmptranslate -Tp -IR myTestTable::testTableRoot(前提mytableTest-MIB.txt放到MIB search path: /home/actiontec/.snmp/mibs:/usr/local/share/snmp/mibs下)或者用snmptranslate -Tp -IR testTableRoot(mytableTest-MIB.txt放到MIB search path: /home/actiontec/.snmp/mibs:/usr/local/share/snmp/mibs并且在目录/usr/local/etc/snmp:/usr/local/share/snmp:/usr/local/lib/snmp:/home/actiontec/.snmp:/var/net-snmp添加snmp.conf文件添加内容mibs +/home/actiontec/.snmp/mibs/mytableTest-MIB.txt)查看有无错误。

    +--testTableRoot(1)
       |
       +--tcTable(1)
          |
          +--tcEntry(1)
             |  Index: tcIndex
             |
             +-- ---- Integer32 tcIndex(1)
             +-- -RW- String    tcString(2)
             |        Textual Convention: DisplayString
             |        Size: 0..100
             +-- -RW- Integer32 tcInteger(3)

  4. 生成代码mib2c -c mib2c.iterate.conf myTestTable::testTableRoot或者mib2c -c mib2c.iterate.conf testTableRoot

    选择1时提供一个缓存来提取数据,一定时间后将更新一次数据,2每次更新

  5. 编译代码net-snmp-config --compile-subagent Test testTableRoot.c,设计是否有误

  6. testTableRoot.c和头文件放到agent/mibgroup/newdir中。建立文件agent/mibgroup/newdir.h添加内容:config_require(newdir/testTableRoot);用于./configure时用。

  7. testTableRoot.c代码

    /*
     * Note: this file originally auto-generated by mib2c using
     *  $
     */

    #include
    #include
    #include
    #include "testTableRoot.h"
    #define MY_ERROR_FILE "/home/actiontec/install-dir/net-snmp/errdir/errtablefile.txt"

    /** Initializes the testTableRoot module */
    void
    init_testTableRoot(void)
    {
      /* here we initialize all the tables we're planning on supporting */
        initialize_table_tcTable();
    }

    //  # Determine the first/last column names

    /** Initialize the tcTable table by defining its contents and how it's structured */
    void
    initialize_table_tcTable(void)
    {
        const oid tcTable_oid[] = {1,3,6,1,4,1,10000,1,1};
        const size_t tcTable_oid_len   = OID_LENGTH(tcTable_oid);
        netsnmp_handler_registration    *reg;
        netsnmp_iterator_info           *iinfo;
        netsnmp_table_registration_info *table_info;

        DEBUGMSGTL(("testTableRoot:init", "initializing table tcTable\n"));

        reg = netsnmp_create_handler_registration(
                  "tcTable",     tcTable_handler,
                  tcTable_oid, tcTable_oid_len,
                  HANDLER_CAN_RWRITE
                  );

        table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
        netsnmp_table_helper_add_indexes(table_info,
                               ASN_INTEGER,  /* index: tcIndex */
                               0);
        table_info->min_column = COLUMN_TCSTRING;
        table_info->max_column = COLUMN_TCINTEGER;
        
        iinfo = SNMP_MALLOC_TYPEDEF( netsnmp_iterator_info );
        iinfo->get_first_data_point = tcTable_get_first_data_point;
        iinfo->get_next_data_point  = tcTable_get_next_data_point;
        iinfo->table_reginfo        = table_info;
        
        netsnmp_register_table_iterator( reg, iinfo );

        tcTable_createEntry(1, "xiaolongxxxwo", sizeof("xiaolongxxxwo"), 556);

        //这句话很重要​,必须创建一个表对象才可以访问他
        /* Initialise the contents of the table here */
    }

        /* Typical data structure for a row entry */
    struct tcTable_entry {
        /* Index values */
        long tcIndex;

        /* Column values */
        char tcString[64];
        size_t tcString_len;
        char old_tcString[64];
        size_t old_tcString_len;
        long tcInteger;
        long old_tcInteger;

        /* Illustrate using a simple linked list */
        int   valid;
        struct tcTable_entry *next;
    };

    struct tcTable_entry  *tcTable_head;

    /* create a new row in the (unsorted) table */
    struct tcTable_entry *
    tcTable_createEntry(
                     long  tcIndex,
                     char* tcString,
                     size_t tcString_len,
                     long  tcInteger
                    ) {
        struct tcTable_entry *entry;
        struct tcTable_entry *entryNext;    
        entry = SNMP_MALLOC_TYPEDEF(struct tcTable_entry);
        entryNext = SNMP_MALLOC_TYPEDEF(struct tcTable_entry);
        if (!entry)
            return NULL;
    //胡乱添加的,这里设计了1,2节点,一会看效果就知道作用了
        entry->tcIndex = tcIndex;
        memcpy(entry->tcString, tcString, tcString_len);
        entry->tcString_len = tcString_len;
        entry->tcInteger = tcInteger;

        entryNext->tcIndex = 2;
        memcpy(entryNext->tcString, "abcdefg", sizeof("abcdefg"));
        entryNext->tcString_len = sizeof("abcdefg");
        entryNext->tcInteger = 321;    
        
        entry->next = entryNext;
        entryNext->next = tcTable_head;
        tcTable_head = entry;
        return entry;
    }

    /* remove a row from the table */
    void
    tcTable_removeEntry( struct tcTable_entry *entry ) {
        struct tcTable_entry *ptr, *prev;

        if (!entry)
            return;    /* Nothing to remove */

        for ( ptr  = tcTable_head, prev = NULL;
              ptr != NULL;
              prev = ptr, ptr = ptr->next ) {
            if ( ptr == entry )
                break;
        }
        if ( !ptr )
            return;    /* Can't find it */

        if ( prev == NULL )
            tcTable_head = ptr->next;
        else
            prev->next = ptr->next;

        SNMP_FREE( entry );   /* XXX - release any other internal resources */
    }


    /* Example iterator hook routines - using 'get_next' to do most of the work */
    netsnmp_variable_list *
    tcTable_get_first_data_point(void **my_loop_context,
                              void **my_data_context,
                              netsnmp_variable_list *put_index_data,
                              netsnmp_iterator_info *mydata)
    {
        *my_loop_context = tcTable_head;
        return tcTable_get_next_data_point(my_loop_context, my_data_context,
                                        put_index_data,  mydata );
    }

    netsnmp_variable_list *
    tcTable_get_next_data_point(void **my_loop_context,
                              void **my_data_context,
                              netsnmp_variable_list *put_index_data,
                              netsnmp_iterator_info *mydata)
    {
        struct tcTable_entry *entry = (struct tcTable_entry *)*my_loop_context;
        netsnmp_variable_list *idx = put_index_data;

        if ( entry ) {
            snmp_set_var_typed_integer( idx, ASN_INTEGER, entry->tcIndex );
            idx = idx->next_variable;
            *my_data_context = (void *)entry;
            *my_loop_context = (void *)entry->next;
            return put_index_data;
        } else {
            return NULL;
        }
    }


    /** handles requests for the tcTable table */
    int
    tcTable_handler(
        netsnmp_mib_handler               *handler,
        netsnmp_handler_registration      *reginfo,
        netsnmp_agent_request_info        *reqinfo,
        netsnmp_request_info              *requests) {
        int ret;
        netsnmp_request_info       *request;
        netsnmp_table_request_info *table_info;
        struct tcTable_entry          *table_entry;
        FILE *fd;
        DEBUGMSGTL(("myTable_MIB:handler", "Processing request (%d)\n", reqinfo->mode));
        fd = fopen(MY_ERROR_FILE, "ar");
        if(fd>0)
        {
            fprintf(fd, "surpas:%s,%d,mode=%d!\n", __FILE__, __LINE__, reqinfo->mode);
            fclose(fd);
        }

        switch (reqinfo->mode) {
            /*
             * Read-support (also covers GetNext requests)
             */
        case MODE_GET:
            for (request=requests; request; request=request->next) {
                table_entry = (struct tcTable_entry *)
                                  netsnmp_extract_iterator_context(request);
                table_info  =     netsnmp_extract_table_info(      request);
        
                switch (table_info->colnum) {
                case COLUMN_TCSTRING:
                    if ( !table_entry ) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_NOSUCHINSTANCE);
                        continue;
                    }
                    snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR,
                                              table_entry->tcString,
                                              table_entry->tcString_len);
                    break;
                case COLUMN_TCINTEGER:
                    if ( !table_entry ) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_NOSUCHINSTANCE);
                        continue;
                    }
                    snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                                table_entry->tcInteger);
                    break;
                default:
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHOBJECT);
                    break;
                }
            }
            break;

            /*
             * Write-support
             */
        case MODE_SET_RESERVE1:
            for (request=requests; request; request=request->next) {
                table_entry = (struct tcTable_entry *)
                                  netsnmp_extract_iterator_context(request);
                table_info  =     netsnmp_extract_table_info(      request);
        
                switch (table_info->colnum) {
                case COLUMN_TCSTRING:
                /* or possibly 'netsnmp_check_vb_type_and_size' */
                    ret = netsnmp_check_vb_type_and_max_size(
                              request->requestvb, ASN_OCTET_STR, sizeof(table_entry->tcString));
                    if ( ret != SNMP_ERR_NOERROR ) {
                        netsnmp_set_request_error( reqinfo, request, ret );
                        return SNMP_ERR_NOERROR;
                    }
                    break;
                case COLUMN_TCINTEGER:
                    /* or possibly 'netsnmp_check_vb_int_range' */
                    ret = netsnmp_check_vb_int( request->requestvb );
                    if ( ret != SNMP_ERR_NOERROR ) {
                        netsnmp_set_request_error( reqinfo, request, ret );
                        return SNMP_ERR_NOERROR;
                    }
                    break;
                default:
                    netsnmp_set_request_error( reqinfo, request,
                                               SNMP_ERR_NOTWRITABLE );
                    return SNMP_ERR_NOERROR;
                }
            }
            break;

        case MODE_SET_RESERVE2:
            break;

        case MODE_SET_FREE:
            break;

        case MODE_SET_ACTION:
            for (request=requests; request; request=request->next) {
                table_entry = (struct tcTable_entry *)
                                  netsnmp_extract_iterator_context(request);
                table_info  =     netsnmp_extract_table_info(      request);
        //here change our own configure
                switch (table_info->colnum) {
                case COLUMN_TCSTRING:
                    memcpy( table_entry->old_tcString,
                            table_entry->tcString,
                            sizeof(table_entry->tcString));
                    table_entry->old_tcString_len =
                            table_entry->tcString_len;
                    memset( table_entry->tcString, 0,
                            sizeof(table_entry->tcString));
                    memcpy( table_entry->tcString,
                            request->requestvb->val.string,
                            request->requestvb->val_len);
                    table_entry->tcString_len =
                            request->requestvb->val_len;
                    break;
                case COLUMN_TCINTEGER:
                    table_entry->old_tcInteger = table_entry->tcInteger;
                    table_entry->tcInteger     = *request->requestvb->val.integer;
                    break;
                }
            }
            break;

        case MODE_SET_UNDO:
            for (request=requests; request; request=request->next) {
                table_entry = (struct tcTable_entry *)
                                  netsnmp_extract_iterator_context(request);
                table_info  =     netsnmp_extract_table_info(      request);
        
                switch (table_info->colnum) {
                case COLUMN_TCSTRING:
                    memcpy( table_entry->tcString,
                            table_entry->old_tcString,
                            sizeof(table_entry->tcString));
                    memset( table_entry->old_tcString, 0,
                            sizeof(table_entry->tcString));
                    table_entry->tcString_len =
                            table_entry->old_tcString_len;
                    break;
                case COLUMN_TCINTEGER:
                    table_entry->tcInteger     = table_entry->old_tcInteger;
                    table_entry->old_tcInteger = 0;
                    break;
                }
            }
            break;

        case MODE_SET_COMMIT:
            break;
        }
        return SNMP_ERR_NOERROR;
    }

  8. 我们先看下7的效果,在create里面可以添加列表的:

    myTestTable::tcString.1 = STRING: xiaolongxxxwo.
    myTestTable::tcString.2 = STRING: abcdefg.
    myTestTable::tcInteger.1 = INTEGER: 556
    myTestTable::tcInteger.2 = INTEGER: 321
    SNMPv2-SMI::enterprises.10000.1.1.1.2.1 = Hex-STRING: 78 69 61 6F 6C 6F 6E 67 78 78 78 77 6F 00 
    SNMPv2-SMI::enterprises.10000.1.1.1.2.2 = Hex-STRING: 61 62 63 64 65 66 67 00 
    SNMPv2-SMI::enterprises.10000.1.1.1.3.1 = INTEGER: 556
    SNMPv2-SMI::enterprises.10000.1.1.1.3.2 = INTEGER: 321

  9. 完成了,先进行编译:./configure --with-default-snmp-version="3"  --with-sys-contact="@@no.where"  --with-sys-location="Unknown" --with-logfile="/var/log/snmpd.log"  --with-persistent-directory="/var/net-snmp" --with-mib-modules="newdir" --enable-mini-agent(mini版)

    make

    sudo make install

  10. 可以使用了

你可能感兴趣的:(snmp,c/c++,ubuntu,centos)