예제 #1
0
int
add_agent_caps_list(netsnmp_session * session, netsnmp_pdu *pdu)
{
    netsnmp_session *sp;
    char* description;

    sp = find_agentx_session(session, pdu->sessid);
    if (sp == NULL)
        return AGENTX_ERR_NOT_OPEN;

    description = netsnmp_strdup_and_null(pdu->variables->val.string,
                                          pdu->variables->val_len);
    register_sysORTable_sess(pdu->variables->name, pdu->variables->name_length,
                             description, sp);
    free(description);
    return AGENTX_ERR_NOERROR;
}
/*
 * send trap 
 */
void
run_mte_events(struct mteTriggerTable_data *item,
               oid * name_oid, size_t name_oid_len,
               const char *eventobjowner, const char *eventobjname)
{
    static oid      objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };     /* snmpTrapIOD.0 */

    netsnmp_variable_list *var_list = NULL;

    netsnmp_table_row *row, *notif_row;
    netsnmp_table_data_set_storage *col1, *tc, *no, *noo;

    for(row = table_set->table->first_row; row; row = row->next) {
        if (strcmp(row->indexes->val.string, eventobjowner) == 0 &&
            strcmp(row->indexes->next_variable->val.string,
                   eventobjname) == 0) {
            /* run this event */
            col1 = (netsnmp_table_data_set_storage *) row->data;
            
            tc = netsnmp_table_data_set_find_column(col1,
                                                    COLUMN_MTEEVENTACTIONS);
            if (!tc->data.bitstring[0] & 0x80) {
                /* not a notification.  next! (XXX: do sets) */
                continue;
            }

            tc = netsnmp_table_data_set_find_column(col1,
                                                    COLUMN_MTEEVENTENABLED);
            if (*(tc->data.integer) != 1) {
                /* not enabled.  next! */
                continue;
            }

            if (!mteEventNotif_table_set) {
                /* no notification info */
                continue;
            }

            /* send the notification */
            var_list = NULL;

            /* XXX: get notif information */
            for(notif_row = mteEventNotif_table_set->table->first_row;
                notif_row; notif_row = notif_row->next) {
                if (strcmp(notif_row->indexes->val.string,
                           eventobjowner) == 0 &&
                    strcmp(notif_row->indexes->next_variable->val.string,
                           eventobjname) == 0) {

                    /* run this event */
                    col1 = (netsnmp_table_data_set_storage *) notif_row->data;
            
                    tc = netsnmp_table_data_set_find_column(col1, COLUMN_MTEEVENTNOTIFICATION);
                    no = netsnmp_table_data_set_find_column(col1, COLUMN_MTEEVENTNOTIFICATIONOBJECTS);
                    noo = netsnmp_table_data_set_find_column(col1, COLUMN_MTEEVENTNOTIFICATIONOBJECTSOWNER);
                    if (!tc)
                        continue; /* no notification to be had. XXX: return? */
                    
                    /*
                     * snmpTrap oid 
                     */
                    snmp_varlist_add_variable(&var_list, objid_snmptrap,
                                              sizeof(objid_snmptrap) /
                                              sizeof(oid),
                                              ASN_OBJECT_ID,
                                              (u_char *) tc->data.objid,
                                              tc->data_len);

                    /* XXX: add objects from the mteObjectsTable */
                    DEBUGMSGTL(("mteEventTable:send_events", "no: %x, no->data: %s", no, no->data.string));
                    DEBUGMSGTL(("mteEventTable:send_events", "noo: %x, noo->data: %s", noo, noo->data.string));
                    DEBUGMSGTL(("mteEventTable:send_events", "name_oid: %x",name_oid));
                    if (no && no->data.string &&
                        noo && noo->data.string && name_oid) {
                        char *tmpowner =
                            netsnmp_strdup_and_null(noo->data.string,
                                                    noo->data_len);
                        char *tmpname =
                            netsnmp_strdup_and_null(no->data.string,
                                                    no->data_len);

                        DEBUGMSGTL(("mteEventTable:send_events", "Adding objects for owner=%s name=%s", tmpowner, tmpname));
                        mte_add_objects(var_list, item,
                                        tmpowner, tmpname, 
                                       name_oid + item->mteTriggerValueIDLen,
                                        name_oid_len - item->mteTriggerValueIDLen);
                        free(tmpowner);
                        free(tmpname);
                    }

                    DEBUGMSGTL(("mteEventTable:send_events", "sending an event "));
                    DEBUGMSGOID(("mteEventTable:send_events", tc->data.objid, tc->data_len / sizeof(oid)));
                    DEBUGMSG(("mteEventTable:send_events", "\n"));
                    
                    send_v2trap(var_list);
                    snmp_free_varbind(var_list);
                }
            }
        }
    }
}
예제 #3
0
/** implements the table data helper.  This is the routine that takes
 *  care of all SNMP requests coming into the table. */
