# Digital TCP/IP Services for OpenVMS
eSNMP Programming and Reference

Previous | Contents

A null pointer means return the current sysUpTime.

## DESCRIPTION

> This routine provides a mechanism to convert UNIX timestamps into eSNMP TimeTicks. The function returns the value that sysUpTime held when the passed timestamp was now. Passing a null timestamp returns the current value of sysUpTime.

> This routine can be used as a TimeTicks data type (the time since the eSNMP master agent started) in units of 1/100 second. The time base is obtained from the master agent at OPEN time so calls to this function before that time will not be accurate.

## Return Values

> 0 | An error occurred because a gettimeofday failed. Otherwise, timestamp time is 1/100 second since the eSNMP protocol started.

## Example

>     #include <include/sys/time.h>
>     #include <esnmp.h>
>     struct timeval timestamp;

>     gettimeofday(&timestamp, NULL);
>     ...
>     o_integer(vb, object, esnmp_sysuptime(&timestamp));

# 5.2 Support Routines

The support routines are optional but are provided as a convenience to developers writing method routines that handle specific management information base (MIB) elements. The support routines provided include the following:

- o_integer
- o_octet
- o_oid
- o_string
- str2oid
- sprintoid
- instance2oid
- oid2instance
- inst2ip
- cmp_oid
- cmp_oid_prefix
- clone_oid
- free_oid
- clone_buf
- mem2oct
- cmp_oct
- clone_oct
- free_oct
- free_varbind_date

# o_integer

> Loads an integer value into the VARBIND structure with the appropriate type.

## Format

> ### int o_integer (VARBIND *vb, OBJECT *obj, unsigned long value)

## ARGUMENTS

> ### *vb

> A pointer to the VARBIND structure that is supposed to receive the data. This function does not allocate the VARBIND structure.

> ### *obj

> A pointer to the OBJECT structure for the MIB variable associated with the OID in the VARBIND structure.

> ### value

> The value to be inserted into the VARBIND structure.

> The real type as defined in the object structure must be one of the following, otherwise an error is returned.

> - ESNMP_TYPE_Integer32:
>   32-bit INTEGER
> - ESNMP_TYPE_Counter32:
>   32-bit Counter (unsigned)
> - ESNMP_TYPE_Gauge32:
>   32-bit Gauge (unsigned)
> - ESNMP_TYPE_TimeTicks:
>   32-bit TimeTicks (unsigned)
> - ESNMP_TYPE_UInteger32:
>   32-bit INTEGER (unsigned)
> - ESNMP_TYPE_Counter64:
>   64-bit Counter (unsigned)
> - ESNMP_TYPE_IpAddress:
>   "IMPLICIT OCTET STRING (4)"

> > Note

> > If the real type is IpAddress, then eSNMP assumes that the 4-byte integer is in network byte order and packaged it into an octet string.

## Return Values

> ESNMP_MTHD_noError | The routine completed successfully.
> ESNMP_MTHD_genErr | An error has occurred.

## Example

>     include <esnmp.h>
>     #include "ip_tbl.h"  <-- for ipNetToMediaEntry_type definition
>     VARBIND     *vb       = method->varbind;
>     OBJECT      *object   = method->object;
>     ipNetToMediaEntry_type *data;

