net-snmp 5.7
|
Note on. More...
Defines | |
#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) |
Functions | |
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, | |
y | |||
) |
do { \ if (x > INT32_MAX) { \ DEBUGMSG(("asn","truncating signed value %ld to 32 bits (%d)\n",(long)(x),y)); \ x &= 0xffffffff; \ } else if (x < INT32_MIN) { \ DEBUGMSG(("asn","truncating signed value %ld to 32 bits (%d)\n",(long)(x),y)); \ x = 0 - (x & 0xffffffff); \ } \ } while(0)