blob: c7b5d9ad65a212361a3043c4190c05133b7b59cb [file] [log] [blame]
/* -*- C -*- */
#if defined(_WIN32) && !defined(_WIN32_WINNT)
#define _WIN32_WINNT 0x501
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <netdb.h>
#include <sys/socket.h>
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#ifndef sv_undef
#define sv_undef PL_sv_undef
#endif
typedef netsnmp_handler_registration *NetSNMP__agent__netsnmp_handler_registration;
/*
* needs to be in sync with the definitions in snmplib/snmpUDPDomain.c
* and snmplib/snmpTCPDomain.c
*/
typedef netsnmp_indexed_addr_pair netsnmp_udp_addr_pair;
typedef struct handler_cb_data_s {
SV *perl_cb;
} handler_cb_data;
typedef struct netsnmp_oid_s {
oid *name;
size_t len;
oid namebuf[ MAX_OID_LEN ];
} netsnmp_oid;
#define TEST_CONSTANT(value, name, C) \
if (strEQ(name, #C)) { \
*value = C; \
return 0; \
}
static int constant_MODE_G(double *value, const char *name, const int len)
{
switch (len >= 8 ? name[8] : -1) {
case '\0':
TEST_CONSTANT(value, name, MODE_GET);
break;
case 'B':
TEST_CONSTANT(value, name, MODE_GETBULK);
break;
case 'N':
TEST_CONSTANT(value, name, MODE_GETNEXT);
break;
}
return EINVAL;
}
static int constant_MODE_SET_R(double *value, const char *name, const int len)
{
switch (len >= 16 ? name[16] : -1) {
#ifndef NETSNMP_NO_WRITE_SUPPORT
case '1':
TEST_CONSTANT(value, name, MODE_SET_RESERVE1);
break;
case '2':
TEST_CONSTANT(value, name, MODE_SET_RESERVE2);
break;
#endif /* NETSNMP_NO_WRITE_SUPPORT */
}
return EINVAL;
}
static int constant_SNMP_ERR(double *value, char *name, int len)
{
switch (len >= 9 ? name[9] : -1) {
case 'A':
TEST_CONSTANT(value, name, SNMP_ERR_AUTHORIZATIONERROR);
break;
case 'B':
TEST_CONSTANT(value, name, SNMP_ERR_BADVALUE);
break;
case 'C':
TEST_CONSTANT(value, name, SNMP_ERR_COMMITFAILED);
break;
case 'G':
TEST_CONSTANT(value, name, SNMP_ERR_GENERR);
break;
case 'I':
TEST_CONSTANT(value, name, SNMP_ERR_INCONSISTENTVALUE);
break;
case 'N':
TEST_CONSTANT(value, name, SNMP_ERR_NOACCESS);
TEST_CONSTANT(value, name, SNMP_ERR_NOCREATION);
TEST_CONSTANT(value, name, SNMP_ERR_NOERROR);
TEST_CONSTANT(value, name, SNMP_ERR_NOSUCHNAME);
TEST_CONSTANT(value, name, SNMP_ERR_NOTWRITABLE);
break;
case 'R':
TEST_CONSTANT(value, name, SNMP_ERR_READONLY);
TEST_CONSTANT(value, name, SNMP_ERR_RESOURCEUNAVAILABLE);
break;
case 'T':
TEST_CONSTANT(value, name, SNMP_ERR_TOOBIG);
break;
case 'U':
TEST_CONSTANT(value, name, SNMP_ERR_UNDOFAILED);
break;
case 'W':
TEST_CONSTANT(value, name, SNMP_ERR_WRONGENCODING);
TEST_CONSTANT(value, name, SNMP_ERR_WRONGLENGTH);
TEST_CONSTANT(value, name, SNMP_ERR_WRONGTYPE);
TEST_CONSTANT(value, name, SNMP_ERR_WRONGVALUE);
break;
}
return EINVAL;
}
static int constant_MODE_S(double *value, char *name, int len)
{
if (!strnEQ(name + 6, "ET_", 3))
return EINVAL;
switch (len >= 9 ? name[9] : -1) {
#ifndef NETSNMP_NO_WRITE_SUPPORT
case 'A':
TEST_CONSTANT(value, name, MODE_SET_ACTION);
break;
case 'B':
TEST_CONSTANT(value, name, MODE_SET_BEGIN);
break;
case 'C':
TEST_CONSTANT(value, name, MODE_SET_COMMIT);
break;
case 'F':
TEST_CONSTANT(value, name, MODE_SET_FREE);
break;
case 'U':
TEST_CONSTANT(value, name, MODE_SET_UNDO);
break;
#endif /* NETSNMP_NO_WRITE_SUPPORT */
case 'R':
return constant_MODE_SET_R(value, name, len);
}
return EINVAL;
}
static int constant(double *value, char *name, int len)
{
switch (len >= 5 ? name[5] : -1) {
case 'G':
if (strnEQ(name + 0,"MODE_", 5))
return constant_MODE_G(value, name, len);
break;
case 'S':
if (strnEQ(name + 0,"MODE_", 5))
return constant_MODE_S(value, name, len);
break;
case 'E':
if (strnEQ(name + 0,"SNMP_ERR_", 9))
return constant_SNMP_ERR(value, name, len);
break;
}
return EINVAL;
}
int
handler_wrapper(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
handler_cb_data *cb_data = (handler_cb_data *) handler->myvoid;
SV *cb;
if (cb_data && (cb = cb_data->perl_cb)) {
SV *arg;
SV *rarg;
dSP;
ENTER;
SAVETMPS;
PUSHMARK(sp);
rarg = newSViv(0);
arg = newSVrv(rarg, "NetSNMP::agent::netsnmp_mib_handler");
sv_setiv(arg, (IV) handler);
XPUSHs(sv_2mortal(rarg));
rarg = newSViv(0);
arg = newSVrv(rarg, "NetSNMP::agent::netsnmp_handler_registrationPtr");
sv_setiv(arg, (IV) reginfo);
XPUSHs(sv_2mortal(rarg));
rarg = newSViv(0);
arg = newSVrv(rarg, "NetSNMP::agent::netsnmp_agent_request_info");
sv_setiv(arg, (IV) reqinfo);
XPUSHs(sv_2mortal(rarg));
rarg = newSViv(0);
arg = newSVrv(rarg, "NetSNMP::agent::netsnmp_request_infoPtr");
sv_setiv(arg, (IV) requests);
XPUSHs(sv_2mortal(rarg));
PUTBACK;
if (SvTYPE(cb) == SVt_PVCV) {
perl_call_sv(cb, G_DISCARD);
} else if (SvROK(cb) && SvTYPE(SvRV(cb)) == SVt_PVCV) {
perl_call_sv(SvRV(cb), G_DISCARD);
}
SPAGAIN;
PUTBACK;
FREETMPS;
LEAVE;
}
return SNMP_ERR_NOERROR;
}
MODULE = NetSNMP::agent PACKAGE = NetSNMP::agent
void
constant(sv)
PREINIT:
STRLEN len;
INPUT:
SV * sv
char * s = SvPV(sv, len);
INIT:
int status;
double value;
PPCODE:
value = 0;
status = constant(&value, s, len);
XPUSHs(sv_2mortal(newSVuv(status)));
XPUSHs(sv_2mortal(newSVnv(value)));
int
__agent_check_and_process(block = 1)
int block;
CODE:
RETVAL = agent_check_and_process(block);
OUTPUT:
RETVAL
int
_uptime()
CODE:
RETVAL = netsnmp_get_agent_uptime();
OUTPUT:
RETVAL
void
init_mib()
CODE:
{
netsnmp_init_mib();
}
int
init_agent(name)
const char *name;
CODE:
SOCK_STARTUP;
RETVAL = init_agent(name);
OUTPUT:
RETVAL
void
init_snmp(name)
const char *name;
int
init_master_agent()
void
snmp_enable_stderrlog()
MODULE = NetSNMP::agent PACKAGE = NetSNMP::agent PREFIX = na_
void
na_shutdown(me)
SV *me;
CODE:
{
if (0)
printf("me = %p\n", me);
snmp_shutdown("perl");
}
void
na_errlog(me,value)
SV *me;
SV *value;
PREINIT:
STRLEN stringlen;
char * stringptr;
CODE:
{
if (0)
printf("me = %p\n", me);
stringptr = SvPV(value, stringlen);
snmp_log(LOG_ERR, "%s", stringptr );
}
MODULE = NetSNMP::agent PACKAGE = NetSNMP::agent::netsnmp_handler_registration PREFIX = nsahr_
NetSNMP::agent::netsnmp_handler_registration
nsahr_new(name, regoid, perlcallback)
char *name;
char *regoid;
SV *perlcallback;
PREINIT:
oid myoid[MAX_OID_LEN];
size_t myoid_len = MAX_OID_LEN;
handler_cb_data *cb_data;
int gotit=1;
CODE:
if (!snmp_parse_oid(regoid, myoid, &myoid_len)) {
if (!read_objid(regoid, myoid, &myoid_len)) {
snmp_log(LOG_ERR, "couldn't parse %s (reg name: %s)\n",
regoid, name);
RETVAL = NULL;
gotit = 0;
}
}
if (gotit) {
cb_data = (handler_cb_data *) malloc(sizeof(handler_cb_data));
RETVAL = netsnmp_create_handler_registration(name, handler_wrapper,
myoid, myoid_len,
HANDLER_CAN_RWRITE);
cb_data->perl_cb = newSVsv(perlcallback);
RETVAL->handler->myvoid = cb_data;
}
OUTPUT:
RETVAL
void
nsahr_DESTROY(reginfo)
netsnmp_handler_registration *reginfo
PREINIT:
handler_cb_data *cb_data;
CODE:
if (reginfo && reginfo->handler && reginfo->handler->myvoid) {
cb_data = (handler_cb_data *) (reginfo->handler->myvoid);
SvREFCNT_dec(cb_data->perl_cb);
free(cb_data);
}
netsnmp_handler_registration_free(reginfo);
int
nsahr_register(me)
SV *me;
PREINIT:
netsnmp_handler_registration *reginfo;
handler_cb_data *cb_data = NULL;
CODE:
{
reginfo = (netsnmp_handler_registration *) SvIV(SvRV(me));
if (reginfo && reginfo->handler && reginfo->handler->myvoid)
cb_data = (handler_cb_data *) (reginfo->handler->myvoid);
RETVAL = netsnmp_register_handler(reginfo);
if (!RETVAL) {
/* the agent now has a "reference" to this reg pointer */
SvREFCNT_inc(me);
} else {
/*
* The reginfo was freed by netsnmp_register_handler,
* don't touch it in nsahr_DESTROY!
*/
sv_setiv(SvRV(me), 0);
if (cb_data) {
/* And just free the callback. */
SvREFCNT_dec(cb_data->perl_cb);
free(cb_data);
}
}
}
OUTPUT:
RETVAL
MODULE = NetSNMP::agent PACKAGE = NetSNMP::agent::netsnmp_handler_registrationPtr PREFIX = nsahr_
void
nsahr_getRootOID(me)
SV *me;
PREINIT:
int i;
netsnmp_oid *o;
netsnmp_handler_registration *reginfo;
SV *arg, *rarg;
PPCODE:
{
dSP;
PUSHMARK(SP);
reginfo = (netsnmp_handler_registration *) SvIV(SvRV(me));
o = malloc(sizeof(netsnmp_oid));
o->name = o->namebuf;
o->len = reginfo->rootoid_len;
memcpy(o->name, reginfo->rootoid,
reginfo->rootoid_len * sizeof(oid));
rarg = newSViv((int) 0);
arg = newSVrv(rarg, "netsnmp_oidPtr");
sv_setiv(arg, (IV) o);
XPUSHs(sv_2mortal(rarg));
PUTBACK;
i = perl_call_pv("NetSNMP::OID::newwithptr", G_SCALAR);
SPAGAIN;
if (i != 1) {
snmp_log(LOG_ERR, "unhandled OID error.\n");
/* ack XXX */
}
ST(0) = POPs;
XSRETURN(1);
}
MODULE = NetSNMP::agent PACKAGE = NetSNMP::agent::netsnmp_request_infoPtr PREFIX = nari_
void
getOID(me)
SV *me;
PREINIT:
int i;
netsnmp_oid *o;
netsnmp_request_info *request;
SV *arg, *rarg;
PPCODE:
{
dSP;
PUSHMARK(SP);
request = (netsnmp_request_info *) SvIV(SvRV(me));
o = malloc(sizeof(netsnmp_oid));
o->name = o->namebuf;
o->len = request->requestvb->name_length;
memcpy(o->name, request->requestvb->name,
request->requestvb->name_length * sizeof(oid));
rarg = newSViv((int) 0);
arg = newSVrv(rarg, "netsnmp_oidPtr");
sv_setiv(arg, (IV) o);
XPUSHs(sv_2mortal(rarg));
PUTBACK;
i = perl_call_pv("NetSNMP::OID::newwithptr", G_SCALAR);
SPAGAIN;
if (i != 1) {
snmp_log(LOG_ERR, "unhandled OID error.\n");
/* ack XXX */
}
ST(0) = POPs;
XSRETURN(1);
}
netsnmp_oid *
nari_getOIDptr(me)
SV *me;
PREINIT:
netsnmp_request_info *request;
CODE:
request = (netsnmp_request_info *) SvIV(SvRV(me));
RETVAL = malloc(sizeof(netsnmp_oid));
RETVAL->name = RETVAL->namebuf;
RETVAL->len = request->requestvb->name_length;
memcpy(RETVAL->name, request->requestvb->name,
request->requestvb->name_length * sizeof(oid));
OUTPUT:
RETVAL
int
nari_getType(me)
SV *me;
PREINIT:
netsnmp_request_info *request;
CODE:
request = (netsnmp_request_info *) SvIV(SvRV(me));
RETVAL = request->requestvb->type ;
OUTPUT:
RETVAL
void
nari_setType(me, newvalue)
SV *me;
int newvalue;
PREINIT:
netsnmp_request_info *request;
CODE:
request = (netsnmp_request_info *) SvIV(SvRV(me));
request->requestvb->type=newvalue;
SV *
nari_getValue(me)
SV *me;
PREINIT:
char *outbuf = NULL;
size_t ob_len = 0, oo_len = 0;
netsnmp_request_info *request;
CODE:
request = (netsnmp_request_info *) SvIV(SvRV(me));
sprint_realloc_by_type((u_char **) &outbuf, &ob_len, &oo_len, 1,
request->requestvb, 0, 0, 0);
RETVAL = newSVpv(outbuf, 0);
netsnmp_free(outbuf);
OUTPUT:
RETVAL
int
nari_getDelegated(me)
SV *me;
PREINIT:
netsnmp_request_info *request;
CODE:
request = (netsnmp_request_info *) SvIV(SvRV(me));
RETVAL = request->delegated;
OUTPUT:
RETVAL
void
nari_setDelegated(me, newdelegated)
SV *me;
int newdelegated;
PREINIT:
netsnmp_request_info *request;
CODE:
request = (netsnmp_request_info *) SvIV(SvRV(me));
request->delegated = newdelegated;
int
nari_getProcessed(me)
SV *me;
PREINIT:
netsnmp_request_info *request;
CODE:
request = (netsnmp_request_info *) SvIV(SvRV(me));
RETVAL = request->processed;
OUTPUT:
RETVAL
void
nari_setProcessed(me, newprocessed)
SV *me;
int newprocessed;
PREINIT:
netsnmp_request_info *request;
CODE:
request = (netsnmp_request_info *) SvIV(SvRV(me));
request->processed = newprocessed;
int
nari_getStatus(me)
SV *me;
PREINIT:
netsnmp_request_info *request;
CODE:
request = (netsnmp_request_info *) SvIV(SvRV(me));
RETVAL = request->status;
OUTPUT:
RETVAL
void
nari_setStatus(me, newstatus)
SV *me;
int newstatus;
PREINIT:
netsnmp_request_info *request;
CODE:
request = (netsnmp_request_info *) SvIV(SvRV(me));
request->status = newstatus;
int
nari_getRepeat(me)
SV *me;
PREINIT:
netsnmp_request_info *request;
CODE:
request = (netsnmp_request_info *) SvIV(SvRV(me));
RETVAL = request->repeat;
OUTPUT:
RETVAL
void
nari_setRepeat(me, newrepeat)
SV *me;
int newrepeat;
PREINIT:
netsnmp_request_info *request;
CODE:
request = (netsnmp_request_info *) SvIV(SvRV(me));
request->repeat = newrepeat;
int
nari_setValue(me, type, value)
SV *me;
int type;
SV *value;
PREINIT:
netsnmp_request_info *request;
u_long utmp;
long ltmp;
uint64_t ulltmp;
struct counter64 c64;
oid myoid[MAX_OID_LEN];
size_t myoid_len;
STRLEN stringlen;
char * stringptr;
CODE:
request = (netsnmp_request_info *) SvIV(SvRV(me));
switch(type) {
case SNMP_NOSUCHINSTANCE :
snmp_set_var_typed_value(request->requestvb,SNMP_NOSUCHINSTANCE,0,0) ;
RETVAL = 1;
break ;
case SNMP_NOSUCHOBJECT :
snmp_set_var_typed_value(request->requestvb,SNMP_NOSUCHOBJECT,0,0) ;
RETVAL = 1;
break ;
case SNMP_ENDOFMIBVIEW :
snmp_set_var_typed_value(request->requestvb,SNMP_ENDOFMIBVIEW,0,0) ;
RETVAL = 1;
break ;
case ASN_INTEGER:
/* We want an integer here */
if ((SvTYPE(value) == SVt_IV) || (SvTYPE(value) == SVt_PVMG) ||
SvIOK(value)) {
/* Good - got a real one (or a blessed object that we hope will turn out OK) */
ltmp = SvIV(value);
snmp_set_var_typed_value(request->requestvb, (u_char)type,
(u_char *) &ltmp, sizeof(ltmp));
RETVAL = 1;
break;
}
else if (SvPOKp(value)) {
/* Might be OK - got a string, so try to convert it, allowing base 10, octal, and hex forms */
stringptr = SvPV(value, stringlen);
ltmp = strtol( stringptr, NULL, 0 );
if (errno == EINVAL) {
snmp_log(LOG_ERR, "Could not convert string to number in setValue: '%s'", stringptr);
RETVAL = 0;
break;
}
snmp_set_var_typed_value(request->requestvb, (u_char)type,
(u_char *) &ltmp, sizeof(ltmp));
RETVAL = 1;
break;
}
else {
snmp_log(LOG_ERR, "Non-integer value passed to setValue with ASN_INTEGER: type was %lu\n",
(unsigned long)SvTYPE(value));
RETVAL = 0;
break;
}
case ASN_UNSIGNED:
case ASN_COUNTER:
case ASN_TIMETICKS:
/* We want an integer here */
if ((SvTYPE(value) == SVt_IV) || (SvTYPE(value) == SVt_PVMG) ||
SvIOK(value)) {
/* Good - got a real one (or a blessed scalar which we have to hope will turn out OK) */
utmp = SvIV(value);
snmp_set_var_typed_value(request->requestvb, (u_char)type,
(u_char *) &utmp, sizeof(utmp));
RETVAL = 1;
break;
}
else if (SvPOKp(value)) {
/* Might be OK - got a string, so try to convert it, allowing base 10, octal, and hex forms */
stringptr = SvPV(value, stringlen);
utmp = strtoul( stringptr, NULL, 0 );
if (errno == EINVAL) {
snmp_log(LOG_ERR, "Could not convert string to number in setValue: '%s'", stringptr);
RETVAL = 0;
break;
}
snmp_set_var_typed_value(request->requestvb, (u_char)type,
(u_char *) &utmp, sizeof(utmp));
RETVAL = 1;
break;
}
else {
snmp_log(LOG_ERR, "Non-unsigned-integer value passed to setValue with ASN_UNSIGNED/ASN_COUNTER/ASN_TIMETICKS: type was %lu\n",
(unsigned long)SvTYPE(value));
RETVAL = 0;
break;
}
case ASN_COUNTER64:
/* We want an integer here */
if ((SvTYPE(value) == SVt_IV) || (SvTYPE(value) == SVt_PVMG)) {
/* Good - got a real one (or a blessed scalar which we have to hope will turn out OK) */
ulltmp = SvIV(value);
RETVAL = 1;
}
else if (SvPOKp(value)) {
/* Might be OK - got a string, so try to convert it, allowing base 10, octal, and hex forms */
stringptr = SvPV(value, stringlen);
errno = 0;
ulltmp = strtoull( stringptr, NULL, 0 );
if (errno != 0) {
snmp_log(LOG_ERR, "Could not convert string to number in setValue: '%s'", stringptr);
RETVAL = 0;
} else
RETVAL = 1;
}
else {
snmp_log(LOG_ERR, "Non-unsigned-integer value passed to setValue with ASN_COUNTER64: type was %lu\n",
(unsigned long)SvTYPE(value));
RETVAL = 0;
}
if (RETVAL) {
c64.high = (uint32_t)(ulltmp >> 32);
c64.low = (uint32_t)(ulltmp >> 0);
snmp_set_var_typed_value(request->requestvb, (u_char)type,
(u_char *) &c64, sizeof(struct counter64));
}
break;
case ASN_OCTET_STR:
case ASN_BIT_STR:
case ASN_OPAQUE:
/* Check that we have been passed something with a string value (or a blessed scalar) */
if (!SvPOKp(value) && (SvTYPE(value) != SVt_PVMG)) {
snmp_log(LOG_ERR, "Non-string value passed to setValue with ASN_OCTET_STR/ASN_BIT_STR: type was %lu\n",
(unsigned long)SvTYPE(value));
RETVAL = 0;
break;
}
/* Find length of string (strlen will *not* do, as these are binary strings) */
stringptr = SvPV(value, stringlen);
snmp_set_var_typed_value(request->requestvb, (u_char)type,
(u_char *) stringptr,
stringlen);
RETVAL = 1;
break;
case ASN_IPADDRESS:
/* IP addresses are passed as *binary* strings.
* In the case of IPv4 addresses, these are 4 bytes long.
* NOTE: the use of binary strings rather than dotted-quad or FQDNs was
* introduced here by Andrew Findlay's patch of March 17th 2003,
* and is effectively a change to the previous implied API which assumed
* the value was a (valid) hostname.
* Responsibility for decoding and resolving has been passed up to the Perl script.
*/
/* Check that we have been passed something with a string value (or a blessed scalar) */
if (!SvPOKp(value) && (SvTYPE(value) != SVt_PVMG)) {
snmp_log(LOG_ERR, "Non-string value passed to setValue with ASN_IPADDRESS: type was %lu\n",
(unsigned long)SvTYPE(value));
RETVAL = 0;
break;
}
/* Find length of string (strlen will *not* do, as these are binary strings) */
stringptr = SvPV(value, stringlen);
# snmp_log(LOG_ERR, "IP address returned with length %d: %u.%u.%u.%u\n", stringlen, stringptr[0],
# stringptr[1], stringptr[2], stringptr[3] );
# Sanity check on address length
if ((stringlen != 4) && (stringlen != 16)) {
snmp_log(LOG_ERR, "IP address of %" NETSNMP_PRIz "d bytes passed to setValue with ASN_IPADDRESS\n", stringlen);
RETVAL = 0;
break;
}
snmp_set_var_typed_value(request->requestvb, (u_char)type,
stringptr, stringlen);
RETVAL = 1;
break;
case ASN_OBJECT_ID:
/* Check that we have been passed something with a string value (or a blessed scalar) */
if (!SvPOKp(value) && (SvTYPE(value) != SVt_PVMG)) {
snmp_log(LOG_ERR, "Non-string value passed to setValue with ASN_OBJECT_ID: type was %lu\n",
(unsigned long)SvTYPE(value));
RETVAL = 0;
break;
}
/* Extract the string */
stringptr = SvPV(value, stringlen);
/* snmp_log(LOG_ERR, "setValue returning OID '%s'\n", stringptr); */
myoid_len = MAX_OID_LEN;
if (!snmp_parse_oid(stringptr, myoid, &myoid_len)) {
snmp_log(LOG_ERR, "couldn't parse %s in setValue\n", stringptr);
RETVAL = 0;
break;
} else {
/* snmp_log(LOG_ERR, "setValue returning OID length %d\n", myoid_len); */
request = (netsnmp_request_info *) SvIV(SvRV(me));
snmp_set_var_typed_value(request->requestvb, (u_char)type,
(u_char *) myoid, (myoid_len * sizeof(myoid[0])) );
}
RETVAL = 1;
break;
default:
snmp_log(LOG_ERR, "unknown var value type: %d\n",
type);
RETVAL = 0;
break;
}
OUTPUT:
RETVAL
void
nari_setOID(me, value)
SV *me;
char *value;
PREINIT:
oid myoid[MAX_OID_LEN];
size_t myoid_len = MAX_OID_LEN;
netsnmp_request_info *request;
CODE:
myoid_len = MAX_OID_LEN;
if (!snmp_parse_oid(value, myoid, &myoid_len)) {
snmp_log(LOG_ERR, "couldn't parse %s in setOID\n", value);
} else {
request = (netsnmp_request_info *) SvIV(SvRV(me));
snmp_set_var_objid(request->requestvb, myoid, myoid_len);
}
void
nari_setError(me, rinfo, ecode)
SV *me;
SV *rinfo;
int ecode;
PREINIT:
netsnmp_request_info *request;
netsnmp_agent_request_info *reqinfo;
CODE:
request = (netsnmp_request_info *) SvIV(SvRV(me));
reqinfo = (netsnmp_agent_request_info *) SvIV(SvRV(rinfo));
netsnmp_set_request_error(reqinfo, request, ecode);
SV *
nari_next(me)
SV *me;
PREINIT:
netsnmp_request_info *request;
SV *arg, *rarg;
CODE:
{
request = (netsnmp_request_info *) SvIV(SvRV(me));
if (request && request->next) {
request = request->next;
rarg = newSViv(0);
arg = newSVrv(rarg, "NetSNMP::agent::netsnmp_request_infoPtr");
sv_setiv(arg, (IV) request);
RETVAL = rarg;
} else {
RETVAL = &sv_undef;
}
}
OUTPUT:
RETVAL
MODULE = NetSNMP::agent PACKAGE = NetSNMP::agent::netsnmp_agent_request_info PREFIX = narqi_
SV *
narqi_getSourceIp(me)
SV *me;
PREINIT:
netsnmp_agent_request_info *reqinfo;
netsnmp_udp_addr_pair *addr_pair;
struct sockaddr_in *from;
SV *rarg;
CODE:
reqinfo = (netsnmp_agent_request_info *) SvIV(SvRV(me));
/* XXX: transport-specific: UDP/IPv4 only! */
addr_pair = (netsnmp_udp_addr_pair *) (reqinfo->asp->pdu->transport_data);
from = (struct sockaddr_in *) &(addr_pair->remote_addr);
rarg = newSVpv((const char *)(&from->sin_addr.s_addr), sizeof(from->sin_addr.s_addr));
RETVAL = rarg;
OUTPUT:
RETVAL
SV *
narqi_getDestIp(me)
SV *me;
PREINIT:
netsnmp_agent_request_info *reqinfo;
netsnmp_udp_addr_pair *addr_pair;
struct in_addr *to;
SV *rarg;
CODE:
reqinfo = (netsnmp_agent_request_info *) SvIV(SvRV(me));
/* XXX: transport-specific: UDP/IPv4 only! */
addr_pair = (netsnmp_udp_addr_pair *) (reqinfo->asp->pdu->transport_data);
to = (struct in_addr *) &(addr_pair->local_addr);
rarg = newSVpv((const char *)(&to->s_addr), sizeof(to->s_addr));
RETVAL = rarg;
OUTPUT:
RETVAL
int
narqi_getMode(me)
SV *me;
PREINIT:
netsnmp_agent_request_info *reqinfo;
CODE:
reqinfo = (netsnmp_agent_request_info *) SvIV(SvRV(me));
RETVAL = reqinfo->mode;
OUTPUT:
RETVAL
void
narqi_setMode(me, newvalue)
SV *me;
int newvalue;
PREINIT:
netsnmp_agent_request_info *reqinfo;
CODE:
reqinfo = (netsnmp_agent_request_info *) SvIV(SvRV(me));
reqinfo->mode = newvalue;
MODULE = NetSNMP::agent PACKAGE = NetSNMP::agent