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.19 by root, Fri Apr 19 14:50:44 2019 UTC vs.
Revision 1.20 by root, Fri Apr 19 15:50:48 2019 UTC

5// C99 required 5// C99 required
6 6
7//#define BENCHMARK 7//#define BENCHMARK
8 8
9enum { 9enum {
10 // ASN_TAG
10 ASN_BOOLEAN = 0x01, 11 ASN_BOOLEAN = 0x01,
11 ASN_INTEGER32 = 0x02, 12 ASN_INTEGER32 = 0x02,
12 ASN_BIT_STRING = 0x03, 13 ASN_BIT_STRING = 0x03,
13 ASN_OCTET_STRING = 0x04, 14 ASN_OCTET_STRING = 0x04,
14 ASN_NULL = 0x05, 15 ASN_NULL = 0x05,
15 ASN_OBJECT_IDENTIFIER = 0x06, 16 ASN_OBJECT_IDENTIFIER = 0x06,
17 ASN_SEQUENCE = 0x10,
16 18
17 ASN_TAG_BER = 0x1f, 19 ASN_TAG_BER = 0x1f,
18 ASN_TAG_MASK = 0x1f, 20 ASN_TAG_MASK = 0x1f,
19 21
22 // primitive/constructed
20 ASN_CONSTRUCTED = 0x20, 23 ASN_CONSTRUCTED = 0x20,
21 24
25 // ASN_CLASS
22 ASN_UNIVERSAL = 0x00, 26 ASN_UNIVERSAL = 0x00,
23 ASN_APPLICATION = 0x40, 27 ASN_APPLICATION = 0x40,
24 ASN_CONTEXT = 0x80, 28 ASN_CONTEXT = 0x80,
25 ASN_PRIVATE = 0xc0, 29 ASN_PRIVATE = 0xc0,
26 30
27 ASN_CLASS_MASK = 0xc0, 31 ASN_CLASS_MASK = 0xc0,
28 ASN_CLASS_SHIFT = 6, 32 ASN_CLASS_SHIFT = 6,
29 33
30 ASN_SEQUENCE = ASN_CONSTRUCTED | 0x10, 34 // ASN_APPLICATION
31 ASN_IPADDRESS = ASN_APPLICATION | 0x00, 35 ASN_IPADDRESS = 0x00,
32 ASN_COUNTER32 = ASN_APPLICATION | 0x01, 36 ASN_COUNTER32 = 0x01,
33 ASN_UNSIGNED32 = ASN_APPLICATION | 0x02, 37 ASN_UNSIGNED32 = 0x02,
34 ASN_TIMETICKS = ASN_APPLICATION | 0x03, 38 ASN_TIMETICKS = 0x03,
35 ASN_OPAQUE = ASN_APPLICATION | 0x04, 39 ASN_OPAQUE = 0x04,
36 ASN_COUNTER64 = ASN_APPLICATION | 0x06, 40 ASN_COUNTER64 = 0x06,
41};
42
43enum {
44 BER_CLASS = 0,
45 BER_TAG = 1,
46 BER_CONSTRUCTED = 2,
47 BER_DATA = 3,
48 BER_ARRAYSIZE
37}; 49};
38 50
39#define MAX_OID_STRLEN 4096 51#define MAX_OID_STRLEN 4096
40 52
41#define HAVE_VERSIONSORT defined (_GNU_SOURCE) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 53#define HAVE_VERSIONSORT defined (_GNU_SOURCE) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
413 425
414 case ASN_INTEGER32: 426 case ASN_INTEGER32:
415 res = process_integer32_sv (); 427 res = process_integer32_sv ();
416 break; 428 break;
417 429
418 case ASN_UNSIGNED32: 430 case ASN_APPLICATION | ASN_UNSIGNED32:
419 case ASN_COUNTER32: 431 case ASN_APPLICATION | ASN_COUNTER32:
420 case ASN_TIMETICKS: 432 case ASN_APPLICATION | ASN_TIMETICKS:
421 res = process_unsigned32_sv (); 433 res = process_unsigned32_sv ();
422 break; 434 break;
423 435
424 case ASN_SEQUENCE: 436 case ASN_SEQUENCE | ASN_CONSTRUCTED:
425 res = newSVuv (process_length ()); 437 res = newSVuv (process_length ());
426 break; 438 break;
427 439
428 case ASN_OCTET_STRING: 440 case ASN_OCTET_STRING:
429 case ASN_OPAQUE: 441 case ASN_APPLICATION | ASN_OPAQUE:
430 res = process_octet_string_sv (); 442 res = process_octet_string_sv ();
431 break; 443 break;
432 444
433 default: 445 default:
434 { 446 {
454 466
455 return errflag ? &PL_sv_undef : res; 467 return errflag ? &PL_sv_undef : res;
456} 468}
457 469
458static SV * 470static SV *
459decode_ber () 471ber_decode ()
460{ 472{
461 int identifier = get8 (); 473 int identifier = get8 ();
462 474
463 SV *res; 475 SV *res;
464 476
479 U32 len = process_length (); 491 U32 len = process_length ();
480 U32 seqend = (cur - buf) + len; 492 U32 seqend = (cur - buf) + len;
481 AV *av = (AV *)sv_2mortal ((SV *)newAV ()); 493 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
482 494
483 while (cur < buf + seqend) 495 while (cur < buf + seqend)
484 {
485 av_push (av, decode_ber ()); 496 av_push (av, ber_decode ());
486 }
487 497
488 if (cur > buf + seqend) 498 if (cur > buf + seqend)
489 croak ("constructed type %02x overflow (%x %x)\n", identifier, cur - buf, seqend); 499 croak ("constructed type %02x overflow (%x %x)\n", identifier, cur - buf, seqend);
490 500
491 res = newRV_inc ((SV *)av); 501 res = newRV_inc ((SV *)av);
492 } 502 }
493 else 503 else
494 switch (identifier) 504 switch (identifier)
495 { 505 {
506 case ASN_NULL:
507 res = &PL_sv_undef;
508 break;
509
496 case ASN_OBJECT_IDENTIFIER: 510 case ASN_OBJECT_IDENTIFIER:
497 res = process_object_identifier_sv (); 511 res = process_object_identifier_sv ();
498 break; 512 break;
499 513
500 case ASN_INTEGER32: 514 case ASN_INTEGER32:
501 res = process_integer32_sv (); 515 res = process_integer32_sv ();
502 break; 516 break;
503 517
504 case ASN_UNSIGNED32: 518 case ASN_APPLICATION | ASN_UNSIGNED32:
505 case ASN_COUNTER32: 519 case ASN_APPLICATION | ASN_COUNTER32:
506 case ASN_TIMETICKS: 520 case ASN_APPLICATION | ASN_TIMETICKS:
507 res = process_unsigned32_sv (); 521 res = process_unsigned32_sv ();
508 break; 522 break;
509 523
510#if 0 // handled by default case 524#if 0 // handled by default case
511 case ASN_IPADDRESS:
512 case ASN_OCTET_STRING: 525 case ASN_OCTET_STRING:
513 case ASN_OPAQUE: 526 case ASN_APPLICATION | ASN_IPADDRESS:
527 case ASN_APPLICATION | ASN_OPAQUE:
514 res = process_octet_string_sv (); 528 res = process_octet_string_sv ();
515 break; 529 break;
516#endif 530#endif
517 531
518 case ASN_COUNTER64: 532 case ASN_APPLICATION | ASN_COUNTER64:
519 res = process_integer64_sv (); 533 res = process_integer64_sv ();
520 break; 534 break;
521 535
522 default: 536 default:
523 res = process_octet_string_sv (); 537 res = process_octet_string_sv ();
526 540
527 if (errflag) 541 if (errflag)
528 croak ("some error"); 542 croak ("some error");
529 543
530 AV *av = newAV (); 544 AV *av = newAV ();
531 av_fill (av, 4-1); 545 av_fill (av, BER_ARRAYSIZE - 1);
532 AvARRAY (av)[0] = newSVcacheint (tag);
533 AvARRAY (av)[1] = newSVcacheint (klass >> ASN_CLASS_SHIFT); 546 AvARRAY (av)[BER_CLASS ] = newSVcacheint (klass >> ASN_CLASS_SHIFT);
547 AvARRAY (av)[BER_TAG ] = newSVcacheint (tag);
534 AvARRAY (av)[2] = newSVcacheint (constructed ? 1 : 0); 548 AvARRAY (av)[BER_CONSTRUCTED] = newSVcacheint (constructed ? 1 : 0);
535 AvARRAY (av)[3] = res; 549 AvARRAY (av)[BER_DATA ] = res;
536 res = newRV_noinc ((SV *)av); 550 res = newRV_noinc ((SV *)av);
537 551
538 return errflag ? &PL_sv_undef : res; 552 return errflag ? &PL_sv_undef : res;
539} 553}
540 554
588 { "ASN_COUNTER32", ASN_COUNTER32 }, 602 { "ASN_COUNTER32", ASN_COUNTER32 },
589 { "ASN_UNSIGNED32", ASN_UNSIGNED32 }, 603 { "ASN_UNSIGNED32", ASN_UNSIGNED32 },
590 { "ASN_TIMETICKS", ASN_TIMETICKS }, 604 { "ASN_TIMETICKS", ASN_TIMETICKS },
591 { "ASN_OPAQUE", ASN_OPAQUE }, 605 { "ASN_OPAQUE", ASN_OPAQUE },
592 { "ASN_COUNTER64", ASN_COUNTER64 }, 606 { "ASN_COUNTER64", ASN_COUNTER64 },
607
608 { "BER_CLASS" , BER_CLASS },
609 { "BER_TAG" , BER_TAG },
610 { "BER_CONSTRUCTED", BER_CONSTRUCTED },
611 { "BER_DATA" , BER_DATA },
593 }; 612 };
594 613
595 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--) 614 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)); 615 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
597 616
603 CODE: 622 CODE:
604 cv = x_get_cv (cv); 623 cv = x_get_cv (cv);
605 assert (SvTYPE (cv) == SVt_PVCV); 624 assert (SvTYPE (cv) == SVt_PVCV);
606 av_store (av_type, type, SvREFCNT_inc_NN (cv)); 625 av_store (av_type, type, SvREFCNT_inc_NN (cv));
607 626
608#if 1
609
610SV * 627SV *
611decode_ber (SV *ber) 628ber_decode (SV *ber)
612 CODE: 629 CODE:
613{ 630{
614 clear_bufobj (); 631 clear_bufobj ();
615 632
616 errflag = 0; 633 errflag = 0;
620 637
621 buf = SvPVbyte (bufsv, len); 638 buf = SvPVbyte (bufsv, len);
622 cur = buf; 639 cur = buf;
623 rem = len; 640 rem = len;
624 641
625 RETVAL = decode_ber (); 642 RETVAL = ber_decode ();
626} 643}
627 OUTPUT: RETVAL 644 OUTPUT: RETVAL
628 645
629#endif 646void
647ber_eq (SV *tuple, SV *klass = &PL_sv_undef, SV *tag = &PL_sv_undef, SV *constructed = &PL_sv_undef, SV *data = &PL_sv_undef)
648 PROTOTYPE: $;$$$
649 PPCODE:
650{
651 if (!SvOK (tuple))
652 XSRETURN_NO;
653
654 if (!SvROK (tuple) || SvTYPE (SvRV (tuple)) != SVt_PVAV)
655 croak ("ber_seq: tuple must be ber tuple (array-ref)");
656
657 AV *av = (AV *)SvRV (tuple);
658
659 XPUSHs (
660 (!SvOK (klass) || SvIV (AvARRAY (av)[BER_CLASS ]) == SvIV (klass))
661 && (!SvOK (tag) || SvIV (AvARRAY (av)[BER_TAG ]) == SvIV (tag))
662 && (!SvOK (constructed) || !SvIV (AvARRAY (av)[BER_CONSTRUCTED]) == !SvIV (constructed))
663 && (!SvOK (data) || sv_eq (AvARRAY (av)[BER_DATA ], data))
664 ? &PL_sv_yes : &PL_sv_no);
665}
666
667void
668ber_seq (SV *tuple)
669 PROTOTYPE: $
670 PPCODE:
671{
672 if (!SvOK (tuple))
673 XSRETURN_UNDEF;
674
675 if (!SvROK (tuple) || SvTYPE (SvRV (tuple)) != SVt_PVAV)
676 croak ("ber_seq: tuple must be ber tuple (array-ref)");
677
678 AV *av = (AV *)SvRV (tuple);
679
680 XPUSHs (
681 SvIV (AvARRAY (av)[BER_CLASS ]) == ASN_UNIVERSAL
682 && SvIV (AvARRAY (av)[BER_TAG ]) == ASN_SEQUENCE
683 && SvIV (AvARRAY (av)[BER_CONSTRUCTED])
684 ? AvARRAY (av)[BER_DATA] : &PL_sv_undef);
685}
686
687void
688ber_i32 (SV *tuple, IV value)
689 PROTOTYPE: $$
690 PPCODE:
691{
692 if (!SvOK (tuple))
693 XSRETURN_NO;
694
695 if (!SvROK (tuple) || SvTYPE (SvRV (tuple)) != SVt_PVAV)
696 croak ("ber_seq: tuple must be ber tuple (array-ref)");
697
698 AV *av = (AV *)SvRV (tuple);
699
700 XPUSHs (
701 SvIV (AvARRAY (av)[BER_CLASS ]) == ASN_UNIVERSAL
702 && SvIV (AvARRAY (av)[BER_TAG ]) == ASN_INTEGER32
703 && !SvIV (AvARRAY (av)[BER_CONSTRUCTED])
704 && SvIV (AvARRAY (av)[BER_DATA ]) == value
705 ? &PL_sv_yes : &PL_sv_no);
706}
707
708void
709ber_oid (SV *tuple, SV *oid)
710 PROTOTYPE: $$
711 PPCODE:
712{
713 if (!SvOK (tuple))
714 XSRETURN_NO;
715
716 if (!SvROK (tuple) || SvTYPE (SvRV (tuple)) != SVt_PVAV)
717 croak ("ber_seq: tuple must be ber tuple (array-ref)");
718
719 AV *av = (AV *)SvRV (tuple);
720
721 XPUSHs (
722 SvIV (AvARRAY (av)[BER_CLASS ]) == ASN_UNIVERSAL
723 && SvIV (AvARRAY (av)[BER_TAG ]) == ASN_OBJECT_IDENTIFIER
724 && !SvIV (AvARRAY (av)[BER_CONSTRUCTED])
725 && sv_eq (AvARRAY (av)[BER_DATA], oid)
726 ? &PL_sv_yes : &PL_sv_no);
727}
630 728
631MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::Message 729MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::Message
632 730
633void 731void
634_buffer_append (BUFOBJ self, SV *value) 732_buffer_append (BUFOBJ self, SV *value)
777 875
778SV * 876SV *
779_process_var_bind_list (BUFOBJ self) 877_process_var_bind_list (BUFOBJ self)
780 CODE: 878 CODE:
781{ 879{
782 if (get8 () != ASN_SEQUENCE) 880 if (get8 () != ASN_SEQUENCE | ASN_CONSTRUCTED)
783 error ("SEQUENCE expected at beginning of VarBindList"); 881 error ("SEQUENCE expected at beginning of VarBindList");
882
784 int seqlen = process_length (); 883 int seqlen = process_length ();
785 U8 *end = cur + seqlen; 884 U8 *end = cur + seqlen;
786 885
787 HV *list = newHV (); 886 HV *list = newHV ();
788 AV *names = newAV (); 887 AV *names = newAV ();
793 hv_store ((HV *)cur_bufobj, "_var_bind_types", sizeof ("_var_bind_types") - 1, newRV_noinc ((SV *)types), 0); 892 hv_store ((HV *)cur_bufobj, "_var_bind_types", sizeof ("_var_bind_types") - 1, newRV_noinc ((SV *)types), 0);
794 893
795 while (cur < end && !errflag) 894 while (cur < end && !errflag)
796 { 895 {
797 // SEQUENCE ObjectName ObjectSyntax 896 // SEQUENCE ObjectName ObjectSyntax
798 if (get8 () != ASN_SEQUENCE) 897 if (get8 () != ASN_SEQUENCE | ASN_CONSTRUCTED)
799 error ("SEQUENCE expected at beginning of VarBind"); 898 error ("SEQUENCE expected at beginning of VarBind");
800 process_length (); 899 process_length ();
801 900
802 if (get8 () != ASN_OBJECT_IDENTIFIER) 901 if (get8 () != ASN_OBJECT_IDENTIFIER)
803 error ("OBJECT IDENTIFIER expected at beginning of VarBind"); 902 error ("OBJECT IDENTIFIER expected at beginning of VarBind");

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines