⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trapreceiver.xs

📁 开发snmp的开发包有两个开放的SNMP开发库
💻 XS
字号:
/* -*- c -*- */#include "EXTERN.h"#include "perl.h"#include "XSUB.h"#include "ppport.h"#include <net-snmp/net-snmp-config.h>#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>#include "perl_snmptrapd.h"#include "const-c.inc"typedef struct trapd_cb_data_s {   SV *perl_cb;} trapd_cb_data;typedef struct netsnmp_oid_s {    oid                 *name;    size_t               len;    oid                  namebuf[ MAX_OID_LEN ];} netsnmp_oid;int   perl_trapd_handler( netsnmp_pdu           *pdu,                          netsnmp_transport     *transport,                          netsnmp_trapd_handler *handler){    trapd_cb_data *cb_data;    SV *pcallback;    netsnmp_variable_list *vb;    netsnmp_oid *o;    SV *arg;    SV *rarg;    SV **tmparray;    int i, c = 0;    u_char *outbuf;    size_t ob_len = 0, oo_len = 0;    AV *varbinds;    HV *pduinfo;    dSP;    ENTER;    SAVETMPS;    if (!pdu || !handler)        return 0;    /* nuke v1 PDUs */    if (pdu->command == SNMP_MSG_TRAP)        pdu = convert_v1pdu_to_v2(pdu);    cb_data = handler->handler_data;    if (!cb_data || !cb_data->perl_cb)        return 0;    pcallback = cb_data->perl_cb;    /* get PDU related info */    pduinfo = newHV();#define STOREPDU(n, v) hv_store(pduinfo, n, strlen(n), v, 0)#define STOREPDUi(n, v) STOREPDU(n, newSViv(v))#define STOREPDUs(n, v) STOREPDU(n, newSVpv(v, 0))    STOREPDUi("version", pdu->version);    STOREPDUs("notificationtype", ((pdu->command == SNMP_MSG_INFORM) ? "INFORM":"TRAP"));    STOREPDUi("requestid", pdu->reqid);    STOREPDUi("messageid", pdu->msgid);    STOREPDUi("transactionid", pdu->transid);    STOREPDUi("errorstatus", pdu->errstat);    STOREPDUi("errorindex", pdu->errindex);    if (pdu->version == 3) {        STOREPDUi("securitymodel", pdu->securityModel);        STOREPDUi("securitylevel", pdu->securityLevel);        STOREPDU("contextName",                 newSVpv(pdu->contextName, pdu->contextNameLen));        STOREPDU("contextEngineID",                 newSVpv(pdu->contextEngineID,                                    pdu->contextEngineIDLen));        STOREPDU("securityEngineID",                 newSVpv(pdu->securityEngineID,                                    pdu->securityEngineIDLen));        STOREPDU("securityName",                 newSVpv(pdu->securityName, pdu->securityNameLen));    } else {        STOREPDU("community",                 newSVpv(pdu->community, pdu->community_len));    }    if (transport && transport->f_fmtaddr) {        char *tstr = transport->f_fmtaddr(transport, pdu->transport_data,                                          pdu->transport_data_length);        STOREPDUs("receivedfrom", tstr);        free(tstr);    }    /*     * collect OID objects in a temp array first     */    /* get VARBIND related info */    i = count_varbinds(pdu->variables);    tmparray = malloc(sizeof(*tmparray) * i);    for(vb = pdu->variables; vb; vb = vb->next_variable) {        /* get the oid */        o = SNMP_MALLOC_TYPEDEF(netsnmp_oid);        o->name = o->namebuf;        o->len = vb->name_length;        memcpy(o->name, vb->name, vb->name_length * sizeof(oid));#undef CALL_EXTERNAL_OID_NEW#ifdef CALL_EXTERNAL_OID_NEW        PUSHMARK(sp);        rarg = sv_2mortal(newSViv((IV) 0));        arg = sv_2mortal(newSVrv(rarg, "netsnmp_oidPtr"));        sv_setiv(arg, (IV) o);        XPUSHs(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 */        }        /* get the value */        tmparray[c++] = POPs;        SvREFCNT_inc(tmparray[c-1]);        PUTBACK;#else /* build it and bless ourselves */        {            HV *hv = newHV();            SV *rv = newRV_noinc((SV *) hv);            SV *rvsub = newRV_noinc((SV *) newSViv((UV) o));            SV *sv;            rvsub = sv_bless(rvsub, gv_stashpv("netsnmp_oidPtr", 1));            hv_store(hv, "oidptr", 6,  rvsub, 0);            rv = sv_bless(rv, gv_stashpv("NetSNMP::OID", 1));            tmparray[c++] = rv;        }        #endif /* build oid ourselves */    }    /*     * build the varbind lists     */    varbinds = newAV();    for(vb = pdu->variables, i = 0; vb; vb = vb->next_variable, i++) {        /* push the oid */        AV *vba;        vba = newAV();        /* get the value */        outbuf = NULL;        ob_len = 0;        oo_len = 0;	sprint_realloc_by_type(&outbuf, &ob_len, &oo_len, 1,                               vb, 0, 0, 0);        av_push(vba,tmparray[i]);        av_push(vba,newSVpvn(outbuf, oo_len));        free(outbuf);        av_push(vba,newSViv(vb->type));        av_push(varbinds, (SV *) newRV_noinc((SV *) vba));    }    PUSHMARK(sp);    /* store the collected information on the stack */    XPUSHs(sv_2mortal(newRV_noinc((SV*) pduinfo)));    XPUSHs(sv_2mortal(newRV_noinc((SV*) varbinds)));    /* put the stack back in order */    PUTBACK;    /* actually call the callback function */    if (SvTYPE(pcallback) == SVt_PVCV) {        perl_call_sv(pcallback, G_DISCARD);        /* XXX: it discards the results, which isn't right */    } else if (SvROK(pcallback) && SvTYPE(SvRV(pcallback)) == SVt_PVCV) {        /* reference to code */        perl_call_sv(SvRV(pcallback), G_DISCARD);    } else {        snmp_log(LOG_ERR, " tried to call a perl function but failed to understand its type: (ref = %x, svrok: %lu, SVTYPE: %lu)\n", (uintptr_t)pcallback, SvROK(pcallback), SvTYPE(pcallback));    }#ifdef DUMPIT    fprintf(stderr, "DUMPDUMPDUMPDUMPDUMPDUMP\n");    sv_dump(pduinfo);    fprintf(stderr, "--------------------\n");    sv_dump(varbinds);#endif        /* svREFCNT_dec((SV *) pduinfo); */#ifdef NOT_THIS    {        SV *vba;        while(vba = av_pop(varbinds)) {            av_undef((AV *) vba);        }    }    av_undef(varbinds);#endif        free(tmparray);    /* Not needed because of the G_DISCARD flag (I think) */    /* SPAGAIN; */    /* PUTBACK; */#ifndef __x86_64__    FREETMPS; /* FIXME: known to cause a segfault on x86-64 */#endif    LEAVE;    return NETSNMPTRAPD_HANDLER_OK;}MODULE = NetSNMP::TrapReceiver		PACKAGE = NetSNMP::TrapReceiver		INCLUDE: const-xs.incMODULE = NetSNMP::TrapReceiver PACKAGE = NetSNMP::TrapReceiver PREFIX=trapd_inttrapd_register(regoid, perlcallback)	char *regoid;        SV   *perlcallback;    PREINIT:	oid myoid[MAX_OID_LEN];	size_t myoid_len = MAX_OID_LEN;        trapd_cb_data *cb_data;        int gotit=1;        netsnmp_trapd_handler *handler = NULL;    CODE:        {            if (!regoid || !perlcallback) {                RETVAL = 0;                return;            }            if (strcmp(regoid,"all") == 0) {                handler =                     netsnmp_add_global_traphandler(NETSNMPTRAPD_POST_HANDLER,                                                   perl_trapd_handler);            } else if (strcmp(regoid,"default") == 0) {                handler =                     netsnmp_add_default_traphandler(perl_trapd_handler);            } else if (!snmp_parse_oid(regoid, myoid, &myoid_len)) {                snmp_log(LOG_ERR,                         "Failed to parse oid for perl registration: %s\n",                         regoid);                RETVAL = 0;                return;            } else {                handler =                     netsnmp_add_traphandler(perl_trapd_handler,                                            myoid, myoid_len);            }                    if (handler) {                cb_data = SNMP_MALLOC_TYPEDEF(trapd_cb_data);                cb_data->perl_cb = newSVsv(perlcallback);                handler->handler_data = cb_data;                handler->authtypes = (1 << VACM_VIEW_EXECUTE);                RETVAL = 1;            } else {                RETVAL = 0;            }        }    OUTPUT:        RETVAL

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -