代码之家  ›  专栏  ›  技术社区  ›  Furynolo

C NET-SNMP通过MIB名称而不是OID专门获取和设置

  •  2
  • Furynolo  · 技术社区  · 6 年前

    我已经用C编写并正在测试通用SNMP客户端模块的软件,以及使用此通用模块的实现。我很难通过传入MIB名称(例如sysDescr)而不是OID(例如1.3.6.1.2.1.1.1)来获得get请求。

    当我将包含OID的字符数组传递给\u snmp\u parse\u OID()\u而不是名称时,我成功了。

    我已经检查了MIB文件,以确保使用了正确的名称。当我在名称上运行命令行SNMP translate时,它会给我上面列出的OID:

    $ snmptranslate -m +<MIB File> -IR -On <MIB Name>
    .#.#.#.#.#.#.#####.#.#.#.#.#.#
    

    (在上面的命令中,我将实际的mib文件替换为 <MIB File> ,mib名称 <MIB Name> ,以及从命令返回的OID编号 # 字符)

    以下是我的通用SNMP get函数代码,假设返回值为#define number,并且为了简洁起见,我删除了一些错误处理:

    /// @Synopsis        Function to send out get request since the 
    ///                  SNMPOidData object has been setup
    ///
    /// @Param oid_name  String containing the OID to set
    /// @Param value     Value to set
    ///
    /// @Returns         Error
    int snmpGet(SNMPAgent *this, char const * const oid_name, SNMPOidData * value)
    {
        netsnmp_pdu           *pdu;
        netsnmp_pdu           *response;
        netsnmp_variable_list *vars;
        oid                   *retrieved_oid;
        oidStruct             oid_to_get;
        int                   status   = 0;
        int                   result   = ERROR_SUCCESS;
    
        // Create the PDU for the data for our request
        pdu = snmp_pdu_create(SNMP_MSG_GET);
    
        oid_to_get.OidLen = MAX_OID_LEN; // Set max length
    
        // Send out the request(s)
        retrieved_oid = snmp_parse_oid(oid_name, oid_to_get.Oid, &oid_to_get.OidLen);
    
        // Set the data
        snmp_add_null_var(pdu, oid_to_get.Oid, oid_to_get.OidLen))
    
        // Send the request out
        status = snmp_synch_response(this->port.snmp_session_handle, pdu, &response);
        if (STAT_SUCCESS == status)
        {
            if (SNMP_ERR_NOERROR == response->errstat)
            {
                vars = response->variables;
                value->type = vars->type;
    
                if (vars->next_variable != NULL)
                {
                    // There are more values, set return type to null
                    value->type = ASN_NULL;
                }
                else if (!(CHECK_END(vars->type))) // Exception
                {
                    result = ERROR_NOT_PRESENT;
                    fprintf(stderr, "Warning: OID=%s gets snmp exception %d \n",
                        oid_name, vars->type);
                }
                else if ((vars->type == ASN_INTEGER)
                      || (vars->type == ASN_COUNTER)
                      || (vars->type == ASN_UNSIGNED))
                {
                    value->integer = *(vars->val.integer);
                    value->str_len = sizeof(value->integer);
                }
                else
                {
                    value->str_len = vars->val_len;
    
                    if (value->str_len >= MAX_ASN_STR_LEN)
                        value->str_len = MAX_ASN_STR_LEN;
    
                    if (value->str_len > 0)
                        memcpy(value->string, vars->val.string, value->str_len);
    
                    // guarantee NULL terminated string
                    value->string[value->str_len] = '\0';
                }
            }
        }
    
        this->freePDU(response); // Clean up: free the response
    
        return result;
    }
    

    我收到的错误:

    oid_name: Unknown Object Identifier (Sub-id not found: (top) -> <MIB Name>)
    

    来自以下调用:

    retrieved_oid = snmp_parse_oid(oid_name, oid_to_get.Oid, &oid_to_get.OidLen);
    

    我已经确保MIB文件在机器上的配置位置(如果不是这样的话,snmptranslate将无法工作)。

    我花了大量时间在Google搜索结果上,也在堆栈溢出上直接搜索这里。 以下是一个很好的教程,但没有解决我的问题(他们直接引用他们想要获得的OID值): http://www.net-snmp.org/wiki/index.php/TUT:Simple_Application

    任何帮助或见解都将不胜感激。

    我能想到的其他一些信息是,这是为了在运行Linux的armv5tejl目标上运行,该目标通过以太网与外部设备通信。

    谢谢

    1 回复  |  直到 6 年前
        1
  •  1
  •   Stephen Rauch Afsar Ali    6 年前

    当我按字符串名称调用MIB变量时,我使用以下net snmp函数。

    read_objid(OID, anOID, &anOID_len);
    snmp_add_null_var(pdu, anOID, anOID_len);
    

    其中:

    oid anOID[MAX_OID_LEN];
    size_t anOID_len = MAX_OID_LEN;
    

    在我的程序中,我将这些都打包到一个函数调用中。

    void packSingleGetOID(const char *OID, struct snmp_pdu *pdu){
        // OID in / PDU out
        oid anOID[MAX_OID_LEN];
        size_t anOID_len = MAX_OID_LEN;
    
        read_objid(OID, anOID, &anOID_len);
        snmp_add_null_var(pdu, anOID, anOID_len);
    }
    

    我传入MIB OID字符串和指向会话pdu的指针。记住OID字符串是 MIB_Name::variable