Hello coders,

It's nice that I implemented RowStatus Table by using mfd.conf, 
on NET-SNMP v5.3.0.1 (v5.3.1 will ok).

Scenario:
A SNMP client will tell the sub-agent server_ip, server_port, game_ip and 
game_port, 
so the sub-agent  could notify the correct server to deny that game's TCP 
connection.

Who may read my info?:
Who know how to handl SNMP GET in a sub-agent, but do not know how to handle 
SNMP SET/ RowStatus.
I should thank [EMAIL PROTECTED] I completed this example with your great helps.

Limitations:
The sub-agent can run.
Client's SET requests will be processed correctly.
snmpset ... Stat i 6
snmpset ... Stat i 5
snmpset ... SrvIp a <IP 1>
snmpset ... SrvPort i <port 1>
snmpset ... GsIp a <IP 2>
snmpset ... GsPort i <port 2>
snmpset ... Stat i 1
So the limitation is no any other things left. 
I think it's enough as an example.

1. First of all you may find the patch (or you need to modify mfd-interface.m2i 
which in snmp/mib2c-data)
    to solve "undefined reference to `_mfd_${context}_rowreq_from_index' ".
    (thanks rstory's help, see my previous posts).
2. Example (private MIBs, table-${context}.m2d, ${context}_data_access.c and 
${context}_data_set.c that you may care about) posts below.

MIBs, take a look at MAX-ACCESS/STATUS/INDEX.
-----------------------
--
-- CCliCtr implementations
--
CCliCtrEntry ::= SEQUENCE{
        Idx4CliCtr      INTEGER,
        Stat4CliCtr     RowStatus,
        SrvIp4CliCtr    IpAddress,
        SrvPort4CliCtr  INTEGER,
        GsIp4CliCtr     IpAddress,
        GsPort4CliCtr   INTEGER
        }

CCliCtrTable OBJECT-TYPE 
        SYNTAX          SEQUENCE OF CCliCtrEntry
        MAX-ACCESS      not-accessible
        STATUS          mandatory
        DESCRIPTION
                "xxx"
        ::= {cliCtr 1}

CCliCtrRow OBJECT-TYPE
        SYNTAX          CCliCtrEntry
        MAX-ACCESS      not-accessible
        STATUS          mandatory
        INDEX{Idx4CliCtr}
        ::= {CCliCtrTable 1} 

Idx4CliCtr OBJECT-TYPE
        SYNTAX          INTEGER
        MAX-ACCESS      not-accessible
        STATUS          mandatory
        DESCRIPTION
                "xxx"
        ::= {CCliCtrRow 1} 

Stat4CliCtr OBJECT-TYPE
        SYNTAX          RowStatus
        MAX-ACCESS      read-create
        STATUS          mandatory
        DESCRIPTION
                "xxx"
        ::= {CCliCtrRow 2} 

SrvIp4CliCtr OBJECT-TYPE
        SYNTAX          IpAddress 
        MAX-ACCESS      read-write
        STATUS          mandatory
        DESCRIPTION
                "xxx"
        ::= {CCliCtrRow 3} 

SrvPort4CliCtr OBJECT-TYPE
        SYNTAX          INTEGER
        MAX-ACCESS      read-write
        STATUS          mandatory
        DESCRIPTION
                "xxx"
        ::= {CCliCtrRow 4} 

GsIp4CliCtr OBJECT-TYPE
        SYNTAX          IpAddress 
        MAX-ACCESS      read-write
        STATUS          mandatory
        DESCRIPTION
                "xxx"
        ::= {CCliCtrRow 5} 

GsPort4CliCtr OBJECT-TYPE
        SYNTAX          INTEGER
        MAX-ACCESS      read-write
        STATUS          mandatory
        DESCRIPTION
                "xxx"
        ::= {CCliCtrRow 6} 
------------------------------------------------

w/t *.c, you may note that I changed the code which I remarked /*rex ... */. 
------------------------------------------------
data_access.c
int
CCliCtrTable_container_load(netsnmp_container * container)
{
    CCliCtrTable_rowreq_ctx *rowreq_ctx;
    size_t          count = 0;

    DEBUGMSGTL(("verbose:CCliCtrTable:CCliCtrTable_container_load",
                "called\n"));

    /*
     * TODO:351:M: |-> Load/update data in the CCliCtrTable container.
     * loop over your CCliCtrTable data, allocate a rowreq context,
     * set the index(es) [and data, optionally] and insert into
     * the container.
     */
    while (1) {

        /*
         * TODO:352:M: |   |-> set indexes in new CCliCtrTable rowreq context.
         */
        rowreq_ctx = CCliCtrTable_allocate_rowreq_ctx();
        if (NULL == rowreq_ctx) {
            snmp_log(LOG_ERR, "memory allocation failed\n");
            return MFD_RESOURCE_UNAVAILABLE;
        }
        if (MFD_SUCCESS !=
            /*rex CCliCtrTable_indexes_set(rowreq_ctx, Idx4CliCtr)) { */
            CCliCtrTable_indexes_set(rowreq_ctx, rand()%10000)) {
            snmp_log(LOG_ERR,
                     "error setting index while loading "
                     "CCliCtrTable data.\n");
            CCliCtrTable_release_rowreq_ctx(rowreq_ctx);
            continue;
        }

        /*
         * TODO:352:r: |   |-> populate CCliCtrTable data context.
         * Populate data context here. (optionally, delay until row prep)
         */
        /*
         * non-TRANSIENT data: no need to copy. set pointer to data 
         */

        /*
         * insert into table container
         */
        CONTAINER_INSERT(container, rowreq_ctx);
        ++count;
    }

    DEBUGMSGT(("verbose:CCliCtrTable:CCliCtrTable_container_load",
               "inserted %d records\n", count));

    return MFD_SUCCESS;
}                               /* CCliCtrTable_container_load */

int
CCliCtrTable_validate_index(CCliCtrTable_registration * CCliCtrTable_reg,
                            CCliCtrTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:CCliCtrTable:CCliCtrTable_validate_index",
                "called\n"));

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:430:M: |-> Validate potential CCliCtrTable index.
     */
    /* rex if (1) { */
        if(0){
        /*************/
        snmp_log(LOG_WARNING, "invalid index for a new row in the "
                 "CCliCtrTable table.\n");
        /*
         * determine failure type.
         *
         * If the index could not ever be created, return MFD_NOT_EVER
         * If the index can not be created under the present circumstances
         * (even though it could be created under other circumstances),
         * return MFD_NOT_NOW.
         */
        if (0) {
            return MFD_CANNOT_CREATE_EVER;
        } else {
            return MFD_CANNOT_CREATE_NOW;
        }
    }

    return rc;
}                               /* CCliCtrTable_validate_index */
-------------------------------------------------------
data_set.c
int
CCliCtrTable_commit(CCliCtrTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;
    int             save_flags;

    DEBUGMSGTL(("verbose:CCliCtrTable:CCliCtrTable_commit", "called\n"));

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * save flags, then clear until we actually do something
     */
    save_flags = rowreq_ctx->column_set_flags;
    rowreq_ctx->column_set_flags = 0;

    /*
     * commit CCliCtrTable data
     * 1) check the column's flag in save_flags to see if it was set.
     * 2) clear the flag when you handle that column
     * 3) set the column's flag in column_set_flags if it needs undo
     *    processing in case of a failure.
     */
    if (save_flags & COLUMN_STAT4CLICTR_FLAG) {
        save_flags &= ~COLUMN_STAT4CLICTR_FLAG; /* clear Stat4CliCtr */
        /*
         * TODO:482:o: |-> commit column Stat4CliCtr.
         */
        /*rex rc = -1; */
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "CCliCtrTable column Stat4CliCtr commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo Stat4CliCtr
             */
            rowreq_ctx->column_set_flags |= COLUMN_STAT4CLICTR_FLAG;
        }
    }

    if (save_flags & COLUMN_SRVIP4CLICTR_FLAG) {
        save_flags &= ~COLUMN_SRVIP4CLICTR_FLAG;        /* clear SrvIp4CliCtr */
        /*
         * TODO:482:o: |-> commit column SrvIp4CliCtr.
         */
        /*rex rc = -1; */
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "CCliCtrTable column SrvIp4CliCtr commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo SrvIp4CliCtr
             */
            rowreq_ctx->column_set_flags |= COLUMN_SRVIP4CLICTR_FLAG;
        }
    }

    if (save_flags & COLUMN_SRVPORT4CLICTR_FLAG) {
        save_flags &= ~COLUMN_SRVPORT4CLICTR_FLAG;      /* clear SrvPort4CliCtr 
*/
        /*
         * TODO:482:o: |-> commit column SrvPort4CliCtr.
         */
        /*rex rc = -1; */
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "CCliCtrTable column SrvPort4CliCtr commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo SrvPort4CliCtr
             */
            rowreq_ctx->column_set_flags |= COLUMN_SRVPORT4CLICTR_FLAG;
        }
    }

    if (save_flags & COLUMN_GSIP4CLICTR_FLAG) {
        save_flags &= ~COLUMN_GSIP4CLICTR_FLAG; /* clear GsIp4CliCtr */
        /*
         * TODO:482:o: |-> commit column GsIp4CliCtr.
         */
        /*rex rc = -1; */
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "CCliCtrTable column GsIp4CliCtr commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo GsIp4CliCtr
             */
            rowreq_ctx->column_set_flags |= COLUMN_GSIP4CLICTR_FLAG;
        }
    }

    if (save_flags & COLUMN_GSPORT4CLICTR_FLAG) {
        save_flags &= ~COLUMN_GSPORT4CLICTR_FLAG;       /* clear GsPort4CliCtr 
*/
        /*
         * TODO:482:o: |-> commit column GsPort4CliCtr.
         */
        /*rex rc = -1; */
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "CCliCtrTable column GsPort4CliCtr commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo GsPort4CliCtr
             */
            rowreq_ctx->column_set_flags |= COLUMN_GSPORT4CLICTR_FLAG;
        }
    }

    /*
     * if we successfully commited this row, set the dirty flag.
     */
    if (MFD_SUCCESS == rc) {
        rowreq_ctx->rowreq_flags |= MFD_ROW_DIRTY;
    }

    if (save_flags) {
        snmp_log(LOG_ERR, "unhandled columns (0x%x) in commit\n",
                 save_flags);
        return MFD_ERROR;
    }

    return rc;
}                               /* CCliCtrTable_commit */
-----------------------------------------------------------------

the table-*.m2d
-------------------------------------------
@eval $m2c_context_reg = "netsnmp_data_list"@
@eval $m2c_data_allocate = 0@
@eval $m2c_data_cache = 0@
@eval $m2c_data_context = "generated"@ [generated|NAME]
@eval $m2c_data_init = 0@
@eval $m2c_data_transient = 0@
@eval $m2c_include_examples = 1@
@eval $m2c_irreversible_commit = 0@
@eval $m2c_table_access = "container-cached"@
@eval $m2c_table_dependencies = 0@
@eval $m2c_table_persistent = 0@
@eval $m2c_table_row_creation = 1@
@eval $m2c_table_settable = 1@
@eval $m2c_table_skip_mapping = 1@
@eval $m2c_table_sparse = 1@
@eval $mfd_generate_makefile = 0@
@eval $mfd_generate_subagent = 0@
------------------------------------------------------------

Hope it is helpful to you.

Thanks & Regards,
Rex Huang

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Net-snmp-coders mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders

Reply via email to