>     switch(arg) {
>     case I_atIfIndex:
>     return o_integer(vb, object, data->ipNetToMediaIfIndex);

# o_octet

> Loads an octet value into the VARBIND structure with the appropriate type.

## Format

> ### int o_octet (VARBIND *vb, OBJECT *obj, OCT *oct)

## ARGUMENTS

> ### *vb

> A pointer to the VARBIND structure that is supposed to receive the data. This function does not allocate the VARBIND structure.

> > Note

> > If the original value in the VARBIND structure is not null, this routine attempts to free it. So if you dynamically allocate memory or issue the malloc command. Fill the structure with zeros before using it.

> ### *obj

> A pointer to the OBJECT structure for the MIB variable associated with the OID in the VARBIND structure.

> ### *oct

> The value to be inserted into the VARBIND structure.

> The real type as defined in the object structure must be one of the following, otherwise an error is returned.

> - ESNMP_TYPE_OCTET_STRING:
>   OCTET STRING (ASN.1)
> - ESNMP_TYPE_IpAddress
>   IMPLICIT OCTET STRING (4) - in octete form, network byte order
> - ESNMP_TYPE_DisplayString
>   DisplayString (Textual Con)
> - ESNMP_TYPE_NsapAddress
>   IMPLICIT OCTET STRING
> - ESNMP_TYPE_Opaque
>   IMPLICIT OCTET STRING
> - ESNMP_TYPE_BIT_STRING:
>   BIT STRING (ASN.1) - The first byte is the number of unused bits in the last byte.

## Return Values

> ESNMP_MTHD_noError | The routine completed successfully.
> ESNMP_MTHD_genErr | An error occurred.

## Example

>     #include <esnmp.h>
>     #include "ip_tbl.h"  <-- for ipNetToMediaEntry_type definition
>     VARBIND     *vb       = method->varbind;
>     OBJECT      *object   = method->object;
>     ipNetToMediaEntry_type *data;

>     switch(arg) {
>      case I_atPhysAddress:
>      return o_octet(vb, object, &data->ipNetToMediaPhysAddress);

# o_oid

> Loads an OID value into the VARBIND structure with the appropriate type.

## Format

> ### int o_integer (VARBIND *vb, OBJECT *obj, OID *oid)

## ARGUMENTS

> ### *vb

> A pointer to the VARBIND structure that is supposed to receive the data. This function does not allocate the VARBIND structure.

> > Note

> > If the original value in the VARBIND structure is not null, this routine attempts to free it. So if you dynamically allocate memory or issue the malloc command. Fill the structure with zeros before using it.

> ### *obj

> A pointer to the OBJECT structure for the MIB variable associated with the OID in the VARBIND structure.

> ### *oid

> The value to be inserted into the VARBIND structure as data.

> The real type as defined in the object structure must be one of the following, otherwise an error is returned.

> - ESNMP_TYPE_OBJECT_IDENTIFIER
> - OBJECT IDENTIFIER (ASN.1)

## Return Values

> ESNMP_MTHD_noError | The routine completed successfully.
> ESNMP_MTHD_genErr | An error occurred.

## Example

>     #include <esnmp.h>
>     #include "ip_tbl.h"  <-- for ipNetToMediaEntry_type definition
>     VARBIND     *vb       = method->varbind;
>     OBJECT      *object   = method->object;
>     ipNetToMediaEntry_type *data;

>     switch(arg) {
>      case I_atObjectID:
>       return o_oid(vb, object, &data->ipNetToMediaObjectID);

# o_string

> Loads a string value into the VARBIND structure with the appropriate type.

## Format

> ### int o_string (VARBIND *vb, OBJECT *obj, unsigned character *ptr, int *len)

## ARGUMENTS

> ### *vb

> A pointer to the VARBIND structure that is supposed to receive the data. This function does not allocate the VARBIND structure.

> > Note

> > If the original value in the VARBIND structure is not null, this routine attempts to free it. So if you dynamically allocate memory or issue the malloc command. Fill the structure with zeros before using it.

> ### *obj

> A pointer to the OBJECT structure for the MIB variable associated with the OID in the VARBIND structure.

> ### *ptr

> The pointer to the buffer containing data to inserted into the VARBIND structure as data.

> ### *len

> The length of the data in buffer pointed to by ptr.

> The real type as defined in the object structure must be one of the following, otherwise an error is returned.

> - ESNMP_TYPE_OCTET_STRING:
>   OCTET STRING (ASN.1)
> - ESNMP_TYPE_IpAddress
>   IMPLICIT OCTET STRING (4) - in octete form, network byte order
> - ESNMP_TYPE_DisplayString
>   DisplayString (Textual Con)
> - ESNMP_TYPE_NsapAddress
>   IMPLICIT OCTET STRING
> - ESNMP_TYPE_Opaque
>   IMPLICIT OCTET STRING
> - ESNMP_TYPE_BIT_STRING:
>   BIT STRING (ASN.1) - The first byte is the number of unused bits in the last byte.
> - ESNMP_TYPE_OBJECT_IDENTIFIER
>   OBJECT IDENTIFIER (ASN.1) - in dot notation, 1.3.4.6.3.

## Return Values

> ESNMP_MTHD_noError | The routine completed successfully.
> ESNMP_MTHD_genErr | An error occurred.

## Example

>     #include <esnmp.h>
>     #include "ip_tbl.h"  <-- for ipNetToMediaEntry_type definition
>     VARBIND     *vb       = method->varbind;
>     OBJECT      *object   = method->object;
>     ipNetToMediaEntry_type *data;

>     switch(arg) {
>      case I_atPhysAddress:
>        return o_string(vb, object, data->ipNetToMediaPhysAddress.ptr,
>                                    data->ipNetToMediaPhysAddress.len);

# str2oid

> Converts a null-terminated string OID in dot notation to an OID structure.

## Format

> ### oid *str2oid (oid *oid, char *s)

## DESCRIPTION

> The routine dynamically allocates the buffer and inserts its pointer into the OID structure passed in. The caller is responsible to free this buffer. The OID can have a maximum of 128 elements.

> > Note

> > The str20id routine does not allocate an OID structure.

## Return Values

> null | An error occurred or the pointer to the OID structure (its first argument) has been returned.

## Example

>     include <esnmp.h>
>     #define SOMETHING_BIG 1024
>     OID abc;
>     char buffer[SOMETHING_BIG];
>     :
>     : assume abc gets initialized with some value
>     :
>     printf("dots=%s\n", sprintoid(buffer, &abc));

# sprintoid

> Converts an OID into a null-terminated string.

## Format

> ### char *sprintoid (char *buffer, oid *oid)

## DESCRIPTION

> An OID can have up to 128 elements. A full-sized OID can require a large buffer.

## Return Values

> The return values are its first argument. |

## Example

>     #include <esnmp.h>
>     #define SOMETHING_BIG 1024
>     OID abc;
>     char buffer[SOMETHING_BIG];
>     :
>     : assume abc gets initialized with some value
>     :
>     printf("dots=%s\n", sprintoid(buffer, &abc));

# instance2oid

> Copies the object's base OID and appends a copy of the instance array to make a complete OID for a value.

## Format

> ### oid instance2oid (oid *new, obj *obj, unsigned int *instance, int *len)

## ARGUMENTS

> ### *new

> A pointer to OID that is to receive the new OID value.

> ### *obj

> A pointer to the object table entry for the MIB variable being obtained. The first part of the new OID is the OID from this MIB object table entry.

> ### *instance

> A pointer to an array of instance values. These values are appended to the base OID obtained from the MIB object table entry to construct the new OID.

> ### *len

> The number of elements in the instance array.

## DESCRIPTION

> The instance is an array of integers and len is the number of elements. The instance array may be created by oid2instance or constructed from key values as a result of a get_next search.

> This routine dynamically allocates the buffer and inserts its pointer into the OID structure passed in. It is the responsibility of the caller to free this buffer.

> You should point to the OID structure receiving the new values and then call the instance2oid routine. Previous values in the OID structure are freed and the new values are dynamically allocated and inserted. Be sure the initail value of the new OID is all zeros. If you do not want the value freed, the instance2oid routine does not allocate an OID structure, only the array containing the elements.

## Return Values

> null | An error occurred or the pointer to the OID structure (its first argument) has been returned.

## Example

>     #include <esnmp.h>
>     VARBIND *vb;      <-- filled in
>     OBJECT  *object;  <-- filled in
>     unsigned int instance[6];

>     -- Construct the outgoing OID in a GETNEXT          --
>     -- Instance is N.1.A.A.A.A where A's are IP address --
>     instance[0] = data->ipNetToMediaIfIndex;
>     instance[1] = 1;
>     for (i = 0; i < 4; i++) {
>     instance[i+2]=((unsigned char *)(&data->ipNetToMediaNetAddress))[i];
>     }
>     instance2oid(&vb->name, object, instance, 6);

# oid2instance

> Extracts the instance values from an OID and copies them to the specified array of integers. The routine then returns the number of elements in the array.

## Format

> ### int oid2instance (oid *oid, obj *obj, unsigned int *instance, int *max_len)

## ARGUMENTS

> ### *oid

> An incoming OID containing an instance or part of an instance.

> ### *obj

> A pointer to the object table entry for the MIB variable.

> ### *instance

> A pointer to an array of unsigned integers where the index is placed.

> ### *max_len

> The number of elements in the instance array.

## DESCRIPTION

> The instance values are the elements of an OID beyond those that identify the MIB variable. These elements identify a specific instance of a MIB value.

> If there are more elements in the OID than specified by the max_len parameter, the function copies the number of elements specified by max_len only and returns the total number of elements that would have been copied had there been space.

## Return Values

> LESS THAN ZERO | An error occurred. This should not occur if the object was obtained by looking at this OID.
> ZERO | No instance elements.
> GREATER THAN ZERO | The number of index elements. This could be larger than the max_len parameter.

## Example

>     #include <esnmp.h>
>     OID         *incoming = &method->varbind->name;
>     OBJECT      *object   = method->object;
>     int         instLength;
>     unsigned int instance[6];

>     -- in a GET operation --
>     -- Expected Instance is N.1.A.A.A.A where A's are IP address --
>     instLength = oid2instance(incoming, object, instance, 6);
>     if (instLength != 6)
>         return ESNMP_MTHD_noSuchInstance;

# inst2ip

> Returns an IP address derived from an OID instance.

## Format

> ### int inst2ip (unsigned int *instance, int *length, unsigned int *ipAddr, int *exact, int *carry)

## ARGUMENTS

> ### *instance

> A pointer to an array of unsigned int containing the instance numbers returned by the oid2instance routine to be converted to an IP address.

> The range for elements is between 0 and 255. Using the EXACT mode, the routine returns 1 if an element is out of range. Using the NEXT mode, a value greater than 255 causes that element to overflow. This value is set to 0 and the next most significant element is incremented, so it returns a lexically equivalent value of the next possible ipaddr.

> ### *length

> The number of elements in the instance array. Instances beyond four are ignored. If the length is less than four the missing values are assumed to be zero. A negative length results in an ipaddr value of zero. For an exact match (such as Get) there must be exactly four elements.

> ### *ipAddr

> A pointer indicating where to return the IP address value. This routine is in network byte order (the most significant element is first).

> ### *exact

> Can either be TRUE or FALSE.

> TRUE means do an EXACT match. If any element is greater than 255 or if there are not exactly four elements, return a value of one. The carry argument is ignored.

> FALSE means do a NEXT match. That is, return the lexically next IP address if the carry is set and the length is at least four. If there are fewer than four elements, assume the missing values are zero. If any one element contains a value greater than 255, then zero the value and increment the next most significant element. Return one only in the case where there is a carry from the most significant (the first) value.

> ### *carry

> Adds to the IP address on a NEXT match. If you are trying to determine the next possible IP address, pass in a one. Otherwise, pass in a zero. A length of less than four cancels the carry.

## DESCRIPTION

> For evaluation of an instance for Get and Set operations use the EXACT mode. For GetNext and GetBulk operations use the NEXT mode. When using this mode, the logic of the routine assumes that the search for data will be performed using greater than or equal to matches.

## Return Values

> CARRY IS ZERO | The routine completed successfully.
> CARRY IS ONE | An error for either EXACT match or NEXT match. (If there was a carry, the returned ipaddr.)

## Examples

>     #include <esnmp.h>
>     OID         *incoming = &method->varbind->name;
>     OBJECT      *object   = method->object;
>     int instLength;
>     unsigned int instance[6];
>     unsigned int ip_addr;
>     int          iface;

>     -- The instance is N.1.A.A.A.A where the A's are the IP address--
>     instLength = oid2instance(incoming, object, instance, 6);
>     if (instLength == 6 && !inst2ip(&instance[2], 4, &ip_addr, TRUE,0)) {
>         iface = (int) instance[0];
>     }
>     else
>        return ESNMP_MTHD_noSuchInstance;

>     #include <esnmp.h>
>     OID         *incoming = &method->varbind->name;
>     OBJECT      *object   = method->object;
>     int instLength;
>     unsigned int instance[6];
>     unsigned int ip_addr;
>     int          iface;

>     -- The instance is N.1.A.A.A.A where the A's are the IP address--
>     instLength = oid2instance(incoming, object, instance, 6);
>     iface = (instLength < 1) ? 0 :(int) instance[0];

>     iface += inst2ip(&instance[2], instLength - 2, &ip_addr, FALSE, 1);

>     #include <esnmp.h>
>     OID         *incoming = &method->varbind->name;
>     OBJECT      *object   = method->object;
>     int instLength;
>     unsigned int instance[9];
>     unsigned int ip_addrA;
>     unsigned int ip_addrB;
>     int          iface;
>     int          carry;

>     -- The instance is N.A.A.A.A.B.B.B.B --
>     instLength = oid2instance(incoming, object, instance, 9);
>     iface = (instLength < 1) ? 0 :(int) instance[0];
>     carry = inst2ip(&instance[1], instLength - 1, &ip_addr, FALSE, 1);
>     carry = inst2ip(&instance[5], instLength - 5, &ip_addr, FALSE, carry);
>     iface += carry;
>     if (iface > 0xFFFFFFFF)
>     -- a carry caused an overflow in the most significant element
>     return ESNMP_MTHD_noSuchInstance;

# cmp_oid

> Compares two OID structures.

## Format

> ### int cmp_oid (oid *q, oid *p)

## DESCRIPTION

> This routine does an element-by-element comparison starting with the most significant element (element 0) and working toward the least significant element. If all other elements are equal, the OID with the fewest number of elements is considered less.

## Return Values

> NEGATIVE ONE | The OID q is less than OID p.
> ZERO | The OID q is in OID p.
> POSITIVE ONE | The OID q is greater than OID p.

# cmp_oid_prefix

> Compares an OID against a prefix.

## Format

> ### int cmp_oid_prefix (oid *q, oid *prefix)

## DESCRIPTION

> A prefix could be the OID on an object in the object table. The elements beyond the prefix are the instance information.

> This routine does an element-by-element comparison, starting with the most significant element (element 0) and working toward the least significant element. If all elements of the prefix OID match exactly with corresponding elements of OID q it is considered an even match if OID q contains additional elements. OID q is considered greater than the prefix if the first nonmatching element is larger. It is considered smaller if the first nonmatching element is less.

## Return Values

> NEGATIVE ONE | The OID is less than the prefix.
> ZERO | The OID is in prefix.
> POSITIVE ONE | The OID is greater than the prefix.

## Example

>     #include <esnmp.h>
>     OID *q;
>     OBJECT *object;
>     if (cmp_oid_prefix(q, &object->oid) == 0)
>        printf("matches prefix\n");

# clone_oid

> Copies the OID.

## Format

> ### oid clone_oid (oid *new, oid *oid)

## ARGUMENTS

> ### *new

> A pointer to the OID structure that is to receive the copy.

> ### *oid

> A pointer to the OID structure where the data is to be obtained.

## DESCRIPTION

> This routine dynamically allocates the element's buffer and inserts its pointer into the OID structure received. It is the responsibility of the caller to free this buffer.

> Point to the OID structure that is to receive the new OID values and call this routine. Any previous value in the new OID structure is freed and the new values are dynamically allocated and inserted. Be sure to initialize the new OID structure with zeros if you do not want it to be freed.

## Return Values

> null | An error or the pointer to the OID is returned.

## Example

>     #include <esnmp.h>
>     OID oid1;
>     OID oid2;
>     :
>     : assume oid1 gets assigned a value
>     :
>     memset(&oid2, 0, sizeof(OCT));
>     if (clone_oid(&oid2, &oid1) == NULL)
>         DPRINTF((WARNING, "It did not work\n"));

# free_oid

> Frees the OID structure's elements buffer.

## Format

> ### void free_oid (oid *oid)

## DESCRIPTION

> This routine frees the buffer pointed to by the OID->elements and zeros the field and the nelem structure.

## Example

>     include <esnmp.h>
>     OID oid;
>     :
>     : assume oid was assigned a value (perhaps with clone_oid()
>     : and we are now finished with it.
>     :
>     free_oid(&oid);

# clone_buf

> Duplicates a buffer in a dynamically allocated space.

## Format

> ### char clone_buf (char *str, int *len)

## ARGUMENTS

> ### *str

> A pointer to the buffer to be duplicated.

> ### *len

> The number of bytes to be copied.

## DESCRIPTION

> One extra byte is always allocated and filled on the end with zeros. If the length is less than zero, the length is set to zero. There is always a buffer pointer, unless there is a malloc error.

## Return Values

> null | A malloc error or the pointer to the allocated buffer that contains a copy of the original buffer is returned.

## Example

>     #include <esnmp.h>
>     char *str = "something nice";
>     char *copy;

# mem2oct

> Converts a string, a buffer and length to an oct structure.

## Format

> ### oct *mem2oct (oct *new, char *buffer, int *len)

## DESCRIPTION

> The mem2oct routine dynamically allocates the buffer and inserts its pointer into the oct structure. The caller must free this buffer.

> This routine does not allocate an oct structure. It calls the free_oct (new) routine first. Therefore, be sure to initialize the new OID structure with zeros if you do not want it to be freed.

## Return Values

> null | An error or the pointer to the oct structure, the first argument, is returned.

## Example

>     #include <esnmp.h>
>     char buffer;
>     int len;
>     OCT abc;

>     ...buffer and len are initialized to something...

>     memset(&abc, 0, sizeof(OCT));
>     if (mem2oct(&abc, buffer, len) == NULL)
>         DPRINTF((WARNING,"It did not work...\n"));

# cmp_oct

> Compares two octets.

## Format

> ### int cmp_oct (oct *oct1, oct *oct2)

## DESCRIPTION

> The two octets are compared byte-by-byte for the length of the shortest octet. If all bytes are equal, the lengths are compared. An octet with a null pointer is considered the same as a zero length octet.

## Return Values

> NEGATIVE ONE | The string pointed to by the first oct is less than the second.
> ZERO | The string pointed to by the first oct is equal.
> POSITIVE ONE | The string pointed to by the first oct is greater than the second.

## Example

>     #include <esnmp.h>
>     OCT abc, efg;

>     ...abc and efg are initialized to something...

>     if (cmp_oct(&abc, &efg) > 0)
>         DPRINTF((WARNING,"octet abc is larger than efg...\n"));

# clone_oct

> Makes a copy of the data in an oct Octet String structure.

## Format

> ### oct clone_oct (oct *new, oct *old)

## ARGUMENTS

> ### *new

> A pointer to the oct structure receiving the data.

> ### *old

> A pointer to the oct structure where the data is to be obtained.

## DESCRIPTION

> The clone_oct routine dynamically allocates the buffer and inserts its pointer and length into the oct structure. The caller must free this buffer.

> > Note

> > This routine does not allocate an oct structure.

> Previous | Next | Contents