【问题标题】:How to print an integer and Counter32 value in net-snmp如何在 net-snmp 中打印整数和 Counter32 值
【发布时间】:2016-05-21 03:08:22
【问题描述】:

我创建了这个打印字符串值的代码,它工作正常:

 add_mibdir("."); 
 pdu = snmp_pdu_create(SNMP_MSG_GET);

 read_objid(if_index, id_oid, &id_len);
 snmp_add_null_var(pdu, id_oid, id_len);    
 status = snmp_synch_response(sess_handle,pdu,&response);

 int count=1;
 for(vars = response->variables; vars; vars = vars->next_variable) 
  {
    if (vars->type == ASN_OCTET_STR) 
    {
        char *sp = (char *)malloc(1 + vars->val_len);
        memcpy(sp, vars->val.string, vars->val_len);
        sp[vars->val_len] = '\0';
        printf("value #%d is a string: %s\n", count++, sp);
        printf("%s\n",vars->val.string);
        free(sp);
}

  }

例如:SNMPv2-SMI::mib-2.47.1.1.1.1.2.1012 = STRING: "GigabitEthernet Container",返回"GigabitEthernet Container"

但我尝试了一个整数值,但它不起作用:

for(vars = response->variables; vars; vars = vars->next_variable)
    printf("%ld",(long int)vars->val.integer);//it returns large numbers;

例如:对于SNMPv2-SMI::mib-2.17.2.11.0 = INTEGER: 1500,我想返回1500,对于IF-MIB::ifOutBroadcastPkts.10103 = Counter32: 14011112,我想返回14011112

如果我使用:

for(vars = response->variables; vars; vars = vars->next_variable)
    print_variable(vars->name, vars->name_length, vars);

它返回Counter32:12132,或INTEGER:12324,或STRING:Gi0/1(但我想解析这个结果并将其用于一些变量,没有数据类型,例如:在var a中存储12132 )。

谢谢!

【问题讨论】:

  • 打印的是什么而不是你想要的数字?

标签: c++ linux network-programming network-protocols net-snmp


【解决方案1】:

如果有人对此仍有疑问,我想出了一个不需要使用 net-snmp 5.7.3 进行解析的替代机制:

template<typename T>
static boost::shared_ptr< std::vector<T> > GetVector(std::string user_oid, struct snmp_session * snmp_session) {

    // Other Initialization ....

    char temp_buf[BUFSIZ];
    size_t temp_buf_len = BUFSIZ;
    bool orig_config_val_qp = netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT);
    bool orig_config_val_bv = netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_BARE_VALUE);

    // Enforce this for correct output in snprint_variable functions
    netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT, 1);
    netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_BARE_VALUE, 1);

    // oid conversion routines ...

    // Processing loop for response vars (similar to netsnmp/app/snmpbulkwalk.c) ...
    if (vars->type == ASN_OCTET_STR) 
    {
        temp_buf_len = BUFSIZ;
        snprint_variable(temp_buf, temp_buf_len, vars->name, vars->name_length, vars);
        result->push_back(boost::lexical_cast<T>(temp_buf));
    }
    // End Processing loop...

    // Restore configuration
    netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT, orig_config_val_qp);
    netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_BARE_VALUE, orig_config_val_bv);

    return result;
} 

这将使您的应用程序配置的其余部分保持原样,并且只会输出值,因此您不需要标记化。我缩写了循环,以便它专注于重要方面。

【讨论】:

  • 谢谢!我只需要知道这两个“netsnmp_ds_set_boolean”命令。你救了我!
【解决方案2】:

好吧,您总是可以直接操作数据...如您所述,计数器存储在 var->val.integer 中。但是从 print_variable 的输出中删除所有 LABEL: 前缀的更快方法是像这样设置 NETSNMP_DS_LIB_QUICK_PRINT 变量:

netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT, 1);

这将删除“Counter32:”前缀。

【讨论】:

  • 谢谢,它打印所有没有标签前缀的值,但是如何使用这些结果,而不仅仅是打印它们。
  • 要使用它们,您需要深入了解您已经提到的 var->val 联合。每种 SNMP 类型都将使用其中一个内部值。请注意,基于整数的值(如 Integer32)实际上使用 val 联合中的 long 数据类型。
【解决方案3】:

我遇到了同样的问题,我用这个解决了这个问题......

      unsigned long val64;
      val64 = vars->val.counter64->high;
      printf("value #%lu is a COUNTER32:\n", val64);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-11
    • 1970-01-01
    • 2015-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多