The following is a very simple example taken from the Net-SNMP site. It initializes a session, adds a MIB in the current working directory to the MIB tree, creates a GET PDU, packs 2 OIDs into the PDU, then sends a synchronous request and returns the response and is finally processed.
#include <net-snmp/net-snmp-config.h> #include <net-snmp/net-snmp-includes.h> #include <string.h> int main(int argc, char ** argv) { struct snmp_session session; struct snmp_session *sess_handle; struct snmp_pdu *pdu; struct snmp_pdu *response; struct variable_list *vars; oid id_oid[MAX_OID_LEN]; oid serial_oid[MAX_OID_LEN]; size_t id_len = MAX_OID_LEN; size_t serial_len = MAX_OID_LEN; int status; struct tree * mib_tree; /*********************/ if(argv[1] == NULL){ printf("Please supply a hostname\n"); exit(1); } init_snmp("APC Check"); snmp_sess_init( &session ); session.version = SNMP_VERSION_1; session.community = "public"; session.community_len = strlen(session.community); session.peername = argv[1]; sess_handle = snmp_open(&session); add_mibdir("."); mib_tree = read_mib("PowerNet-MIB.txt"); pdu = snmp_pdu_create(SNMP_MSG_GET); read_objid("PowerNet-MIB::upsBasicIdentModel.0", id_oid, &id_len); snmp_add_null_var(pdu, id_oid, id_len); read_objid("PowerNet-MIB::upsAdvIdentSerialNumber.0", serial_oid, &serial_len); snmp_add_null_var(pdu, serial_oid, serial_len); status = snmp_synch_response(sess_handle, pdu, &response); for(vars = response->variables; vars; vars = vars->next_variable) print_value(vars->name, vars->name_length, vars); snmp_free_pdu(response); snmp_close(sess_handle); return (0); }
This example can be compiled like this and run like this:
$ gcc `net-snmp-config --cflags` `net-snmp-config --libs` \ > `net-snmp-config --external-libs` snmp_test.c -o snmp_test $ ./snmp_test apc STRING: "Silcon DP340E" STRING: "SE00XXXXXX " $
You can see in the code that init_snmp() gets the ball rolling. snmp_sess_init() accepts a session structure address, this function will populate the bulk of the session structure with default values. Once the session structure is primed we can modify it to meet our needs, such as defining the SNMP version, community name (not forgetting the length of the community name), and the hostname of agent referred to as the peername. When the session structure is ready for use, we can open the session with snmp_open() which will return a new session structure as a handle.
While you normally should refrain from using non-installed MIBs, in this example I've demonstrated how to add a directory to the internal MIB path and then read a MIB into the MIB tree using the add_mibdir() and read_mib() functions.
Now that the session is open and the MIBs we'll use are loaded into the tree we can create and populate the PDU(s) we'll be sending. snmp_pdu_create() will setup the base PDU information based on the supplied type of PDU (specified in macro form) and return the populated PDU structure. Now that we have the PDU we can use the read_objid() and snmp_add_null_var() functions to first read the OID from the MIB and then add that OID as a variable to the variable list used by the PDU. We can repeat this process several times to continue packing our PDU full of OIDs. Typically you'll see this type of operation wrapped in a loop, but I've illustrated it long hand for simplicity sake.
Once our session is open and our PDU is ready with all the OIDs we want crammed into the variable list we can actually send the request and await the response. This action is done in a single step using the snmp_synch_response() function. The function is passed the open session handle, the PDU to send, and an empty PDU structure to accept the response which includes the populated values for each OID in the variable list.
At this point you can extract and manipulate the returned data either by utilizing built in functions such as print_value() or by simply directly accessing the structures. Other convince functions for value output can be found in the net-snmp/library/mib.h header.
Finally, to properly clean up, the PDU(s) should be freed and the sessions closed using the snmp_free_pdu() and snmp_close() functions.