asn1 parsing and datatype manipulation routines.
[The Net-SNMP library]

Note on [詳細]

マクロ定義

#define NULL   0
#define INT32_MAX   2147483647
#define INT32_MIN   (0 - INT32_MAX - 1)
#define CHECK_OVERFLOW_S(x, y)
#define CHECK_OVERFLOW_U(x, y)

関数

int asn_check_packet (u_char *pkt, size_t len)
u_char * asn_parse_int (u_char *data, size_t *datalength, u_char *type, long *intp, size_t intsize)
u_char * asn_parse_unsigned_int (u_char *data, size_t *datalength, u_char *type, u_long *intp, size_t intsize)
u_char * asn_build_int (u_char *data, size_t *datalength, u_char type, const long *intp, size_t intsize)
u_char * asn_build_unsigned_int (u_char *data, size_t *datalength, u_char type, const u_long *intp, size_t intsize)
u_char * asn_parse_string (u_char *data, size_t *datalength, u_char *type, u_char *str, size_t *strlength)
u_char * asn_build_string (u_char *data, size_t *datalength, u_char type, const u_char *str, size_t strlength)
u_char * asn_parse_header (u_char *data, size_t *datalength, u_char *type)
u_char * asn_parse_sequence (u_char *data, size_t *datalength, u_char *type, u_char expected_type, const char *estr)
u_char * asn_build_header (u_char *data, size_t *datalength, u_char type, size_t length)
u_char * asn_build_sequence (u_char *data, size_t *datalength, u_char type, size_t length)
u_char * asn_parse_length (u_char *data, u_long *length)
u_char * asn_build_length (u_char *data, size_t *datalength, size_t length)
u_char * asn_parse_objid (u_char *data, size_t *datalength, u_char *type, oid *objid, size_t *objidlength)
u_char * asn_build_objid (u_char *data, size_t *datalength, u_char type, oid *objid, size_t objidlength)
u_char * asn_parse_null (u_char *data, size_t *datalength, u_char *type)
u_char * asn_build_null (u_char *data, size_t *datalength, u_char type)
u_char * asn_parse_bitstring (u_char *data, size_t *datalength, u_char *type, u_char *str, size_t *strlength)
u_char * asn_build_bitstring (u_char *data, size_t *datalength, u_char type, const u_char *str, size_t strlength)
u_char * asn_parse_unsigned_int64 (u_char *data, size_t *datalength, u_char *type, struct counter64 *cp, size_t countersize)
u_char * asn_build_unsigned_int64 (u_char *data, size_t *datalength, u_char type, const struct counter64 *cp, size_t countersize)
int asn_realloc (u_char **pkt, size_t *pkt_len)

説明

Note on

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;
 }

マクロ定義

#define CHECK_OVERFLOW_S ( x,
 ) 

値:

do { int trunc = 0;                     \
        if (x > INT32_MAX) {                                            \
            trunc = 1;                                                  \
            x &= 0xffffffff;                                            \
        } else if (x < INT32_MIN) {                                     \
            trunc = 1;                                                  \
            x = 0 - (x & 0xffffffff);                                   \
        }                                                               \
        if (trunc)                                                      \
            snmp_log(LOG_ERR,"truncating signed value to 32 bits (%d)\n",y); \
    } while(0)

asn1.c214 行で定義されています。

参照元 asn_build_int()asn_parse_int().

#define CHECK_OVERFLOW_U ( x,
 ) 

値:

do {                                    \
        if (x > UINT32_MAX) {                                           \
            x &= 0xffffffff;                                            \
            snmp_log(LOG_ERR,"truncating unsigned value to 32 bits (%d)\n",y); \
        }                                                               \
    } while(0)

asn1.c226 行で定義されています。

参照元 asn_build_objid()asn_build_unsigned_int()asn_build_unsigned_int64()asn_parse_unsigned_int()asn_parse_unsigned_int64().


net-snmpに対してSat Sep 5 13:14:28 2009に生成されました。  doxygen 1.4.7