asn1.h
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:18k
- #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, const 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,
- const 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,
- const 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,
- const 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,
- const struct counter64 *, size_t);
- u_char *asn_build_float(u_char *, size_t *, u_char, const 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, const 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,
- const 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,
- const 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,
- const 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
- const *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,
- const 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, const 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, const double *data,
- size_t data_size);
- #endif
- #ifdef __cplusplus
- }
- #endif
- #endif /* ASN1_H */