agent.xs
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:25k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. /* -*- C -*- */
  2. #include "EXTERN.h"
  3. #include "perl.h"
  4. #include "XSUB.h"
  5. #include <netdb.h>
  6. #include <sys/socket.h>
  7. #include <net-snmp/net-snmp-config.h>
  8. #include <net-snmp/net-snmp-includes.h>
  9. #include <net-snmp/agent/net-snmp-agent-includes.h>
  10. #ifndef sv_undef
  11. #define sv_undef PL_sv_undef
  12. #endif
  13. typedef struct handler_cb_data_s {
  14.    SV *perl_cb;
  15. } handler_cb_data;
  16. typedef struct netsnmp_oid_s {
  17.     unsigned int        *name;
  18.     unsigned int         len;
  19.     unsigned int         namebuf[ MAX_OID_LEN ];
  20. } netsnmp_oid;
  21. static int have_done_agent = 0;
  22. static int have_done_lib = 0;
  23. static int
  24. not_here(char *s)
  25. {
  26.     croak("%s not implemented on this architecture", s);
  27.     return -1;
  28. }
  29. static double
  30. constant_MODE_G(char *name, int len, int arg)
  31. {
  32.     if (6 + 2 > len ) {
  33. errno = EINVAL;
  34. return 0;
  35.     }
  36.     switch (name[6 + 2]) {
  37.     case '':
  38. if (strEQ(name + 6, "ET")) { /* MODE_G removed */
  39. #ifdef MODE_GET
  40.     return MODE_GET;
  41. #else
  42.     goto not_there;
  43. #endif
  44. }
  45.     case 'B':
  46. if (strEQ(name + 6, "ETBULK")) { /* MODE_G removed */
  47. #ifdef MODE_GETBULK
  48.     return MODE_GETBULK;
  49. #else
  50.     goto not_there;
  51. #endif
  52. }
  53.     case 'N':
  54. if (strEQ(name + 6, "ETNEXT")) { /* MODE_G removed */
  55. #ifdef MODE_GETNEXT
  56.     return MODE_GETNEXT;
  57. #else
  58.     goto not_there;
  59. #endif
  60. }
  61.     }
  62.     errno = EINVAL;
  63.     return 0;
  64. not_there:
  65.     errno = ENOENT;
  66.     return 0;
  67. }
  68. static double
  69. constant_MODE_SET_R(char *name, int len, int arg)
  70. {
  71.     if (10 + 6 >= len ) {
  72. errno = EINVAL;
  73. return 0;
  74.     }
  75.     switch (name[10 + 6]) {
  76.     case '1':
  77. if (strEQ(name + 10, "ESERVE1")) { /* MODE_SET_R removed */
  78. #ifdef MODE_SET_RESERVE1
  79.     return MODE_SET_RESERVE1;
  80. #else
  81.     goto not_there;
  82. #endif
  83. }
  84.     case '2':
  85. if (strEQ(name + 10, "ESERVE2")) { /* MODE_SET_R removed */
  86. #ifdef MODE_SET_RESERVE2
  87.     return MODE_SET_RESERVE2;
  88. #else
  89.     goto not_there;
  90. #endif
  91. }
  92.     }
  93.     errno = EINVAL;
  94.     return 0;
  95. not_there:
  96.     errno = ENOENT;
  97.     return 0;
  98. }
  99. static double
  100. constant_SNMP_ERR(char *name, int len, int arg)
  101. {
  102.     if (9 + 1 >= len ) {
  103. errno = EINVAL;
  104. return 0;
  105.     }
  106.     switch (name[9]) {
  107.     case 'A':
  108. if (strEQ(name + 10, "UTHORIZATIONERROR")) { /* SNMP_ERR_A removed */
  109. #ifdef SNMP_ERR_AUTHORIZATIONERROR
  110.     return SNMP_ERR_AUTHORIZATIONERROR;
  111. #else
  112.     goto not_there;
  113. #endif
  114. }
  115.         break;
  116.     case 'B':
  117. if (strEQ(name + 10, "ADVALUE")) { /* SNMP_ERR_B removed */
  118. #ifdef SNMP_ERR_BADVALUE
  119.     return SNMP_ERR_BADVALUE;
  120. #else
  121.     goto not_there;
  122. #endif
  123. }
  124.         break;
  125.     case 'C':
  126. if (strEQ(name + 10, "OMMITFAILED")) { /* SNMP_ERR_C removed */
  127. #ifdef SNMP_ERR_COMMITFAILED
  128.     return SNMP_ERR_COMMITFAILED;
  129. #else
  130.     goto not_there;
  131. #endif
  132. }
  133.         break;
  134.     case 'G':
  135. if (strEQ(name + 10, "ENERR")) { /* SNMP_ERR_G removed */
  136. #ifdef SNMP_ERR_GENERR
  137.     return SNMP_ERR_GENERR;
  138. #else
  139.     goto not_there;
  140. #endif
  141. }
  142.         break;
  143.     case 'I':
  144. if (strEQ(name + 10, "NCONSISTENTVALUE")) { /* SNMP_ERR_I removed */
  145. #ifdef SNMP_ERR_INCONSISTENTVALUE
  146.     return SNMP_ERR_INCONSISTENTVALUE;
  147. #else
  148.     goto not_there;
  149. #endif
  150. }
  151.         break;
  152.     case 'N':
  153. if (strEQ(name + 10, "OACCESS")) { /* SNMP_ERR_N removed */
  154. #ifdef SNMP_ERR_NOACCESS
  155.     return SNMP_ERR_NOACCESS;
  156. #else
  157.     goto not_there;
  158. #endif
  159. }
  160. if (strEQ(name + 10, "OCREATION")) { /* SNMP_ERR_N removed */
  161. #ifdef SNMP_ERR_NOCREATION
  162.     return SNMP_ERR_NOCREATION;
  163. #else
  164.     goto not_there;
  165. #endif
  166. }
  167. if (strEQ(name + 10, "OERROR")) { /* SNMP_ERR_N removed */
  168. #ifdef SNMP_ERR_NOERROR
  169.     return SNMP_ERR_NOERROR;
  170. #else
  171.     goto not_there;
  172. #endif
  173. }
  174. if (strEQ(name + 10, "OSUCHNAME")) { /* SNMP_ERR_N removed */
  175. #ifdef SNMP_ERR_NOSUCHNAME
  176.     return SNMP_ERR_NOSUCHNAME;
  177. #else
  178.     goto not_there;
  179. #endif
  180. }
  181. if (strEQ(name + 10, "OTWRITABLE")) { /* SNMP_ERR_N removed */
  182. #ifdef SNMP_ERR_NOTWRITABLE
  183.     return SNMP_ERR_NOTWRITABLE;
  184. #else
  185.     goto not_there;
  186. #endif
  187. }
  188.         break;
  189.     case 'R':
  190. if (strEQ(name + 10, "EADONLY")) { /* SNMP_ERR_R removed */
  191. #ifdef SNMP_ERR_READONLY
  192.     return SNMP_ERR_READONLY;
  193. #else
  194.     goto not_there;
  195. #endif
  196. }
  197. if (strEQ(name + 10, "ESOURCEUNAVAILABLE")) { /* SNMP_ERR_R removed */
  198. #ifdef SNMP_ERR_RESOURCEUNAVAILABLE
  199.     return SNMP_ERR_RESOURCEUNAVAILABLE;
  200. #else
  201.     goto not_there;
  202. #endif
  203. }
  204.         break;
  205.     case 'T':
  206. if (strEQ(name + 10, "OOBIG")) { /* SNMP_ERR_T removed */
  207. #ifdef SNMP_ERR_TOOBIG
  208.     return SNMP_ERR_TOOBIG;
  209. #else
  210.     goto not_there;
  211. #endif
  212. }
  213.         break;
  214.     case 'U':
  215. if (strEQ(name + 10, "NDOFAILED")) { /* SNMP_ERR_U removed */
  216. #ifdef SNMP_ERR_UNDOFAILED
  217.     return SNMP_ERR_UNDOFAILED;
  218. #else
  219.     goto not_there;
  220. #endif
  221. }
  222.         break;
  223.     case 'W':
  224. if (strEQ(name + 10, "RONGENCODING")) { /* SNMP_ERR_W removed */
  225. #ifdef SNMP_ERR_WRONGENCODING
  226.     return SNMP_ERR_WRONGENCODING;
  227. #else
  228.     goto not_there;
  229. #endif
  230. }
  231. if (strEQ(name + 10, "RONGLENGTH")) { /* SNMP_ERR_W removed */
  232. #ifdef SNMP_ERR_WRONGLENGTH
  233.     return SNMP_ERR_WRONGLENGTH;
  234. #else
  235.     goto not_there;
  236. #endif
  237. }
  238. if (strEQ(name + 10, "RONGTYPE")) { /* SNMP_ERR_W removed */
  239. #ifdef SNMP_ERR_WRONGTYPE
  240.     return SNMP_ERR_WRONGTYPE;
  241. #else
  242.     goto not_there;
  243. #endif
  244. }
  245. if (strEQ(name + 10, "RONGVALUE")) { /* SNMP_ERR_W removed */
  246. #ifdef SNMP_ERR_WRONGVALUE
  247.     return SNMP_ERR_WRONGVALUE;
  248. #else
  249.     goto not_there;
  250. #endif
  251. }
  252.     }
  253. not_there:
  254.     errno = ENOENT;
  255.     return 0;
  256. }
  257.     
  258. static double
  259. constant_MODE_S(char *name, int len, int arg)
  260. {
  261.     if (6 + 3 >= len ) {
  262. errno = EINVAL;
  263. return 0;
  264.     }
  265.     switch (name[6 + 3]) {
  266.     case 'A':
  267. if (strEQ(name + 6, "ET_ACTION")) { /* MODE_S removed */
  268. #ifdef MODE_SET_ACTION
  269.     return MODE_SET_ACTION;
  270. #else
  271.     goto not_there;
  272. #endif
  273. }
  274.     case 'B':
  275. if (strEQ(name + 6, "ET_BEGIN")) { /* MODE_S removed */
  276. #ifdef MODE_SET_BEGIN
  277.     return MODE_SET_BEGIN;
  278. #else
  279.     goto not_there;
  280. #endif
  281. }
  282.     case 'C':
  283. if (strEQ(name + 6, "ET_COMMIT")) { /* MODE_S removed */
  284. #ifdef MODE_SET_COMMIT
  285.     return MODE_SET_COMMIT;
  286. #else
  287.     goto not_there;
  288. #endif
  289. }
  290.     case 'F':
  291. if (strEQ(name + 6, "ET_FREE")) { /* MODE_S removed */
  292. #ifdef MODE_SET_FREE
  293.     return MODE_SET_FREE;
  294. #else
  295.     goto not_there;
  296. #endif
  297. }
  298.     case 'R':
  299. if (!strnEQ(name + 6,"ET_", 3))
  300.     break;
  301. return constant_MODE_SET_R(name, len, arg);
  302.     case 'U':
  303. if (strEQ(name + 6, "ET_UNDO")) { /* MODE_S removed */
  304. #ifdef MODE_SET_UNDO
  305.     return MODE_SET_UNDO;
  306. #else
  307.     goto not_there;
  308. #endif
  309. }
  310.     }
  311.     errno = EINVAL;
  312.     return 0;
  313. not_there:
  314.     errno = ENOENT;
  315.     return 0;
  316. }
  317. static double
  318. constant(char *name, int len, int arg)
  319. {
  320.     errno = 0;
  321.     if (0 + 5 >= len ) {
  322. errno = EINVAL;
  323. return 0;
  324.     }
  325.     switch (name[0 + 5]) {
  326.     case 'G':
  327. if (!strnEQ(name + 0,"MODE_", 5))
  328.     break;
  329. return constant_MODE_G(name, len, arg);
  330.     case 'S':
  331. if (!strnEQ(name + 0,"MODE_", 5))
  332.     break;
  333. return constant_MODE_S(name, len, arg);
  334.     case 'E':
  335. if (!strnEQ(name + 0,"SNMP_ERR_", 9))
  336.     break;
  337. return constant_SNMP_ERR(name, len, arg);
  338.     }
  339.     errno = EINVAL;
  340.     return 0;
  341. not_there:
  342.     errno = ENOENT;
  343.     return 0;
  344. }
  345. int
  346. handler_wrapper(netsnmp_mib_handler          *handler,
  347.                 netsnmp_handler_registration *reginfo,
  348.                 netsnmp_agent_request_info   *reqinfo,
  349.                 netsnmp_request_info         *requests) 
  350. {
  351.     u_long intret = 5;
  352.     handler_cb_data *cb_data = (handler_cb_data *) handler->myvoid;
  353.     SV *cb;
  354.     if (cb_data && (cb = cb_data->perl_cb)) {
  355.         SV *arg;
  356.         SV *rarg;
  357.         dSP;
  358.         ENTER;
  359.         SAVETMPS;
  360.         PUSHMARK(sp);
  361.         rarg = newSViv(0);
  362.         arg = newSVrv(rarg, "NetSNMP::agent::netsnmp_mib_handler");
  363.         sv_setiv(arg, (int) handler);
  364.         XPUSHs(sv_2mortal(rarg));
  365.         rarg = newSViv(0);
  366.         arg = newSVrv(rarg, "NetSNMP::agent::reginfo");
  367.         sv_setiv(arg, (int) reginfo);
  368.         XPUSHs(sv_2mortal(rarg));
  369.         rarg = newSViv(0);
  370.         arg = newSVrv(rarg, "NetSNMP::agent::netsnmp_agent_request_info");
  371.         sv_setiv(arg, (int) reqinfo);
  372.         XPUSHs(sv_2mortal(rarg));
  373.         rarg = newSViv(0);
  374.         arg = newSVrv(rarg, "NetSNMP::agent::netsnmp_request_infoPtr");
  375.         sv_setiv(arg, (int) requests);
  376.         XPUSHs(sv_2mortal(rarg));
  377.         PUTBACK;
  378.         if (SvTYPE(cb) == SVt_PVCV) {
  379.             perl_call_sv(cb, G_DISCARD);
  380.                                        
  381.         } else if (SvROK(cb) && SvTYPE(SvRV(cb)) == SVt_PVCV) {
  382.             perl_call_sv(SvRV(cb), G_DISCARD); 
  383.         }
  384.         SPAGAIN;
  385.         PUTBACK;
  386.         FREETMPS;
  387.         LEAVE;
  388.     }
  389.     return SNMP_ERR_NOERROR;
  390. }
  391. MODULE = NetSNMP::agent PACKAGE = NetSNMP::agent
  392. double
  393. constant(sv,arg)
  394.     PREINIT:
  395. STRLEN len;
  396.     INPUT:
  397. SV * sv
  398. char * s = SvPV(sv, len);
  399. int arg
  400.     CODE:
  401. RETVAL = constant(s,len,arg);
  402.     OUTPUT:
  403. RETVAL
  404. int
  405. __agent_check_and_process(block = 1)
  406. int block;
  407.     CODE:
  408. RETVAL = agent_check_and_process(block);
  409.     OUTPUT:
  410. RETVAL
  411. void
  412. init_mib()
  413. int
  414. init_agent(name)
  415.         const char *name;
  416. void
  417. init_snmp(name)
  418.         const char *name;
  419. int
  420. init_master_agent()
  421. void    
  422. snmp_enable_stderrlog()    
  423. MODULE = NetSNMP::agent  PACKAGE = NetSNMP::agent PREFIX = na_
  424. void
  425. na_shutdown(me)
  426.     SV *me;
  427.     CODE:
  428.     {
  429.         snmp_shutdown("perl");
  430.     }
  431. void
  432. na_errlog(me,value)
  433.     SV *me;
  434.     SV *value;
  435.    PREINIT:
  436.         STRLEN stringlen;
  437.         char * stringptr;
  438.     CODE:
  439.     {
  440.         stringptr = SvPV(value, stringlen);
  441.         snmp_log(LOG_ERR, stringptr );
  442.     }
  443. MODULE = NetSNMP::agent  PACKAGE = NetSNMP::agent::netsnmp_handler_registration  PREFIX = nsahr_
  444. netsnmp_handler_registration *
  445. nsahr_new(name, regoid, perlcallback)
  446.         char *name;
  447. char *regoid;
  448.         SV   *perlcallback;
  449.     PREINIT:
  450. oid myoid[MAX_OID_LEN];
  451. size_t myoid_len = MAX_OID_LEN;
  452.         handler_cb_data *cb_data;
  453.         int gotit=1;
  454.     CODE:
  455. if (!snmp_parse_oid(regoid, myoid, &myoid_len)) {
  456.             if (!read_objid(regoid, myoid, &myoid_len)) {
  457.                 snmp_log(LOG_ERR, "couldn't parse %s (reg name: %s)n",
  458.                         regoid, name);
  459.                 RETVAL = NULL;
  460.                 gotit = 0;
  461.             }
  462.         }
  463.         if (gotit) {
  464.             cb_data = (handler_cb_data *) malloc(sizeof(handler_cb_data));
  465.             RETVAL = netsnmp_create_handler_registration(name, handler_wrapper,
  466.                                                  myoid, myoid_len,
  467.                                                  HANDLER_CAN_RWRITE);
  468.             cb_data->perl_cb = newSVsv(perlcallback);
  469.             RETVAL->handler->myvoid = cb_data;
  470.         }
  471.     OUTPUT:
  472.         RETVAL
  473. MODULE = NetSNMP::agent  PACKAGE = netsnmp_handler_registrationPtr  PREFIX = nsahr_
  474. void
  475. nsahr_DESTROY(reginfo)
  476. netsnmp_handler_registration *reginfo
  477.     CODE:
  478. netsnmp_handler_registration_free(reginfo);
  479. int
  480. nsahr_register(me)
  481.         SV *me;
  482.         PREINIT:
  483.         netsnmp_handler_registration *reginfo;
  484.         CODE:
  485.             {
  486.                 reginfo = (netsnmp_handler_registration *) SvIV(SvRV(me));
  487.                 RETVAL = netsnmp_register_handler(reginfo);
  488.                 if (!RETVAL) {
  489.                     /* the agent now has a "reference" to this reg pointer */
  490.                     SvREFCNT_inc(me);
  491.                 }
  492.             }
  493.     OUTPUT:
  494. RETVAL
  495. void
  496. nsahr_getRootOID(me)
  497.     SV *me;
  498.     PREINIT:
  499.         int i;
  500.         netsnmp_oid *o;
  501.         netsnmp_handler_registration *reginfo;
  502.         SV *arg, *rarg;
  503.     PPCODE:
  504.     {
  505.         dSP;
  506.         PUSHMARK(SP);
  507.         reginfo = (netsnmp_handler_registration *) SvIV(SvRV(me));
  508.         o = SNMP_MALLOC_TYPEDEF(netsnmp_oid);
  509.         o->name = o->namebuf;
  510.         o->len = reginfo->rootoid_len;
  511.         memcpy(o->name, reginfo->rootoid,
  512.                reginfo->rootoid_len * sizeof(oid));
  513.         rarg = newSViv((int) 0);
  514.         arg = newSVrv(rarg, "netsnmp_oidPtr");
  515.         sv_setiv(arg, (int) o);
  516.         XPUSHs(rarg);
  517.         PUTBACK;
  518.         i = perl_call_pv("NetSNMP::OID::newwithptr", G_SCALAR);
  519.         SPAGAIN;
  520.         if (i != 1) {
  521.             snmp_log(LOG_ERR, "unhandled OID error.n");
  522.             /* ack XXX */
  523.         }
  524.         ST(0) = POPs;
  525.         XSRETURN(1);
  526.     }
  527. MODULE = NetSNMP::agent  PACKAGE = NetSNMP::agent::netsnmp_request_infoPtr PREFIX = nari_
  528. void
  529. getOID(me)
  530.     SV *me;
  531.     PREINIT:
  532.         int i;
  533.         netsnmp_oid *o;
  534.         netsnmp_request_info *request;
  535.         SV *arg, *rarg;
  536.     PPCODE:
  537.     {
  538.         dSP;
  539.         PUSHMARK(SP);
  540.         request = (netsnmp_request_info *) SvIV(SvRV(me));
  541.         o = SNMP_MALLOC_TYPEDEF(netsnmp_oid);
  542.         o->name = o->namebuf;
  543.         o->len = request->requestvb->name_length;
  544.         memcpy(o->name, request->requestvb->name,
  545.                request->requestvb->name_length * sizeof(oid));
  546.         rarg = newSViv((int) 0);
  547.         arg = newSVrv(rarg, "netsnmp_oidPtr");
  548.         sv_setiv(arg, (int) o);
  549.         XPUSHs(rarg);
  550.         PUTBACK;
  551.         i = perl_call_pv("NetSNMP::OID::newwithptr", G_SCALAR);
  552.         SPAGAIN;
  553.         if (i != 1) {
  554.             snmp_log(LOG_ERR, "unhandled OID error.n");
  555.             /* ack XXX */
  556.         }
  557.         ST(0) = POPs;
  558.         XSRETURN(1);
  559.     }
  560.         
  561. netsnmp_oid *
  562. nari_getOIDptr(me)
  563.         SV *me;
  564.         PREINIT:
  565.         netsnmp_request_info *request;
  566.         CODE:
  567.         request = (netsnmp_request_info *) SvIV(SvRV(me));
  568.         RETVAL = SNMP_MALLOC_TYPEDEF(netsnmp_oid);
  569.         RETVAL->name = RETVAL->namebuf;
  570.         RETVAL->len = request->requestvb->name_length;
  571.         memcpy(RETVAL->name, request->requestvb->name,
  572.                request->requestvb->name_length * sizeof(oid));
  573.     OUTPUT:
  574.         RETVAL
  575. int
  576. nari_getType(me)
  577.         SV *me;
  578.     PREINIT:
  579.         netsnmp_request_info *request;
  580.     CODE:
  581.         request = (netsnmp_request_info *) SvIV(SvRV(me));
  582.         RETVAL =  request->requestvb->type ;
  583.     OUTPUT:
  584.         RETVAL 
  585. void
  586. nari_setType(me, newvalue)
  587.         SV *me;
  588.         int newvalue;
  589.     PREINIT:
  590.         netsnmp_request_info *request;
  591.     CODE:
  592.         request = (netsnmp_request_info *) SvIV(SvRV(me));
  593.         request->requestvb->type=newvalue;
  594. char *
  595. nari_getValue(me)
  596.         SV *me;
  597.     PREINIT:
  598.         u_char buf[1024] ;
  599.         u_char *oidbuf = buf ;
  600.         size_t ob_len = 1024, oo_len = 0;
  601.         netsnmp_request_info *request;
  602.     CODE:
  603.         request = (netsnmp_request_info *) SvIV(SvRV(me));
  604. sprint_realloc_by_type(&oidbuf, &ob_len, &oo_len, 0,
  605.                                request->requestvb, 0, 0, 0);
  606.         RETVAL = oidbuf; /* mem leak */
  607.     OUTPUT:
  608.         RETVAL
  609. int
  610. nari_getDelegated(me)
  611.         SV *me;
  612.     PREINIT:
  613.         netsnmp_request_info *request;
  614.     CODE:
  615.         request = (netsnmp_request_info *) SvIV(SvRV(me));
  616.         RETVAL = request->delegated;
  617.     OUTPUT:
  618.         RETVAL
  619. void
  620. nari_setDelegated(me, newdelegated)
  621.         SV *me;
  622.         int newdelegated;
  623.     PREINIT:
  624.         netsnmp_request_info *request;
  625.     CODE:
  626.         request = (netsnmp_request_info *) SvIV(SvRV(me));
  627.         request->delegated = newdelegated;
  628. int
  629. nari_getProcessed(me)
  630.         SV *me;
  631.     PREINIT:
  632.         netsnmp_request_info *request;
  633.     CODE:
  634.         request = (netsnmp_request_info *) SvIV(SvRV(me));
  635.         RETVAL = request->processed;
  636.     OUTPUT:
  637.         RETVAL
  638. void
  639. nari_setProcessed(me, newprocessed)
  640.         SV *me;
  641.         int newprocessed;
  642.     PREINIT:
  643.         netsnmp_request_info *request;
  644.     CODE:
  645.         request = (netsnmp_request_info *) SvIV(SvRV(me));
  646.         request->processed = newprocessed;
  647. int
  648. nari_getStatus(me)
  649.         SV *me;
  650.     PREINIT:
  651.         netsnmp_request_info *request;
  652.     CODE:
  653.         request = (netsnmp_request_info *) SvIV(SvRV(me));
  654.         RETVAL = request->status;
  655.     OUTPUT:
  656.         RETVAL
  657. void
  658. nari_setStatus(me, newstatus)
  659.         SV *me;
  660.         int newstatus;
  661.     PREINIT:
  662.         netsnmp_request_info *request;
  663.     CODE:
  664.         request = (netsnmp_request_info *) SvIV(SvRV(me));
  665.         request->status = newstatus;
  666. int
  667. nari_getRepeat(me)
  668.         SV *me;
  669.     PREINIT:
  670.         netsnmp_request_info *request;
  671.     CODE:
  672.         request = (netsnmp_request_info *) SvIV(SvRV(me));
  673.         RETVAL = request->repeat;
  674.     OUTPUT:
  675.         RETVAL
  676. void
  677. nari_setRepeat(me, newrepeat)
  678.         SV *me;
  679.         int newrepeat;
  680.     PREINIT:
  681.         netsnmp_request_info *request;
  682.     CODE:
  683.         request = (netsnmp_request_info *) SvIV(SvRV(me));
  684.         request->repeat = newrepeat;
  685. int
  686. nari_setValue(me, type, value)
  687.         SV *me;
  688.         int type;
  689.         SV *value;
  690.     PREINIT:
  691.         u_char *oidbuf = NULL;
  692.         size_t ob_len = 0, oo_len = 0;
  693.         netsnmp_request_info *request;
  694.         u_long utmp;
  695.         long ltmp;
  696. oid myoid[MAX_OID_LEN];
  697. size_t myoid_len;
  698.         STRLEN stringlen;
  699.         char * stringptr;
  700.     CODE:
  701.         request = (netsnmp_request_info *) SvIV(SvRV(me));
  702.         switch(type) {
  703.           case  SNMP_NOSUCHINSTANCE :
  704.               snmp_set_var_typed_value(request->requestvb,SNMP_NOSUCHINSTANCE,0,0) ;
  705.               RETVAL = 1;
  706.               break ;
  707.           case  SNMP_NOSUCHOBJECT :
  708.               snmp_set_var_typed_value(request->requestvb,SNMP_NOSUCHOBJECT,0,0) ;
  709.               RETVAL = 1;
  710.               break ;
  711.           case  SNMP_ENDOFMIBVIEW :
  712.               snmp_set_var_typed_value(request->requestvb,SNMP_ENDOFMIBVIEW,0,0) ;
  713.               RETVAL = 1;
  714.               break ;
  715.           case ASN_INTEGER:
  716.       /* We want an integer here */
  717.       if ((SvTYPE(value) == SVt_IV) || (SvTYPE(value) == SVt_PVMG)) {
  718.   /* Good - got a real one (or a blessed object that we hope will turn out OK) */
  719.   ltmp = SvIV(value);
  720.   snmp_set_var_typed_value(request->requestvb, (u_char)type,
  721.    (u_char *) &ltmp, sizeof(ltmp));
  722.   RETVAL = 1;
  723.   break;
  724.       }
  725.       else if (SvPOKp(value)) {
  726.           /* Might be OK - got a string, so try to convert it, allowing base 10, octal, and hex forms */
  727.           stringptr = SvPV(value, stringlen);
  728.   ltmp = strtol( stringptr, NULL, 0 );
  729.   if (errno == EINVAL) {
  730.    snmp_log(LOG_ERR, "Could not convert string to number in setValue: '%s'", stringptr);
  731. RETVAL = 0;
  732. break;
  733.   }
  734.   snmp_set_var_typed_value(request->requestvb, (u_char)type,
  735.    (u_char *) &ltmp, sizeof(ltmp));
  736.   RETVAL = 1;
  737.   break;
  738.       }
  739.       else {
  740. snmp_log(LOG_ERR, "Non-integer value passed to setValue with ASN_INTEGER: type was %dn",
  741. SvTYPE(value));
  742. RETVAL = 0;
  743. break;
  744.       }
  745.           case ASN_UNSIGNED:
  746.           case ASN_COUNTER:
  747.           case ASN_COUNTER64:
  748.           case ASN_TIMETICKS:
  749.       /* We want an integer here */
  750.       if ((SvTYPE(value) == SVt_IV) || (SvTYPE(value) == SVt_PVMG)) {
  751.   /* Good - got a real one (or a blessed scalar which we have to hope will turn out OK) */
  752.   utmp = SvIV(value);
  753.                   snmp_set_var_typed_value(request->requestvb, (u_char)type,
  754.                                        (u_char *) &utmp, sizeof(utmp));
  755.   RETVAL = 1;
  756.   break;
  757.       }
  758.       else if (SvPOKp(value)) {
  759.           /* Might be OK - got a string, so try to convert it, allowing base 10, octal, and hex forms */
  760.           stringptr = SvPV(value, stringlen);
  761.   utmp = strtoul( stringptr, NULL, 0 );
  762.   if (errno == EINVAL) {
  763.    snmp_log(LOG_ERR, "Could not convert string to number in setValue: '%s'", stringptr);
  764. RETVAL = 0;
  765. break;
  766.   }
  767.                   snmp_set_var_typed_value(request->requestvb, (u_char)type,
  768.                                        (u_char *) &utmp, sizeof(utmp));
  769.   RETVAL = 1;
  770.   break;
  771.       }
  772.       else {
  773. snmp_log(LOG_ERR, "Non-unsigned-integer value passed to setValue with ASN_UNSIGNED/ASN_COUNTER/ASN_TIMETICKS: type was %dn",
  774. SvTYPE(value));
  775. RETVAL = 0;
  776. break;
  777.       }
  778.           case ASN_OCTET_STR:
  779.           case ASN_BIT_STR:
  780.       /* Check that we have been passed something with a string value (or a blessed scalar) */
  781.       if (!SvPOKp(value) && (SvTYPE(value) != SVt_PVMG)) {
  782. snmp_log(LOG_ERR, "Non-string value passed to setValue with ASN_OCTET_STR/ASN_BIT_STR: type was %dn",
  783. SvTYPE(value));
  784. RETVAL = 0;
  785. break;
  786.       }
  787.       /* Find length of string (strlen will *not* do, as these are binary strings) */
  788.       stringptr = SvPV(value, stringlen);
  789.               snmp_set_var_typed_value(request->requestvb, (u_char)type,
  790.                                        (u_char *) stringptr,
  791.                                        stringlen);
  792.               RETVAL = 1;
  793.               break;
  794.           case ASN_IPADDRESS:
  795.       /* IP addresses are passed as *binary* strings.
  796.        * In the case of IPv4 addresses, these are 4 bytes long.
  797.        * NOTE: the use of binary strings rather than dotted-quad or FQDNs was
  798.        * introduced here by Andrew Findlay's patch of March 17th 2003,
  799.        * and is effectively a change to the previous implied API which assumed
  800.        * the value was a (valid) hostname.
  801.        * Responsibility for decoding and resolving has been passed up to the Perl script.
  802.        */
  803.       /* Check that we have been passed something with a string value (or a blessed scalar) */
  804.       if (!SvPOKp(value) && (SvTYPE(value) != SVt_PVMG)) {
  805. snmp_log(LOG_ERR, "Non-string value passed to setValue with ASN_IPADDRESS: type was %dn",
  806. SvTYPE(value));
  807. RETVAL = 0;
  808. break;
  809.       }
  810.       /* Find length of string (strlen will *not* do, as these are binary strings) */
  811.       stringptr = SvPV(value, stringlen);
  812.       # snmp_log(LOG_ERR, "IP address returned with length %d: %u.%u.%u.%un", stringlen, stringptr[0],
  813.       #     stringptr[1], stringptr[2], stringptr[3] );
  814.       # Sanity check on address length
  815.       if ((stringlen != 4) && (stringlen != 16)) {
  816.        snmp_log(LOG_ERR, "IP address of %d bytes passed to setValue with ASN_IPADDRESSn", stringlen);
  817. RETVAL = 0;
  818. break;
  819.       }
  820.               snmp_set_var_typed_value(request->requestvb, (u_char)type,
  821.                                    stringptr, stringlen);
  822.               RETVAL = 1;
  823.               break;
  824.           case ASN_OBJECT_ID:
  825.       /* Check that we have been passed something with a string value (or a blessed scalar) */
  826.       if (!SvPOKp(value) && (SvTYPE(value) != SVt_PVMG)) {
  827. snmp_log(LOG_ERR, "Non-string value passed to setValue with ASN_OBJECT_ID: type was %dn",
  828. SvTYPE(value));
  829. RETVAL = 0;
  830. break;
  831.       }
  832.       /* Extract the string */
  833.       stringptr = SvPV(value, stringlen);
  834.       /* snmp_log(LOG_ERR, "setValue returning OID '%s'n", stringptr); */
  835.       myoid_len = MAX_OID_LEN;
  836.               if (!snmp_parse_oid(stringptr, myoid, &myoid_len)) {
  837.                   snmp_log(LOG_ERR, "couldn't parse %s in setValuen", stringptr);
  838.   RETVAL = 0;
  839.   break;
  840.               } else {
  841.   /* snmp_log(LOG_ERR, "setValue returning OID length %dn", myoid_len); */
  842.                   request = (netsnmp_request_info *) SvIV(SvRV(me));
  843.                   snmp_set_var_typed_value(request->requestvb, (u_char)type,
  844.                                            (u_char *) myoid, (myoid_len * sizeof(myoid[0])) );
  845.               }
  846.               RETVAL = 1;
  847.               break;
  848.               
  849.             default:
  850.                 snmp_log(LOG_ERR, "unknown var value type: %dn",
  851.                         type);
  852.                 RETVAL = 0;
  853.                 break;
  854.         }
  855.     OUTPUT:
  856.         RETVAL
  857.         
  858. void
  859. nari_setOID(me, value)
  860.         SV *me;
  861.         char *value;
  862.     PREINIT:
  863. oid myoid[MAX_OID_LEN];
  864. size_t myoid_len = MAX_OID_LEN;
  865.         netsnmp_request_info *request;
  866.     CODE:
  867. myoid_len = MAX_OID_LEN;
  868. if (!snmp_parse_oid(value, myoid, &myoid_len)) {
  869.             snmp_log(LOG_ERR, "couldn't parse %s in setOIDn", value);
  870.         } else {
  871.             request = (netsnmp_request_info *) SvIV(SvRV(me));
  872.             snmp_set_var_objid(request->requestvb, myoid, myoid_len);
  873.         }
  874. void
  875. nari_setError(me, rinfo, ecode)
  876.         SV *me;
  877.         SV *rinfo;
  878.         int ecode;
  879.     PREINIT:
  880. oid myoid[MAX_OID_LEN];
  881. size_t myoid_len = MAX_OID_LEN;
  882.         netsnmp_request_info *request;
  883.         netsnmp_agent_request_info *reqinfo;
  884.     CODE:
  885.         request = (netsnmp_request_info *) SvIV(SvRV(me));
  886.         reqinfo = (netsnmp_agent_request_info *) SvIV(SvRV(rinfo));
  887.         netsnmp_set_request_error(reqinfo, request, ecode);
  888. SV *
  889. nari_next(me)
  890.         SV *me;
  891.     PREINIT:
  892.         netsnmp_request_info *request;
  893.         SV *arg, *rarg;
  894.     CODE:
  895.         {
  896.             request = (netsnmp_request_info *) SvIV(SvRV(me));
  897.             if (request && request->next) {
  898.                 request = request->next;
  899.                 rarg = newSViv(0);
  900.                 arg = newSVrv(rarg, "NetSNMP::agent::netsnmp_request_infoPtr");
  901.                 sv_setiv(arg, (int) request);
  902.                 ST(0) = rarg;
  903.             } else {
  904.                 ST(0) = &sv_undef;
  905.             }
  906.         }
  907. MODULE = NetSNMP::agent  PACKAGE = NetSNMP::agent::netsnmp_agent_request_info PREFIX = narqi_
  908. int
  909. narqi_getMode(me)
  910.         SV *me;
  911.     PREINIT:
  912.         netsnmp_agent_request_info *reqinfo;
  913.     CODE:
  914.         reqinfo = (netsnmp_agent_request_info *) SvIV(SvRV(me));
  915.         RETVAL = reqinfo->mode;
  916.     OUTPUT:
  917.         RETVAL
  918. void
  919. narqi_setMode(me, newvalue)
  920.         SV *me;
  921.         int newvalue;
  922.     PREINIT:
  923.         netsnmp_agent_request_info *reqinfo;
  924.     CODE:
  925.         reqinfo = (netsnmp_agent_request_info *) SvIV(SvRV(me));
  926.         reqinfo->mode = newvalue;
  927.         
  928. MODULE = NetSNMP::agent PACKAGE = NetSNMP::agent