Before a subagent can receive or send any DPI packets from
or to the SNMP DPI-capable agent, it must connect to the agent and
identify itself to the agent.
The following example code returns
a response. It is assumed that there are no errors in the request,
but proper code should do the checking for that. Proper checking
is done for lexicographic next object, but no checking is done for
ULONG_MAX, or making sure that the instance ID is indeed valid (digits
and periods). If the code gets to the end of our dpiSimpleMIB, an
endOfMibView must be returned as defined by the SNMP Version 2 rules.
You will need to specify:
- A host name or IP address in dotted decimal notation that specifies
where the agent is running. Often the name loopback can be
used if the subagent runs on the same system as the agent.
- A community name that is used to obtain the dpi TCP port from
the agent. Internally that is done by sending a regular SNMP GET
request to the agent. In an open environment, the well-known community
name public can probably be used.
The function returns a negative error code if an error
occurs. If the connection setup is successful, it returns a handle
that represents the connection and that must be used on subsequent
calls to send or await DPI packets.
The second step is to identify the subagent
to the agent. This is done by making a DPI-OPEN packet, sending it
to the agent, and then awaiting the response from the agent. The
agent can accept or deny the OPEN request. Making a DPI-OPEN packet
is done by calling mkDPIopen(), which expects the following parameters:
- A unique subagent identification (an object identifier).
- A description, which can be the NULL string ("").
- Overall subagent timeout in seconds. The agent uses this value
as a timeout value for a response when it sends a request to the subagent.
The agent may have a maximum value for this timeout that will be
used if you exceed it.
- The maximum number of varBinds per DPI packet that the subagent is willing or is
able to handle.
- The desired character set. In most cases you want to use the
native character set.
- Length of a password. A 0 means no password.
- Pointer to the password or NULL if no password. It depends on
the agent if subagents must specify a password to open up a connection.
The function returns a pointer to a static buffer holding
the DPI packet
if successful. If it fails, it returns a NULL pointer.
When
the DPI-OPEN packet has been created, you must send it to the agent.
You can use the DPIsend_packet_to_agent() function, which expects
the following parameters:
- The handle of a connection from DPIconnect_to_agent_TCP.
- A pointer to the DPI packet from mkDPIopen.
- The length of the packet. The snmp_dpi.h include file provides
a macro DPI_PACKET_LEN that calculates the packet length of a DPI packet.
This function returns DPI_RC_OK (value 0) if successful.
Otherwise, an appropriate DPI_RC_xxxx error code as defined in snmp_dpi.h
is returned.
Now wait for a response to the DPI-OPEN. To await
such a response, you call the DPIawait_packet_from_agent() function,
which expects the following parameters:
- The handle of a connection from DPIconnect_to_agent_TCP.
- A timeout in seconds, which is the maximum time to wait for response.
- A pointer to a pointer, which will receive a pointer to a static
buffer containing the awaited DPI packet. If the system fails to receive a
packet, a NULL pointer is stored.
- A pointer to a long integer (32-bit), which will receive the length
of the awaited packet. If it fails, it will be set to 0.
This function returns DPI_RC_OK (value 0) if successful.
Otherwise, an appropriate DPI_RC_xxxx error code as defined in snmp_dpi.h
is returned.
The last step is to ensure that you received a
DPI-RESPONSE back from the agent. If so, ensure that the agent accepted
you as a valid subagent. This will be shown by the error_code field
in the DPI response packet.
The following example code establishes a
connection and opens it by identifying you to the agent.
static void do_connect_and_open(char *hostname_p, char *community_p)
{
unsigned char *packet_p;
int rc;
unsigned long length;
snmp_dpi_hdr *hdr_p;
#ifdef MVS
__etoa(community_p); /* Translate to ASCII */
#endif /* MVS */
#ifndef DPI_MINIMAL_SUBAGENT
#ifdef INCLUDE_UNIX_DOMAIN_FOR_DPI
if (unix_sock) {
handle =
DPIconnect_to_agent_UNIXstream( /* (UNIX) connect to */
hostname_p, /* agent on this host */
community_p); /* snmp community name */
} else
#endif /* def INCLUDE_UNIX_DOMAIN_FOR_DPI */
#endif /* ndef DPI_MINIMAL_SUBAGENT */
handle =
DPIconnect_to_agent_TCP( /* (TCP) connect to agent */
hostname_p, /* on this host */
community_p); /* snmp community name */
if (handle < 0) exit(1); /* If it failed, exit */
packet_p = mkDPIopen( /* Make DPI-OPEN packet */
DPI_SIMPLE_SUBAGENT, /* Our identification */
"Simple DPI subAgent", /* description */
10L, /* Our overall timeout */
1L, /* max varBinds/packet */
DPI_NATIVE_CSET, /* native character set */
0L, /* password length */
(unsigned char *)0); /* ptr to password */
if (!packet_p) exit(1); /* If it failed, exit */
rc = DPIsend_packet_to_agent( /* send OPEN packet */
handle, /* on this connection */
packet_p, /* this is the packet */
DPI_PACKET_LEN(packet_p));/* and this is its length */
if (rc != DPI_RC_OK) exit(1); /* If it failed, exit */
rc = DPIawait_packet_from_agent( /* wait for response */
handle, /* on this connection */
10, /* timeout in seconds */
packet_p, /* receives ptr to packet */
length;); /* receives packet length */
if (rc != DPI_RC_OK) exit(1); /* If it failed, exit */
hdr_p = pDPIpacket(packet_p); /* parse DPI packet */
if (hdr_p == snmp_dpi_hdr_NULL_p) /* If we fail to parse it */
exit(1); /* then exit */
if (hdr_p->packet_type != SNMP_DPI_RESPONSE) exit(1);
rc = hdr_p->data_u.resp_p->error_code;
if (rc != SNMP_ERROR_DPI_noError) exit(1);
} /* end of do_connect_and_open() */