Hello,
I want to do data acquisition from a SNMPv1 device periodically and dump the findings into a PF. Fortunately, OS/400 includes an SNMP client API since V3R6, so I can use this with V4R5 on my model 150. :-)
Unfortunately, said API is completely unrelated to the NetSNMP API everybody else in the Linux-world uses, so examples are scarce.
https://www.ibm.com/docs/en/i/7.4?topic=ssw_ibm_i_74/apis/snmpexmp.htm
Here are two routines, AddVarbind, and FreePdu which I copied 1:1. They're said to make life easier, so I'm following. ;-)
When scolling down a bit more, there are examples of snmpGet (and their SNMPv3 counterparts).
The documenters were so incredibly funny. After setting up and doing the request exchange, there's no example how to actually extract the data from those struct(s). Instead, they just write:
/* Perform operations on the data in the response PDU. */
Not funny.
Looking at the qtomeapi header file in QSYSINC, I can see there is the main PDU struct. It references to another struct "varBind".
typedef struct {
unsigned char pdu_type;
int error_status;
int error_index;
varBind * varbind;
} snmppdu;
typedef struct _varBind{
struct _varBind * next;
char *oid; /* NULL terminated */
unsigned char asn_type;
int val_len;
union {
int * int_val;
char * str_val;
} val;
};
typedef struct _varBind varBind;
I'm using the charset conversion wrappers from Chris Hird (thanks a lot!) to convert the community name.
/* SNMP-Stuf starts here. */
pdu = NULL; /* Nullify PDU pointer. */
rc = AddVarbind(&pdu, /* Add second varbind. */
"1.3.6.1.2.1.1.1.0", /* PDU pointer is now */
v, /* non-null after 1st */
GET_PDU_TYPE, /* invocation of Add- */
0); /* Varbind. */
if ( rc < 0 ) {
Qp0zLprintf("Error: %d\n",rc); /* Again, check return code.*/
exit(1);
}
/* Set community name. */
convert_buffer("public", community_name, 6, 6, e_a_ccsid);
rc = snmpGet(pdu, /* Invoke operation. */
"192.168.1.1", /* Hostname. */
10, /* Time-out value. */
community_name, /* Pointer to community name. */
6); /* Correct length of */
/* community name. */
if ( rc < 0 ) {
Qp0zLprintf("Error: %d\n",rc); /* Again, check return code.*/
exit(1);
}
Running the program so far yields immediate "no error" and a short run time, so no retries: The charset conversion works. And I get data back from the OID 1.3.6.1.2.1.1.1.0 (which is just the sysDescr), as well as a program run immediately completes.
I try to output the data:
convert_buffer(pdu->varbind->val.str_val, buf, pdu->varbind->val_len, pdu->varbind->val_len, a_e_ccsid);
Qp0zLprintf("Result has %d bytes and is: %s\n", pdu->varbind->val_len, buf);
buf is just a "char buf[1024];".
In the job log I get the output:
Result has 251 bytes and is:
And that's it.
Also, when I do the same from a Linux command line, I get this blob back:
$ snmpget -c public -v1 192.168.1.1 1.3.6.1.2.1.1.1.0
RFC1213-MIB::sysDescr.0 = STRING: "Cisco IOS Software, C3750 Software (C3750-IPSERVICESK9-M), Version 12.2(55)SE12, RELEASE SOFTWARE (fc2)
Technical Support:
http://www.cisco.com/techsupport
Copyright (c) 1986-2017 by Cisco Systems, Inc.
Compiled Thu 28-Sep-17 02:29 by prod_rel_team"
What am I doing wrong?
Thanks for any help!
:wq! PoC
As an Amazon Associate we earn from qualifying purchases.