… | |
… | |
2 | #include "perl.h" |
2 | #include "perl.h" |
3 | #include "XSUB.h" |
3 | #include "XSUB.h" |
4 | |
4 | |
5 | // C99 required |
5 | // C99 required |
6 | |
6 | |
7 | #define BENCHMARK |
7 | //#define BENCHMARK |
8 | |
8 | |
9 | #define ASN_BOOLEAN 0x01 |
9 | #define ASN_BOOLEAN 0x01 |
10 | #define ASN_INTEGER32 0x02 |
10 | #define ASN_INTEGER32 0x02 |
11 | #define ASN_OCTET_STRING 0x04 |
11 | #define ASN_OCTET_STRING 0x04 |
12 | #define ASN_NULL 0x05 |
12 | #define ASN_NULL 0x05 |
… | |
… | |
19 | #define ASN_OPAQUE 0x44 |
19 | #define ASN_OPAQUE 0x44 |
20 | #define ASN_COUNTER64 0x46 |
20 | #define ASN_COUNTER64 0x46 |
21 | |
21 | |
22 | #define MAX_OID_STRLEN 4096 |
22 | #define MAX_OID_STRLEN 4096 |
23 | |
23 | |
|
|
24 | #define HAVE_VERSIONSORT defined (_GNU_SOURCE) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 |
|
|
25 | |
24 | static SV *msg; |
26 | static SV *msg; |
25 | static int errflag, leading_dot; |
27 | static int errflag, leading_dot; |
26 | static U8 *buf, *cur; |
28 | static U8 *buf, *cur; |
27 | static STRLEN len, rem; |
29 | static STRLEN len, rem; |
28 | |
30 | |
… | |
… | |
38 | |
40 | |
39 | return (SV *)cv; |
41 | return (SV *)cv; |
40 | } |
42 | } |
41 | |
43 | |
42 | static void |
44 | static void |
43 | error (const char *msg) |
45 | error (const char *errmsg) |
44 | { |
46 | { |
45 | errflag = 1; |
47 | errflag = 1; |
46 | |
48 | |
47 | printf ("<<<%s>>>\n", msg);//D |
49 | if (!msg) |
|
|
50 | croak ("Net::SNMP::XS fatal error, parser called without parsing context"); |
|
|
51 | |
|
|
52 | dSP; |
|
|
53 | PUSHMARK (SP); |
|
|
54 | EXTEND (SP, 2); |
|
|
55 | PUSHs (msg); |
|
|
56 | PUSHs (sv_2mortal (newSVpv (errmsg, 0))); |
|
|
57 | PUTBACK; |
|
|
58 | call_method ("_error", G_VOID | G_DISCARD); |
48 | } |
59 | } |
49 | |
60 | |
50 | static int |
61 | static int |
51 | need (int count) |
62 | need (int count) |
52 | { |
63 | { |
… | |
… | |
183 | process_unsigned32_sv (void) |
194 | process_unsigned32_sv (void) |
184 | { |
195 | { |
185 | return newSVuv ((U32)process_integer32 ()); |
196 | return newSVuv ((U32)process_integer32 ()); |
186 | } |
197 | } |
187 | |
198 | |
|
|
199 | #if IVSIZE >= 8 |
|
|
200 | |
|
|
201 | static U64TYPE |
|
|
202 | process_integer64 (void) |
|
|
203 | { |
|
|
204 | U32 length = process_length (); |
|
|
205 | |
|
|
206 | if (length <= 0) |
|
|
207 | { |
|
|
208 | error ("INTEGER64 length equal to zero"); |
|
|
209 | return 0; |
|
|
210 | } |
|
|
211 | |
|
|
212 | U8 *data = getn (length, 0); |
|
|
213 | |
|
|
214 | if (!data) |
|
|
215 | return 0; |
|
|
216 | |
|
|
217 | if (length > 9 || (length > 8 && data [0])) |
|
|
218 | { |
|
|
219 | error ("INTEGER64 length too long"); |
|
|
220 | return 0; |
|
|
221 | } |
|
|
222 | |
|
|
223 | U64TYPE res = data [0] & 0x80 ? 0xffffffffffffffff : 0; |
|
|
224 | |
|
|
225 | while (length--) |
|
|
226 | res = (res << 8) | *data++; |
|
|
227 | |
|
|
228 | return res; |
|
|
229 | } |
|
|
230 | |
|
|
231 | static SV * |
|
|
232 | process_integer64_sv (void) |
|
|
233 | { |
|
|
234 | return newSViv ((I64TYPE)process_integer64 ()); |
|
|
235 | } |
|
|
236 | |
|
|
237 | static SV * |
|
|
238 | process_unsigned64_sv (void) |
|
|
239 | { |
|
|
240 | return newSVuv ((U64TYPE)process_integer64 ()); |
|
|
241 | } |
|
|
242 | |
|
|
243 | #endif |
|
|
244 | |
188 | static SV * |
245 | static SV * |
189 | process_octet_string_sv (void) |
246 | process_octet_string_sv (void) |
190 | { |
247 | { |
191 | U32 length = process_length (); |
248 | U32 length = process_length (); |
192 | |
249 | |
… | |
… | |
218 | U32 length = process_length (); |
275 | U32 length = process_length (); |
219 | |
276 | |
220 | if (length <= 0) |
277 | if (length <= 0) |
221 | { |
278 | { |
222 | error ("OBJECT IDENTIFIER length equal to zero"); |
279 | error ("OBJECT IDENTIFIER length equal to zero"); |
223 | return ""; |
280 | return &PL_sv_undef; |
224 | } |
281 | } |
225 | |
282 | |
226 | U8 *end = cur + length; |
283 | U8 *end = cur + length; |
227 | U32 w = getb (); |
284 | U32 w = getb (); |
228 | |
285 | |
… | |
… | |
302 | } |
359 | } |
303 | |
360 | |
304 | return errflag ? &PL_sv_undef : res; |
361 | return errflag ? &PL_sv_undef : res; |
305 | } |
362 | } |
306 | |
363 | |
|
|
364 | ///////////////////////////////////////////////////////////////////////////// |
|
|
365 | |
|
|
366 | #if HAVE_VERSIONSORT |
|
|
367 | |
|
|
368 | static int |
|
|
369 | oid_lex_cmp (const void *a_, const void *b_) |
|
|
370 | { |
|
|
371 | const char *a = SvPVX (*(SV **)a_); |
|
|
372 | const char *b = SvPVX (*(SV **)b_); |
|
|
373 | |
|
|
374 | a += *a == '.'; |
|
|
375 | b += *b == '.'; |
|
|
376 | |
|
|
377 | return strverscmp (a, b); |
|
|
378 | } |
|
|
379 | |
|
|
380 | #endif |
|
|
381 | |
307 | MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::XS |
382 | MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::XS |
308 | |
383 | |
309 | PROTOTYPES: ENABLE |
384 | PROTOTYPES: ENABLE |
310 | |
385 | |
311 | BOOT: |
386 | BOOT: |
… | |
… | |
317 | av_store (av_type, type, SvREFCNT_inc (x_get_cv (cv))); |
392 | av_store (av_type, type, SvREFCNT_inc (x_get_cv (cv))); |
318 | |
393 | |
319 | void |
394 | void |
320 | set_msg (SV *msg_, SV *buf_) |
395 | set_msg (SV *msg_, SV *buf_) |
321 | CODE: |
396 | CODE: |
|
|
397 | { |
|
|
398 | if (msg) |
|
|
399 | croak ("recursive invocation of Net::SNMP::XS parser is not supported"); |
|
|
400 | |
322 | errflag = 0; |
401 | errflag = 0; |
323 | leading_dot = -1; |
402 | leading_dot = -1; |
324 | msg = SvREFCNT_inc (msg_); |
403 | msg = SvREFCNT_inc (msg_); |
325 | buf = SvPVbyte (buf_, len); |
404 | buf = SvPVbyte (buf_, len); |
326 | cur = buf; |
405 | cur = buf; |
327 | rem = len; |
406 | rem = len; |
328 | #ifdef BENCHMARK |
407 | #ifdef BENCHMARK |
329 | t1 = tstamp (); |
408 | t1 = tstamp (); |
330 | #endif |
409 | #endif |
|
|
410 | } |
331 | |
411 | |
332 | void |
412 | void |
333 | clr_msg () |
413 | clr_msg () |
334 | CODE: |
414 | CODE: |
335 | SvREFCNT_dec (msg); |
415 | SvREFCNT_dec (msg); msg = 0; |
336 | buf = cur = ""; |
416 | buf = cur = (U8 *)""; |
337 | len = rem = 0; |
417 | len = rem = 0; |
338 | #ifdef BENCHMARK |
418 | #ifdef BENCHMARK |
339 | printf ("%f\n", tstamp () - t1);//D |
419 | printf ("%f\n", tstamp () - t1);//D |
340 | #endif |
420 | #endif |
341 | |
421 | |
… | |
… | |
400 | _process_timeticks = 0 |
480 | _process_timeticks = 0 |
401 | CODE: |
481 | CODE: |
402 | RETVAL = process_unsigned32_sv (); |
482 | RETVAL = process_unsigned32_sv (); |
403 | OUTPUT: |
483 | OUTPUT: |
404 | RETVAL |
484 | RETVAL |
|
|
485 | |
|
|
486 | #if IVSIZE >= 8 |
|
|
487 | |
|
|
488 | SV * |
|
|
489 | _process_counter64 (SV *self, ...) |
|
|
490 | CODE: |
|
|
491 | RETVAL = process_unsigned64_sv (); |
|
|
492 | OUTPUT: |
|
|
493 | RETVAL |
|
|
494 | |
|
|
495 | #endif |
405 | |
496 | |
406 | SV * |
497 | SV * |
407 | _process_object_identifier (SV *self, ...) |
498 | _process_object_identifier (SV *self, ...) |
408 | CODE: |
499 | CODE: |
409 | RETVAL = process_object_identifier_sv (); |
500 | RETVAL = process_object_identifier_sv (); |
… | |
… | |
495 | RETVAL = newRV_inc ((SV *)list); |
586 | RETVAL = newRV_inc ((SV *)list); |
496 | } |
587 | } |
497 | OUTPUT: |
588 | OUTPUT: |
498 | RETVAL |
589 | RETVAL |
499 | |
590 | |
|
|
591 | MODULE = Net::SNMP::XS PACKAGE = Net::SNMP |
500 | |
592 | |
|
|
593 | void |
|
|
594 | oid_base_match (SV *base_, SV *oid_) |
|
|
595 | PROTOTYPE: $$ |
|
|
596 | ALIAS: |
|
|
597 | oid_context_match = 0 |
|
|
598 | PPCODE: |
|
|
599 | { |
|
|
600 | if (!SvOK (base_) || !SvOK (oid_)) |
|
|
601 | XSRETURN_NO; |
|
|
602 | |
|
|
603 | STRLEN blen, olen; |
|
|
604 | char *base = SvPV (base_, blen); |
|
|
605 | char *oid = SvPV (oid_ , olen); |
|
|
606 | |
|
|
607 | blen -= *base == '.'; base += *base == '.'; |
|
|
608 | olen -= *base == '.'; oid += *oid == '.'; |
|
|
609 | |
|
|
610 | if (olen < blen) |
|
|
611 | XSRETURN_NO; |
|
|
612 | |
|
|
613 | if (memcmp (base, oid, blen)) |
|
|
614 | XSRETURN_NO; |
|
|
615 | |
|
|
616 | if (oid [blen] && oid [blen] != '.') |
|
|
617 | XSRETURN_NO; |
|
|
618 | |
|
|
619 | XSRETURN_YES; |
|
|
620 | } |
|
|
621 | |
|
|
622 | #if HAVE_VERSIONSORT |
|
|
623 | |
|
|
624 | void |
|
|
625 | oid_lex_sort (...) |
|
|
626 | PROTOTYPE: @ |
|
|
627 | PPCODE: |
|
|
628 | { |
|
|
629 | // make sure SvPVX is valid |
|
|
630 | int i; |
|
|
631 | for (i = items; i--; ) |
|
|
632 | { |
|
|
633 | SV *sv = ST (i); |
|
|
634 | |
|
|
635 | if (SvTYPE (sv) < SVt_PV || SvTYPE (sv) == SVt_PVAV && SvTYPE (sv) == SVt_PVHV) |
|
|
636 | SvPV_force_nolen (sv); |
|
|
637 | } |
|
|
638 | |
|
|
639 | qsort (&ST (0), items, sizeof (SV *), oid_lex_cmp); |
|
|
640 | |
|
|
641 | EXTEND (SP, items); |
|
|
642 | // we cheat somewhat by not returning copies here |
|
|
643 | for (i = 0; i < items; ++i) |
|
|
644 | PUSHs (sv_2mortal (SvREFCNT_inc (ST (i)))); |
|
|
645 | } |
|
|
646 | |
|
|
647 | int |
|
|
648 | _index_cmp (const char *a, const char *b) |
|
|
649 | PROTOTYPE: $$ |
|
|
650 | CODE: |
|
|
651 | RETVAL = strverscmp (a, b); |
|
|
652 | OUTPUT: |
|
|
653 | RETVAL |
|
|
654 | |
|
|
655 | #endif |
|
|
656 | |