int
netsnmp_table_data_set_helper_handler(netsnmp_mib_handler *handler,
                                      netsnmp_handler_registration
                                      *reginfo,
                                      netsnmp_agent_request_info *reqinfo,
                                      netsnmp_request_info *requests)
{

    netsnmp_table_data_set_storage *data = NULL;
    newrow_stash   *newrowstash = NULL;
    netsnmp_table_row *row, *newrow = NULL;
    netsnmp_table_request_info *table_info;
    netsnmp_request_info *request;
    oid            *suffix;
    size_t          suffix_len;
    netsnmp_oid_stash_node **stashp = NULL;

    if (!handler)
        return SNMPERR_GENERR;
        
    DEBUGMSGTL(("netsnmp_table_data_set", "handler starting\n"));
    for (request = requests; request; request = request->next) {
        netsnmp_table_data_set *datatable =
            (netsnmp_table_data_set *) handler->myvoid;
        if (request->processed)
            continue;

        /*
         * extract our stored data and table info 
         */
        row = netsnmp_extract_table_row(request);
        table_info = netsnmp_extract_table_info(request);
        suffix = requests->requestvb->name + reginfo->rootoid_len + 2;
        suffix_len = requests->requestvb->name_length -
            (reginfo->rootoid_len + 2);

        if (MODE_IS_SET(reqinfo->mode)) {

            char buf[256]; /* is this reasonable size?? */
            int  rc;
            size_t len;

            /*
             * use a cached copy of the row for modification 
             */

            /*
             * cache location: may have been created already by other
             * SET requests in the same master request. 
             */
            rc = snprintf(buf, sizeof(buf), "dataset_row_stash:%s:",
                          datatable->table->name);
            if ((-1 == rc) || (rc >= sizeof(buf))) {
                snmp_log(LOG_ERR,"%s handler name too long\n",
                         datatable->table->name);
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_GENERR);
                continue;
            }
            len = sizeof(buf) - rc;
            rc = snprint_objid(&buf[rc], len, table_info->index_oid,
                               table_info->index_oid_len);
            if (-1 == rc) {
                snmp_log(LOG_ERR,"%s oid or name too long\n",
                         datatable->table->name);
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_GENERR);
                continue;
            }
            stashp = (netsnmp_oid_stash_node **)
                netsnmp_table_get_or_create_row_stash(reqinfo, buf);

            newrowstash
                = netsnmp_oid_stash_get_data(*stashp, suffix, suffix_len);

            if (!newrowstash) {
                if (!row) {
                    if (datatable->allow_creation) {
                        /*
                         * entirely new row.  Create the row from the template 
                         */
                        newrowstash =
                             netsnmp_table_data_set_create_newrowstash(
                                                 datatable, table_info);
                        newrow = newrowstash->newrow;
                    } else if (datatable->rowstatus_column == 0) {
                        /*
                         * A RowStatus object may be used to control the
                         *  creation of a new row.  But if this object
                         *  isn't declared (and the table isn't marked as
                         *  'auto-create'), then we can't create a new row.
                         */
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_NOCREATION);
                        continue;
                    }
                } else {
                    /*
                     * existing row that needs to be modified 
                     */
                    newrowstash = SNMP_MALLOC_TYPEDEF(newrow_stash);
                    newrow = netsnmp_table_data_set_clone_row(row);
                    newrowstash->newrow = newrow;
                }
                netsnmp_oid_stash_add_data(stashp, suffix, suffix_len,
                                           newrowstash);
            } else {
                newrow = newrowstash->newrow;
            }
            /*
             * all future SET data modification operations use this
             * temp pointer 
             */
            if (reqinfo->mode == MODE_SET_RESERVE1 ||
                reqinfo->mode == MODE_SET_RESERVE2)
                row = newrow;
        }

        if (row)
            data = (netsnmp_table_data_set_storage *) row->data;

        if (!row || !table_info || !data) {
            if (!MODE_IS_SET(reqinfo->mode)) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHINSTANCE);
                continue;
            }
        }

        data =
            netsnmp_table_data_set_find_column(data, table_info->colnum);

        switch (reqinfo->mode) {
        case MODE_GET:
        case MODE_GETNEXT:
        case MODE_GETBULK:     /* XXXWWW */
            if (data && data->data.voidp)
                netsnmp_table_data_build_result(reginfo, reqinfo, request,
                                                row,
                                                table_info->colnum,
                                                data->type,
                                                data->data.voidp,
                                                data->data_len);
            break;

        case MODE_SET_RESERVE1:
            if (data) {
                /*
                 * Can we modify the existing row?
                 */
                if (!data->writable) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_NOTWRITABLE);
                } else if (request->requestvb->type != data->type) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGTYPE);
                }
            } else if (datatable->rowstatus_column == table_info->colnum) {
                /*
                 * Otherwise, this is where we create a new row using
                 * the RowStatus object (essentially duplicating the
                 * steps followed earlier in the 'allow_creation' case)
                 */
                switch (*(request->requestvb->val.integer)) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    newrowstash =
                             netsnmp_table_data_set_create_newrowstash(
                                                 datatable, table_info);
                    newrow = newrowstash->newrow;
                    row    = newrow;
                    netsnmp_oid_stash_add_data(stashp, suffix, suffix_len,
                                               newrowstash);
                }
            }
            break;

        case MODE_SET_RESERVE2:
            /*
             * If the agent receives a SET request for an object in a non-existant
             *  row, then the RESERVE1 pass will create the row automatically.
             *
             * But since the row doesn't exist at that point, the test for whether
             *  the object is writable or not will be skipped.  So we need to check
             *  for this possibility again here.
             *
             * Similarly, if row creation is under the control of the RowStatus
             *  object (i.e. allow_creation == 0), but this particular request
             *  doesn't include such an object, then the row won't have been created,
             *  and the writable check will also have been skipped.  Again - check here.
             */
            if (data && data->writable == 0) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOTWRITABLE);
                continue;
            }
            if (datatable->rowstatus_column == table_info->colnum) {
                switch (*(request->requestvb->val.integer)) {
                case RS_ACTIVE:
                case RS_NOTINSERVICE:
                    /*
                     * Can only operate on pre-existing rows.
                     */
                    if (!newrowstash || newrowstash->created) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_INCONSISTENTVALUE);
                        continue;
                    }
                    break;

                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    /*
                     * Can only operate on newly created rows.
                     */
                    if (!(newrowstash && newrowstash->created)) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_INCONSISTENTVALUE);
                        continue;
                    }
                    break;

                case RS_DESTROY:
                    /*
                     * Can operate on new or pre-existing rows.
                     */
                    break;

                case RS_NOTREADY:
                default:
                    /*
                     * Not a valid value to Set 
                     */
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGVALUE);
                    continue;
                }
            }
            if (!data ) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOCREATION);
                continue;
            }

            /*
             * modify row and set new value 
             */
            SNMP_FREE(data->data.string);
            data->data.string =
                netsnmp_strdup_and_null(request->requestvb->val.string,
                                        request->requestvb->val_len);
            if (!data->data.string) {
                netsnmp_set_request_error(reqinfo, requests,
                                          SNMP_ERR_RESOURCEUNAVAILABLE);
            }
            data->data_len = request->requestvb->val_len;

            if (datatable->rowstatus_column == table_info->colnum) {
                switch (*(request->requestvb->val.integer)) {
                case RS_CREATEANDGO:
                    /*
                     * XXX: check legality 
                     */
                    *(data->data.integer) = RS_ACTIVE;
                    break;

                case RS_CREATEANDWAIT:
                    /*
                     * XXX: check legality 
                     */
                    *(data->data.integer) = RS_NOTINSERVICE;
                    break;

                case RS_DESTROY:
                    newrowstash->deleted = 1;
                    break;
                }
            }
            break;

        case MODE_SET_ACTION:

            /*
             * Install the new row into the stored table.
	     * Do this only *once* per row ....
             */
            if (newrowstash->state != STATE_ACTION) {
                newrowstash->state = STATE_ACTION;
		if (newrowstash->created) {
                    netsnmp_table_dataset_add_row(datatable, newrow);
                } else {
                    netsnmp_table_dataset_replace_row(datatable,
                                                      row, newrow);
                }
            }
            /*
             * ... but every (relevant) varbind in the request will
	     * need to know about this new row, so update the
	     * per-request row information regardless
             */
            if (newrowstash->created) {
		netsnmp_request_add_list_data(request,
			netsnmp_create_data_list(TABLE_DATA_NAME,
						 newrow, NULL));
            }
            break;

        case MODE_SET_UNDO:
            /*
             * extract the new row, replace with the old or delete 
             */
            if (newrowstash->state != STATE_UNDO) {
                newrowstash->state = STATE_UNDO;
                if (newrowstash->created) {
                    netsnmp_table_dataset_remove_and_delete_row(datatable, newrow);
                } else {
                    netsnmp_table_dataset_replace_row(datatable,
                                                      newrow, row);
                    netsnmp_table_dataset_delete_row(newrow);
                }
            }
            break;

        case MODE_SET_COMMIT:
            if (newrowstash->state != STATE_COMMIT) {
                newrowstash->state = STATE_COMMIT;
                if (!newrowstash->created) {
                    netsnmp_table_dataset_delete_row(row);
                }
                if (newrowstash->deleted) {
                    netsnmp_table_dataset_remove_and_delete_row(datatable, newrow);
                }
            }
            break;

        case MODE_SET_FREE:
            if (newrowstash && newrowstash->state != STATE_FREE) {
                newrowstash->state = STATE_FREE;
                netsnmp_table_dataset_delete_row(newrow);
            }
            break;
        }
    }

    /* next handler called automatically - 'AUTO_NEXT' */
    return SNMP_ERR_NOERROR;
}
예제 #4
0
/*
 * save info from incoming trap
 *
 * return 0 on success, anything else is an error
 */
