Hi There,

I'm experiencing strange behaviour with a test program for NET-SNMP
I've made (in Linux that is).

The test program source code is concatenated below and executes the
following things in chronological order:

  ** Initialise a SNMP session
  ** Build a PDU that requests 'IF-MIB::ifNumber.0' to get the total
amount of interfaces, this value is used to build the next PDU
  ** Build a PDU that requests 'IF-MIB::ifPhysAddress.x' for each
interface (thus request the MAC-addresses).
  ** Close the SNMP session

The program will be used to check the MAC addresses against an other list.

When I compile and run the program I get:
---
#  gcc -Wall `net-snmp-config --cflags` `net-snmp-config --libs`
`net-snmp-config --external-libs` snmptest.c -o snmptest
#  ./snmptest
INTEGER: 3
num_if = 3
No log handling enabled - turning on stderr logging
snmp_build: unknown failureE: snmp_synch_response() failed! (ret = 1)
---

Hmmm...a search for this error did not turn up any useful information.
I came to discover that the error is due to the combination of
requests I make; I request 'ifNumber.0' and then, for every interface
'ifPhysAddress.x' (where 'x' is the index of the interface of course).
I can make the error disappear by doing a request for
'ifAdminStatus.2' (for example) instead of 'ifNumber.0'; in this case
I get:

---
# ./snmptest
INTEGER: up(1)
num_if = 1
STRING: xx:xx:xx:xx:xx:xx
---

The MAC-address is scrambled, and because now 'if_num' receives the
wrong value, I set it to '3' afterwards. The program works and
finished without an error, as it should.

How can this be? Am I not allowed to make this combination of
requests? Can anyone help me on this?

Thanks in advance!

Greetings,

Kris van Rens


PS. Another thing. What about the error that is printed when the
failure happens, is there some way to turn this off? snmp_build prints
an error but I'd like to do my own error handling and print it when
appropriate, thank you.


---------< start program source code: >-----------
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <string.h>

int main(void)
{
        struct snmp_session sess, *sess_h;
        struct snmp_pdu *req, *resp;
        oid if_oid[MAX_OID_LEN];
        size_t if_oid_len = MAX_OID_LEN;
        struct variable_list *vars;
        int ret, i, num_if;
        char oid_str[32];

        // Initialise SNMP session
        init_snmp("test");
        snmp_sess_init(&sess);
        
        sess.version = SNMP_VERSION_1;
        sess.community = (unsigned char *)"public";
        sess.community_len = strlen((char *)sess.community);
        sess.peername = "localhost";
        sess_h = snmp_open(&sess);
        if (sess_h == NULL)
                goto out_snmp_open;

        //
        // STEP 1: Get the # of network interfaces 
-----------------------------------
        //

        // Create a PDU (SNMP packet)
        req = snmp_pdu_create(SNMP_MSG_GET);
        read_objid("IF-MIB::ifAdminStatus.2", if_oid, &if_oid_len);     // 
...works
        //read_objid("IF-MIB::ifNumber.0", if_oid, &if_oid_len);        // 
...doesn't work
        snmp_add_null_var(req, if_oid, if_oid_len);

        // Send request PDU
        ret = snmp_synch_response(sess_h, req, &resp);
        if (ret != STAT_SUCCESS || resp->errstat != SNMP_ERR_NOERROR)
                goto out_snmp_synch_response;

        // Copy value
        memmove(&num_if, resp->variables->val.integer, 
resp->variables->val_len);

        // DEBUG -- will be removed
        print_value(resp->variables->name, resp->variables->name_length,
resp->variables);
        printf("num_if = %d\n", num_if);

        // Free response PDU
        if (resp)
                snmp_free_pdu(resp);

        //
        // STEP 2: Request information for every interface 
---------------------------
        //

        // Create a PDU (SNMP packet)
        req = snmp_pdu_create(SNMP_MSG_GET);

        // Pack in variables
        for (i = 0; i < num_if; i++) {
                sprintf(oid_str, "IF-MIB::ifPhysAddress.%d", i+1);
                read_objid(oid_str, if_oid, &if_oid_len);
                snmp_add_null_var(req, if_oid, if_oid_len);
        }

        // Send request PDU
        ret = snmp_synch_response(sess_h, req, &resp);
        if (ret != STAT_SUCCESS || resp->errstat != SNMP_ERR_NOERROR)
                goto out_snmp_synch_response;

        // Save MAC addresses
        for (vars = resp->variables; vars; vars = vars->next_variable) {
                if (vars->val_len != 0) {
                        //
                        // COMPARISON OF MACs ...
                        //
                        // DEBUG -- will be removed
                        print_value(vars->name, vars->name_length, vars);
                }
        }

        // Free response PDU
        if (resp)
                snmp_free_pdu(resp);

        // Close SNMP session
        snmp_close(sess_h);
        
        // Normal exit
        return 0;

out_snmp_open:
        printf("E: snmp_open() failed!\n");
        snmp_sess_perror("test", &sess);
        return -1;

out_snmp_synch_response:
        printf("E: snmp_synch_response() failed! (ret = %d)\n", ret);
        snmp_close(sess_h);
        return -1;
}
---------< end program source code: >-----------

---------< start snmpwalk snippet >--------------
...
IF-MIB::ifNumber.0 = INTEGER: 3
IF-MIB::ifIndex.1 = INTEGER: 1
IF-MIB::ifIndex.2 = INTEGER: 2
IF-MIB::ifIndex.3 = INTEGER: 3
IF-MIB::ifDescr.1 = STRING: lo
IF-MIB::ifDescr.2 = STRING: eth0
IF-MIB::ifDescr.3 = STRING: sit0
IF-MIB::ifType.1 = INTEGER: softwareLoopback(24)
IF-MIB::ifType.2 = INTEGER: ethernetCsmacd(6)
IF-MIB::ifType.3 = INTEGER: tunnel(131)
IF-MIB::ifMtu.1 = INTEGER: 16436
IF-MIB::ifMtu.2 = INTEGER: 1500
IF-MIB::ifMtu.3 = INTEGER: 1480
IF-MIB::ifSpeed.1 = Gauge32: 10000000
IF-MIB::ifSpeed.2 = Gauge32: 100000000
IF-MIB::ifSpeed.3 = Gauge32: 0
IF-MIB::ifPhysAddress.1 = STRING:
IF-MIB::ifPhysAddress.2 = STRING: xx:xx:xx:xx:xx:xx
IF-MIB::ifPhysAddress.3 = STRING:
...
---------< end snmpwalk snippet >---------------

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Register now and save $200. Hurry, offer ends at 11:59 p.m., 
Monday, April 7! Use priority code J8TLD2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Net-snmp-coders mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders

Reply via email to