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

时间:2018-04-18 03:11:43

标签: c linux arm snmp net-snmp

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

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

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

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

(在上面的命令中,我使用<MIB File>替换了我的实际mib文件,使用<MIB Name>替换了mib名称,并使用#个字符从命令返回了OID编号)

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

/// @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搜索结果上,并直接在Stack Overflow上搜索。 以下是一个很好的教程,但没有解决我的问题(他们直接引用他们想要得到的值的OID): http://www.net-snmp.org/wiki/index.php/TUT:Simple_Application

非常感谢任何帮助或见解。

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

谢谢,

1 个答案:

答案 0 :(得分:1)

当我通过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