---
name: "netsnmp_asn1_packet_parse"
section: "3snmp"
platform: "linux"
package: "libsnmp5-dev"
version: "5.1.2-6.2"
release: "Debian 3.1 (Sarge)"
platforms: ["linux"]
url: "https://new.carta.tech/netsnmp_asn1_packet_parse"
---

# netsnmp\_asn1\_packet\_parse(3snmp)

## NAME

asn1 parsing and datatype manipulation routines. -

### Defines

\#define **NULL**   0\

### 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, long \*intp, size\_t intsize)\
 u\_char \* **asn\_build\_unsigned\_int** (u\_char \*data, size\_t \*datalength, u\_char type, u\_long \*intp, size\_t intsize)\
 u\_char \* **asn\_parse\_string** (u\_char \*data, size\_t \*datalength, u\_char \*type, u\_char \*string, size\_t \*strlength)\
 u\_char \* **asn\_build\_string** (u\_char \*data, size\_t \*datalength, u\_char type, const u\_char \*string, 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 \*string, size\_t \*strlength)\
 u\_char \* **asn\_build\_bitstring** (u\_char \*data, size\_t \*datalength, u\_char type, u\_char \*string, 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, struct counter64 \*cp, size\_t countersize)\
 int **asn\_realloc** (u\_char \*\*pkt, size\_t \*pkt\_len)\

## Detailed Description

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