4

I founded this code that print string values and it works fine:

 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);
}

  }

Example: for SNMPv2-SMI::mib-2.47.1.1.1.1.2.1012 = STRING: "GigabitEthernet Container", it returns "GigabitEthernet Container";

But I tried that for an integer value and it didn't work:

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

Example: for SNMPv2-SMI::mib-2.17.2.11.0 = INTEGER: 1500, I want to return 1500 and for IF-MIB::ifOutBroadcastPkts.10103 = Counter32: 14011112 I want to return 14011112

If I use:

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

it returns Counter32:12132, or INTEGER:12324, or STRING:Gi0/1 (but I want to parse this result and use it into some variables, without data type, for example: in var a to store 12132).

Thanks!

Matvey Aksenov
  • 3,802
  • 3
  • 23
  • 45
user1101467
  • 41
  • 1
  • 3

3 Answers3

2

In case anyone still has issues with this, I figured out an alternate mechanic that doesn't require parsing using 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;
} 

This will leave the rest of your application configuration as it was and only spit out the value so you don't need to tokenize. I abbreviated the looping so that it focuses on the important aspects.

Gary
  • 1,515
  • 1
  • 14
  • 22
0

I had the same problem I got it working with this...

      unsigned long val64;
      val64 = vars->val.counter64->high;
      printf("value #%lu is a COUNTER32:\n", val64);
Sam Sanders
  • 31
  • 1
  • 4
0

Well, you can always manipulate the data directly... The counter is stored in var->val.integer as you noted. But the faster way to get all of the LABEL: prefixes to be dropped from the output of print_variable is to set the NETSNMP_DS_LIB_QUICK_PRINT variable like so:

netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT, 1);

Which will drop the "Counter32:" prefix.

Wes Hardaker
  • 21,735
  • 2
  • 38
  • 69
  • Thanks man,it print all values without label prefix, but how to use these results, not just print them. – user1101467 Dec 20 '11 at 06:48
  • To use them, you'll need to dive into the var->val union you already mentioned. Each SNMP type will make use of one of those internal values. Note that integer based values (like Integer32) actually use the long datatype within the val union. – Wes Hardaker Dec 21 '11 at 04:09