ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Net-SNMP-XS/XS.xs
(Generate patch)

Comparing Net-SNMP-XS/XS.xs (file contents):
Revision 1.6 by root, Thu Apr 9 05:56:36 2009 UTC vs.
Revision 1.19 by root, Fri Apr 19 14:50:44 2019 UTC

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 ASN_BOOLEAN 0x01
8#define ASN_INTEGER32 0x02
9#define ASN_OCTET_STRING 0x04
10#define ASN_NULL 0x05
11#define ASN_OBJECT_IDENTIFIER 0x06
12#define ASN_SEQUENCE 0x30
13#define ASN_IPADDRESS 0x40
14#define ASN_COUNTER32 0x41
15#define ASN_UNSIGNED32 0x42
16#define ASN_TIMETICKS 0x43
17#define ASN_OPAQUE 0x44
18#define ASN_COUNTER64 0x46
19
20//#define BENCHMARK 7//#define BENCHMARK
21 8
9enum {
10 ASN_BOOLEAN = 0x01,
11 ASN_INTEGER32 = 0x02,
12 ASN_BIT_STRING = 0x03,
13 ASN_OCTET_STRING = 0x04,
14 ASN_NULL = 0x05,
15 ASN_OBJECT_IDENTIFIER = 0x06,
16
17 ASN_TAG_BER = 0x1f,
18 ASN_TAG_MASK = 0x1f,
19
20 ASN_CONSTRUCTED = 0x20,
21
22 ASN_UNIVERSAL = 0x00,
23 ASN_APPLICATION = 0x40,
24 ASN_CONTEXT = 0x80,
25 ASN_PRIVATE = 0xc0,
26
27 ASN_CLASS_MASK = 0xc0,
28 ASN_CLASS_SHIFT = 6,
29
30 ASN_SEQUENCE = ASN_CONSTRUCTED | 0x10,
31 ASN_IPADDRESS = ASN_APPLICATION | 0x00,
32 ASN_COUNTER32 = ASN_APPLICATION | 0x01,
33 ASN_UNSIGNED32 = ASN_APPLICATION | 0x02,
34 ASN_TIMETICKS = ASN_APPLICATION | 0x03,
35 ASN_OPAQUE = ASN_APPLICATION | 0x04,
36 ASN_COUNTER64 = ASN_APPLICATION | 0x06,
37};
38
22#define MAX_OID_STRLEN 4096 39#define MAX_OID_STRLEN 4096
23 40
41#define HAVE_VERSIONSORT defined (_GNU_SOURCE) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
42
43static SV *cur_bufobj;
24static SV *msg; 44static SV *msg, *bufsv;
25static int errflag, leading_dot; 45static int errflag, leading_dot;
26static U8 *buf, *cur; 46static U8 *buf, *cur;
27static STRLEN len, rem; 47static STRLEN len, rem;
28 48
49typedef SV *BUFOBJ;
50
51// for "small" integers, return a readonly sv, otherwise create a new one
52static SV *newSVcacheint (int val)
53{
54 static SV *cache[32];
55
56 if (val < 0 || val >= sizeof (cache))
57 return newSViv (val);
58
59 if (!cache [val])
60 {
61 cache [val] = newSVuv (val);
62 SvREADONLY_on (cache [val]);
63 }
64
65 return SvREFCNT_inc_NN (cache [val]);
66}
67
68/////////////////////////////////////////////////////////////////////////////
69
70#if 0
71 if (msg)
72 croak ("recursive invocation of Net::SNMP::XS parser is not supported");
73
74
75void
76clr_msg ()
77 CODE:
78 SvREFCNT_dec (msg); msg = 0;
79 buf = cur = (U8 *)"";
80 len = rem = 0;
81#endif
82
83static void
84clear_bufobj (void)
85{
86 // serialise our state back
87 if (msg && SvROK (msg))
88 {
89 SV *idx_sv = *hv_fetch ((HV *)cur_bufobj, "_index" , sizeof ("_index" ) - 1, 1);
90 sv_setiv (idx_sv, cur - buf);
91 }
92
93 SvREFCNT_dec (msg);
94 msg = 0;
95 cur_bufobj = 0;
96}
97
98static void
99switch_bufobj (BUFOBJ neu)
100{
101 clear_bufobj ();
102
103 msg = newSVsv (neu);
104 cur_bufobj = SvRV (msg);
105 sv_rvweaken (msg);
106
107 errflag = 0;
108 leading_dot = -1;
109
110 IV index = SvIV (*hv_fetch ((HV *)cur_bufobj, "_index" , sizeof ("_index" ) - 1, 1));
111 bufsv = *hv_fetch ((HV *)cur_bufobj, "_buffer", sizeof ("_buffer") - 1, 1);
112
113 buf = SvPVbyte (bufsv, len);
114 cur = buf + index;
115 rem = len - index;
116}
117
118/////////////////////////////////////////////////////////////////////////////
119
29static SV * 120static SV *
30x_get_cv (SV *cb_sv) 121x_get_cv (SV *cb_sv)
31{ 122{
32 HV *st; 123 HV *st;
33 GV *gvp; 124 GV *gvp;
38 129
39 return (SV *)cv; 130 return (SV *)cv;
40} 131}
41 132
42static void 133static void
43error (const char *msg) 134error (const char *errmsg)
44{ 135{
45 errflag = 1; 136 errflag = 1;
46 137
47 printf ("<<<%s>>>\n", msg);//D 138 if (!msg)
139 croak ("Net::SNMP::XS fatal error, parser called without parsing context");
140
141 dSP;
142 PUSHMARK (SP);
143 EXTEND (SP, 2);
144 PUSHs (msg);
145 PUSHs (sv_2mortal (newSVpv (errmsg, 0)));
146 PUTBACK;
147 call_method ("_error", G_VOID | G_DISCARD);
48} 148}
49 149
50static int 150static int
51need (int count) 151need (int count)
52{ 152{
183process_unsigned32_sv (void) 283process_unsigned32_sv (void)
184{ 284{
185 return newSVuv ((U32)process_integer32 ()); 285 return newSVuv ((U32)process_integer32 ());
186} 286}
187 287
288#if IVSIZE >= 8
289
290static U64TYPE
291process_integer64 (void)
292{
293 U32 length = process_length ();
294
295 if (length <= 0)
296 {
297 error ("INTEGER64 length equal to zero");
298 return 0;
299 }
300
301 U8 *data = getn (length, 0);
302
303 if (!data)
304 return 0;
305
306 if (length > 9 || (length > 8 && data [0]))
307 {
308 error ("INTEGER64 length too long");
309 return 0;
310 }
311
312 U64TYPE res = data [0] & 0x80 ? 0xffffffffffffffff : 0;
313
314 while (length--)
315 res = (res << 8) | *data++;
316
317 return res;
318}
319
320static SV *
321process_integer64_sv (void)
322{
323 return newSViv ((I64TYPE)process_integer64 ());
324}
325
326static SV *
327process_unsigned64_sv (void)
328{
329 return newSVuv ((U64TYPE)process_integer64 ());
330}
331
332#endif
333
188static SV * 334static SV *
189process_octet_string_sv (void) 335process_octet_string_sv (void)
190{ 336{
191 U32 length = process_length (); 337 U32 length = process_length ();
192 338
210 buf += sprintf (buf, "%u", (unsigned int)u); 356 buf += sprintf (buf, "%u", (unsigned int)u);
211 357
212 return buf; 358 return buf;
213} 359}
214 360
215static char * 361static SV *
216process_object_identifier (int *len) 362process_object_identifier_sv (void)
217{ 363{
218 U32 length = process_length (); 364 U32 length = process_length ();
219 365
220 if (length <= 0) 366 if (length <= 0)
221 { 367 {
222 error ("OBJECT IDENTIFIER length equal to zero"); 368 error ("OBJECT IDENTIFIER length equal to zero");
223 return ""; 369 return &PL_sv_undef;
224 } 370 }
225 371
226 U8 *end = cur + length; 372 U8 *end = cur + length;
227 U32 w = getb (); 373 U32 w = getb ();
228 374
229 static char oid[MAX_OID_STRLEN]; // must be static 375 static char oid[MAX_OID_STRLEN]; // must be static
230 char *app = oid; 376 char *app = oid;
377
378 if (leading_dot < 0)
379 leading_dot = SvTRUE (*hv_fetch ((HV *)SvRV (msg), "_leading_dot", sizeof ("_leading_dot") - 1, 1));
231 380
232 *app = '.'; app += ! ! leading_dot; 381 *app = '.'; app += ! ! leading_dot;
233 app = write_uv (app, (U8)w / 40); 382 app = write_uv (app, (U8)w / 40);
234 *app++ = '.'; 383 *app++ = '.';
235 app = write_uv (app, (U8)w % 40); 384 app = write_uv (app, (U8)w % 40);
240 w = getb (); 389 w = getb ();
241 *app++ = '.'; 390 *app++ = '.';
242 app = write_uv (app, w); 391 app = write_uv (app, w);
243 } 392 }
244 393
245 *len = app - oid;
246 return oid;
247}
248
249static SV *
250process_object_identifier_sv (void)
251{
252 int len;
253 char *oid = process_object_identifier (&len);
254
255 return newSVpvn (oid, len); 394 return newSVpvn (oid, app - oid);
256} 395}
257 396
258static AV *av_type; 397static AV *av_type;
259 398
260static SV * 399static SV *
291 res = process_octet_string_sv (); 430 res = process_octet_string_sv ();
292 break; 431 break;
293 432
294 default: 433 default:
295 { 434 {
296 if (type > AvFILLp (av_type) || !SvTYPE (AvARRAY (av_type)[type]) == SVt_PVCV) 435 if (type > AvFILLp (av_type)
436 || AvARRAY (av_type)[type] == 0
437 || AvARRAY (av_type)[type] == &PL_sv_undef)
297 { 438 {
298 error ("Unknown ASN.1 type"); 439 error ("Unknown ASN.1 type");
299 return &PL_sv_undef; 440 return &PL_sv_undef;
300 } 441 }
301 442
312 } 453 }
313 454
314 return errflag ? &PL_sv_undef : res; 455 return errflag ? &PL_sv_undef : res;
315} 456}
316 457
458static SV *
459decode_ber ()
460{
461 int identifier = get8 ();
462
463 SV *res;
464
465 int constructed = identifier & ASN_CONSTRUCTED;
466 int klass = identifier & ASN_CLASS_MASK;
467 int tag = identifier & ASN_TAG_MASK;
468
469 if (tag == ASN_TAG_BER)
470 tag = getb ();
471
472#if 0
473 if (/type & ASN_TAG_MASK) == ASN_TAG_MASK)
474 /* TODO: ber tag follows */;
475#endif
476
477 if (constructed)
478 {
479 U32 len = process_length ();
480 U32 seqend = (cur - buf) + len;
481 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
482
483 while (cur < buf + seqend)
484 {
485 av_push (av, decode_ber ());
486 }
487
488 if (cur > buf + seqend)
489 croak ("constructed type %02x overflow (%x %x)\n", identifier, cur - buf, seqend);
490
491 res = newRV_inc ((SV *)av);
492 }
493 else
494 switch (identifier)
495 {
496 case ASN_OBJECT_IDENTIFIER:
497 res = process_object_identifier_sv ();
498 break;
499
500 case ASN_INTEGER32:
501 res = process_integer32_sv ();
502 break;
503
504 case ASN_UNSIGNED32:
505 case ASN_COUNTER32:
506 case ASN_TIMETICKS:
507 res = process_unsigned32_sv ();
508 break;
509
510#if 0 // handled by default case
511 case ASN_IPADDRESS:
512 case ASN_OCTET_STRING:
513 case ASN_OPAQUE:
514 res = process_octet_string_sv ();
515 break;
516#endif
517
518 case ASN_COUNTER64:
519 res = process_integer64_sv ();
520 break;
521
522 default:
523 res = process_octet_string_sv ();
524 break;
525 }
526
527 if (errflag)
528 croak ("some error");
529
530 AV *av = newAV ();
531 av_fill (av, 4-1);
532 AvARRAY (av)[0] = newSVcacheint (tag);
533 AvARRAY (av)[1] = newSVcacheint (klass >> ASN_CLASS_SHIFT);
534 AvARRAY (av)[2] = newSVcacheint (constructed ? 1 : 0);
535 AvARRAY (av)[3] = res;
536 res = newRV_noinc ((SV *)av);
537
538 return errflag ? &PL_sv_undef : res;
539}
540
541/////////////////////////////////////////////////////////////////////////////
542
543#if HAVE_VERSIONSORT
544
545static int
546oid_lex_cmp (const void *a_, const void *b_)
547{
548 const char *a = SvPVX (*(SV **)a_);
549 const char *b = SvPVX (*(SV **)b_);
550
551 a += *a == '.';
552 b += *b == '.';
553
554 return strverscmp (a, b);
555}
556
557#endif
558
317MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::XS 559MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::XS
318 560
319PROTOTYPES: ENABLE 561PROTOTYPES: ENABLE
320 562
321BOOT: 563BOOT:
564{
565 HV *stash = gv_stashpv ("Net::SNMP::XS", 1);
566
567 static const struct {
568 const char *name;
569 IV iv;
570 } *civ, const_iv[] = {
571 { "ASN_BOOLEAN", ASN_BOOLEAN },
572 { "ASN_INTEGER32", ASN_INTEGER32 },
573 { "ASN_BIT_STRING", ASN_BIT_STRING },
574 { "ASN_OCTET_STRING", ASN_OCTET_STRING },
575 { "ASN_NULL", ASN_NULL },
576 { "ASN_OBJECT_IDENTIFIER", ASN_OBJECT_IDENTIFIER },
577 { "ASN_TAG_BER", ASN_TAG_BER },
578 { "ASN_TAG_MASK", ASN_TAG_MASK },
579 { "ASN_CONSTRUCTED", ASN_CONSTRUCTED },
580 { "ASN_UNIVERSAL", ASN_UNIVERSAL >> ASN_CLASS_SHIFT },
581 { "ASN_APPLICATION", ASN_APPLICATION >> ASN_CLASS_SHIFT },
582 { "ASN_CONTEXT", ASN_CONTEXT >> ASN_CLASS_SHIFT },
583 { "ASN_PRIVATE", ASN_PRIVATE >> ASN_CLASS_SHIFT },
584 { "ASN_CLASS_MASK", ASN_CLASS_MASK },
585 { "ASN_CLASS_SHIFT", ASN_CLASS_SHIFT },
586 { "ASN_SEQUENCE", ASN_SEQUENCE },
587 { "ASN_IPADDRESS", ASN_IPADDRESS },
588 { "ASN_COUNTER32", ASN_COUNTER32 },
589 { "ASN_UNSIGNED32", ASN_UNSIGNED32 },
590 { "ASN_TIMETICKS", ASN_TIMETICKS },
591 { "ASN_OPAQUE", ASN_OPAQUE },
592 { "ASN_COUNTER64", ASN_COUNTER64 },
593 };
594
595 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
596 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
597
322 av_type = newAV (); 598 av_type = newAV ();
599}
323 600
324void 601void
325set_type (int type, SV *cv) 602set_type (int type, SV *cv)
326 CODE: 603 CODE:
604 cv = x_get_cv (cv);
605 assert (SvTYPE (cv) == SVt_PVCV);
327 av_store (av_type, type, SvREFCNT_inc (x_get_cv (cv))); 606 av_store (av_type, type, SvREFCNT_inc_NN (cv));
607
608#if 1
609
610SV *
611decode_ber (SV *ber)
612 CODE:
613{
614 clear_bufobj ();
615
616 errflag = 0;
617 leading_dot = 0;
618
619 bufsv = ber;
620
621 buf = SvPVbyte (bufsv, len);
622 cur = buf;
623 rem = len;
624
625 RETVAL = decode_ber ();
626}
627 OUTPUT: RETVAL
628
629#endif
630
631MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::Message
328 632
329void 633void
330set_msg (SV *msg_, SV *buf_) 634_buffer_append (BUFOBJ self, SV *value)
635 ALIAS:
636 _buffer_put = 1
331 CODE: 637 PPCODE:
332 errflag = 0; 638{
333 leading_dot = -1; 639 STRLEN vlen;
334 msg = SvREFCNT_inc (msg_); 640 const char *vstr = SvPVbyte (value, vlen);
641
642 if (ix)
643 sv_insert (bufsv, 0, 0, vstr, vlen);
644 else
645 sv_catpvn (bufsv, vstr, vlen);
646
335 buf = SvPVbyte (buf_, len); 647 buf = SvPVbyte (bufsv, len);
336 cur = buf; 648 cur = buf;
337 rem = len; 649 rem = len;
338#ifdef BENCHMARK 650
339 t1 = tstamp (); 651 SV *len_sv = *hv_fetch ((HV *)cur_bufobj, "_length", sizeof ("_length") - 1, 1);
340#endif 652 sv_setiv (len_sv, len);
653
654 // some callers test for defined'ness of the returnvalue. *sigh*
655 XPUSHs (&PL_sv_yes);
656}
341 657
342void 658void
343clr_msg ()
344 CODE:
345 SvREFCNT_dec (msg);
346 buf = cur = "";
347 len = rem = 0;
348#ifdef BENCHMARK
349 printf ("%f\n", tstamp () - t1);//D
350#endif
351
352MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::Message
353
354void
355_buffer_get (SV *self, int count = -1) 659_buffer_get (BUFOBJ self, int count = -1)
356 PPCODE: 660 PPCODE:
357{ 661{
358 // grrr. 662 // grrr.
359 if (count < 0) 663 if (count < 0)
360 { 664 {
361 hv_delete ((HV *)SvRV (self), "_index" , 6, G_DISCARD); 665 hv_delete ((HV *)SvRV (self), "_index" , 6, G_DISCARD);
362 hv_delete ((HV *)SvRV (self), "_length", 7, G_DISCARD); 666 hv_delete ((HV *)SvRV (self), "_length", 7, G_DISCARD);
363 SV **svp = hv_fetch ((HV *)SvRV (self), "_buffer", 7, 1);
364 XPUSHs (sv_2mortal (newSVsv (*svp))); 667 XPUSHs (sv_2mortal (newSVsv (bufsv)));
365 sv_setpvn (*svp, "", 0); 668 sv_setpvn (bufsv, "", 0);
669
670 buf = "";
671 cur = buf;
672 rem = 0;
673
366 XSRETURN (1); 674 XSRETURN (1);
367 } 675 }
368 676
369 char *data = getn (count, 0); 677 char *data = getn (count, 0);
370 678
371 if (data) 679 if (data)
372 XPUSHs (sv_2mortal (newSVpvn (data, count))); 680 XPUSHs (sv_2mortal (newSVpvn (data, count)));
373} 681}
374 682
375U32 683U32
376index (SV *self, int ndx = -1) 684index (BUFOBJ self, int ndx = -1)
377 CODE: 685 CODE:
378{ 686{
379 if (ndx >= 0 && ndx < len) 687 if (ndx >= 0 && ndx < len)
380 { 688 {
381 cur = buf + ndx; 689 cur = buf + ndx;
382 rem = len - ndx; 690 rem = len - ndx;
383 } 691 }
384 692
385 RETVAL = cur - buf; 693 RETVAL = cur - buf;
386} 694}
387 OUTPUT: 695 OUTPUT: RETVAL
388 RETVAL
389 696
390U32 697U32
391_process_length (SV *self, ...) 698_process_length (BUFOBJ self, ...)
392 ALIAS: 699 ALIAS:
393 _process_sequence = 0 700 _process_sequence = 0
394 CODE: 701 CODE:
395 RETVAL = process_length (); 702 RETVAL = process_length ();
396 OUTPUT: 703 OUTPUT: RETVAL
397 RETVAL
398 704
399SV * 705SV *
400_process_integer32 (SV *self, ...) 706_process_integer32 (BUFOBJ self, ...)
401 CODE: 707 CODE:
402 RETVAL = process_integer32_sv (); 708 RETVAL = process_integer32_sv ();
403 OUTPUT: 709 OUTPUT: RETVAL
404 RETVAL
405 710
406SV * 711SV *
407_process_counter (SV *self, ...) 712_process_counter (BUFOBJ self, ...)
408 ALIAS: 713 ALIAS:
409 _process_gauge = 0 714 _process_gauge = 0
410 _process_timeticks = 0 715 _process_timeticks = 0
411 CODE: 716 CODE:
412 RETVAL = process_unsigned32_sv (); 717 RETVAL = process_unsigned32_sv ();
413 OUTPUT: 718 OUTPUT: RETVAL
414 RETVAL 719
720#if IVSIZE >= 8
415 721
416SV * 722SV *
723_process_counter64 (BUFOBJ self, ...)
724 CODE:
725 RETVAL = process_unsigned64_sv ();
726 OUTPUT: RETVAL
727
728#endif
729
730SV *
417_process_object_identifier (SV *self, ...) 731_process_object_identifier (BUFOBJ self, ...)
418 CODE: 732 CODE:
419 RETVAL = process_object_identifier_sv (); 733 RETVAL = process_object_identifier_sv ();
420 OUTPUT: 734 OUTPUT: RETVAL
421 RETVAL
422 735
423SV * 736SV *
424_process_octet_string (SV *self, ...) 737_process_octet_string (BUFOBJ self, ...)
425 ALIAS: 738 ALIAS:
426 _process_opaque = 0 739 _process_opaque = 0
427 CODE: 740 CODE:
428 RETVAL = process_octet_string_sv (); 741 RETVAL = process_octet_string_sv ();
429 OUTPUT: 742 OUTPUT: RETVAL
430 RETVAL
431 743
432SV * 744SV *
433_process_ipaddress (SV *self, ...) 745_process_ipaddress (BUFOBJ self, ...)
434 CODE: 746 CODE:
435{ 747{
436 U32 length = process_length (); 748 U32 length = process_length ();
437 if (length != 4) 749 if (length != 4)
438 { 750 {
439 error ("IP ADDRESS length not four"); 751 error ("IP ADDRESS length not four");
440 XSRETURN_UNDEF; 752 XSRETURN_UNDEF;
441 } 753 }
442 754
443 U8 *data = getn (4, "\x00\x00\x00\x00"); 755 U8 *data = getn (4, "\x00\x00\x00\x00");
444 RETVAL = newSVpvf ("%d.%d.%d.%d", data [0], data [1], data [2], data [3]); 756 RETVAL = newSVpvf ("%d.%d.%d.%d", data [0], data [1], data [2], data [3]);
445} 757}
446 OUTPUT: 758 OUTPUT: RETVAL
447 RETVAL
448 759
449SV * 760SV *
450process (SV *self, SV *expected = &PL_sv_undef, SV *found = 0) 761process (BUFOBJ self, SV *expected = &PL_sv_undef, SV *found = 0)
451 CODE: 762 CODE:
452{ 763{
453 int type; 764 int type;
454 765
455 RETVAL = process_sv (&type); 766 RETVAL = process_sv (&type);
456 767
457 if (found) 768 if (found)
458 sv_setiv (found, type); 769 sv_setiv (found, type);
459 770
460 if (SvOK (expected) && type != SvIV (expected)) 771 if (SvOK (expected) && type != SvIV (expected))
461 error ("Expected a different type than found"); 772 error ("Expected a different type than found");
462} 773}
463 OUTPUT: 774 OUTPUT: RETVAL
464 RETVAL
465 775
466MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::PDU 776MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::PDU
467 777
468SV * 778SV *
469_process_var_bind_list (SV *self) 779_process_var_bind_list (BUFOBJ self)
470 CODE: 780 CODE:
471{ 781{
472 if (get8 () != ASN_SEQUENCE) 782 if (get8 () != ASN_SEQUENCE)
473 error ("SEQUENCE expected at beginning of VarBindList"); 783 error ("SEQUENCE expected at beginning of VarBindList");
474 int seqlen = process_length (); 784 int seqlen = process_length ();
476 786
477 HV *list = newHV (); 787 HV *list = newHV ();
478 AV *names = newAV (); 788 AV *names = newAV ();
479 HV *types = newHV (); 789 HV *types = newHV ();
480 790
481 hv_store ((HV *)SvRV (self), "_var_bind_list" , sizeof ("_var_bind_list" ) - 1, newRV_noinc ((SV *)list ), 0); 791 hv_store ((HV *)cur_bufobj, "_var_bind_list" , sizeof ("_var_bind_list" ) - 1, newRV_noinc ((SV *)list ), 0);
482 hv_store ((HV *)SvRV (self), "_var_bind_names", sizeof ("_var_bind_names") - 1, newRV_noinc ((SV *)names), 0); 792 hv_store ((HV *)cur_bufobj, "_var_bind_names", sizeof ("_var_bind_names") - 1, newRV_noinc ((SV *)names), 0);
483 hv_store ((HV *)SvRV (self), "_var_bind_types", sizeof ("_var_bind_types") - 1, newRV_noinc ((SV *)types), 0); 793 hv_store ((HV *)cur_bufobj, "_var_bind_types", sizeof ("_var_bind_types") - 1, newRV_noinc ((SV *)types), 0);
484 794
485 while (cur < end && !errflag) 795 while (cur < end && !errflag)
486 { 796 {
487 // SEQUENCE ObjectName ObjectSyntax 797 // SEQUENCE ObjectName ObjectSyntax
488 if (get8 () != ASN_SEQUENCE) 798 if (get8 () != ASN_SEQUENCE)
490 process_length (); 800 process_length ();
491 801
492 if (get8 () != ASN_OBJECT_IDENTIFIER) 802 if (get8 () != ASN_OBJECT_IDENTIFIER)
493 error ("OBJECT IDENTIFIER expected at beginning of VarBind"); 803 error ("OBJECT IDENTIFIER expected at beginning of VarBind");
494 int type, oidlen; 804 int type, oidlen;
495 char *oid = process_object_identifier (&oidlen); 805 SV *oid = process_object_identifier_sv ();
496 SV *val = process_sv (&type); 806 SV *val = process_sv (&type);
497 807
498 hv_store (types, oid, oidlen, newSViv (type), 0); 808 hv_store_ent (types, oid, newSViv (type), 0);
499 hv_store (list , oid, oidlen, val, 0); 809 hv_store_ent (list , oid, val, 0);
500 av_push (names, newSVpvn (oid, oidlen)); 810 av_push (names, oid);
501 } 811 }
502 812
503 //return $this->_report_pdu_error if ($this->{_pdu_type} == REPORT); 813 // sigh - great design to do it here
814 SV *pdu_type = *hv_fetch ((HV *)cur_bufobj, "_pdu_type" , sizeof ("_pdu_type" ) - 1, 1);
815
816 if (SvIV (pdu_type) == 0xa8) // REPORT
817 {
818 PUSHMARK (SP);
819 XPUSHs (msg);
820 PUTBACK;
821 call_method ("_report_pdu_error", G_VOID | G_DISCARD);
822 SPAGAIN;
823 XSRETURN_EMPTY;
824 }
504 825
505 RETVAL = newRV_inc ((SV *)list); 826 RETVAL = newRV_inc ((SV *)list);
506} 827}
507 OUTPUT: 828 OUTPUT: RETVAL
829
830MODULE = Net::SNMP::XS PACKAGE = Net::SNMP
831
832void
833oid_base_match (SV *base_, SV *oid_)
834 PROTOTYPE: $$
835 ALIAS:
836 oid_context_match = 0
837 PPCODE:
838{
839 if (!SvOK (base_) || !SvOK (oid_))
840 XSRETURN_NO;
841
842 STRLEN blen, olen;
843 char *base = SvPVbyte (base_, blen);
844 char *oid = SvPVbyte (oid_ , olen);
845
846 blen -= *base == '.'; base += *base == '.';
847 olen -= *base == '.'; oid += *oid == '.';
848
849 if (olen < blen)
850 XSRETURN_NO;
851
852 if (memcmp (base, oid, blen))
853 XSRETURN_NO;
854
855 if (oid [blen] && oid [blen] != '.')
856 XSRETURN_NO;
857
858 XSRETURN_YES;
859}
860
861#if HAVE_VERSIONSORT
862
863void
864oid_lex_sort (...)
865 PROTOTYPE: @
866 PPCODE:
867{
868 // make sure SvPVX is valid
869 int i;
870 for (i = items; i--; )
871 {
872 SV *sv = ST (i);
873
874 if (SvTYPE (sv) < SVt_PV || SvTYPE (sv) == SVt_PVAV && SvTYPE (sv) == SVt_PVHV)
875 SvPV_force_nolen (sv);
876 }
877
878 qsort (&ST (0), items, sizeof (SV *), oid_lex_cmp);
879
880 EXTEND (SP, items);
881 // we cheat somewhat by not returning copies here
882 for (i = 0; i < items; ++i)
883 PUSHs (sv_2mortal (SvREFCNT_inc (ST (i))));
884}
885
886int
887_index_cmp (const char *a, const char *b)
888 PROTOTYPE: $$
889 CODE:
890 RETVAL = strverscmp (a, b);
508 RETVAL 891 OUTPUT: RETVAL
509 892
893#endif
510 894

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines