net-snmp 代理端开发问题记录

来源:互联网 发布:sai软件上色 编辑:程序博客网 时间:2024/05/21 17:27

1.需要在Table中使用rowstatus操作来添加数据,先附上大部分代码

int eocTrapTable_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_info;
    netsnmp_variable_list *var;
    struct commitInfo *ci = NULL;
    void *data_context = NULL;
    oid *suffix;
    size_t suffix_len;

    suffix = requests->requestvb->name + reginfo->rootoid_len + 1;
    suffix_len = requests->requestvb->name_length - (reginfo->rootoid_len + 1);
    
    for(request=requests; request; request=request->next)
    {
        var = request->requestvb;
        if(request->processed != 0)
        {
            continue;
        }
        
        switch(reqinfo->mode)
        {
            case MODE_GET:
                data_context =  netsnmp_extract_iterator_context(request);
                if(data_context == NULL)
                {
                    netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
                    continue;
                }
                break;
            case MODE_SET_RESERVE1:
                data_context =  netsnmp_extract_iterator_context(request);
                break;
            default:
                ci = netsnmp_oid_stash_get_data(commitStorage, suffix+1, suffix_len-1);
                break;
        }

        table_info = netsnmp_extract_table_info(request);
        if(table_info == NULL)
        {
            continue;
        }

        switch(reqinfo->mode)
        {
            case MODE_GET:
                switch(table_info->colnum)
                {
                      case XXXXXXXXX:              
                        break;

                        case XXXXXXXXX:              
                        break;

                         case XXXXXXXXX:              
                        break;
                    default:
                        snmp_log(LOG_ERR, "problem encountered in eocTrapTable_handler: unknown column\n");
                }
                break;

            case MODE_SET_RESERVE1:
                ci = netsnmp_oid_stash_get_data(commitStorage, suffix+1, suffix_len-1);
                
                if(!ci)
                {
                    ci = (struct commitInfo *)SNMP_MALLOC_STRUCT(commitInfo);
                    if(!data_context)
                    {
                        ci->data_context = eocTrapTable_create_data_context(table_info->indexes, 0);
                        ci->new_row = 1;
                    }
                    else
                    {
                        ci->data_context = data_context;
                    }
                    netsnmp_oid_stash_add_data(&commitStorage, suffix+1, suffix_len-1, ci);
                }
                break;
                
            case MODE_SET_RESERVE2:
                 /********************/
                break;

            case MODE_SET_ACTION:
                switch(table_info->colnum)
                {
                        
                    case COLUMN_EOCTRAPIP:
                       
                          /********************/
                        break;
                    case COLUMN_EOCTRAPCOMMUNITY:
                       /********************/
                        break;
                    case COLUMN_EOCTRAPSTATUS:
                      /********************/
                        break;
                    case COLUMN_EOCTRAPROWSTATUS:
                        {
                            int ret;
                            ret = set_eocTrapRowStatus(ci->data_context,
                                                       (long *)request->requestvb->val.string,
                                                       request->requestvb->val_len);
                            if(ret)
                            {
                                netsnmp_set_request_error(reqinfo, request, ret);
                            }
                            
                            if(*request->requestvb->val.integer == RS_DESTROY)
                            {
                                ci->new_row = -1;
                            }
                        }
                        break;
                 }
                break;

            case MODE_SET_COMMIT:
                if(!ci->have_committed)
                {
                    eocTrapTable_commit_row(&ci->data_context, ci->new_row);
                    ci->have_committed = 1;
                }
                break;

            case MODE_SET_UNDO:
                switch(table_info->colnum)
                {
                    case COLUMN_EOCTRAPIP:
                        {
                            int retval;
                            struct undoInfo *ui;
                            
                            ui = netsnmp_oid_stash_get_data(undoStorage, suffix, suffix_len);

                            retval = set_eocTrapIP(ci->data_context, ui->ptr, ui->len);
                            if(retval)
                            {
                                netsnmp_set_request_error(reqinfo, request, SNMP_ERR_UNDOFAILED);
                            }
                        }
                        break;
                    case COLUMN_EOCTRAPROWSTATUS:
                        {
                            int retval;
                            struct undoInfo *ui;

                            ui = netsnmp_oid_stash_get_data(undoStorage, suffix, suffix_len);
                            
                            retval = set_eocTrapRowStatus(ci->data_context, ui->ptr, ui->len);
                            if(retval)
                            {
                                netsnmp_set_request_error(reqinfo, request, SNMP_ERR_UNDOFAILED);
                            }
                        }
                        break;
                    case COLUMN_EOCTRAPCOMMUNITY:
                    case COLUMN_EOCTRAPSTATUS:
                        break;
                }
                break;
                
            case MODE_SET_FREE:
                break;

            default:
                snmp_log(LOG_ERR, "problem encountered in eocTrapTable_handler: unsupported mode\n");
        }
    }

    switch(reqinfo->mode)
    {
        case MODE_SET_UNDO:
        case MODE_SET_FREE:
        case MODE_SET_COMMIT:
            netsnmp_oid_stash_free(&undoStorage, eocTrapGroup_free_undoInfo);
            netsnmp_oid_stash_free(&commitStorage, netsnmp_oid_stash_no_free);
            break;
    }

    return SNMP_ERR_NOERROR;
}

int set_eocTrapRowStatus(void* data_context, long* val, size_t val_len)
{
    struct eocTrapTable_entry *entry = (struct eocTrapTable_entry*)data_context;
     printf("BBBBBBB\n");
    printf("index=%d\n",entry->index);
    printf("len=%ld\n",val_len);
    printf("lval=%ld\n",*val);
    memcpy(&entry->rowStatus, val, val_len);
     printf("CCCCCCC\n");
    printf("rowStatus==%d\n",entry->rowStatus);    
    return SNMP_ERR_NOERROR;
}

void* eocTrapTable_create_data_context(netsnmp_variable_list* index_data, int column)
{
    struct eocTrapTable_entry *entry = NULL;
            
    entry = (struct eocTrapTable_entry *)SNMP_MALLOC_STRUCT(eocTrapTable_entry);
    if(!entry)
    {
            snmp_log(LOG_ERR,"%s:%d\n", __FUNCTION__,__LINE__);
            return;
    }
    memset(entry, 0, sizeof(struct eocTrapTable_entry));
    
    entry->index = *(index_data->val.integer);
    
    entry->next = g_eocTrapTable_head;
    g_eocTrapTable_head = entry;
            
    return entry;

}


本人刚接触snmp不久 ,在对于给一个空表添加数据 的问题很是烦恼,因为在mibbrowser工具中空表是选不到表变量来直行set操作,然后我在工具加载好的mib库中选中某个节点和rowstatus一起set  ,会返回设置失败,原因是没有加上索引,那么问题来了既然是空表,又哪来的索引,所以在set的时候,要对set的的oid加上索引,才能执行set操作。这一步走过了 ,但是我发现我的程序snmpd 在执行set的时候发生了段错误,我找来找去结果发现,段错误出现在set_eocTrapRowStatus中只要一使用entry->index就段错误 只打印出BBBBBBB,我发现这个entry等于NULL  ,使用指针才发生段错误。我就往上面的代码找,经过不懈努力 原来的代码中case MODE_SET_RESERVE1:中执行的eocTrapTable_create_data_context(table_info->indexes, 0);这个函数   是一个假函数  是直接return NULL;问题就在这里  之后我仿写了这个函数创建了表项之后执行上述空表添加就ok了。