summaryrefslogtreecommitdiff
path: root/perl/ASN/ASN.xs
diff options
context:
space:
mode:
Diffstat (limited to 'perl/ASN/ASN.xs')
-rw-r--r--perl/ASN/ASN.xs177
1 files changed, 177 insertions, 0 deletions
diff --git a/perl/ASN/ASN.xs b/perl/ASN/ASN.xs
new file mode 100644
index 0000000..e3f6181
--- /dev/null
+++ b/perl/ASN/ASN.xs
@@ -0,0 +1,177 @@
+/* -*- 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)));