VxWorks Reference Manual : Libraries
subagentLib - encode, decode, and process agent and subagent messages
snmpSubEncode( ) - encode a packet for transmission to master agent or subagent
snmpSaHandlerAsync( ) - asynchronous message processing routine for the subagent
snmpSaHandlerWR( ) - provide snmpSaHandlerAsync( ) functionality synchronously
snmpSaHandlerContinue( ) - subagent continuation function
snmpSaHandlerFinish( ) - encode packet for subagent IO completion
snmpSaHandlerCleanup( ) - cleanup routine for subagent
snmpMasterHandlerAsync( ) - process messages from the subagent asynchronously
snmpMasterHandlerWR( ) - synchronous version of snmpMasterHandlerAsync( )
snmpMasterQueryHandler( ) - handles replies from the subagent
snmpMasterCleanup( ) - free up resources after a query times out
This module provides the core routines for processing the messages passed between the SNMP master agent and its subagents. Thus, this library includes routines for encoding and decoding a package. It also includes the routines used to sort the messages according to type and then respond to each specific message appropriately.
snmpSubEncode( ) - encode a packet for transmission to master agent or subagent
INT_32_T snmpSubEncode ( VBL_T * pVblist, /* varbindlist to be encoded */ SA_HEADER_T * pHdr, /* header block structure */ SA_DEMUX_T * pDemuxer, /* demuxer structure */ EBUFFER_T * pBuf /* buffer to place result in */ )
This routine encodes a memory-resident varbind list. The result is a buffer containing a message ready for transmission. Most of the arguments are values to be encoded into the buffer.
- pVblist
- Expects a pointer to a VBL_T structure containing the list of the varbinds to be encoded in the message. In a control message, the varbinds identify the nodes or instances to be added or removed from the master agents MIB tree. In a query message, the varbinds identify the variables to be gotten or set. In a trap message sent from a subagent to its master agent, the varbinds specify the objects to be sent in a trap message to the SNMP manager. A trap message from a subagent follows the SNMPv2 trap style. Thus, the first object in the list must always be sysUpTime. The second object must be a snmpTrapOID.0 whose value is the administratively assigned name of the notification.
- pHdr
- Expects a pointer to a SA_HEADER_T structure containing all the items that go into the message header.
- pDemuxer
- Expects a pointer to an SA_DEMUX_T structure containing all the information the subagent might need to demux the packet. That is, to determine the time and space contexts for this request. In a v1 request, the string part of the demuxer is the community string and the object ID is unused. In a v2 request, the string is the local entity string from the context and the Object ID is the local time ID from the context.
- pBuf
- Expects a pointer to an EBUFFER_T structure into which snmpSubEncode( ) can write the encoded packet. If pBuf references a previously allocated EBUFFER_T structure, snmpSubEncode( ) uses that space. Otherwise, snmpSubEncode( ) tries to the necessary space.
0, if successful (that is, the structure at pBuf is ready for
transmission); 1, if there is an illegal or unknown argument;
2, if there is insufficient buffer space at pBuf or space
cannot be allocated.
snmpSaHandlerAsync( ) - asynchronous message processing routine for the subagent
void snmpSaHandlerAsync ( OCTET_T * pMsg, /* message from the master-agent */ ALENGTH_T msglength, /* length of message in octets */ PTR_T root, /* root of mib tree */ SA_IO_COMPLETE_T * pIoComp, /* IO completion routine */ SA_ERR_COMPLETE_T * pErrComp, /* error completion routine */ SA_REG_COMPLETE_T * pRegComp, /* registration complete routine */ PTR_T cookie /* cookie */ )
It decodes the message in pMsg and responds appropriately, which can include testing, getting, and setting variables. After the message is processed, snmpSaHandlerAsync( ) then calls whichever completion routine is appropriate.
- pMsg
- Expects pointer to an octet string containing the message from the master agent.
- msglength
- Expects the length of the message.
- root
- Expects a pointer to the root of the subagent's MIB tree. If root is NULL, the default mib_root_node is used.
- pIoComp
- Expects a pointer to the function snmpSaHandlerAsync( ) should call after it has processed the message from the master agent. This routine should be able to send a response to the master agent, if necessary. This function must handle the building, encoding, transmission of the response to the master agent. This function must be of the form:
void SA_IO_COMPLETE_T(PTR_T pktp, SA_HEADER_T *hdr_blk, PTR_T cookie)When the subagent calls this routine, it uses the pktp parameter to pass in a pointer to the data to be sent to the master agent. It uses the hdr_blk parameter to pass in a pointer to the header to be included with the packet. It uses the cookie parameter to pass in the cookie specified in the call to snmpSaHandlerAsync( ). You can use this cookie to carry information specific to your environment and application.
- pErrComp
- Expects a pointer to the function snmpSaHandlerAsync( ) should call if it cannot generate an appropriate response to a message from the master agent. This function must be of the form:
void SA_ERR_COMPLETE_T(int error_code, PTR_T cookie)The error_code passes in one of the following error codes:SA_GEN_ERROR SA_UNKNOWN_VERSION SA_UNKNOWN_OPCODE1 SA_UNKNOWN_OPCODE2 SA_UNKNOWN_ENCODING SA_DECODE_FAILURE SA_ENCODE_FAILURE SA_UNKNOWN_NODE SA_UNKNOWN_TAG SA_UNKNOWN_GRP SA_SHORT_MSG SA_IPC_ERROR SA_LOCK_ERROR SA_NODE_ERROR SA_MEMORY_ERROR SA_UNSUPPORTED_TYPE SA_NO_SAVED_PACKETThe cookie parameter passes in the cookie specified in the call to snmpSaHandlerAsync( ). You can use this cookie to carry information specific to your environment and application.
- pRegComp
- Expects a pointer to the function snmpSaHandlerAsync( ) should call in response to a registration completion message from the master agent. If successful, this message should contain a group ID for the MIB variables that the registration request added to the master agent's MIB tree. The subagent needs this ID when it comes time to deregister and remove those variables from the master agent's MIB tree. This function must be of the form:
void SA_REG_COMPLETE_T ( INT_32_T ecode, SA_HEADER_T *hdr_blk, VBL_T *vblp, PTR_T cookie )This completion routine expects an error code in ecode, a header block in hdr_blk, a list of nodes at vblp, and the cookie passed into the snmpSaHandlerAsync( ).
- cookie
- Expects a pointer that you can use to pass data unchanged to the functions you specified in the pIoComp, pErrComp, and pRegComp functions.
N/A
snmpSaHandlerWR( ) - provide snmpSaHandlerAsync( ) functionality synchronously
INT_32_T snmpSaHandlerWR ( OCTET_T * pMsg, /* message from the master-agent */ ALENGTH_T msgl, /* kength of message in octets */ EBUFFER_T * pBuf, /* buffer to hold reply packet */ SA_HEADER_T * pHdr, /* place for header structure */ VBL_T * pVblist, /* place for vblist */ PTR_T root /* root of mib tree */ )
This routine puts a synchronous shell around snmpSaHandlerAsync( ). Like snmpSaHandlerAsync( ), this function can decode a message from the master agent. If the message is a query against a variable in the subagent's MIB tree, snmpSaHandlerWR( ) processes the request and generates a response. However, snmpSaHandlerWR( ) does not handle the completion processing for the message that would have been handled by the pIoComp, pErrComp, and pRegComp routines specified as input to snmpSaHandlerAsync( ).
Instead, it uses its returned function value to indicate that status of the message processing and uses pBuf, pHdr, and pVblist as output parameters if that status requires additional processing on your part. For example, if the message was a successfully processed query, the response data is included in pVblist and a header is included in pHdr, but that response is not yet encoded in a packet or transmitted back to the master agent. In snmpSaHandlerAsyn( ), all that would normally be handled in the pIoComp routine. Effectively, you must now call your pIoComp routine explicitly.
- pMsg
- Expects a pointer to the message, an octet string, from the master agent.
- msgl
- Expects the length of the message starting at pMsg.
- pBuf
- Expects a pointer to a previously allocate EBUFFER_T into which this function can write a response, if any. In some cases (if opcode1 is SA_QUERY_REQUEST), instead of indicating an error in the returned value of snmpSaHandlerWR( ), the error is encoded into this message. This is done for errors more appropriately handled by the SNMP manager.
- pHdr
- Expects a pointer to a previously allocated SA_HEADER_T structure into which this function can writer header block information, if necessary. If hdr_blk.sa_error is non-zero, other members might not contain valid data.
- pVblist
- Expects a pointer to a previously allocated VBL_T structure into which this function can write the list of nodes found in the original message from the master agent.
- root
- Expects a pointer to the root of the subagent's MIB tree. If root is NULL, the default mib_root_node is used.
0 on success, or a positive value indicating an error. For return code values, see subagent.h. Using these values as a switch, you should call one of the functions you would have specified for pIoComp, pErrComp, or pRegComp in a call to snmpSaHandlerAsync( ).
snmpSaHandlerContinue( ) - subagent continuation function
void snmpSaHandlerContinue ( SNMP_PKT_T * pPkt /* pointer to the SNMP packet */ )
This routine is similar to snmpdContinue( ). Method routines that do not complete their tasks before returning should arrange to have this routine called when the task is finished. This routine should not be called if you call snmpSaHandlerWR( ). The pPkt parameter expects a pointer to the packet. If SNMP_CONTINUE_REENTRANT is installed, this routine will attempt to release the per-packet write lock.
N/A
snmpSaHandlerFinish( ) - encode packet for subagent IO completion
INT_32_T snmpSaHandlerFinish ( PTR_T pkt, /* pointer to the packet */ SA_HEADER_T * pHdr, /* header block */ EBUFFER_T * pBuf /* buffer to place the result in */ )
This routine encodes the packet at pkt and the header block at pHdr. If pBuf is empty, this routine tries to allocate space. If it cannot or if the space provided is too small, an error is returned.
0 on success, or a non-zero value on failure.
snmpSaHandlerCleanup( ) - cleanup routine for subagent
void snmpSaHandlerCleanup ( PTR_T pPkt, /* pointer to the packet */ SA_HEADER_T * pHdr /* header block */ )
This routine is called by the IO completion routine if it detects an error. It either frees or arranges to free any resources that might have been allocated for processing a query from the master agent. The information at pPkt and pHdr is passed unchanged into the completion routine.
N/A
snmpMasterHandlerAsync( ) - process messages from the subagent asynchronously
void snmpMasterHandlerAsync ( OCTET_T * pMsg, /* pointer to the message */ ALENGTH_T msgl, /* length of the message */ IPCCOMP_T * pIpcComp, /* completion routine */ IPCSEND_AS_T * pIpcSend, /* send routine */ IPCRCV_T * pIpcRcv, /* receive routine */ IPCFREE_T * pIpcFree, /* free routine */ IPCAYT_T * pIpcAyt, /* status check routine */ PTR_T ipchandle, /* ipchandle for the IPC scheme used */ PTR_T user_priv /* MIB tree identifier */ )
This function provides support for an asynchronous communication scheme between the master agent and its subagents. The shipped version of WindNet SNMP does not call this function. Instead, it calls snmpMasterHandlerWR( ), a function that supports a synchronous communication scheme. If you want master agents and subagents to use an asynchronous communication scheme, you must rewrite snmpQueMonitor( ) to call snmpMasterHandlerAsync( ) instead of snmpMasterHandlerWR( ). In addition, because snmpMasterHandlerAsync( ) does not return a function value, you will need to remove the snmpQueMonitor( ) code that responded to the snmpMasterHandlerWR( ) function value. The functionality handled by the removed code should instead be implemented in the function referenced by the ipcComp parameter. Use the parameters as follows:
- pMsg
- Expects a pointer to an EBUFFER_T structure containing the data part of the message from the subagent. The message shows up on the queue as an SA_MESSAGE_T structure. The message expected by this parameter is contained in the mesg member of this structure. To extract this pointer, use EbufferStart macro defined in defined in buffer.h.
- msgl
- Expects the length of the message referenced in pMsg. To retrieve this length value, use the EBufferUsed macro defined in buffer.h.
- pIpcComp
- Expects a pointer to the completion function, which must be of the form:
void masterIpcComp ( OCTET_T opcode, /* this specifies what needs to be done */ EBUFFER_T * ebuf, /* reply message to be sent */ VBL_T * vblist, /* list of varbinds that the message contained */ PTR_T ipchandle /* subagent address */ )The master agent executes this function upon completing processing for an unsolicited control message from a subagent (primarily registration requests, although a trap from the subagent will eventually find its way to this function). Your masterIcpComp( ) should be able handle things such as letting the subagent know the completion status of message it sent to the master agent.For a registration routine, it must send the message in ebuf back to the subagent. This message contains the group ID of the MIB variables added to the master agent's MIB tree. The subagent needs this ID to make a deregistration request.
If you decide to support traps from subagents, this function must be able to forward the varbind list in vblist to the SNMP manager. In addition, it is your responsibility to acquire any values not specified in vblist and include it in the message you send the to the SNMP manager. Use the opcode to know when you are handling the completion processing for a registration request, a deregistration request, or a trap from a subagent.
For an example of an IPC completion routine, see masterIpcComp( ) defined in masterIoLib.c.
- pIpcSend
- Expects a pointer to the function that method routines should use to send messages to the subagent. This function must be of the form:
INT_32_T masterIpcSend ( EBUFFER_T * pBuf, /* message to be sent */ PTR_T ipchandle /* address of subagent */ UINT_16_T reqid /* ID for request sent */ )To make the communication between the master agent and subagent asynchronous, this send routine should send the message to the subagent and return. Eventually, a response shows up on the master agent's local queue, or the query times out. How you process a query response or a query time out is almost entirely up to you.To process a query response, you must call snmpMasterQueryHandler( ). This function will handle the details of integrating the message from the subagent into a message to the SNMP manager.
To clean up after a send that times out, you must call snmpMasterCleanup( ). The specifics of the mechanism you use are up to you, but you will likely need to integrate the mechanism with your masterIpcSend( ) routine. That is because this function gets the request ID that you will need for clean up. The request ID is a number generated internally to the SNMP master agent. It passes this value into your masterIpcSend( ) using the reqid parameter. To clean up after a send that times out, you submit the reqid in a call to snmpMasterCleanup( ).
For an example of an masterIpcSend( ), see the masterIpcSend( ) defined in masterIoLib.c.
- pIpcRcv
- This parameter is not used by snmpMasterHandlerAsync( ) and so should be null. It is included to maintain parallelism with snmpMasterHandlerWR( ).
- pIpcFree
- Expects a pointer to a function of the form:
void masterIpcFree ( PTR_T ipchandle )The master agent uses this function to free any resources it might have allocated to maintain the IPC link with the subagent. The master agent calls this function when a subagent deregisters.
- pIpcAyt
- Expects a pointer to the function the master agent can use to test the connection with the subagent. This function must be of the form:
INT_32_T masterIpcAyt ( PTR_T ipchandle )For an example of such a function, see the masterIpcAyt( ) defined in masterIoLib.c.
- ipchandle
- Expects a pointer to the IPC handle used to access the subagent that sent this message. In the shipped implementation, this is a pointer to a message queue.
- user_priv
- Expects a pointer to the MIB tree from which registration and deregistration requests want to add or delete objects or instances. If this pointer is NULL, the default MIB tree specified by mib_root_node is used.
N/A
snmpMasterHandlerWR( ) - synchronous version of snmpMasterHandlerAsync( )
INT_32_T snmpMasterHandlerWR ( OCTET_T * pMsg, /* pointer to the message */ ALENGTH_T msgl, /* length of the message */ IPCSEND_T * pIpcSend, /* send routine */ IPCRCV_T * pIpcRcv, /* receive routine */ IPCFREE_T * pIpcFree, /* free routine */ IPCAYT_T * pIpcAyt, /* status Check Routine */ PTR_T ipchandle, /* ipchandle for the IPC scheme used */ EBUFFER_T * pBuf, /* buffer to place reply in */ VBL_T * pVblist, /* place to put varbinds */ PTR_T user_priv /* MIB tree identifier */ )
This function is called to process the control messages received from subagents when the communication method between master and subagent is synchronous.
To process a registration request, this function extracts the objects from the message and adds them as a group to the master agent's MIB tree. The actual get, test, and set methods for these objects reside in the subagent. To set up local methods for these routines, snmpMasterHandlerAsync( ) uses the function referenced in pIpcSend and pIpcRcv.
The methods local to the master agent use pIpcSend to send queries to the subagent which locally executes the actual method routine for the object. The subagent then transmits the results back to the master agent's public queue. When the function monitoring this queue sees the query response, it transfers the message to the master agent's local queue where the pIpcRcv function is waiting for the response.
To process a deregistration request, this function extracts a group ID from the message and removes that group of objects from the master agent's MIB tree. It also executes the function in pIpcFree to free any resources allocated locally to maintain the IPC link with the deregistered subagent.
The snmpMasterHandlerWR( ) routine returns information using the output parameters pBuf and pVblist and its function return value. If the returned function value indicates success, the master agent sends the message returned in pBuf to the subagent that sent the registration or deregistration request. If the returned value of this function indicates failure, the master agent silently drops the packet.
This function as has the ability to return an opcode value, although this functionality is unused in the shipped version of WindNet SNMP. In fact, if snmpMasterHandlerWR( ) were to return an opcode, the current implementation of the master agent would silently drop the packet. The possibility of returning an opcode is supported to make it possible for you to create subagents that send traps. In this case, snmpMasterHandlerWR( ) would return an opcode and a varbind list using the pVblist parameter. You could then rewrite snmpQueMonitor( ), the master agent function that calls snmpMasterHandlerWR( ), so that it responds appropriately to the returned opcode and forwards the contents of pVblist to the SNMP manager.
Use the snmpMasterHandlerWR( ) parameters as follows:
- pMsg
- Expects a pointer to an EBUFFER_T structure containing the data part of the message from the subagent. The message shows up on the queue as an SA_MESSAGE_T structure. The message expected by this parameter is contained in the mesg member of the SA_MESSAGE_T structure. To extract this pointer, you can use the EbufferStart macro defined in defined in buffer.h.
- msgl
- Expects the length of the message referenced in pMsg. To retrieve this length value, use the EBufferUsed macro defined in buffer.h.
- pIpcSend
- Expects a pointer to the function that method routines should use to send messages to the subagent. This function must be of the form:
INT_32_T masterIpcSend ( EBUFFER_T * pBuf, /* message to be sent */ PTR_T ipchandle /* address of subagent */ )If snmpMasterHandlerWR( ) is processing a registration request from the subagent, it associates this function pointer with the group of objects it adds to the master agent's MIB tree. The methods for those objects call this routine to send a message to the subagent to make a test, get, or set query against those variables. After using this function to send the message, the master agent then calls the function referenced in pIpcRcv. The pIpcRcv function waits on a local queue for a response from the subagent. For an example of an masterIpcSend( ) routine, see the masterIpcSend( ) defined in masterIoLib.c.
- ipcRcv
- Expects a pointer to a function of the form:
INT_32_T masterIpcRcv ( EBUFFER_T * pBuf, /* buffer to receive message */ PTR_T ipchandle /* address of subagent */ )If snmpMasterHandlerWR( ) is processing a registration request from the subagent, it associates this function pointer with the group of objects it adds to the master agent's MIB tree. The methods for those objects call this routine to wait on a local queue for a response from the subagent. For an example of an masterIpcRcv( ), see the masterIpcRcv( ) defined in masterIoLib.c.
- ipcFree
- Expects a pointer to a function of the form:
void masterIpcFree ( PTR_T ipchandle )The master agent uses this function to free any resources it allocated to maintain the IPC link with the subagent. The master agent calls this function when a subagent deregisters.
- pIpcAyt
- Expects a pointer to the function the master agent can use to test the connection with the subagent. This function must be of the form:
INT_32_T masterIpcAyt ( PTR_T ipchandle )For an example of such a function, see the masterIpcAyt( ) defined in masterIoLib.c.
- ipchandle
- Expects a pointer to the IPC handle used to access the subagent that sent this message. In the shipped implementation, this is a pointer to a message queue.
- pBuf
- Expects a pointer to a previously allocated EBUFFER_T. This is an output parameter that snmpMasterHandlerWR( ) uses this to return a reply packet, if one is generated. For example, if snmpMasterHandlerWR( ) successfully processes a registration request, it writes a message to the EBUFFER_T at pBuf. This message contains the group ID for the objects just added to the master agent's MIB tree. When control returns from snmpMasterHandlerWR( ), you must transmit this message back to the subagent, which will store the group ID for use in a deregistration request. In the current implementation, snmpQueMonitor( ) already handles this for you.
- pVblist
- Expects a pointer to a previously allocated VBL_T. The intended use of this parameter is to provide an output vehicle for the varbind list received in a trap message from a subagent. Because of the application-dependent nature of traps, the shipped implementation of snmpQueMonitor( ) just drops the packet. However, if you want to support traps from your subagents, you can modify snmpQueMonitor( ) to check the returned value of snmpMasterHandlerWR( ) to watch for a trap message. You can then use snmpIoTrapSend( ) to forward the trap message in pVblist to the SNMP manager.
- user_priv
- Expects a pointer to the MIB tree from which registration and deregistration requests want to add or delete objects or instances. If this pointer is NULL, the default MIB tree specified by mib_root_node is used.
If the message is trap request, it is the responsibility of the user code to acquire any values not specified in the trap message and to send the trap to the manager.
The opcode from the decoded packet or 0 or -1. An returned value of 0 indicates an error for which you should just drop the packet. A return value of -1 indicates success.
If this function returns an opcode, a value from 1 to 127, the shipped implementation just drops the packet. However, to support traps from the subagent, you could modify snmpQueMonitor( ) to note a returned value of SA_TRAP_REQUEST and then forward the varbind list in pVblist to the SNMP manager.
snmpMasterQueryHandler( ) - handles replies from the subagent
UINT_16_T snmpMasterQueryHandler ( OCTET_T * pMsg, /* pointer to the packet */ ALENGTH_T msgl, /* length of packet */ int flag /* should be 1 */ )
This routine is for use with snmpMasterHandlerAsync( ). It handles the replies to queries generated by the method routines. It decodes the message and tries to integrate the response with an outstanding packet. The pMsg and msgl parameters are pointers to the message and the length respectively. The flag parameter specifies whether the continuation routines should be run. This should always be set to 1.
The request ID if routine could decode the packet or 0 in case of error.
snmpMasterCleanup( ) - free up resources after a query times out
void snmpMasterCleanup ( UINT_16_T reqid, /* request Id to track state block */ UINT_16_T options /* as mentioned above */ )
If you use snmpMasterHandlerAsync( ), the master agent calls this routine if the IPC layer determines that a timeout period for a query response has been exceeded. The reqid parameter is the same as the requestId value passed to the send routine. It is used to track the correct state block. The options parameter passes in a set of flags that control what actions the cleanup routine. Currently, there are three flags: SA_CLEANUP_INACTIVE, SA_CLEANUP_TIMEOUT, and SA_CLEANUP_CONTINUE. The continue and timeout flags should always be set. The inactive flag indicates that any objects associated with the subagent should be removed. Set this flag when the IPC layer determines that the subagent has stopped rather than timed out.
N/A