static int
_sql_save_trap_info(sql_buf *sqlb, netsnmp_pdu  *pdu,
                    netsnmp_transport     *transport)
{
    static oid   trapoids[] = { 1, 3, 6, 1, 6, 3, 1, 1, 5, 0 };
    oid         *trap_oid, tmp_oid[MAX_OID_LEN];
    time_t       now;
    struct tm   *cur_time;
    size_t       tmp_size;
    size_t       buf_host_len_t, buf_oid_len_t, buf_user_len_t;
    int          oid_overflow, trap_oid_len;
    netsnmp_variable_list *vars;

    if ((NULL == sqlb) || (NULL == pdu) || (NULL == transport))
        return -1;

    DEBUGMSGTL(("sql:queue", "queueing incoming trap\n"));

    /** time */
    (void) time(&now);
    cur_time = localtime(&now);
    sqlb->time.year = cur_time->tm_year + 1900;
    sqlb->time.month = cur_time->tm_mon + 1;
    sqlb->time.day = cur_time->tm_mday;
    sqlb->time.hour = cur_time->tm_hour;
    sqlb->time.minute = cur_time->tm_min;
    sqlb->time.second = cur_time->tm_sec;
    sqlb->time.second_part = 0;
    sqlb->time.neg = 0;

    /** host name */
    buf_host_len_t = 0;
    tmp_size = sizeof(sqlb->host);
    realloc_format_trap((u_char**)&sqlb->host, &tmp_size,
                        &buf_host_len_t, 1, "%B", pdu, transport);
    sqlb->host_len = buf_host_len_t;

    /* snmpTrapOID */
    if (pdu->command == SNMP_MSG_TRAP) {
        /*
         * convert a v1 trap to a v2 varbind
         */
        if (pdu->trap_type == SNMP_TRAP_ENTERPRISESPECIFIC) {
            trap_oid_len = pdu->enterprise_length;
            memcpy(tmp_oid, pdu->enterprise, sizeof(oid) * trap_oid_len);
            if (tmp_oid[trap_oid_len - 1] != 0)
                tmp_oid[trap_oid_len++] = 0;
            tmp_oid[trap_oid_len++] = pdu->specific_type;
            trap_oid = tmp_oid;
        } else {
            trapoids[9] = pdu->trap_type + 1;
            trap_oid = trapoids;
            trap_oid_len = OID_LENGTH(trapoids);
        }
    }
    else {
        vars = pdu->variables;
        if (vars && vars->next_variable) {
            trap_oid_len = vars->next_variable->val_len / sizeof(oid);
            trap_oid = vars->next_variable->val.objid;
        }
        else {
            static oid null_oid[] = { 0, 0 };
            trap_oid_len = OID_LENGTH(null_oid);
            trap_oid = null_oid;
        }
    }
    tmp_size = 0;
    buf_oid_len_t = oid_overflow = 0;
    netsnmp_sprint_realloc_objid_tree((u_char**)&sqlb->oid,&tmp_size,
                                      &buf_oid_len_t, 1, &oid_overflow,
                                      trap_oid, trap_oid_len);
    sqlb->oid_len = buf_oid_len_t;
    if (oid_overflow)
        snmp_log(LOG_WARNING,"OID truncated in sql buffer\n");

    /** request id */
    sqlb->reqid = pdu->reqid;

    /** version (convert to 1 based, for sql enum) */
    sqlb->version = pdu->version + 1;

    /** command type (convert to 1 based, for sql enum) */
    sqlb->type = pdu->command - 159;

    /** community string/user name */
    tmp_size = 0;
    buf_user_len_t = 0;
    realloc_format_trap((u_char**)&sqlb->user, &tmp_size,
                        &buf_user_len_t, 1, "%u", pdu, transport);
    sqlb->user_len = buf_user_len_t;

    /** transport */
    sqlb->transport = transport->f_fmtaddr(transport, pdu->transport_data,
                                           pdu->transport_data_length);

    /** security model */
    sqlb->security_model = pdu->securityModel;

    if ((SNMP_MP_MODEL_SNMPv3+1) == sqlb->version) {

        sqlb->msgid = pdu->msgid;
        sqlb->security_level = pdu->securityLevel;

        if (pdu->contextName) {
            sqlb->context = netsnmp_strdup_and_null((u_char*)pdu->contextName,
                                                    pdu->contextNameLen);
            sqlb->context_len = pdu->contextNameLen;
        }
        if (pdu->contextEngineID) {
            sqlb->context_engine_len = 
                binary_to_hex(pdu->contextEngineID, pdu->contextEngineIDLen,
                              &sqlb->context_engine);
        }

        if (pdu->securityName) {
            sqlb->security_name =
                netsnmp_strdup_and_null((u_char*)pdu->securityName,
                                        pdu->securityNameLen);
            sqlb->security_name_len = pdu->securityNameLen;
        }
        if (pdu->securityEngineID) {
            sqlb->security_engine_len = 
                binary_to_hex(pdu->securityEngineID, pdu->securityEngineIDLen,
                              &sqlb->security_engine);
        }
    }

    return 0;
}
예제 #5
0
int
write_mteTriggerBooleanEvent (int action,
                              u_char * var_val,
                              u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len)
{
    static char *tmpvar;

    struct mteTriggerTable_data *StorageTmp = NULL;

    static size_t tmplen;

    size_t newlen = name_len - (sizeof (mteTriggerBooleanTable_variables_oid) / sizeof (oid) + 3 - 1);


    DEBUGMSGTL (("mteTriggerBooleanTable", "write_mteTriggerBooleanEvent entering action=%d...  \n", action));
    if ((StorageTmp =
         header_complex (mteTriggerTableStorage, NULL,
                         &name[sizeof (mteTriggerBooleanTable_variables_oid)
                               / sizeof (oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL)
        return SNMP_ERR_NOSUCHNAME;    /* remove if you support creation here */


    switch (action)
    {
        case RESERVE1:
            if (var_val_type != ASN_OCTET_STR)
            {
                fprintf (stderr, "write to mteTriggerBooleanEvent not ASN_OCTET_STR\n");
                return SNMP_ERR_WRONGTYPE;
            }
            if (StorageTmp->storageType != ST_NONVOLATILE)
                return SNMP_ERR_NOTWRITABLE;
            break;


        case RESERVE2:
            /*
             * memory reseveration, final preparation... 
             */
            break;


        case FREE:
            /*
             * Release any resources that have been allocated 
             */
            break;


        case ACTION:
            /*
             * The variable has been stored in string for
             * you to use, and you have just been asked to do something with
             * it.  Note that anything done here must be reversable in the UNDO case 
             */
            tmpvar = StorageTmp->mteTriggerBooleanEvent;
            tmplen = StorageTmp->mteTriggerBooleanEventLen;
            StorageTmp->mteTriggerBooleanEvent = netsnmp_strdup_and_null (var_val, var_val_len);
            StorageTmp->mteTriggerBooleanEventLen = var_val_len;
            break;


        case UNDO:
            /*
             * Back out any changes made in the ACTION case 
             */
            SNMP_FREE (StorageTmp->mteTriggerBooleanEvent);
            StorageTmp->mteTriggerBooleanEvent = tmpvar;
            StorageTmp->mteTriggerBooleanEventLen = tmplen;
            break;


        case COMMIT:
            /*
             * Things are working well, so it's now safe to make the change
             * permanently.  Make sure that anything done here can't fail! 
             */
            SNMP_FREE (tmpvar);
            break;
    }
    return SNMP_ERR_NOERROR;
}
예제 #6
0
int
mte_add_object_to_table(const char *owner, const char *objname,
                        oid * oidname, size_t oidname_len, int iswild)
{
    struct header_complex_index *hcptr = mteObjectsTableStorage, *lastnode;
    static struct mteObjectsTable_data *StorageNew;

    /*
     * malloc initial struct 
     */
    StorageNew = SNMP_MALLOC_STRUCT(mteObjectsTable_data);
    if (StorageNew == NULL)
        return SNMP_ERR_GENERR;
    StorageNew->mteOwner = netsnmp_strdup_and_null(owner, strlen(owner));
    StorageNew->mteOwnerLen = strlen(owner);
    StorageNew->mteObjectsName = netsnmp_strdup_and_null(objname,
                                                         strlen(objname));
    StorageNew->mteObjectsNameLen = strlen(objname);

    /*
     * find the next number 
     */
    /*
     * get to start of objects list 
     */
    while (hcptr &&
           (strcmp(((struct mteObjectsTable_data *) hcptr->data)->mteOwner,
                   owner) != 0 ||
            strcmp(((struct mteObjectsTable_data *) hcptr->data)->
                   mteObjectsName, objname) != 0))
        hcptr = hcptr->next;

    if (hcptr) {
        /*
         * an object existed.  Find the first one past and increment
         * the previous number 
         */
        lastnode = hcptr;
        while (hcptr &&
               strcmp(((struct mteObjectsTable_data *) hcptr->data)->
                      mteOwner, owner) == 0
               && strcmp(((struct mteObjectsTable_data *) hcptr->data)->
                         mteObjectsName, objname) == 0) {
            lastnode = hcptr;
            hcptr = hcptr->next;
        }
        StorageNew->mteObjectsIndex =
            ((struct mteObjectsTable_data *) lastnode->data)->
            mteObjectsIndex + 1;
    } else {
        StorageNew->mteObjectsIndex = 1;
    }

    /*
     * XXX: fill in default row values here into StorageNew 
     */
    StorageNew->mteObjectsID = snmp_duplicate_objid(oidname, oidname_len);
    StorageNew->mteObjectsIDLen = oidname_len;

    if (iswild)
        StorageNew->mteObjectsIDWildcard = MTEOBJECTSIDWILDCARD_TRUE;
    else
        StorageNew->mteObjectsIDWildcard = MTEOBJECTSIDWILDCARD_FALSE;

    StorageNew->mteObjectsEntryStatus = RS_ACTIVE;
    StorageNew->storagetype = ST_READONLY;
    return mteObjectsTable_add(StorageNew);
}
예제 #7
0
int
write_mteObjectsEntryStatus(int action,
                            u_char * var_val,
                            u_char var_val_type,
                            size_t var_val_len,
                            u_char * statP, oid * name, size_t name_len)
{
    struct mteObjectsTable_data *StorageTmp = NULL;
    static struct mteObjectsTable_data *StorageNew, *StorageDel;
    size_t          newlen =
        name_len - (sizeof(mteObjectsTable_variables_oid) / sizeof(oid) +
                    3 - 1);
    static int      old_value;
    int             set_value;
    static netsnmp_variable_list *vars, *vp;
    struct header_complex_index *hciptr;


    StorageTmp =
        header_complex(mteObjectsTableStorage, NULL,
                       &name[sizeof(mteObjectsTable_variables_oid) /
                             sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL);

    if (var_val_type != ASN_INTEGER || var_val == NULL) {
        snmp_log(LOG_ERR,
                 "write to mteObjectsEntryStatus not ASN_INTEGER\n");
        return SNMP_ERR_WRONGTYPE;
    }

    if (StorageTmp && StorageTmp->storagetype == ST_READONLY) {
        return SNMP_ERR_NOTWRITABLE;
    }

    set_value = *((long *) var_val);


    /*
     * check legal range, and notReady is reserved for us, not a user 
     */
    if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY)
        return SNMP_ERR_INCONSISTENTVALUE;


    switch (action) {
    case RESERVE1:
        /*
         * stage one: test validity 
         */
        if (StorageTmp == NULL) {
            /*
             * create the row now? 
             */


            /*
             * ditch illegal values now 
             */
            if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE)
                return SNMP_ERR_INCONSISTENTVALUE;


            /*
             * destroying a non-existent row is actually legal 
             */
            if (set_value == RS_DESTROY) {
                return SNMP_ERR_NOERROR;
            }


            /*
             * illegal creation values 
             */
            if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) {
                return SNMP_ERR_INCONSISTENTVALUE;
            }
        } else {
            /*
             * row exists.  Check for a valid state change 
             */
            if (set_value == RS_CREATEANDGO
                || set_value == RS_CREATEANDWAIT) {
                /*
                 * can't create a row that exists 
                 */
                return SNMP_ERR_INCONSISTENTVALUE;
            }
            /*
             * XXX: interaction with row storage type needed 
             */
        }
        break;




    case RESERVE2:
        /*
         * memory reseveration, final preparation... 
         */
        if (StorageTmp == NULL) {
            /*
             * creation 
             */
            vars = NULL;


            snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0);  /* mteOwner */
            snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0);  /* mteObjectsName */
            snmp_varlist_add_variable(&vars, NULL, 0, ASN_UNSIGNED, NULL, 0);   /* mteObjectsIndex */

            if (header_complex_parse_oid
                (&
                 (name
                  [sizeof(mteObjectsTable_variables_oid) / sizeof(oid) +
                   2]), newlen, vars) != SNMPERR_SUCCESS) {
                /*
                 * XXX: free, zero vars 
                 */
                return SNMP_ERR_INCONSISTENTNAME;
            }
            vp = vars;


            StorageNew = SNMP_MALLOC_STRUCT(mteObjectsTable_data);
            if (StorageNew == NULL)
                return SNMP_ERR_GENERR;
            StorageNew->mteOwner = netsnmp_strdup_and_null(vp->val.string,
                                                           vp->val_len);
            StorageNew->mteOwnerLen = vp->val_len;
            vp = vp->next_variable;
            StorageNew->mteObjectsName  =
                netsnmp_strdup_and_null(vp->val.string,
                                        vp->val_len);
            StorageNew->mteObjectsNameLen = vp->val_len;
            vp = vp->next_variable;
            StorageNew->mteObjectsIndex = *(vp->val.integer);

            /*
             * XXX: fill in default row values here into StorageNew 
             */
            StorageNew->mteObjectsID = calloc(1, sizeof(oid) * sizeof(2));      /* 0.0 */
            StorageNew->mteObjectsIDLen = 2;
            StorageNew->mteObjectsIDWildcard = MTEOBJECTSIDWILDCARD_FALSE;

            StorageNew->mteObjectsEntryStatus = set_value;
            /*
             * XXX: free, zero vars, no longer needed? 
             */
        }


        break;




    case FREE:
        /*
         * XXX: free, zero vars 
         */
        /*
         * Release any resources that have been allocated 
         */
        break;




    case ACTION:
        /*
         * The variable has been stored in set_value for you to
         * use, and you have just been asked to do something with
         * it.  Note that anything done here must be reversable in
         * the UNDO case 
         */


        if (StorageTmp == NULL) {
            /*
             * row creation, so add it 
             */
            if (StorageNew != NULL)
                mteObjectsTable_add(StorageNew);
            /*
             * XXX: ack, and if it is NULL? 
             */
        } else if (set_value != RS_DESTROY) {
            /*
             * set the flag? 
             */
            old_value = StorageTmp->mteObjectsEntryStatus;
            StorageTmp->mteObjectsEntryStatus = *((long *) var_val);
        } else {
            /*
             * destroy...  extract it for now 
             */
            hciptr =
                header_complex_find_entry(mteObjectsTableStorage,
                                          StorageTmp);
            StorageDel =
                header_complex_extract_entry(&mteObjectsTableStorage,
                                             hciptr);
        }
        break;




    case UNDO:
        /*
         * Back out any changes made in the ACTION case 
         */
        if (StorageTmp == NULL) {
            /*
             * row creation, so remove it again 
             */
            hciptr =
                header_complex_find_entry(mteObjectsTableStorage,
                                          StorageTmp);
            StorageDel =
                header_complex_extract_entry(&mteObjectsTableStorage,
                                             hciptr);
            /*
             * XXX: free it 
             */
        } else if (StorageDel != NULL) {
            /*
             * row deletion, so add it again 
             */
            mteObjectsTable_add(StorageDel);
        } else {
            StorageTmp->mteObjectsEntryStatus = old_value;
        }
        break;




    case COMMIT:
        /*
         * Things are working well, so it's now safe to make the change
         * permanently.  Make sure that anything done here can't fail! 
         */
        if (StorageDel != NULL) {
            StorageDel = 0;
            /*
             * XXX: free it, its dead 
             */
        } else {
            if (StorageTmp
                && StorageTmp->mteObjectsEntryStatus == RS_CREATEANDGO) {
                StorageTmp->mteObjectsEntryStatus = RS_ACTIVE;
            } else if (StorageTmp &&
                       StorageTmp->mteObjectsEntryStatus ==
                       RS_CREATEANDWAIT) {
                StorageTmp->mteObjectsEntryStatus = RS_NOTINSERVICE;
            }
        }
        snmp_store_needed(NULL);

        break;
    }
    return SNMP_ERR_NOERROR;
}