예제 #1
0
/** handles requests for the mteTriggerThresholdTable table */
int
mteTriggerThresholdTable_handler(netsnmp_mib_handler *handler,
                                 netsnmp_handler_registration *reginfo,
                                 netsnmp_agent_request_info *reqinfo,
                                 netsnmp_request_info *requests)
{

    netsnmp_request_info       *request;
    netsnmp_table_request_info *tinfo;
    struct mteTrigger          *entry;
    int ret;

    DEBUGMSGTL(("disman:event:mib", "Threshold Table handler (%d)\n",
                                     reqinfo->mode));

    switch (reqinfo->mode) {
        /*
         * Read-support (also covers GetNext requests)
         */
    case MODE_GET:
        for (request = requests; request; request = request->next) {
            entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
            tinfo = netsnmp_extract_table_info(request);

            /*
             * The mteTriggerThresholdTable should only contains entries for
             *   rows where the mteTriggerTest 'threshold(2)' bit is set.
             * So skip entries where this isn't the case.
             */
            if (!entry || !(entry->mteTriggerTest & MTE_TRIGGER_THRESHOLD ))
                continue;

            switch (tinfo->colnum) {
            case COLUMN_MTETRIGGERTHRESHOLDSTARTUP:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           entry->mteTThStartup);
                break;
            case COLUMN_MTETRIGGERTHRESHOLDRISING:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           entry->mteTThRiseValue);
                break;
            case COLUMN_MTETRIGGERTHRESHOLDFALLING:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           entry->mteTThFallValue);
                break;
            case COLUMN_MTETRIGGERTHRESHOLDDELTARISING:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           entry->mteTThDRiseValue);
                break;
            case COLUMN_MTETRIGGERTHRESHOLDDELTAFALLING:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           entry->mteTThDFallValue);
                break;
            case COLUMN_MTETRIGGERTHRESHOLDOBJECTSOWNER:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                              (u_char *) entry->mteTThObjOwner,
                                  strlen(entry->mteTThObjOwner));
                break;
            case COLUMN_MTETRIGGERTHRESHOLDOBJECTS:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                              (u_char *) entry->mteTThObjects,
                                  strlen(entry->mteTThObjects));
                break;
            case COLUMN_MTETRIGGERTHRESHOLDRISINGEVENTOWNER:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                              (u_char *) entry->mteTThRiseOwner,
                                  strlen(entry->mteTThRiseOwner));
                break;
            case COLUMN_MTETRIGGERTHRESHOLDRISINGEVENT:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                              (u_char *) entry->mteTThRiseEvent,
                                  strlen(entry->mteTThRiseEvent));
                break;
            case COLUMN_MTETRIGGERTHRESHOLDFALLINGEVENTOWNER:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                              (u_char *) entry->mteTThFallOwner,
                                  strlen(entry->mteTThFallOwner));
                break;
            case COLUMN_MTETRIGGERTHRESHOLDFALLINGEVENT:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                              (u_char *) entry->mteTThFallEvent,
                                  strlen(entry->mteTThFallEvent));
                break;
            case COLUMN_MTETRIGGERTHRESHOLDDELTARISINGEVENTOWNER:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                              (u_char *) entry->mteTThDRiseOwner,
                                  strlen(entry->mteTThDRiseOwner));
                break;
            case COLUMN_MTETRIGGERTHRESHOLDDELTARISINGEVENT:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                              (u_char *) entry->mteTThDRiseEvent,
                                  strlen(entry->mteTThDRiseEvent));
                break;
            case COLUMN_MTETRIGGERTHRESHOLDDELTAFALLINGEVENTOWNER:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                              (u_char *) entry->mteTThDFallOwner,
                                  strlen(entry->mteTThDFallOwner));
                break;
            case COLUMN_MTETRIGGERTHRESHOLDDELTAFALLINGEVENT:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                              (u_char *) entry->mteTThDFallEvent,
                                  strlen(entry->mteTThDFallEvent));
                break;
            }
        }
        break;

#ifndef NETSNMP_NO_WRITE_SUPPORT
        /*
         * Write-support
         */
    case MODE_SET_RESERVE1:
        for (request = requests; request; request = request->next) {
            entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
            tinfo = netsnmp_extract_table_info(request);

            /*
             * Since the mteTriggerThresholdTable only contains entries for
             *   rows where the mteTriggerTest 'threshold(2)' bit is set,
             *   strictly speaking we should reject assignments where
             *   this isn't the case.
             * But SET requests that include an assignment of the
             *   'threshold(2)' bit at the same time are valid, so would
             *    need to be accepted. Unfortunately, this assignment
             *   is only applied in the COMMIT pass, so it's difficult
             *   to detect whether this holds or not.
             *
             * Let's fudge things for now, by processing assignments
             *   even if the 'threshold(2)' bit isn't set.
             */
            switch (tinfo->colnum) {
            case COLUMN_MTETRIGGERTHRESHOLDSTARTUP:
                ret = netsnmp_check_vb_int_range(request->requestvb,
                                                 MTE_THRESH_START_RISE,
                                                 MTE_THRESH_START_RISEFALL );
                if (ret != SNMP_ERR_NOERROR) {
                    netsnmp_set_request_error(reqinfo, request, ret);
                    return SNMP_ERR_NOERROR;
                }
                break;
            case COLUMN_MTETRIGGERTHRESHOLDRISING:
            case COLUMN_MTETRIGGERTHRESHOLDFALLING:
            case COLUMN_MTETRIGGERTHRESHOLDDELTARISING:
            case COLUMN_MTETRIGGERTHRESHOLDDELTAFALLING:
                ret = netsnmp_check_vb_int(request->requestvb);
                if (ret != SNMP_ERR_NOERROR) {
                    netsnmp_set_request_error(reqinfo, request, ret);
                    return SNMP_ERR_NOERROR;
                }
                break;
            case COLUMN_MTETRIGGERTHRESHOLDOBJECTSOWNER:
            case COLUMN_MTETRIGGERTHRESHOLDOBJECTS:
            case COLUMN_MTETRIGGERTHRESHOLDRISINGEVENTOWNER:
            case COLUMN_MTETRIGGERTHRESHOLDRISINGEVENT:
            case COLUMN_MTETRIGGERTHRESHOLDFALLINGEVENTOWNER:
            case COLUMN_MTETRIGGERTHRESHOLDFALLINGEVENT:
            case COLUMN_MTETRIGGERTHRESHOLDDELTARISINGEVENTOWNER:
            case COLUMN_MTETRIGGERTHRESHOLDDELTARISINGEVENT:
            case COLUMN_MTETRIGGERTHRESHOLDDELTAFALLINGEVENTOWNER:
            case COLUMN_MTETRIGGERTHRESHOLDDELTAFALLINGEVENT:
                ret = netsnmp_check_vb_type_and_max_size(
                          request->requestvb, ASN_OCTET_STR, MTE_STR1_LEN);
                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;
            }

            /*
             * The Event MIB is somewhat ambiguous as to whether the
             *  various trigger table entries can be modified once the
             *  main mteTriggerTable entry has been marked 'active'. 
             * But it's clear from discussion on the DisMan mailing
             *  list is that the intention is not.
             *
             * So check for whether this row is already active,
             *  and reject *all* SET requests if it is.
             */
            entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
            if (entry &&
                entry->flags & MTE_TRIGGER_FLAG_ACTIVE ) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_INCONSISTENTVALUE);
                return SNMP_ERR_NOERROR;
            }
        }
        break;

    case MODE_SET_RESERVE2:
    case MODE_SET_FREE:
    case MODE_SET_UNDO:
        break;

    case MODE_SET_ACTION:
        for (request = requests; request; request = request->next) {
            entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
            if (!entry) {
                /*
                 * New rows must be created via the RowStatus column
                 *   (in the main mteTriggerTable)
                 */
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOCREATION);
                                      /* or inconsistentName? */
                return SNMP_ERR_NOERROR;
            }
        }
        break;

    case MODE_SET_COMMIT:
        /*
         * All these assignments are "unfailable", so it's
         *  (reasonably) safe to apply them in the Commit phase
         */
        for (request = requests; request; request = request->next) {
            entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
            tinfo = netsnmp_extract_table_info(request);

            switch (tinfo->colnum) {
            case COLUMN_MTETRIGGERTHRESHOLDSTARTUP:
                entry->mteTThStartup    = *request->requestvb->val.integer;
                break;
            case COLUMN_MTETRIGGERTHRESHOLDRISING:
                entry->mteTThRiseValue  = *request->requestvb->val.integer;
                break;
            case COLUMN_MTETRIGGERTHRESHOLDFALLING:
                entry->mteTThFallValue  = *request->requestvb->val.integer;
                break;
            case COLUMN_MTETRIGGERTHRESHOLDDELTARISING:
                entry->mteTThDRiseValue = *request->requestvb->val.integer;
                break;
            case COLUMN_MTETRIGGERTHRESHOLDDELTAFALLING:
                entry->mteTThDFallValue = *request->requestvb->val.integer;
                break;
            case COLUMN_MTETRIGGERTHRESHOLDOBJECTSOWNER:
                memset(entry->mteTThObjOwner, 0, sizeof(entry->mteTThObjOwner));
                memcpy(entry->mteTThObjOwner, request->requestvb->val.string,
                                              request->requestvb->val_len);
                break;
            case COLUMN_MTETRIGGERTHRESHOLDOBJECTS:
                memset(entry->mteTThObjects,  0, sizeof(entry->mteTThObjects));
                memcpy(entry->mteTThObjects,  request->requestvb->val.string,
                                              request->requestvb->val_len);
                break;
            case COLUMN_MTETRIGGERTHRESHOLDRISINGEVENTOWNER:
                memset(entry->mteTThRiseOwner, 0, sizeof(entry->mteTThRiseOwner));
                memcpy(entry->mteTThRiseOwner, request->requestvb->val.string,
                                               request->requestvb->val_len);
                break;
            case COLUMN_MTETRIGGERTHRESHOLDRISINGEVENT:
                memset(entry->mteTThRiseEvent, 0, sizeof(entry->mteTThRiseEvent));
                memcpy(entry->mteTThRiseEvent, request->requestvb->val.string,
                                               request->requestvb->val_len);
                break;
            case COLUMN_MTETRIGGERTHRESHOLDFALLINGEVENTOWNER:
                memset(entry->mteTThFallOwner, 0, sizeof(entry->mteTThFallOwner));
                memcpy(entry->mteTThFallOwner, request->requestvb->val.string,
                                               request->requestvb->val_len);
                break;
            case COLUMN_MTETRIGGERTHRESHOLDFALLINGEVENT:
                memset(entry->mteTThFallEvent, 0, sizeof(entry->mteTThFallEvent));
                memcpy(entry->mteTThFallEvent, request->requestvb->val.string,
                                               request->requestvb->val_len);
                break;
            case COLUMN_MTETRIGGERTHRESHOLDDELTARISINGEVENTOWNER:
                memset(entry->mteTThDRiseOwner, 0, sizeof(entry->mteTThDRiseOwner));
                memcpy(entry->mteTThDRiseOwner, request->requestvb->val.string,
                                                request->requestvb->val_len);
                break;
            case COLUMN_MTETRIGGERTHRESHOLDDELTARISINGEVENT:
                memset(entry->mteTThDRiseEvent, 0, sizeof(entry->mteTThDRiseEvent));
                memcpy(entry->mteTThDRiseEvent, request->requestvb->val.string,
                                                request->requestvb->val_len);
                break;
            case COLUMN_MTETRIGGERTHRESHOLDDELTAFALLINGEVENTOWNER:
                memset(entry->mteTThDFallOwner, 0, sizeof(entry->mteTThDFallOwner));
                memcpy(entry->mteTThDFallOwner, request->requestvb->val.string,
                                                request->requestvb->val_len);
                break;
            case COLUMN_MTETRIGGERTHRESHOLDDELTAFALLINGEVENT:
                memset(entry->mteTThDFallEvent, 0, sizeof(entry->mteTThDFallEvent));
                memcpy(entry->mteTThDFallEvent, request->requestvb->val.string,
                                                request->requestvb->val_len);
                break;
            }
        }
        break;
