and added files
[bcm963xx.git] / userapps / opensource / net-snmp / include / net-snmp / library / asn1.h
diff --git a/userapps/opensource/net-snmp/include/net-snmp/library/asn1.h b/userapps/opensource/net-snmp/include/net-snmp/library/asn1.h
new file mode 100644 (file)
index 0000000..3b49b80
--- /dev/null
@@ -0,0 +1,444 @@
+#ifndef ASN1_H
+#define ASN1_H
+
+#ifdef __cplusplus
+extern          "C" {
+#endif
+
+#define PARSE_PACKET   0
+#define DUMP_PACKET    1
+
+    /*
+     * Definitions for Abstract Syntax Notation One, ASN.1
+     * As defined in ISO/IS 8824 and ISO/IS 8825
+     *
+     *
+     */
+/***********************************************************
+       Copyright 1988, 1989 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+
+
+#ifndef MAX_SUBID               /* temporary - duplicate definition protection */
+#ifndef EIGHTBIT_SUBIDS
+    typedef u_long  oid;
+#define MAX_SUBID   0xFFFFFFFF
+#else
+    typedef u_char  oid;
+#define MAX_SUBID   0xFF
+#endif
+#endif
+
+#define MIN_OID_LEN        2
+#define MAX_OID_LEN        128 /* max subid's in an oid */
+#ifndef MAX_NAME_LEN            /* conflicts with some libraries */
+#define MAX_NAME_LEN       MAX_OID_LEN /* obsolete. use MAX_OID_LEN */
+#endif
+
+#define OID_LENGTH(x)  (sizeof(x)/sizeof(oid))
+
+
+#define ASN_BOOLEAN        ((u_char)0x01)
+#define ASN_INTEGER        ((u_char)0x02)
+#define ASN_BIT_STR        ((u_char)0x03)
+#define ASN_OCTET_STR      ((u_char)0x04)
+#define ASN_NULL           ((u_char)0x05)
+#define ASN_OBJECT_ID      ((u_char)0x06)
+#define ASN_SEQUENCE       ((u_char)0x10)
+#define ASN_SET                    ((u_char)0x11)
+
+#define ASN_UNIVERSAL      ((u_char)0x00)
+#define ASN_APPLICATION     ((u_char)0x40)
+#define ASN_CONTEXT        ((u_char)0x80)
+#define ASN_PRIVATE        ((u_char)0xC0)
+
+#define ASN_PRIMITIVE      ((u_char)0x00)
+#define ASN_CONSTRUCTOR            ((u_char)0x20)
+
+#define ASN_LONG_LEN       (0x80)
+#define ASN_EXTENSION_ID    (0x1F)
+#define ASN_BIT8           (0x80)
+
+#define IS_CONSTRUCTOR(byte)   ((byte) & ASN_CONSTRUCTOR)
+#define IS_EXTENSION_ID(byte)  (((byte) & ASN_EXTENSION_ID) == ASN_EXTENSION_ID)
+
+    struct counter64 {
+        u_long          high;
+        u_long          low;
+    };
+
+#ifdef OPAQUE_SPECIAL_TYPES
+    typedef struct counter64 integer64;
+    typedef struct counter64 unsigned64;
+
+    /*
+     * The BER inside an OPAQUE is an context specific with a value of 48 (0x30)
+     * plus the "normal" tag. For a Counter64, the tag is 0x46 (i.e., an
+     * applications specific tag with value 6). So the value for a 64 bit
+     * counter is 0x46 + 0x30, or 0x76 (118 base 10). However, values
+     * greater than 30 can not be encoded in one octet. So the first octet
+     * has the class, in this case context specific (ASN_CONTEXT), and
+     * the special value (i.e., 31) to indicate that the real value follows
+     * in one or more octets. The high order bit of each following octet
+     * indicates if the value is encoded in additional octets. A high order
+     * bit of zero, indicates the last. For this "hack", only one octet
+     * will be used for the value. 
+     */
+
+    /*
+     * first octet of the tag 
+     */
+#define ASN_OPAQUE_TAG1 (ASN_CONTEXT | ASN_EXTENSION_ID)
+    /*
+     * base value for the second octet of the tag - the
+     * second octet was the value for the tag 
+     */
+#define ASN_OPAQUE_TAG2 ((u_char)0x30)
+
+#define ASN_OPAQUE_TAG2U ((u_char)0x2f) /* second octet of tag for union */
+
+    /*
+     * All the ASN.1 types for SNMP "should have been" defined in this file,
+     * but they were not. (They are defined in snmp_impl.h)  Thus, the tag for
+     * Opaque and Counter64 is defined, again, here with a different names. 
+     */
+#define ASN_APP_OPAQUE (ASN_APPLICATION | 4)
+#define ASN_APP_COUNTER64 (ASN_APPLICATION | 6)
+#define ASN_APP_FLOAT (ASN_APPLICATION | 8)
+#define ASN_APP_DOUBLE (ASN_APPLICATION | 9)
+#define ASN_APP_I64 (ASN_APPLICATION | 10)
+#define ASN_APP_U64 (ASN_APPLICATION | 11)
+#define ASN_APP_UNION (ASN_PRIVATE | 1) /* or ASN_PRIV_UNION ? */
+
+    /*
+     * value for Counter64 
+     */
+#define ASN_OPAQUE_COUNTER64 (ASN_OPAQUE_TAG2 + ASN_APP_COUNTER64)
+    /*
+     * max size of BER encoding of Counter64 
+     */
+#define ASN_OPAQUE_COUNTER64_MX_BER_LEN 12
+
+    /*
+     * value for Float 
+     */
+#define ASN_OPAQUE_FLOAT (ASN_OPAQUE_TAG2 + ASN_APP_FLOAT)
+    /*
+     * size of BER encoding of Float 
+     */
+#define ASN_OPAQUE_FLOAT_BER_LEN 7
+
+    /*
+     * value for Double 
+     */
+#define ASN_OPAQUE_DOUBLE (ASN_OPAQUE_TAG2 + ASN_APP_DOUBLE)
+    /*
+     * size of BER encoding of Double 
+     */
+#define ASN_OPAQUE_DOUBLE_BER_LEN 11
+
+    /*
+     * value for Integer64 
+     */
+#define ASN_OPAQUE_I64 (ASN_OPAQUE_TAG2 + ASN_APP_I64)
+    /*
+     * max size of BER encoding of Integer64 
+     */
+#define ASN_OPAQUE_I64_MX_BER_LEN 11
+
+    /*
+     * value for Unsigned64 
+     */
+#define ASN_OPAQUE_U64 (ASN_OPAQUE_TAG2 + ASN_APP_U64)
+    /*
+     * max size of BER encoding of Unsigned64 
+     */
+#define ASN_OPAQUE_U64_MX_BER_LEN 12
+
+#endif                          /* OPAQUE_SPECIAL_TYPES */
+
+
+#define ASN_PRIV_INCL_RANGE (ASN_PRIVATE | 2)
+#define ASN_PRIV_EXCL_RANGE (ASN_PRIVATE | 3)
+#define ASN_PRIV_DELEGATED  (ASN_PRIVATE | 5)
+#define ASN_PRIV_IMPLIED_OCTET_STR  (ASN_PRIVATE | ASN_OCTET_STR)       /* 4 */
+#define ASN_PRIV_IMPLIED_OBJECT_ID  (ASN_PRIVATE | ASN_OBJECT_ID)       /* 6 */
+#define ASN_PRIV_RETRY      (ASN_PRIVATE | 7)
+#define IS_DELEGATED(x)   ((x) == ASN_PRIV_DELEGATED)
+
+
+    int             asn_check_packet(u_char *, size_t);
+    u_char         *asn_parse_int(u_char *, size_t *, u_char *, long *,
+                                  size_t);
+    u_char         *asn_build_int(u_char *, size_t *, u_char, long *,
+                                  size_t);
+    u_char         *asn_parse_unsigned_int(u_char *, size_t *, u_char *,
+                                           u_long *, size_t);
+    u_char         *asn_build_unsigned_int(u_char *, size_t *, u_char,
+                                           u_long *, size_t);
+    u_char         *asn_parse_string(u_char *, size_t *, u_char *,
+                                     u_char *, size_t *);
+    u_char         *asn_build_string(u_char *, size_t *, u_char,
+                                     const u_char *, size_t);
+    u_char         *asn_parse_header(u_char *, size_t *, u_char *);
+    u_char         *asn_parse_sequence(u_char *, size_t *, u_char *, u_char expected_type,      /* must be this type */
+                                       const char *estr);       /* error message prefix */
+    u_char         *asn_build_header(u_char *, size_t *, u_char, size_t);
+    u_char         *asn_build_sequence(u_char *, size_t *, u_char, size_t);
+    u_char         *asn_parse_length(u_char *, u_long *);
+    u_char         *asn_build_length(u_char *, size_t *, size_t);
+    u_char         *asn_parse_objid(u_char *, size_t *, u_char *, oid *,
+                                    size_t *);
+    u_char         *asn_build_objid(u_char *, size_t *, u_char, oid *,
+                                    size_t);
+    u_char         *asn_parse_null(u_char *, size_t *, u_char *);
+    u_char         *asn_build_null(u_char *, size_t *, u_char);
+    u_char         *asn_parse_bitstring(u_char *, size_t *, u_char *,
+                                        u_char *, size_t *);
+    u_char         *asn_build_bitstring(u_char *, size_t *, u_char,
+                                        u_char *, size_t);
+    u_char         *asn_parse_unsigned_int64(u_char *, size_t *, u_char *,
+                                             struct counter64 *, size_t);
+    u_char         *asn_build_unsigned_int64(u_char *, size_t *, u_char,
+                                             struct counter64 *, size_t);
+    u_char         *asn_parse_signed_int64(u_char *, size_t *, u_char *,
+                                           struct counter64 *, size_t);
+    u_char         *asn_build_signed_int64(u_char *, size_t *, u_char,
+                                           struct counter64 *, size_t);
+    u_char         *asn_build_float(u_char *, size_t *, u_char, float *,
+                                    size_t);
+    u_char         *asn_parse_float(u_char *, size_t *, u_char *, float *,
+                                    size_t);
+    u_char         *asn_build_double(u_char *, size_t *, u_char, double *,
+                                     size_t);
+    u_char         *asn_parse_double(u_char *, size_t *, u_char *,
+                                     double *, size_t);
+
+#ifdef USE_REVERSE_ASNENCODING
+
+    /*
+     * Re-allocator function for below.  
+     */
+
+    int             asn_realloc(u_char **, size_t *);
+
+    /*
+     * Re-allocating reverse ASN.1 encoder functions.  Synopsis:
+     * 
+     * u_char *buf = (u_char*)malloc(100);
+     * u_char type = (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER);
+     * size_t buf_len = 100, offset = 0;
+     * long data = 12345;
+     * int allow_realloc = 1;
+     * 
+     * if (asn_realloc_rbuild_int(&buf, &buf_len, &offset, allow_realloc,
+     * type, &data, sizeof(long)) == 0) {
+     * error;
+     * }
+     * 
+     * NOTE WELL: after calling one of these functions with allow_realloc
+     * non-zero, buf might have moved, buf_len might have grown and
+     * offset will have increased by the size of the encoded data.
+     * You should **NEVER** do something like this:
+     * 
+     * u_char *buf = (u_char *)malloc(100), *ptr;
+     * u_char type = (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER);
+     * size_t buf_len = 100, offset = 0;
+     * long data1 = 1234, data2 = 5678;
+     * int rc = 0, allow_realloc = 1;
+     * 
+     * rc  = asn_realloc_rbuild_int(&buf, &buf_len, &offset, allow_realloc,
+     * type, &data1, sizeof(long));
+     * ptr = buf[buf_len - offset];   / * points at encoding of data1 * /
+     * if (rc == 0) {
+     * error;
+     * }
+     * rc  = asn_realloc_rbuild_int(&buf, &buf_len, &offset, allow_realloc,
+     * type, &data2, sizeof(long));
+     * make use of ptr here;
+     * 
+     * 
+     * ptr is **INVALID** at this point.  In general, you should store the
+     * offset value and compute pointers when you need them:
+     * 
+     * 
+     * 
+     * u_char *buf = (u_char *)malloc(100), *ptr;
+     * u_char type = (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER);
+     * size_t buf_len = 100, offset = 0, ptr_offset;
+     * long data1 = 1234, data2 = 5678;
+     * int rc = 0, allow_realloc = 1;
+     * 
+     * rc  = asn_realloc_rbuild_int(&buf, &buf_len, &offset, allow_realloc,
+     * type, &data1, sizeof(long));
+     * ptr_offset = offset;
+     * if (rc == 0) {
+     * error;
+     * }
+     * rc  = asn_realloc_rbuild_int(&buf, &buf_len, &offset, allow_realloc,
+     * type, &data2, sizeof(long));
+     * ptr = buf + buf_len - ptr_offset
+     * make use of ptr here;
+     * 
+     * 
+     * 
+     * Here, you can see that ptr will be a valid pointer even if the block of
+     * memory has been moved, as it may well have been.  Plenty of examples of
+     * usage all over asn1.c, snmp_api.c, snmpusm.c.
+     * 
+     * The other thing you should **NEVER** do is to pass a pointer to a buffer
+     * on the stack as the first argument when allow_realloc is non-zero, unless
+     * you really know what you are doing and your machine/compiler allows you to
+     * free non-heap memory.  There are rumours that such things exist, but many
+     * consider them no more than the wild tales of a fool.
+     * 
+     * Of course, you can pass allow_realloc as zero, to indicate that you do not
+     * wish the packet buffer to be reallocated for some reason; perhaps because
+     * it is on the stack.  This may be useful to emulate the functionality of
+     * the old API:
+     * 
+     * u_char my_static_buffer[100], *cp = NULL;
+     * size_t my_static_buffer_len = 100;
+     * float my_pi = (float)22/(float)7;
+     * 
+     * cp = asn_rbuild_float(my_static_buffer, &my_static_buffer_len,
+     * ASN_OPAQUE_FLOAT, &my_pi, sizeof(float));
+     * if (cp == NULL) {
+     * error;
+     * }
+     * 
+     * 
+     * IS EQUIVALENT TO:
+     * 
+     * 
+     * u_char my_static_buffer[100];
+     * size_t my_static_buffer_len = 100, my_offset = 0;
+     * float my_pi = (float)22/(float)7;
+     * int rc = 0;
+     * 
+     * rc = asn_realloc_rbuild_float(&my_static_buffer, &my_static_buffer_len,
+     * &my_offset, 0,
+     * ASN_OPAQUE_FLOAT, &my_pi, sizeof(float));
+     * if (rc == 0) {
+     * error;
+     * }
+     * 
+     * 
+     */
+
+
+    int             asn_realloc_rbuild_int(u_char ** pkt, size_t * pkt_len,
+                                           size_t * offset,
+                                           int allow_realloc, u_char type,
+                                           long *data, size_t data_size);
+
+    int             asn_realloc_rbuild_string(u_char ** pkt,
+                                              size_t * pkt_len,
+                                              size_t * offset,
+                                              int allow_realloc,
+                                              u_char type,
+                                              const u_char * data,
+                                              size_t data_size);
+
+    int             asn_realloc_rbuild_unsigned_int(u_char ** pkt,
+                                                    size_t * pkt_len,
+                                                    size_t * offset,
+                                                    int allow_realloc,
+                                                    u_char type,
+                                                    u_long * data,
+                                                    size_t data_size);
+
+    int             asn_realloc_rbuild_header(u_char ** pkt,
+                                              size_t * pkt_len,
+                                              size_t * offset,
+                                              int allow_realloc,
+                                              u_char type,
+                                              size_t data_size);
+
+    int             asn_realloc_rbuild_sequence(u_char ** pkt,
+                                                size_t * pkt_len,
+                                                size_t * offset,
+                                                int allow_realloc,
+                                                u_char type,
+                                                size_t data_size);
+
+    int             asn_realloc_rbuild_length(u_char ** pkt,
+                                              size_t * pkt_len,
+                                              size_t * offset,
+                                              int allow_realloc,
+                                              size_t data_size);
+
+    int             asn_realloc_rbuild_objid(u_char ** pkt,
+                                             size_t * pkt_len,
+                                             size_t * offset,
+                                             int allow_realloc,
+                                             u_char type, const oid *,
+                                             size_t);
+
+    int             asn_realloc_rbuild_null(u_char ** pkt,
+                                            size_t * pkt_len,
+                                            size_t * offset,
+                                            int allow_realloc,
+                                            u_char type);
+
+    int             asn_realloc_rbuild_bitstring(u_char ** pkt,
+                                                 size_t * pkt_len,
+                                                 size_t * offset,
+                                                 int allow_realloc,
+                                                 u_char type,
+                                                 u_char * data,
+                                                 size_t data_size);
+
+    int             asn_realloc_rbuild_unsigned_int64(u_char ** pkt,
+                                                      size_t * pkt_len,
+                                                      size_t * offset,
+                                                      int allow_realloc,
+                                                      u_char type,
+                                                      struct counter64
+                                                      *data, size_t);
+
+    int             asn_realloc_rbuild_signed_int64(u_char ** pkt,
+                                                    size_t * pkt_len,
+                                                    size_t * offset,
+                                                    int allow_realloc,
+                                                    u_char type,
+                                                    struct counter64 *data,
+                                                    size_t);
+
+    int             asn_realloc_rbuild_float(u_char ** pkt,
+                                             size_t * pkt_len,
+                                             size_t * offset,
+                                             int allow_realloc,
+                                             u_char type, float *data,
+                                             size_t data_size);
+
+    int             asn_realloc_rbuild_double(u_char ** pkt,
+                                              size_t * pkt_len,
+                                              size_t * offset,
+                                              int allow_realloc,
+                                              u_char type, double *data,
+                                              size_t data_size);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif                          /* ASN1_H */