| /* -*- C -*- */ |
| #if defined(_WIN32) && !defined(_WIN32_WINNT) |
| #define _WIN32_WINNT 0x501 |
| #endif |
| |
| #include "EXTERN.h" |
| #include "perl.h" |
| #include "XSUB.h" |
| |
| #include <net-snmp/net-snmp-config.h> |
| #include <net-snmp/library/asn1.h> |
| #include <net-snmp/library/snmp_impl.h> |
| |
| #define TEST_CONSTANT(value, name, C) \ |
| if (strEQ(name, #C)) { \ |
| *value = C; \ |
| return 0; \ |
| } |
| |
| static int constant_ASN_O(double *value, const char *name, const int len) |
| { |
| switch (len >= 5 ? name[5] : -1) { |
| case 'B': |
| TEST_CONSTANT(value, name, ASN_OBJECT_ID); |
| break; |
| case 'C': |
| TEST_CONSTANT(value, name, ASN_OCTET_STR); |
| break; |
| case 'P': |
| TEST_CONSTANT(value, name, ASN_OPAQUE); |
| break; |
| } |
| return EINVAL; |
| } |
| |
| static int constant_ASN_B(double *value, const char *name, const int len) |
| { |
| switch (len >= 5 ? name[5] : -1) { |
| case 'I': |
| TEST_CONSTANT(value, name, ASN_BIT_STR); |
| break; |
| case 'O': |
| TEST_CONSTANT(value, name, ASN_BOOLEAN); |
| break; |
| } |
| return EINVAL; |
| } |
| |
| static int constant_ASN_S(double *value, const char *name, const int len) |
| { |
| switch (len >= 6 ? name[6] : -1) { |
| case 'Q': |
| TEST_CONSTANT(value, name, ASN_SEQUENCE); |
| break; |
| case 'T': |
| TEST_CONSTANT(value, name, ASN_SET); |
| break; |
| } |
| return EINVAL; |
| } |
| |
| static int constant_ASN_C(double *value, const char *name, const int len) |
| { |
| switch (len >= 11 ? name[11] : -1) { |
| case '\0': |
| TEST_CONSTANT(value, name, ASN_COUNTER); |
| break; |
| case '6': |
| TEST_CONSTANT(value, name, ASN_COUNTER64); |
| break; |
| } |
| return EINVAL; |
| } |
| |
| static int constant_ASN_U(double *value, const char *name, const int len) |
| { |
| switch (len >= 12 ? name[12] : -1) { |
| case '\0': |
| TEST_CONSTANT(value, name, ASN_UNSIGNED); |
| break; |
| #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES |
| case '6': |
| TEST_CONSTANT(value, name, ASN_UNSIGNED64); |
| break; |
| #endif |
| } |
| return EINVAL; |
| } |
| |
| static int constant_ASN_IN(double *value, const char *name, const int len) |
| { |
| switch (len >= 11 ? name[11] : -1) { |
| case '\0': |
| TEST_CONSTANT(value, name, ASN_INTEGER); |
| break; |
| #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES |
| case '6': |
| TEST_CONSTANT(value, name, ASN_INTEGER64); |
| break; |
| #endif |
| } |
| return EINVAL; |
| } |
| |
| static int constant_ASN_I(double* value, const char *name, const int len) |
| { |
| switch (len >= 5 ? name[5] : -1) { |
| case 'N': |
| return constant_ASN_IN(value, name, len); |
| case 'P': |
| TEST_CONSTANT(value, name, ASN_IPADDRESS); |
| break; |
| } |
| return EINVAL; |
| } |
| |
| static int constant(double *value, const char *const name, const int len) |
| { |
| if (!strnEQ(name, "ASN_", 4)) |
| return EINVAL; |
| |
| switch (name[4]) { |
| case 'A': |
| TEST_CONSTANT(value, name, ASN_APPLICATION); |
| break; |
| case 'B': |
| return constant_ASN_B(value, name, len); |
| case 'C': |
| return constant_ASN_C(value, name, len); |
| #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES |
| case 'D': |
| TEST_CONSTANT(value, name, ASN_DOUBLE); |
| break; |
| case 'F': |
| TEST_CONSTANT(value, name, ASN_FLOAT); |
| break; |
| #endif |
| case 'G': |
| TEST_CONSTANT(value, name, ASN_GAUGE); |
| break; |
| case 'I': |
| return constant_ASN_I(value, name, len); |
| case 'N': |
| TEST_CONSTANT(value, name, ASN_NULL); |
| break; |
| case 'O': |
| return constant_ASN_O(value, name, len); |
| case 'S': |
| return constant_ASN_S(value, name, len); |
| case 'T': |
| TEST_CONSTANT(value, name, ASN_TIMETICKS); |
| break; |
| case 'U': |
| return constant_ASN_U(value, name, len); |
| } |
| return EINVAL; |
| } |
| |
| |
| MODULE = NetSNMP::ASN PACKAGE = NetSNMP::ASN |
| |
| |
| void |
| constant(sv) |
| PREINIT: |
| STRLEN len; |
| INPUT: |
| SV * sv |
| char * s = SvPV(sv, len); |
| INIT: |
| int status; |
| double value; |
| PPCODE: |
| value = 0; |
| status = constant(&value, s, len); |
| XPUSHs(sv_2mortal(newSVuv(status))); |
| XPUSHs(sv_2mortal(newSVnv(value))); |