#endif /* !NETSNMP_NO_WRITE_SUPPORT */

    }
    return SNMP_ERR_NOERROR;
}
예제 #2
0
static int mib_ipRouteTable_handler(netsnmp_mib_handler *handler,
                    netsnmp_handler_registration *reginfo,
                    netsnmp_agent_request_info *reqinfo,
                    netsnmp_request_info *requests)
{
    netsnmp_request_info       *request;
    netsnmp_table_request_info *table_req_info;
    struct ipRouteTable_entry *table_entry;
    int                         ret;
    switch (reqinfo->mode)
    {
    case MODE_GET:
        for (request=requests; request; request=request->next)
        {
            table_entry = (struct ipRouteTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_req_info  = netsnmp_extract_table_info(request);
            if(NULL == table_req_info)
            {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOACCESS);
                continue;
            }

            switch (table_req_info->colnum)
            {
            case COLUMN_IPROUTEDEST:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_IPADDRESS,
                                            htonl(table_entry->ipRouteDest));
                break;

            case COLUMN_IPROUTEIFINDEX:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->ipRouteIfIndex);
                break;

            case COLUMN_IPROUTEMETRIC1:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->ipRouteMetric1);
                break;

            case COLUMN_IPROUTEMETRIC2:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->ipRouteMetric2);
                break;

            case COLUMN_IPROUTEMETRIC3:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->ipRouteMetric3);
                break;

            case COLUMN_IPROUTEMETRIC4:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->ipRouteMetric4);
                break;

            case COLUMN_IPROUTENEXTHOP:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_IPADDRESS,
                                            htonl(table_entry->ipRouteNextHop));
                break;

            case COLUMN_IPROUTETYPE:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->ipRouteType);
                break;

            case COLUMN_IPROUTEPROTO:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->ipRouteProto);
                break;

            case COLUMN_IPROUTEAGE:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->ipRouteAge);
                break;

            case COLUMN_IPROUTEMASK:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_IPADDRESS,
                                            htonl(table_entry->ipRouteMask));
                break;

            case COLUMN_IPROUTEMETRIC5:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->ipRouteMetric5);
                break;

            case COLUMN_IPROUTEINFO:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_value( request->requestvb, ASN_OBJECT_ID,
                                 (u_char*)table_entry->ipRouteInfo,
                                          table_entry->ipRouteInfo_len);
                break;

            default:
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHOBJECT);
                break;

            }
        }
        break;
    case MODE_SET_RESERVE1:
        for (request=requests; request; request=request->next)
        {
            table_entry = (struct ipRouteTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_req_info  = netsnmp_extract_table_info(request);
            if(NULL == table_req_info)
            {
                netsnmp_set_request_error( reqinfo, request,
                                           SNMP_ERR_NOACCESS );
                return SNMP_ERR_NOERROR;
            }

            switch (table_req_info->colnum)
            {
            case COLUMN_IPROUTEDEST:
                ret = netsnmp_check_vb_type_and_size(
                          request->requestvb, ASN_IPADDRESS, sizeof(table_entry->ipRouteDest));
                if ( ret != SNMP_ERR_NOERROR )
                {
                    netsnmp_set_request_error( reqinfo, request, ret );
                    return SNMP_ERR_NOERROR;
                }
                break;

            case COLUMN_IPROUTEIFINDEX:
                ret = netsnmp_check_vb_int( request->requestvb );
                if ( ret != SNMP_ERR_NOERROR )
                {
                    netsnmp_set_request_error( reqinfo, request, ret );
                    return SNMP_ERR_NOERROR;
                }
                break;

            case COLUMN_IPROUTEMETRIC1:
                ret = netsnmp_check_vb_int( request->requestvb );
                if ( ret != SNMP_ERR_NOERROR )
                {
                    netsnmp_set_request_error( reqinfo, request, ret );
                    return SNMP_ERR_NOERROR;
                }
                break;

            case COLUMN_IPROUTEMETRIC2:
                ret = netsnmp_check_vb_int( request->requestvb );
                if ( ret != SNMP_ERR_NOERROR )
                {
                    netsnmp_set_request_error( reqinfo, request, ret );
                    return SNMP_ERR_NOERROR;
                }
                break;

            case COLUMN_IPROUTEMETRIC3:
                ret = netsnmp_check_vb_int( request->requestvb );
                if ( ret != SNMP_ERR_NOERROR )
                {
                    netsnmp_set_request_error( reqinfo, request, ret );
                    return SNMP_ERR_NOERROR;
                }
                break;

            case COLUMN_IPROUTEMETRIC4:
                ret = netsnmp_check_vb_int( request->requestvb );
                if ( ret != SNMP_ERR_NOERROR )
                {
                    netsnmp_set_request_error( reqinfo, request, ret );
                    return SNMP_ERR_NOERROR;
                }
                break;

            case COLUMN_IPROUTENEXTHOP:
                ret = netsnmp_check_vb_type_and_size(
                          request->requestvb, ASN_IPADDRESS, sizeof(table_entry->ipRouteNextHop));
                if ( ret != SNMP_ERR_NOERROR )
                {
                    netsnmp_set_request_error( reqinfo, request, ret );
                    return SNMP_ERR_NOERROR;
                }
                break;

            case COLUMN_IPROUTETYPE:
                ret = netsnmp_check_vb_int( request->requestvb );
                if ( ret != SNMP_ERR_NOERROR )
                {
                    netsnmp_set_request_error( reqinfo, request, ret );
                    return SNMP_ERR_NOERROR;
                }
                break;

            case COLUMN_IPROUTEAGE:
                ret = netsnmp_check_vb_int( request->requestvb );
                if ( ret != SNMP_ERR_NOERROR )
                {
                    netsnmp_set_request_error( reqinfo, request, ret );
                    return SNMP_ERR_NOERROR;
                }
                break;

            case COLUMN_IPROUTEMASK:
                ret = netsnmp_check_vb_type_and_size(
                          request->requestvb, ASN_IPADDRESS, sizeof(table_entry->ipRouteMask));
                if ( ret != SNMP_ERR_NOERROR )
                {
                    netsnmp_set_request_error( reqinfo, request, ret );
                    return SNMP_ERR_NOERROR;
                }
                break;

            case COLUMN_IPROUTEMETRIC5:
                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 ipRouteTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_req_info  = netsnmp_extract_table_info(request);

            switch (table_req_info->colnum)
            {
            case COLUMN_IPROUTEDEST:
                table_entry->old_ipRouteDest = table_entry->ipRouteDest;
                table_entry->ipRouteDest     = *request->requestvb->val.integer;
                break;

            case COLUMN_IPROUTEIFINDEX:
                table_entry->old_ipRouteIfIndex = table_entry->ipRouteIfIndex;
                table_entry->ipRouteIfIndex     = *request->requestvb->val.integer;
                break;

            case COLUMN_IPROUTEMETRIC1:
                table_entry->old_ipRouteMetric1 = table_entry->ipRouteMetric1;
                table_entry->ipRouteMetric1     = *request->requestvb->val.integer;
                break;

            case COLUMN_IPROUTEMETRIC2:
                table_entry->old_ipRouteMetric2 = table_entry->ipRouteMetric2;
                table_entry->ipRouteMetric2     = *request->requestvb->val.integer;
                break;

            case COLUMN_IPROUTEMETRIC3:
                table_entry->old_ipRouteMetric3 = table_entry->ipRouteMetric3;
                table_entry->ipRouteMetric3     = *request->requestvb->val.integer;
                break;

            case COLUMN_IPROUTEMETRIC4:
                table_entry->old_ipRouteMetric4 = table_entry->ipRouteMetric4;
                table_entry->ipRouteMetric4     = *request->requestvb->val.integer;
                break;

            case COLUMN_IPROUTENEXTHOP:
                table_entry->old_ipRouteNextHop = table_entry->ipRouteNextHop;
                table_entry->ipRouteNextHop     = *request->requestvb->val.integer;
                break;

            case COLUMN_IPROUTETYPE:
                table_entry->old_ipRouteType = table_entry->ipRouteType;
                table_entry->ipRouteType     = *request->requestvb->val.integer;
                break;

            case COLUMN_IPROUTEAGE:
                table_entry->old_ipRouteAge = table_entry->ipRouteAge;
                table_entry->ipRouteAge     = *request->requestvb->val.integer;
                break;

            case COLUMN_IPROUTEMASK:
                table_entry->old_ipRouteMask = table_entry->ipRouteMask;
                table_entry->ipRouteMask     = *request->requestvb->val.integer;
                break;

            case COLUMN_IPROUTEMETRIC5:
                table_entry->old_ipRouteMetric5 = table_entry->ipRouteMetric5;
                table_entry->ipRouteMetric5     = *request->requestvb->val.integer;
                break;

            }
        }
        break;

    case MODE_SET_COMMIT:
        break;

    case MODE_SET_UNDO:
        for (request=requests; request; request=request->next)
        {
            table_entry = (struct ipRouteTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_req_info  = netsnmp_extract_table_info( request);

            switch (table_req_info->colnum)
            {
            case COLUMN_IPROUTEDEST:
                table_entry->ipRouteDest     = table_entry->old_ipRouteDest;
                table_entry->old_ipRouteDest = 0;
                break;

            case COLUMN_IPROUTEIFINDEX:
                table_entry->ipRouteIfIndex     = table_entry->old_ipRouteIfIndex;
                table_entry->old_ipRouteIfIndex = 0;
                break;

            case COLUMN_IPROUTEMETRIC1:
                table_entry->ipRouteMetric1     = table_entry->old_ipRouteMetric1;
                table_entry->old_ipRouteMetric1 = 0;
                break;

            case COLUMN_IPROUTEMETRIC2:
                table_entry->ipRouteMetric2     = table_entry->old_ipRouteMetric2;
                table_entry->old_ipRouteMetric2 = 0;
                break;

            case COLUMN_IPROUTEMETRIC3:
                table_entry->ipRouteMetric3     = table_entry->old_ipRouteMetric3;
                table_entry->old_ipRouteMetric3 = 0;
                break;

            case COLUMN_IPROUTEMETRIC4:
                table_entry->ipRouteMetric4     = table_entry->old_ipRouteMetric4;
                table_entry->old_ipRouteMetric4 = 0;
                break;

            case COLUMN_IPROUTENEXTHOP:
                table_entry->ipRouteNextHop     = table_entry->old_ipRouteNextHop;
                table_entry->old_ipRouteNextHop = 0;
                break;

            case COLUMN_IPROUTETYPE:
                table_entry->ipRouteType     = table_entry->old_ipRouteType;
                table_entry->old_ipRouteType = 0;
                break;

            case COLUMN_IPROUTEAGE:
                table_entry->ipRouteAge     = table_entry->old_ipRouteAge;
                table_entry->old_ipRouteAge = 0;
                break;

            case COLUMN_IPROUTEMASK:
                table_entry->ipRouteMask     = table_entry->old_ipRouteMask;
                table_entry->old_ipRouteMask = 0;
                break;

            case COLUMN_IPROUTEMETRIC5:
                table_entry->ipRouteMetric5     = table_entry->old_ipRouteMetric5;
                table_entry->old_ipRouteMetric5 = 0;
                break;

            }
        }
        break;

    }
    return SNMP_ERR_NOERROR;
}
예제 #3
0
/** handles requests for the mteEventSetTable table */
int
mteEventSetTable_handler (netsnmp_mib_handler * handler,
                          netsnmp_handler_registration * reginfo,
                          netsnmp_agent_request_info * reqinfo, netsnmp_request_info * requests)
{

    netsnmp_request_info *request;

    netsnmp_table_request_info *tinfo;

    struct mteEvent *entry;

    int ret;

    DEBUGMSGTL (("disman:event:mib", "Set Table handler (%d)\n", reqinfo->mode));

    switch (reqinfo->mode)
    {
            /*
             * Read-support (also covers GetNext requests)
             */
        case MODE_GET:
            for (request = requests; request; request = request->next)
            {
                if (request->processed)
                    continue;

                entry = (struct mteEvent *) netsnmp_tdata_extract_entry (request);
                tinfo = netsnmp_extract_table_info (request);

                /*
                 * The mteEventSetTable should only contains entries for
                 *   rows where the mteEventActions 'set(1)' bit is set.
                 * So skip entries where this isn't the case.
                 */
                if (!entry || !(entry->mteEventActions & MTE_EVENT_SET))
                    continue;

                switch (tinfo->colnum)
                {
                    case COLUMN_MTEEVENTSETOBJECT:
                        snmp_set_var_typed_value (request->requestvb, ASN_OBJECT_ID,
                                                  (u_char *) entry->mteSetOID, entry->mteSetOID_len * sizeof (oid));
                        break;
                    case COLUMN_MTEEVENTSETOBJECTWILDCARD:
                        ret = (entry->flags & MTE_SET_FLAG_OBJWILD) ? TV_TRUE : TV_FALSE;
                        snmp_set_var_typed_integer (request->requestvb, ASN_INTEGER, ret);
                        break;
                    case COLUMN_MTEEVENTSETVALUE:
                        snmp_set_var_typed_integer (request->requestvb, ASN_INTEGER, entry->mteSetValue);
                        break;
                    case COLUMN_MTEEVENTSETTARGETTAG:
                        snmp_set_var_typed_value (request->requestvb, ASN_OCTET_STR,
                                                  (u_char *) entry->mteSetTarget, strlen (entry->mteSetTarget));
                        break;
                    case COLUMN_MTEEVENTSETCONTEXTNAME:
                        snmp_set_var_typed_value (request->requestvb, ASN_OCTET_STR,
                                                  (u_char *) entry->mteSetContext, strlen (entry->mteSetContext));
                        break;
                    case COLUMN_MTEEVENTSETCONTEXTNAMEWILDCARD:
                        ret = (entry->flags & MTE_SET_FLAG_CTXWILD) ? TV_TRUE : TV_FALSE;
                        snmp_set_var_typed_integer (request->requestvb, ASN_INTEGER, ret);
                        break;
                }
            }
            break;

#ifndef NETSNMP_NO_WRITE_SUPPORT
            /*
             * Write-support
             */
        case MODE_SET_RESERVE1:
            for (request = requests; request; request = request->next)
            {
                if (request->processed)
                    continue;

                tinfo = netsnmp_extract_table_info (request);

                /*
                 * Since the mteEventSetTable only contains entries for
                 *   rows where the mteEventActions 'set(1)' bit is set,
                 *   strictly speaking we should reject assignments where
                 *   this isn't the case.
                 * But SET requests that include an assignment of the
                 *   'set(1)' bit at the same time are valid, so would
                 *    need to be accepted. Unfortunately, this assignment
                 *   is only applied in the COMMIT pass, so it's difficult
                 *   to detect whether this holds or not.
                 *
                 * Let's fudge things for now, by processing assignments
                 *   even if the 'set(1)' bit isn't set.
                 */
                switch (tinfo->colnum)
                {
                    case COLUMN_MTEEVENTSETOBJECT:
                        ret = netsnmp_check_vb_oid (request->requestvb);
                        if (ret != SNMP_ERR_NOERROR)
                        {
                            netsnmp_set_request_error (reqinfo, request, ret);
                            return SNMP_ERR_NOERROR;
                        }
                        break;
                    case COLUMN_MTEEVENTSETOBJECTWILDCARD:
                    case COLUMN_MTEEVENTSETCONTEXTNAMEWILDCARD:
                        ret = netsnmp_check_vb_truthvalue (request->requestvb);
                        if (ret != SNMP_ERR_NOERROR)
                        {
                            netsnmp_set_request_error (reqinfo, request, ret);
                            return SNMP_ERR_NOERROR;
                        }
                        break;
                    case COLUMN_MTEEVENTSETVALUE:
                        ret = netsnmp_check_vb_int (request->requestvb);
                        if (ret != SNMP_ERR_NOERROR)
                        {
                            netsnmp_set_request_error (reqinfo, request, ret);
                            return SNMP_ERR_NOERROR;
                        }
                        break;
                    case COLUMN_MTEEVENTSETTARGETTAG:
                    case COLUMN_MTEEVENTSETCONTEXTNAME:
                        ret = netsnmp_check_vb_type_and_max_size (request->requestvb, ASN_OCTET_STR, MTE_STR2_LEN);
                        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;
                }

                /*
                 * The Event MIB is somewhat ambiguous as to whether
                 *  mteEventSetTable (and mteEventNotificationTable)
                 *  entries can be modified once the main mteEventTable
                 *  entry has been marked 'active'. 
                 * But it's clear from discussion on the DisMan mailing
                 *  list is that the intention is not.
                 *
                 * So check for whether this row is already active,
                 *  and reject *all* SET requests if it is.
                 */
                entry = (struct mteEvent *) netsnmp_tdata_extract_entry (request);
                if (entry && entry->flags & MTE_EVENT_FLAG_ACTIVE)
                {
                    netsnmp_set_request_error (reqinfo, request, SNMP_ERR_INCONSISTENTVALUE);
                    return SNMP_ERR_NOERROR;
                }
            }
            break;

        case MODE_SET_RESERVE2:
        case MODE_SET_FREE:
        case MODE_SET_UNDO:
            break;

        case MODE_SET_ACTION:
            for (request = requests; request; request = request->next)
            {
                if (request->processed)
                    continue;

                entry = (struct mteEvent *) netsnmp_tdata_extract_entry (request);
                if (!entry)
                {
                    /*
                     * New rows must be created via the RowStatus column
                     *   (in the main mteEventTable)
                     */
                    netsnmp_set_request_error (reqinfo, request, SNMP_ERR_NOCREATION);
                    /* or inconsistentName? */
                    return SNMP_ERR_NOERROR;

                }
            }
            break;

        case MODE_SET_COMMIT:
            /*
             * All these assignments are "unfailable", so it's
             *  (reasonably) safe to apply them in the Commit phase
             */
            for (request = requests; request; request = request->next)
            {
                if (request->processed)
                    continue;

                entry = (struct mteEvent *) netsnmp_tdata_extract_entry (request);
                tinfo = netsnmp_extract_table_info (request);

                switch (tinfo->colnum)
                {
                    case COLUMN_MTEEVENTSETOBJECT:
                        memset (entry->mteSetOID, 0, sizeof (entry->mteSetOID));
                        memcpy (entry->mteSetOID, request->requestvb->val.objid, request->requestvb->val_len);
                        entry->mteSetOID_len = request->requestvb->val_len / sizeof (oid);
                        break;
                    case COLUMN_MTEEVENTSETOBJECTWILDCARD:
                        if (*request->requestvb->val.integer == TV_TRUE)
                            entry->flags |= MTE_SET_FLAG_OBJWILD;
                        else
                            entry->flags &= ~MTE_SET_FLAG_OBJWILD;
                        break;
                    case COLUMN_MTEEVENTSETVALUE:
                        entry->mteSetValue = *request->requestvb->val.integer;
                        break;
                    case COLUMN_MTEEVENTSETTARGETTAG:
                        memset (entry->mteSetTarget, 0, sizeof (entry->mteSetTarget));
                        memcpy (entry->mteSetTarget, request->requestvb->val.string, request->requestvb->val_len);
                        break;
                    case COLUMN_MTEEVENTSETCONTEXTNAME:
                        memset (entry->mteSetContext, 0, sizeof (entry->mteSetContext));
                        memcpy (entry->mteSetContext, request->requestvb->val.string, request->requestvb->val_len);
                        break;
                    case COLUMN_MTEEVENTSETCONTEXTNAMEWILDCARD:
                        if (*request->requestvb->val.integer == TV_TRUE)
                            entry->flags |= MTE_SET_FLAG_CTXWILD;
                        else
                            entry->flags &= ~MTE_SET_FLAG_CTXWILD;
                        break;
                }
            }
            break;
#endif                            /* !NETSNMP_NO_WRITE_SUPPORT */
    }
    return SNMP_ERR_NOERROR;
}
예제 #4
0
/** handles requests for the schedTable table */
int
schedTable_handler(netsnmp_mib_handler *handler,
                   netsnmp_handler_registration *reginfo,
                   netsnmp_agent_request_info *reqinfo,
                   netsnmp_request_info *requests)
{

    netsnmp_request_info       *request;
    netsnmp_table_request_info *tinfo;
    netsnmp_tdata_row          *row;
    struct schedTable_entry    *entry;
    int    recalculate = 0;
    size_t len;
    char  *cp;
    char   owner[SCHED_STR1_LEN+1];
    char   name[ SCHED_STR1_LEN+1];
    int    ret;

    DEBUGMSGTL(("disman:schedule:mib", "Schedule handler (%d)\n",
                                        reqinfo->mode));
    switch (reqinfo->mode) {
        /*
         * Read-support (also covers GetNext requests)
         */
    case MODE_GET:
        for (request = requests; request; request = request->next) {
            if (request->processed)
                continue;

            entry = (struct schedTable_entry *)
                    netsnmp_tdata_extract_entry(request);
            tinfo = netsnmp_extract_table_info( request);

            switch (tinfo->colnum) {
            case COLUMN_SCHEDDESCR:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                         entry->schedDescr,
                                  strlen(entry->schedDescr));
                break;
            case COLUMN_SCHEDINTERVAL:
                snmp_set_var_typed_integer(request->requestvb, ASN_UNSIGNED,
                                           entry->schedInterval);
                break;
            case COLUMN_SCHEDWEEKDAY:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                        &entry->schedWeekDay,
                                  sizeof(entry->schedWeekDay));
                break;
            case COLUMN_SCHEDMONTH:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                         entry->schedMonth,
                                  sizeof(entry->schedMonth));
                break;
            case COLUMN_SCHEDDAY:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                         entry->schedDay,
                                  sizeof(entry->schedDay));
                break;
            case COLUMN_SCHEDHOUR:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                         entry->schedHour,
                                  sizeof(entry->schedHour));
                break;
            case COLUMN_SCHEDMINUTE:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                         entry->schedMinute,
                                  sizeof(entry->schedMinute));
                break;
            case COLUMN_SCHEDCONTEXTNAME:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                         entry->schedContextName,
                                  strlen(entry->schedContextName));
                break;
            case COLUMN_SCHEDVARIABLE:
                snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID,
                               (u_char *)entry->schedVariable,
                                         entry->schedVariable_len*sizeof(oid));
                break;
            case COLUMN_SCHEDVALUE:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           entry->schedValue);
                break;
            case COLUMN_SCHEDTYPE:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           entry->schedType);
                break;
            case COLUMN_SCHEDADMINSTATUS:
                ret = (entry->flags & SCHEDULE_FLAG_ENABLED ) ?
                           TV_TRUE : TV_FALSE;
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, ret);
                break;
            case COLUMN_SCHEDOPERSTATUS:
                ret = (entry->flags & SCHEDULE_FLAG_ENABLED ) ?
                           TV_TRUE : TV_FALSE;
                /*
                 * Check for one-shot entries that have already fired
                 */
                if ((entry->schedType == SCHED_TYPE_ONESHOT) &&
                    (entry->schedLastRun != 0 ))
                    ret = 3;  /* finished(3) */
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, ret);
                break;
            case COLUMN_SCHEDFAILURES:
                snmp_set_var_typed_integer(request->requestvb, ASN_COUNTER,
                                           entry->schedFailures);
                break;
            case COLUMN_SCHEDLASTFAILURE:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           entry->schedLastFailure);
                break;
            case COLUMN_SCHEDLASTFAILED:
                /*
                 * Convert 'schedLastFailed' timestamp
                 *   into DateAndTime string
                 */
                cp = (char *) date_n_time( &entry->schedLastFailed, &len );
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                         cp, len);
                break;
            case COLUMN_SCHEDSTORAGETYPE:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           entry->schedStorageType);
                break;
            case COLUMN_SCHEDROWSTATUS:
                ret = (entry->flags & SCHEDULE_FLAG_ACTIVE ) ?
                           TV_TRUE : TV_FALSE;
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, ret);
                break;
            case COLUMN_SCHEDTRIGGERS:
                snmp_set_var_typed_integer(request->requestvb, ASN_COUNTER,
                                           entry->schedTriggers);
                break;
            }
        }
        break;

        /*
         * Write-support
         */
    case MODE_SET_RESERVE1:
        for (request = requests; request; request = request->next) {
            if (request->processed)
                continue;

            entry = (struct schedTable_entry *)
                    netsnmp_tdata_extract_entry(request);
            tinfo = netsnmp_extract_table_info( request);

            switch (tinfo->colnum) {
            case COLUMN_SCHEDDESCR:
                ret = netsnmp_check_vb_type_and_max_size(
                          request->requestvb, ASN_OCTET_STR, SCHED_STR2_LEN);
                if (ret != SNMP_ERR_NOERROR) {
                    netsnmp_set_request_error(reqinfo, request, ret);
                    return SNMP_ERR_NOERROR;
                }
                break;
            case COLUMN_SCHEDINTERVAL:
                ret = netsnmp_check_vb_uint( request->requestvb );
                if (ret != SNMP_ERR_NOERROR) {
                    netsnmp_set_request_error(reqinfo, request, ret);
                    return SNMP_ERR_NOERROR;
                }
                break;
            case COLUMN_SCHEDWEEKDAY:
                ret = netsnmp_check_vb_type_and_size(
                          request->requestvb, ASN_OCTET_STR, 1);
                /* XXX - check for bit(7) set */
                if (ret != SNMP_ERR_NOERROR) {
                    netsnmp_set_request_error(reqinfo, request, ret);
                    return SNMP_ERR_NOERROR;
                }
                break;
            case COLUMN_SCHEDMONTH:
                ret = netsnmp_check_vb_type_and_size(  /* max_size ?? */
                          request->requestvb, ASN_OCTET_STR, 2);
                /* XXX - check for bit(12)-bit(15) set */
                if (ret != SNMP_ERR_NOERROR) {
                    netsnmp_set_request_error(reqinfo, request, ret);
                    return SNMP_ERR_NOERROR;
                }
                break;
            case COLUMN_SCHEDDAY:
                ret = netsnmp_check_vb_type_and_size(  /* max_size ?? */
                          request->requestvb, ASN_OCTET_STR, 4+4);
                /* XXX - check for bit(62) or bit(63) set */
                if (ret != SNMP_ERR_NOERROR) {
                    netsnmp_set_request_error(reqinfo, request, ret);
                    return SNMP_ERR_NOERROR;
                }
                break;
            case COLUMN_SCHEDHOUR:
                ret = netsnmp_check_vb_type_and_size(  /* max_size ?? */
                          request->requestvb, ASN_OCTET_STR, 3);
                if (ret != SNMP_ERR_NOERROR) {
                    netsnmp_set_request_error(reqinfo, request, ret);
                    return SNMP_ERR_NOERROR;
                }
                break;
            case COLUMN_SCHEDMINUTE:
                ret = netsnmp_check_vb_type_and_size(  /* max_size ?? */
                          request->requestvb, ASN_OCTET_STR, 8);
                /* XXX - check for bit(60)-bit(63) set */
                if (ret != SNMP_ERR_NOERROR) {
                    netsnmp_set_request_error(reqinfo, request, ret);
                    return SNMP_ERR_NOERROR;
                }
                break;
            case COLUMN_SCHEDCONTEXTNAME:
                ret = netsnmp_check_vb_type_and_max_size(
                          request->requestvb, ASN_OCTET_STR, SCHED_STR1_LEN);
                if (ret != SNMP_ERR_NOERROR) {
                    netsnmp_set_request_error(reqinfo, request, ret);
                    return SNMP_ERR_NOERROR;
                }
                break;
            case COLUMN_SCHEDVARIABLE:
                ret = netsnmp_check_vb_oid( request->requestvb );
                if (ret != SNMP_ERR_NOERROR) {
                    netsnmp_set_request_error(reqinfo, request, ret);
                    return SNMP_ERR_NOERROR;
                }
                break;
            case COLUMN_SCHEDVALUE:
                ret = netsnmp_check_vb_int( request->requestvb );
                if (ret != SNMP_ERR_NOERROR) {
                    netsnmp_set_request_error(reqinfo, request, ret);
                    return SNMP_ERR_NOERROR;
                }
                break;
            case COLUMN_SCHEDTYPE:
                ret = netsnmp_check_vb_int_range( request->requestvb,
                             SCHED_TYPE_PERIODIC, SCHED_TYPE_ONESHOT );
                if (ret != SNMP_ERR_NOERROR) {
                    netsnmp_set_request_error(reqinfo, request, ret);
                    return SNMP_ERR_NOERROR;
                }
                break;
            case COLUMN_SCHEDADMINSTATUS:
                ret = netsnmp_check_vb_truthvalue( request->requestvb );
                if (ret != SNMP_ERR_NOERROR) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGTYPE);
                    return SNMP_ERR_NOERROR;
                }
                break;
            case COLUMN_SCHEDSTORAGETYPE:
                ret = netsnmp_check_vb_int_range( request->requestvb,
                                                  ST_NONE, ST_READONLY );
                /* XXX - check valid/consistent assignments */
                if (ret != SNMP_ERR_NOERROR) {
                    netsnmp_set_request_error(reqinfo, request, ret);
                    return SNMP_ERR_NOERROR;
                }
                break;
            case COLUMN_SCHEDROWSTATUS:
                ret = netsnmp_check_vb_rowstatus( request->requestvb,
                          (entry ? RS_ACTIVE: RS_NONEXISTENT));
                /* XXX - check consistency assignments */
                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:
        for (request = requests; request; request = request->next) {
            if (request->processed)
                continue;

            tinfo = netsnmp_extract_table_info(request);

            switch (tinfo->colnum) {
            case COLUMN_SCHEDROWSTATUS:
                switch (*request->requestvb->val.integer) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    /*
                     * Create an (empty) new row structure
                     */
                    memset(owner, 0, SCHED_STR1_LEN+1);
                    memset(name,  0, SCHED_STR1_LEN+1);
                    memcpy(owner, tinfo->indexes->val.string,
                                  tinfo->indexes->val_len);
                    memcpy(name,  tinfo->indexes->next_variable->val.string,
                                  tinfo->indexes->next_variable->val_len);
                    row = schedTable_createEntry(owner, name);
                    if (!row) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_RESOURCEUNAVAILABLE);
                        return SNMP_ERR_NOERROR;
                    }
                    netsnmp_insert_tdata_row(request, row);
                }
            }
        }
        break;

    case MODE_SET_FREE:
        for (request = requests; request; request = request->next) {
            if (request->processed)
                continue;

            tinfo = netsnmp_extract_table_info(request);

            switch (tinfo->colnum) {
            case COLUMN_SCHEDROWSTATUS:
                switch (*request->requestvb->val.integer) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    /*
                     * Tidy up after a failed row creation request
                     */ 
                    entry = (struct schedTable_entry *)
                                netsnmp_tdata_extract_entry(request);
                    if (entry &&
                      !(entry->flags & SCHEDULE_FLAG_VALID)) {
                        row = (netsnmp_tdata_row *)
                                netsnmp_tdata_extract_row(request);
                        schedTable_removeEntry(row);
                    }
                }
            }
        }
        break;

    case MODE_SET_ACTION:
        for (request = requests; request; request = request->next) {
            entry = (struct schedTable_entry *)
                    netsnmp_tdata_extract_entry(request);
            if (!entry) {
                /*
                 * New rows must be created via the RowStatus column
                 */
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOCREATION);
                                      /* or inconsistentName? */
                return SNMP_ERR_NOERROR;
            }
        }
        break;

    case MODE_SET_UNDO:
        break;

    case MODE_SET_COMMIT:
        /*
         * All these assignments are "unfailable", so it's
         *  (reasonably) safe to apply them in the Commit phase
         */
        entry = NULL;
        for (request = requests; request; request = request->next) {
            if (request->processed)
                continue;

            entry = (struct schedTable_entry *)
                    netsnmp_tdata_extract_entry(request);
            tinfo = netsnmp_extract_table_info( request);

            switch (tinfo->colnum) {
            case COLUMN_SCHEDDESCR:
                memset(entry->schedDescr, 0, sizeof(entry->schedDescr));
                memcpy(entry->schedDescr, request->requestvb->val.string,
                                          request->requestvb->val_len);
                break;
            case COLUMN_SCHEDINTERVAL:
                entry->schedInterval = *request->requestvb->val.integer;
                recalculate = 1;
                break;
            case COLUMN_SCHEDWEEKDAY:
                entry->schedWeekDay  = request->requestvb->val.string[0];
                recalculate = 1;
                break;
            case COLUMN_SCHEDMONTH:
                entry->schedMonth[0] = request->requestvb->val.string[0];
                entry->schedMonth[1] = request->requestvb->val.string[1];
                recalculate = 1;
                break;
            case COLUMN_SCHEDDAY:
                memset(entry->schedDay, 0, sizeof(entry->schedDay));
                memcpy(entry->schedDay, request->requestvb->val.string,
                                        request->requestvb->val_len);
                recalculate = 1;
                break;
            case COLUMN_SCHEDHOUR:
                entry->schedHour[0]  = request->requestvb->val.string[0];
                entry->schedHour[1]  = request->requestvb->val.string[1];
                entry->schedHour[2]  = request->requestvb->val.string[2];
                recalculate = 1;
                break;
            case COLUMN_SCHEDMINUTE:
                memset(entry->schedMinute, 0, sizeof(entry->schedMinute));
                memcpy(entry->schedMinute, request->requestvb->val.string,
                                           request->requestvb->val_len);
                recalculate = 1;
                break;
            case COLUMN_SCHEDCONTEXTNAME:
                memset(entry->schedContextName, 0, sizeof(entry->schedContextName));
                memcpy(entry->schedContextName,
                                           request->requestvb->val.string,
                                           request->requestvb->val_len);
                break;
            case COLUMN_SCHEDVARIABLE:
                memset(entry->schedVariable, 0, sizeof(entry->schedVariable));
                memcpy(entry->schedVariable,
                                           request->requestvb->val.string,
                                           request->requestvb->val_len);
                entry->schedVariable_len =
                                  request->requestvb->val_len/sizeof(oid);
                break;
            case COLUMN_SCHEDVALUE:
                entry->schedValue = *request->requestvb->val.integer;
                break;
            case COLUMN_SCHEDTYPE:
                entry->schedType  = *request->requestvb->val.integer;
                break;
            case COLUMN_SCHEDADMINSTATUS:
                if (*request->requestvb->val.integer == TV_TRUE)
                    entry->flags |=  SCHEDULE_FLAG_ENABLED;
                else
                    entry->flags &= ~SCHEDULE_FLAG_ENABLED;
                break;
            case COLUMN_SCHEDSTORAGETYPE:
                entry->schedStorageType = *request->requestvb->val.integer;
                break;
            case COLUMN_SCHEDROWSTATUS:
                switch (*request->requestvb->val.integer) {
                case RS_ACTIVE:
                    entry->flags |= SCHEDULE_FLAG_ACTIVE;
                    break;
                case RS_CREATEANDGO:
                    entry->flags |= SCHEDULE_FLAG_ACTIVE;
                    entry->flags |= SCHEDULE_FLAG_VALID;
                    entry->session =
                        netsnmp_iquery_pdu_session(reqinfo->asp->pdu);
                    break;
                case RS_CREATEANDWAIT:
                    entry->flags |= SCHEDULE_FLAG_VALID;
                    entry->session =
                        netsnmp_iquery_pdu_session(reqinfo->asp->pdu);
                    break;

                case RS_DESTROY:
                    row = (netsnmp_tdata_row *)
                               netsnmp_tdata_extract_row(request);
                    schedTable_removeEntry(row);
                }
                recalculate = 1;
                break;
            }
        }
        if (recalculate) {
            netsnmp_assert(entry);
            sched_nextTime(entry);
        }
        break;
    }
    return SNMP_ERR_NOERROR;
}
예제 #5
0
/*******************************************************************************
 函数名称  : mib_dot1qPortVlanTable_handler
 功能描述  : handles requests for the dot1qPortVlanTable table
 输入参数  :
 输出参数  :
 返 回 值  :
 --------------------------------------------------------------------------------
 最近一次修改记录 :
 修改作者   :
 修改目的   :
 修改日期   :
*******************************************************************************/
static int mib_dot1qPortVlanTable_handler(netsnmp_mib_handler *handler,
                    netsnmp_handler_registration *reginfo,
                    netsnmp_agent_request_info *reqinfo,
                    netsnmp_request_info *requests)
{
    netsnmp_request_info       *request;
    netsnmp_table_request_info *table_req_info;
    struct dot1qPortVlanTable_entry *table_entry;
    int                         ret;

    switch (reqinfo->mode)
    {
    /*
     * 这里的GET操作已经覆盖了GET_NEXT操作
     */
    case MODE_GET:
        for (request=requests; request; request=request->next)
        {
            table_entry = (struct dot1qPortVlanTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_req_info  = netsnmp_extract_table_info(request);
            if(NULL == table_req_info)
            {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOACCESS);
                continue;
            }

            switch (table_req_info->colnum)
            {
            case COLUMN_DOT1QPVID:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_UNSIGNED,
                                            htonl(table_entry->dot1qPvid));
                break;

            case COLUMN_DOT1QPORTACCEPTABLEFRAMETYPES:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            htonl(table_entry->dot1qPortAcceptableFrameTypes));
                break;

            case COLUMN_DOT1QPORTINGRESSFILTERING:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            htonl(table_entry->dot1qPortIngressFiltering));
                break;

            case COLUMN_DOT1QPORTGVRPSTATUS:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            htonl(table_entry->dot1qPortGvrpStatus));
                break;

            case COLUMN_DOT1QPORTGVRPFAILEDREGISTRATIONS:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_COUNTER,
                                            htonl(table_entry->dot1qPortGvrpFailedRegistrations));
                break;

            case COLUMN_DOT1QPORTGVRPLASTPDUORIGIN:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR,
                                 (u_char*)table_entry->dot1qPortGvrpLastPduOrigin,
                                          table_entry->dot1qPortGvrpLastPduOrigin_len);
                break;

            default:
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHOBJECT);
                break;

            }
        }
        break;

    /*
     * SET 操作
     */
    case MODE_SET_RESERVE1:
        /* SET第一阶段,检查参数类型 */
        for (request=requests; request; request=request->next)
        {
            table_entry = (struct dot1qPortVlanTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_req_info  = netsnmp_extract_table_info(request);
            if(NULL == table_req_info)
            {
                netsnmp_set_request_error( reqinfo, request,
                                           SNMP_ERR_NOACCESS );
                return SNMP_ERR_NOERROR;
            }

            switch (table_req_info->colnum)
            {
            case COLUMN_DOT1QPVID:
                /* 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;

            case COLUMN_DOT1QPORTGVRPSTATUS:
                /* 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:
        /* SET第二阶段,检查参数值是否正常并分配内存 */
        break;

    case MODE_SET_FREE:
        /* 出错处理,MODE_SET_RESERVE1或MODE_SET_RESERVE2出错时调用。
                  需要释放第一阶段和第二阶段分配的内存 */
        break;

    case MODE_SET_ACTION:
        /* SET第三阶段,执行设置值的具体动作 */
        for (request=requests; request; request=request->next)
        {
            table_entry = (struct dot1qPortVlanTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_req_info  = netsnmp_extract_table_info(request);

            switch (table_req_info->colnum)
            {
            case COLUMN_DOT1QPVID:
                table_entry->old_dot1qPvid = table_entry->dot1qPvid;
                table_entry->dot1qPvid     = *request->requestvb->val.integer;
                break;

            case COLUMN_DOT1QPORTGVRPSTATUS:
                table_entry->old_dot1qPortGvrpStatus = table_entry->dot1qPortGvrpStatus;
                table_entry->dot1qPortGvrpStatus     = *request->requestvb->val.integer;
                break;

            }
        }
        break;

    case MODE_SET_COMMIT:
        /* SET第四阶段,提交设置的值,并释放第三阶段的内存 */
        break;

    case MODE_SET_UNDO:
        /* 出错处理,MODE_SET_ACTION出错时调用
                  需要释放第三阶段分配的内存 */
        for (request=requests; request; request=request->next)
        {
            table_entry = (struct dot1qPortVlanTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_req_info  = netsnmp_extract_table_info( request);

            switch (table_req_info->colnum)
            {
            case COLUMN_DOT1QPVID:
                table_entry->dot1qPvid     = table_entry->old_dot1qPvid;
                table_entry->old_dot1qPvid = 0;
                break;

            case COLUMN_DOT1QPORTGVRPSTATUS:
                table_entry->dot1qPortGvrpStatus     = table_entry->old_dot1qPortGvrpStatus;
                table_entry->old_dot1qPortGvrpStatus = 0;
                break;

            }
        }
        break;

    }
    return SNMP_ERR_NOERROR;
}
예제 #6
0
/*******************************************************************************
 函数名称  : mib_historyControlTable_handler
 功能描述  : handles requests for the historyControlTable table
 输入参数  :
 输出参数  :
 返 回 值  :
 --------------------------------------------------------------------------------
 最近一次修改记录 :
 修改作者   :
 修改目的   :
 修改日期   :
*******************************************************************************/
static int mib_historyControlTable_handler(netsnmp_mib_handler *handler,
                    netsnmp_handler_registration *reginfo,
                    netsnmp_agent_request_info *reqinfo,
                    netsnmp_request_info *requests)
{
    netsnmp_request_info       *request;
    netsnmp_table_request_info *table_req_info;
    struct historyControlTable_entry *table_entry;
    int                         ret;
	
    switch (reqinfo->mode)
    {
    /*
     * 这里的GET操作已经覆盖了GET_NEXT操作
     */
    case MODE_GET:
        for (request=requests; request; request=request->next)
        {
            table_entry = (struct historyControlTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_req_info  = netsnmp_extract_table_info(request);
            if(NULL == table_req_info)
            {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOACCESS);
                continue;
            }

            switch (table_req_info->colnum)
            {
            case COLUMN_HISTORYCONTROLINDEX:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            htonl(table_entry->historyControlIndex));
                break;

            case COLUMN_HISTORYCONTROLDATASOURCE:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_value( request->requestvb, ASN_OBJECT_ID,
                                 (u_char*)table_entry->historyControlDataSource,
                                          table_entry->historyControlDataSource_len);
                break;

            case COLUMN_HISTORYCONTROLBUCKETSREQUESTED:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            htonl(table_entry->historyControlBucketsRequested));
                break;

            case COLUMN_HISTORYCONTROLBUCKETSGRANTED:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            htonl(table_entry->historyControlBucketsGranted));
                break;

            case COLUMN_HISTORYCONTROLINTERVAL:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            htonl(table_entry->historyControlInterval));
                break;

            case COLUMN_HISTORYCONTROLOWNER:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR,
                                 (u_char*)table_entry->historyControlOwner,
                                          table_entry->historyControlOwner_len);
                break;

            case COLUMN_HISTORYCONTROLSTATUS:
                if ( !table_entry )
                {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            htonl(table_entry->historyControlStatus));
                break;

            default:
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHOBJECT);
                break;

            }
        }
        break;

    /*
     * SET 操作
     */
    case MODE_SET_RESERVE1:
        /* SET第一阶段,检查参数类型 */
        for (request=requests; request; request=request->next)
        {
            table_entry = (struct historyControlTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_req_info  = netsnmp_extract_table_info(request);
            if(NULL == table_req_info)
            {
                netsnmp_set_request_error( reqinfo, request,
                                           SNMP_ERR_NOACCESS );
                return SNMP_ERR_NOERROR;
            }

            switch (table_req_info->colnum)
            {
            case COLUMN_HISTORYCONTROLDATASOURCE:
                /* or possibly 'netsnmp_check_vb_type_and_size' */
                ret = netsnmp_check_vb_type_and_max_size(
                          request->requestvb, ASN_OBJECT_ID, sizeof(table_entry->historyControlDataSource));
                if ( ret != SNMP_ERR_NOERROR )
                {
                    netsnmp_set_request_error( reqinfo, request, ret );
                    return SNMP_ERR_NOERROR;
                }
                break;

            case COLUMN_HISTORYCONTROLBUCKETSREQUESTED:
                /* 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;

            case COLUMN_HISTORYCONTROLINTERVAL:
                /* 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;

            case COLUMN_HISTORYCONTROLOWNER:
                /* or possibly 'netsnmp_check_vb_type_and_size' */
                ret = netsnmp_check_vb_type_and_max_size(
                          request->requestvb, ASN_OCTET_STR, sizeof(table_entry->historyControlOwner));
                if ( ret != SNMP_ERR_NOERROR )
                {
                    netsnmp_set_request_error( reqinfo, request, ret );
                    return SNMP_ERR_NOERROR;
                }
                break;

            case COLUMN_HISTORYCONTROLSTATUS:
                /* 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:
        /* 出错处理,MODE_SET_RESERVE1或MODE_SET_RESERVE2出错时调用。
                  需要释放第一阶段和第二阶段分配的内存 */
        for (request=requests; request; request=request->next)
        {
            table_entry = (struct historyControlTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_req_info  = netsnmp_extract_table_info( request);

            switch (table_req_info->colnum)
            {
            case COLUMN_HISTORYCONTROLDATASOURCE:
            case COLUMN_HISTORYCONTROLBUCKETSREQUESTED:
            case COLUMN_HISTORYCONTROLINTERVAL:
            case COLUMN_HISTORYCONTROLOWNER:
            case COLUMN_HISTORYCONTROLSTATUS:
                if ( table_entry && table_entry->new_record )
                {
                    mib_historyControlTable_removeEntry(table_entry );
                    (void)netsnmp_remove_iterator_context(request);
                }
                break;

            }
        }
        break;

    case MODE_SET_ACTION:
        /* SET第三阶段,执行设置值的具体动作 */
        for (request=requests; request; request=request->next)
        {
            table_entry = (struct historyControlTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_req_info  = netsnmp_extract_table_info(request);

            switch (table_req_info->colnum)
            {
            case COLUMN_HISTORYCONTROLDATASOURCE:
                memcpy( table_entry->old_historyControlDataSource,
                        table_entry->historyControlDataSource,
                        sizeof(table_entry->historyControlDataSource));
                table_entry->old_historyControlDataSource_len =
                        table_entry->historyControlDataSource_len;
                memset( table_entry->historyControlDataSource, 0,
                        sizeof(table_entry->historyControlDataSource));
                memcpy( table_entry->historyControlDataSource,
                        request->requestvb->val.string,
                        request->requestvb->val_len);
                table_entry->historyControlDataSource_len =
                        request->requestvb->val_len;
                break;

            case COLUMN_HISTORYCONTROLBUCKETSREQUESTED:
                table_entry->old_historyControlBucketsRequested = table_entry->historyControlBucketsRequested;
                table_entry->historyControlBucketsRequested     = *request->requestvb->val.integer;
                break;

            case COLUMN_HISTORYCONTROLINTERVAL:
                table_entry->old_historyControlInterval = table_entry->historyControlInterval;
                table_entry->historyControlInterval     = *request->requestvb->val.integer;
                break;

            case COLUMN_HISTORYCONTROLOWNER:
                memcpy( table_entry->old_historyControlOwner,
                        table_entry->historyControlOwner,
                        sizeof(table_entry->historyControlOwner));
                table_entry->old_historyControlOwner_len =
                        table_entry->historyControlOwner_len;
                memset( table_entry->historyControlOwner, 0,
                        sizeof(table_entry->historyControlOwner));
                memcpy( table_entry->historyControlOwner,
                        request->requestvb->val.string,
                        request->requestvb->val_len);
                table_entry->historyControlOwner_len =
                        request->requestvb->val_len;
                break;

            case COLUMN_HISTORYCONTROLSTATUS:
                table_entry->old_historyControlStatus = table_entry->historyControlStatus;
                table_entry->historyControlStatus     = *request->requestvb->val.integer;
                break;

            }
        }
        break;

    case MODE_SET_COMMIT:
        /* SET第四阶段,提交设置的值,并释放第三阶段的内存 */
        for (request=requests; request; request=request->next)
        {
            table_entry = (struct historyControlTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_req_info  = netsnmp_extract_table_info( request);

            switch (table_req_info->colnum)
            {
            case COLUMN_HISTORYCONTROLDATASOURCE:
            case COLUMN_HISTORYCONTROLBUCKETSREQUESTED:
            case COLUMN_HISTORYCONTROLINTERVAL:
            case COLUMN_HISTORYCONTROLOWNER:
            case COLUMN_HISTORYCONTROLSTATUS:
                if ( table_entry && table_entry->new_record )
                {
                    mib_historyControlTable_removeEntry( table_entry );
                    (void)netsnmp_remove_iterator_context(request);
                }
            }
        }
        break;

    case MODE_SET_UNDO:
        /* 出错处理,MODE_SET_ACTION出错时调用
                  需要释放第三阶段分配的内存 */
        for (request=requests; request; request=request->next)
        {
            table_entry = (struct historyControlTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_req_info  = netsnmp_extract_table_info( request);

            switch (table_req_info->colnum)
            {
            case COLUMN_HISTORYCONTROLDATASOURCE:
                if ( table_entry && table_entry->new_record )
                {
                    mib_historyControlTable_removeEntry( table_entry );
                    (void)netsnmp_remove_iterator_context(request);
                }
                else if (table_entry)
                {
                    memcpy( table_entry->historyControlDataSource,
                            table_entry->old_historyControlDataSource,
                            sizeof(table_entry->historyControlDataSource));
                    memset( table_entry->old_historyControlDataSource, 0,
                            sizeof(table_entry->historyControlDataSource));
                    table_entry->historyControlDataSource_len =
                            table_entry->old_historyControlDataSource_len;
                }
                break;

            case COLUMN_HISTORYCONTROLBUCKETSREQUESTED:
                if ( table_entry && table_entry->new_record )
                {
                    mib_historyControlTable_removeEntry( table_entry );
                    (void)netsnmp_remove_iterator_context(request);
                }
                else if (table_entry)
                {
                    table_entry->historyControlBucketsRequested     = table_entry->old_historyControlBucketsRequested;
                    table_entry->old_historyControlBucketsRequested = 0;
                }
                break;

            case COLUMN_HISTORYCONTROLINTERVAL:
                if ( table_entry && table_entry->new_record )
                {
                    mib_historyControlTable_removeEntry( table_entry );
                    (void)netsnmp_remove_iterator_context(request);
                }
                else if (table_entry)
                {
                    table_entry->historyControlInterval     = table_entry->old_historyControlInterval;
                    table_entry->old_historyControlInterval = 0;
                }
                break;

            case COLUMN_HISTORYCONTROLOWNER:
                if ( table_entry && table_entry->new_record )
                {
                    mib_historyControlTable_removeEntry( table_entry );
                    (void)netsnmp_remove_iterator_context(request);
                }
                else if (table_entry)
                {
                    memcpy( table_entry->historyControlOwner,
                            table_entry->old_historyControlOwner,
                            sizeof(table_entry->historyControlOwner));
                    memset( table_entry->old_historyControlOwner, 0,
                            sizeof(table_entry->historyControlOwner));
                    table_entry->historyControlOwner_len =
                            table_entry->old_historyControlOwner_len;
                }
                break;

            case COLUMN_HISTORYCONTROLSTATUS:
                if ( table_entry && table_entry->new_record )
                {
                    mib_historyControlTable_removeEntry( table_entry );
                    (void)netsnmp_remove_iterator_context(request);
                }
                else if (table_entry)
                {
                    table_entry->historyControlStatus     = table_entry->old_historyControlStatus;
                    table_entry->old_historyControlStatus = 0;
                }
                break;

            }
        }
        break;

    }
    return SNMP_ERR_NOERROR;
}