📄 agent.xs
字号:
/* -*- C -*- */#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#endiftypedef struct handler_cb_data_s { SV *perl_cb;} handler_cb_data;typedef struct netsnmp_oid_s { unsigned int *name; unsigned int len; unsigned int namebuf[ MAX_OID_LEN ];} netsnmp_oid;static int have_done_agent = 0;static int have_done_lib = 0;static intnot_here(char *s){ croak("%s not implemented on this architecture", s); return -1;}static doubleconstant_MODE_G(char *name, int len, int arg){ if (6 + 2 > len ) { errno = EINVAL; return 0; } switch (name[6 + 2]) { case '\0': if (strEQ(name + 6, "ET")) { /* MODE_G removed */#ifdef MODE_GET return MODE_GET;#else goto not_there;#endif } case 'B': if (strEQ(name + 6, "ETBULK")) { /* MODE_G removed */#ifdef MODE_GETBULK return MODE_GETBULK;#else goto not_there;#endif } case 'N': if (strEQ(name + 6, "ETNEXT")) { /* MODE_G removed */#ifdef MODE_GETNEXT return MODE_GETNEXT;#else goto not_there;#endif } } errno = EINVAL; return 0;not_there: errno = ENOENT; return 0;}static doubleconstant_MODE_SET_R(char *name, int len, int arg){ if (10 + 6 >= len ) { errno = EINVAL; return 0; } switch (name[10 + 6]) { case '1': if (strEQ(name + 10, "ESERVE1")) { /* MODE_SET_R removed */#ifdef MODE_SET_RESERVE1 return MODE_SET_RESERVE1;#else goto not_there;#endif } case '2': if (strEQ(name + 10, "ESERVE2")) { /* MODE_SET_R removed */#ifdef MODE_SET_RESERVE2 return MODE_SET_RESERVE2;#else goto not_there;#endif } } errno = EINVAL; return 0;not_there: errno = ENOENT; return 0;}static doubleconstant_SNMP_ERR(char *name, int len, int arg){ if (9 + 1 >= len ) { errno = EINVAL; return 0; } switch (name[9]) { case 'A': if (strEQ(name + 10, "UTHORIZATIONERROR")) { /* SNMP_ERR_A removed */#ifdef SNMP_ERR_AUTHORIZATIONERROR return SNMP_ERR_AUTHORIZATIONERROR;#else goto not_there;#endif } break; case 'B': if (strEQ(name + 10, "ADVALUE")) { /* SNMP_ERR_B removed */#ifdef SNMP_ERR_BADVALUE return SNMP_ERR_BADVALUE;#else goto not_there;#endif } break; case 'C': if (strEQ(name + 10, "OMMITFAILED")) { /* SNMP_ERR_C removed */#ifdef SNMP_ERR_COMMITFAILED return SNMP_ERR_COMMITFAILED;#else goto not_there;#endif } break; case 'G': if (strEQ(name + 10, "ENERR")) { /* SNMP_ERR_G removed */#ifdef SNMP_ERR_GENERR return SNMP_ERR_GENERR;#else goto not_there;#endif } break; case 'I': if (strEQ(name + 10, "NCONSISTENTVALUE")) { /* SNMP_ERR_I removed */#ifdef SNMP_ERR_INCONSISTENTVALUE return SNMP_ERR_INCONSISTENTVALUE;#else goto not_there;#endif } break; case 'N': if (strEQ(name + 10, "OACCESS")) { /* SNMP_ERR_N removed */#ifdef SNMP_ERR_NOACCESS return SNMP_ERR_NOACCESS;#else goto not_there;#endif } if (strEQ(name + 10, "OCREATION")) { /* SNMP_ERR_N removed */#ifdef SNMP_ERR_NOCREATION return SNMP_ERR_NOCREATION;#else goto not_there;#endif } if (strEQ(name + 10, "OERROR")) { /* SNMP_ERR_N removed */#ifdef SNMP_ERR_NOERROR return SNMP_ERR_NOERROR;#else goto not_there;#endif } if (strEQ(name + 10, "OSUCHNAME")) { /* SNMP_ERR_N removed */#ifdef SNMP_ERR_NOSUCHNAME return SNMP_ERR_NOSUCHNAME;#else goto not_there;#endif } if (strEQ(name + 10, "OTWRITABLE")) { /* SNMP_ERR_N removed */#ifdef SNMP_ERR_NOTWRITABLE return SNMP_ERR_NOTWRITABLE;#else goto not_there;#endif } break; case 'R': if (strEQ(name + 10, "EADONLY")) { /* SNMP_ERR_R removed */#ifdef SNMP_ERR_READONLY return SNMP_ERR_READONLY;#else goto not_there;#endif } if (strEQ(name + 10, "ESOURCEUNAVAILABLE")) { /* SNMP_ERR_R removed */#ifdef SNMP_ERR_RESOURCEUNAVAILABLE return SNMP_ERR_RESOURCEUNAVAILABLE;#else goto not_there;#endif } break; case 'T': if (strEQ(name + 10, "OOBIG")) { /* SNMP_ERR_T removed */#ifdef SNMP_ERR_TOOBIG return SNMP_ERR_TOOBIG;#else goto not_there;#endif } break; case 'U': if (strEQ(name + 10, "NDOFAILED")) { /* SNMP_ERR_U removed */#ifdef SNMP_ERR_UNDOFAILED return SNMP_ERR_UNDOFAILED;#else goto not_there;#endif } break; case 'W': if (strEQ(name + 10, "RONGENCODING")) { /* SNMP_ERR_W removed */#ifdef SNMP_ERR_WRONGENCODING return SNMP_ERR_WRONGENCODING;#else goto not_there;#endif } if (strEQ(name + 10, "RONGLENGTH")) { /* SNMP_ERR_W removed */#ifdef SNMP_ERR_WRONGLENGTH return SNMP_ERR_WRONGLENGTH;#else goto not_there;#endif } if (strEQ(name + 10, "RONGTYPE")) { /* SNMP_ERR_W removed */#ifdef SNMP_ERR_WRONGTYPE return SNMP_ERR_WRONGTYPE;#else goto not_there;#endif } if (strEQ(name + 10, "RONGVALUE")) { /* SNMP_ERR_W removed */#ifdef SNMP_ERR_WRONGVALUE return SNMP_ERR_WRONGVALUE;#else goto not_there;#endif } }not_there: errno = ENOENT; return 0;} static doubleconstant_MODE_S(char *name, int len, int arg){ if (6 + 3 >= len ) { errno = EINVAL; return 0; } switch (name[6 + 3]) { case 'A': if (strEQ(name + 6, "ET_ACTION")) { /* MODE_S removed */#ifdef MODE_SET_ACTION return MODE_SET_ACTION;#else goto not_there;#endif } case 'B': if (strEQ(name + 6, "ET_BEGIN")) { /* MODE_S removed */#ifdef MODE_SET_BEGIN return MODE_SET_BEGIN;#else goto not_there;#endif } case 'C': if (strEQ(name + 6, "ET_COMMIT")) { /* MODE_S removed */#ifdef MODE_SET_COMMIT return MODE_SET_COMMIT;#else goto not_there;#endif } case 'F': if (strEQ(name + 6, "ET_FREE")) { /* MODE_S removed */#ifdef MODE_SET_FREE return MODE_SET_FREE;#else goto not_there;#endif } case 'R': if (!strnEQ(name + 6,"ET_", 3)) break; return constant_MODE_SET_R(name, len, arg); case 'U': if (strEQ(name + 6, "ET_UNDO")) { /* MODE_S removed */#ifdef MODE_SET_UNDO return MODE_SET_UNDO;#else goto not_there;#endif } } errno = EINVAL; return 0;not_there: errno = ENOENT; return 0;}static doubleconstant(char *name, int len, int arg){ errno = 0; if (0 + 5 >= len ) { errno = EINVAL; return 0; } switch (name[0 + 5]) { case 'G': if (!strnEQ(name + 0,"MODE_", 5)) break; return constant_MODE_G(name, len, arg); case 'S': if (!strnEQ(name + 0,"MODE_", 5)) break; return constant_MODE_S(name, len, arg); case 'E': if (!strnEQ(name + 0,"SNMP_ERR_", 9)) break; return constant_SNMP_ERR(name, len, arg); } errno = EINVAL; return 0;not_there: errno = ENOENT; return 0;}inthandler_wrapper(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { u_long intret = 5; 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, (int) handler); XPUSHs(rarg); rarg = newSViv(0); arg = newSVrv(rarg, "NetSNMP::agent::reginfo"); sv_setiv(arg, (int) reginfo); XPUSHs(rarg); rarg = newSViv(0); arg = newSVrv(rarg, "NetSNMP::agent::netsnmp_agent_request_info"); sv_setiv(arg, (int) reqinfo); XPUSHs(rarg); rarg = newSViv(0); arg = newSVrv(rarg, "NetSNMP::agent::netsnmp_request_infoPtr"); sv_setiv(arg, (int) requests); XPUSHs(rarg); PUTBACK; if (SvTYPE(cb) == SVt_PVCV) { perl_call_sv(cb, G_DISCARD); /* I have no idea what discard does */ /* XXX: it discards the results, which isn't right */ } else if (SvROK(cb) && SvTYPE(SvRV(cb)) == SVt_PVCV) { /* reference to code */ perl_call_sv(SvRV(cb), G_DISCARD); } SPAGAIN; PUTBACK; FREETMPS; LEAVE; } return SNMP_ERR_NOERROR;}MODULE = NetSNMP::agent PACKAGE = NetSNMP::agent doubleconstant(sv,arg) PREINIT: STRLEN len; INPUT: SV * sv char * s = SvPV(sv, len); int arg CODE: RETVAL = constant(s,len,arg); OUTPUT: RETVALint__agent_check_and_process(block = 1) int block; CODE: RETVAL = agent_check_and_process(block); OUTPUT: RETVALvoidinit_mib()intinit_agent(name) const char *name;voidinit_snmp(name) const char *name;intinit_master_agent()void snmp_enable_stderrlog() MODULE = NetSNMP::agent PACKAGE = NetSNMP::agent PREFIX = na_voidna_shutdown(me) SV *me; CODE: { snmp_shutdown("perl"); }MODULE = NetSNMP::agent PACKAGE = NetSNMP::agent::netsnmp_handler_registration PREFIX = nsahr_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)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -