WinSNMP v2.0 Addendum Document version information: November 1, 1997 - Initial Release Version December 5, 1997 - Typos wrt SnmpListen() params fixed Document contents information: I - Introduction II - Clarifications for WinSNMP v2.0: 1. Version 2.0 2. Level definitions 3. Operating system dependencies 4. Retransmission support 5. Timeout notification methods 6. SNMPv1 Trap-PDU generation 7. Notification port usage 8. Request-ID/SnmpCreatePdu()/SnmpSetPdu() 9. SnmpGetPduData() and hVbl 10. GetBulk -> GetNext mapping 11. IPX support in SnmpStrToEntity() 12. SnmpDecodeMsg() outputs 13. Inform processing 14. Thread-safeness 15. WinSNMP++ -> SNMP++ change 16. SnmpRegister() III - New functions for WinSNMP v2.0: 1. SnmpCreateSession() 2. SnmpCreateEntity() 3. SnmpCreateContext() 4. SnmpCancelMsg() 5. SnmpSetPort() 6. SnmpListen() 7. SnmpGetVendorInfo() 8. SnmpOpen() [Re-written for v2.0] I - Introduction This document is an update Addendum to the WinSNMP/Manager API Specification, v1.1a, dated August 9, 1995). In some places (Section II below, especially) it modifies (via clarifying text) that earlier document; in other places (Section III below, especially) it adds completely new functionality. Users of the WinSNMP API--implementors and application developers must be familiar with both documents until such time as the new WinSNMP API v2.0 specification document is published. Said document will incorporate all of the text in the final version of this update Addendum. Like the WinSNMP API specification document itself, this document is intended to be freely available for use by all interested parties. It is the product of an open, collaborative effort via the ad hoc WinSNMP Industry Forum e-mail discussion list (winsnmp@mailbag.intel.com). Numerous individuals have contributed to the WinSNMP API since this work was started in the 1992/93 time frame. II - Clarifications 1. Version 2.0 The collection of clarifications to v1.1a of the WinSNMP/Manager API specification described herein defines v2.0 of the WinSNMP API specification. A compliant v2.0 implementation MUST support ALL of the functions and operations defined in both the WinSNMP v1.1a specification and is this WinSNMP v2.0 Addendum. Where this WinSNMP v2.0 Addendum differs from the WinSNMP v1.1a specification, this Addendum has precedence. Note that for v2.0, the SnmpStartup() function must return a value of 2 for the lMajor parameter and a value of 0 for the lMinor parameter. Note also that the "/Manager" qualifier is dropped for v2.0. This version explicitly supports agent-side SNMP operations, in addition to the manager-side SNMP operations. 2. Level definitions The concept of "levels of support" is deprecated for v2.0. Implementations must report a value of 2 for the lLevel parameter of SnmpStartup(). Level 2 equates to full support for the IETF standard SNMPv2 protocol as defined in RFCs 1902-1908 with the community- based message wrapper as defined in RFC 1901 (SNMPv2c). Levels 0 and 1 are fully subsumed under Level 2. That is, in addition to full SNMPv2 support (as defined in the previous paragraph), all WinSNMP v2.0 implementations must implement the SnmpEncodeMsg() and SnmpDecodeMsg() functions (since no WinSNMP functions are optional in any case) and must also support all SNMPv1 protocol operations (except that, as always, all received SNMPv1 traps are converted to SNMPv2 Trap-PDU format for delivery to registered WinSNMP applications). Level 3, as originally defined, is no longer germane since the "Manager-to-Manager" MIB of "SNMPv2-Classic" was deprecated to "Historic" status by the IESG and, on the positive side, the combination of SNMPv2 support (especially, InformRequest-PDUs and their associated Response-PDUs) and the new functions to support agent applications under WinSNMP v2.0 (especially, the SnmpListen() function) now provide the basis for building Mid-Level Manager (MLM) solutions using WinSNMP. Additionally, it is envisioned that the next major revision of WinSNMP (v3) will correspond to adding support for the eventual IETF SNMPv3. (You will note that the proposed SnmpCreateEntity() and SnmpCreateContext() functions which were included in the earlier drafts of this Addendum have been dropped. It is anticipated that they will be added in WinSNMP v3 to support the corresponding constructs which will (almost surely!) be included in SNMPv3.) "SNMPAPI_UNTRANSLATED_V2" mode now means "SNMPv2c"; all the party stuff is gone (deprecated to "Historic" RFCs) and this mode uses community names in a manner identical to "SNMPAPI_UNTRANSLATED_V1" in terms of entity and context definitions. The only difference is that messages built for SNMPv2 destination entities will use the SNMPv2 value [1] in the "version" member of the SNMP message in the PDUs on the wire. 3. Operating system dependencies WinSNMP v1 was targeted at the Microsoft Windows family of operating systems. WinSNMP v2 is not targeted at any particular operating systems or environments; however, to ensure backward compatibility with fielded WinSNMP v1 applications, the fundamental design objectives and architectural constructs of WinSNMP v1 are retained. The degree of operating system independence targeted in WinSNMP v2 is realized via the new SnmpCreateSession() function (specified in Section III.1 of this document). The original session creation function--SnmpOpen()--is retained and comprises a proper subset of the possible forms of using SnmpCreateSession(). Some minor clarifying text has been added to SnmpOpen() for WinSNMP v2 (specified in Section III.8 of this document). 4. Retransmission support Execution of the retransmission policy was optional for implementations in WinSNMP v1. It is mandatory capability for implementations in WinSNMP v2. Implementations may still announce their "default" mode of operation at each call to SnmpStartup(). The default mode is whatever the implementation says it is in response to the given call to SnmpStartup(). Applications may elect to operate with the RetransmitMode set to SNMPAPI_ON or SNMPAPI_OFF at any given point in time. The RetransmitMode setting is evaluated by the implementation at SnmpSendMsg() time. Unless and until a response is received, a message sent when the RetransmitMode is "on" will result in retries (if a non- zero retry count is specified for the dstEntity at the time SnmpSendMsg() is called) and issuance of a timeout notification to the associated session (when no response is received within the timeout interval and the retry count is exhausted). A message sent when RetransmitMode is "off" does not result in retries and no timeout notification is sent to the associated session. See the "Timeout notification methods" clarification for related information. See the new SnmpCancelMsg() function for associated functionality. 5. Timeout notification methods The method for notifying a session of a timed out request message was not specified for WinSNMP v1. It is specified for WinSNMP v2. The implementation must return the SNMPAPI_TL_TIMEOUT error value in wParam and the RequestID of the timed out PDU in lParam (this is true regardless of the notification mode of the session...i.e., message-based or callback-based). Note that for normal request, response, or trap delivery, the implementation must set wParam to zero and lParam to the RequestID of the PDU to be retrieved. Applications should check wParam on all notifications, regardless of notification mode (message or callback). If it is non-zero, then its value is one of the "transport layer" (SNMPAPI_TL_) error codes and the application does not need to (and should not) call SnmpRecvMsg() in response to this notification. However, if the application elects to make the SnmpRecvMsg() call, then one of three results may occur: 1. If there is a pending message for this session, the DLL may deliver it at this time; or, 2. If there is no pending message for this session, then SnmpRecvMsg() must return SNMPAPI_FAILURE, with SnmpGetLastError() set to: a. SNMPAPI_NOOP [8], or b. SNMPAPI_TL_TIMEOUT [108]. Note that if Result 1 obtains, the session may eventually receive a notification that will yield Result 2a, since that notification may have happened asynchronously to the early retrieval of the message. Note to implementors: If there is no message pending for the calling application, then Result 2a is the preferred error setting. Result 2b is allowed for backward compatibility with certain fielded applications. 6. SNMPv1 Trap-PDU generation The WinSNMP API is oriented towards SNMPv2. No standard function is provided to accommodate the unique fields of an SNMPv1 Trap-PDU (SNMP_PDU_V1TRAP). All SNMPv1 and SNMPv2 Trap-PDUs which are received by a WinSNMP implementation and delivered to applications who requested them via SnmpRegister(), are delivered as SNMPv2 traps (SNMP_PDU_TRAP). Furthermore, only SNMPv2 Trap-PDUs can be assembled directly via SnmpCreatePdu() and/or SnmpSetPduData(). However, WinSNMP entities operating in an agent role may need to emit traps to non-WinSNMP SNMPv1 targets. To accommodate this requirement, the SnmpSendMsg() must evaluate the SNMP-version level of the dstEntity parameter of any out-going SNMP_PDU_TRAP message. If the dstEntity is an SNMPv1 entity, then the message must be automatically and transparently converted to an SNMP_PDU_V1TRAP message via the following procedure: The WinSNMP API is intended to be a common interface that provides bilingual protocol support as transparently as possible. To this end, the API takes on a "v2-style interface" in all other areas, and "downgrades" a request appropriate to communicate with either v1 or v2 agents using the *SAME* interface. For example, WinSNMP v1.1a specified that all implementations (level 1 or 2) must support the GetBulk operator. However, if the request is sent to a v1 entity, then the WinSNMP implementation transparently "downgrades" the GetBulk to a GetNext request per RFC 1908. This enables an application to be coded to always use GetBulk and not care whether the dstEntity is a v1 or a v2 entity, especially in "translated mode". While RFC 1908 does not specify how to "downgrade" an SNMP_PDU_TRAP message into an SNMP_PDU_V1TRAP message, the translation is straight forward. As such, the WinSNMP interface for sending traps--whether to a v1 or a v2 destination-is stipulated hereby as an SNMPv2 Trap-PDU (SNMP_PDU_TRAP). If the dstEntity of an SNMP_TRAP_PDU submitted to SnmpSendMessage() or SnmpEncodeMsg() is a v1 entity, then the WinSNMP implementation must "downgrade" (translate) the trap into an SNMP_PDU_V1TRAP during assembly of the corresponding SNMP message. This action taken on out-going SNMP trap messages has no bearing on SNMP traps received by an implementation. As with v1 of the WinSNMP API specification, in all cases, received traps are presented to WinSNMP applications as SNMPv2 traps (SNMP_PDU_TRAP). The translation procedure (e.g., during serialization) is simply the converse of the v1-to-v2 trap translation that is already done by WinSNMP implementations when v1traps are received and presented to the application. The steps are defined in Section 3.3 of RFC 2089, "V2ToV1 Mapping SNMPv2 onto SNMPv1 within a bi-lingual SNMP agent" by Bert Wijnen and David Levi. From an implementation perspective, it is straight-forward and rather easy to implement. From an application developer perspective, eliminating the need for the application to know/care about differences in v1 vs v2 traps enormously simplifies the application. The bottom line is that this approach preserves the "single interface / bilingual protocol" value proposition that WinSNMP was founded on. It also eliminates the need for a new / additional function in the WinSNMP API. 7. Notification port usage The term "notification" as used here applies to both traps (SNMPv1 and SNMPv2c) and informs (SNMPv2c only). Trap mapping between entities of different SNMP versions is described above. Important details wrt Inform requests are given in Section II.13, "Inform Processing", below. InformRequest-PDUs may only be sent to a destination entity that supports SNMPv2c. An attempt by an application to send an InformRequest-PDU to an SNMPv1 destination entity using SnmpSendMsg() results in SNMPAPI_FAILURE, with SnmpGetLastError() set to return SNMPAPI_OPERATION_INVALID. The well-known notification port for any protocol supported by an implementation (e.g., 162 for UDP and 36880 for IPX) should be held by an implementation of this WinSNMP API, if at all, only when there are active SnmpRegister() entries that might accept an incoming notification message. Where possible, an implementation should use some de facto or de jure standard "system service" for receiving notification messages to be dispatched to registered WinSNMP applications, such that other (non-WinSNMP) notification targets may operate concurrently with it. For Microsoft Windows NT, this standard mechanism is the "SNMPTRAP" system service. 8. Request-ID/SnmpCreatePdu()/SnmpSetPdu() Applications should specify "meaningful" Request-ID values via SnmpCreatePdu() and/or SnmpSetPduData(). Implementations will automatically assign an arbitrary Request-ID value when SnmpCreatePdu() is called without a specified Request-ID value (i.e., the value is zero). The SnmpSetPduData() function may be used by an application to assign any Request-ID value it wants, including a value of zero. Implementations must use the resulting Request-ID value at SnmpSendMsg() time to return the eventual Response-PDU or timeout notification (if a corresponding Response-PDU is not received) to the application. Note that the Request-ID used in the "on-the-wire" messages is assigned by the implementation independently and may or may not be the same as the Request-ID used at the application level for any given message. 9. SnmpGetPduData() and hVbl If an hVbl output parameter is specified on a call to SnmpGetPduData() it will return a new instance of the VarBindList associated with the corresponding hPdu. This behavior is consistent with both the basic purpose of SnmpGetPduData()--which is to de-reference the components of a received PDU--and a basic characteristic of all WinSNMP functions which return WinSNMP resource objects (sessions, entities, contexts, PDUs, and VarBindLists) as outputs... namely, each output represents a new "instance" (used loosely) of the object. Such a new "instance" may be either a new unique value for that object type or may correspond to some internal, implementation-specific mechanism (such as a "reference count"). The key underlying principle is that actual value of a WinSNMP resource object is not meaningful to the application, but is meaningful to the implementation. Applications need only be certain to match up each WinSNMP resource object creation operation with a corresponding "free" operation or, as may be appropriate, to free them via calls to SnmpClose() or SnmpCleanup(). 10. GetBulk -> GetNext mapping When the dstEntity used in an SnmpSendMsg() operation is an SNMPv1 entity and the PDU type is SNMP_PDU_GETBULK, the implementation must automatically and transparently modify the PDU type to SNMP_PDU_GETNEXT, per RFC 1908. Note that this "translation" occurs during serialization of the WinSNMP components (hContext, hPdu, and hVbl, in this case) into the SNMP message that will be transmitted. It does NOT alter the submitted components themselves. 11. IPX support in SnmpStrToEntity() WinSNMP v1 was highly oriented toward IP/UDP, but was not meant to exclude the compatible, symmetrical use of other transport protocols by specific implementations. As a result, some implementations accepted alternative string formats as arguments to SnmpStrToEntity()--when called by an application operating in "untranslated" mode--to signal the use of protocols other than UDP. In particular, the use of "" for the IPX protocol found a significant degree of usage. Hence, it is considered helpful to the community to specify a standard format for this purpose and to explicitly allow its use in SnmpStrToEntity(). This standard format consists of three collated parts: 1. A "network number" , consisting of eight hexadecimal digits (zero-filled, if necessary). 2. A separator (i.e., either ":" or "-"). 3. A "node number" , consisting of twelve hexadecimal digits (zero-filled, if necessary). For example: "00000001:00080A0D01C2" or: "00000001-00008A0D01C2" Note that SnmpEntityToStr() is also modified to return a properly formatted IPX address string, per above, for any IPX entity--when called by an application operating in "untranslated" mode at the time, or in "translated" mode but with no "friendlyName" value available. The ":" separator is the recommended default for use in the output string. 12. SnmpDecodeMsg() outputs This clarification has to do with return values for the hSrc and hDst output parameters. The key point is that an implementation cannot be required to supply information that is not unambiguously available to it. When WinSNMP v1 was designed, party-based SNMPv2 (since deprecated to "Historic" status) was being actively considered by the IETF. That form of the protocol might have included more address-type information in the encoded SNMP messages. If it had, then this information could have been used by the implementation of the SnmpDecodeMsg() function to instantiate hSrc and hDst entity values. However, the IETF adopted a different form of SNMPv2 (SNMPv2c, as defined in RFCs 1901-1908) and this form retains the same message format as SNMPv1 and that message format does not include the addressing information needed to properly create WinSNMP entity resources. Therefore, SnmpDecodeMsg() cannot return meaningful values for the hSrc or hDst parameter for SNMPv1 or SNMPv2 messages submitted to it and must return a value of zero in these output parameters. 13. Inform processing SNMPv2 Inform requests are only supported to a destination entity that supports SNMPv2. An attempt to send an Inform request to an SNMPv1 destination using SnmpSendMsg() must return SNMPAPI_FAILURE, with SnmpGetLastError() set to return SNMPAPI_OPERATION_INVALID. The implementation is responsible for generating and transmitting the (single) Response-PDU for any received InformRequest-PDU. Applications that receive an InformRequest-PDU via a WinSNMP session must not issue a corresponding Response-PDU. 14. Thread-safeness A multi-threaded application must ensure the thread-safeness of its own WinSNMP operations. The implementation must ensure "thread-safeness" at the application (process) level. That is, the implementation must ensure that the WinSNMP operations of one process do not unilaterally modify the WinSNMP settings of any other process. The WinSNMP operations that might merit attention on the part of a multi-threaded application are those which set application-level parameters. At this time, there are only two such settings: - SnmpSetTranslateMode() - SnmpSetRetransmitMode() It is often, not always, the case that an application-- multi-threaded or not--will operate with a single constant value for each of these settings, with this value normally being either the default supplied by the SnmpStartup() call or an application-specified value (via SnmpSetTranslateMode() and/or SnmpSetRetransmitMode()) before any calls to the WinSNMP entity or context creation functions (for "translate" mode) or calls to SnmpSendMsg() (for "retransmit" mode). Nonetheless, implementors providing WinSNMP for operating environments which support multi-threaded applications are encouraged to include guidance on this issue in their developer-oriented documentation. 15. WinSNMP++ -> SNMP++ change The embryonic WinSNMP++ appendix to the WinSNMP v1 specification has been deprecated and deleted from the WinSNMP v2 specification. Implementors are now directed to the open SNMP++ specification (and reference code) published by Hewlett- Packard (http://rosegarden.external.hp.com/snmp++). 16. SnmpRegister() The primary purpose of SnmpRegister() is to enable an application to indicate that it wants to receive traps that arrive at the default SNMP trap port(s) (UDP 162 and/or IPX 36880) on the local machine. This can be accomplished by passing the following parameter values in the call to SnmpRegister(): session - a valid session handle srcEntity - NULL dstEntity - NULL context - NULL notification - NULL status - SNMPAPI_ON This sequence of parameter values, assuming the call is otherwise successful, will result in all notifications (traps and informs) received by the WinSNMP implementation being delivered to the session. We will refer to the above setting as an "unfiltered" registration. A secondary purpose of SnmpRegister() is to function as a minimal "trap filter" on notifications received by the WinSNMP implementation. In this mode, non-NULL values for any combination of one or more of the srcEntity, dstEntity, context, or notification parameters, will be used to form a filter to be applied to traps received by the WinSNMP implementation for the indicated session. We will refer to any such operation as a "filtered" registration. Note that while an "unfiltered" registration is in effect for a session, it makes no sense to issue any "filtered" registration requests for that same session. They would be totally superfluous--since all notifications would already be delivered to the session anyway due to the "unfiltered" registration. This is one of three types of "redundant" registrations. Another type of "redundant" registration is a duplicate call to SnmpRegister()--that is, one in which the parameter list is identical to the parameter list used to instantiate an active registration for the same session. The third type of "redundant" registration is one in which the notification parameter (when dereferenced) fully contains (as a prefix) a notification parameter used on an active registration for the same session. This is redundant due to the wildcard interpretation of the notification parameter specified in the WinSNMP v1.1a spec. In all cases of "redundant" registrations, SnmpRegister() should return SNMPAPI_SUCCESS, since the action requested by the application--namely, to deliver the specified notifications to the indicated session--will be carried out. [Yes, we could have gone with SNMPAPI_FAILURE in these cases and setting SnmpGetLastError() to return SNMPAPI_NOOP, but the incidence of problems resulting form such "redundant" calls has proven to be close to zero in practice and, therefore, we are taking a more streamlined approach.] Also, note that such redundant "register" requests are idempotent, meaning that only a single corresponding "unregister" call is required. To "unregister" means to call SnmpRegister() with a status parameter value of SNMPAPI_OFF and with the first five parameters having the same effective values as some previously successful call with a status parameter of SNMPAPI_ON. Implementations do not maintain a "count" of redundant registrations that must be matched with an equal number of corresponding unregistrations. Of course, each unique (non-redundant) register must be matched with an unregister call to remove it, if desired by the application. III - New Functions: 1. SnmpCreateSession() The SnmpCreateSession() function is used to create a WinSNMP "session" and to specify the notification mode-either a "window/message" pair or callback function--that will be used for the session. With this function, Windows programmers now have the option of having the implementation use either the standard Windows message notification method (as in SnmpOpen()) or a direct callback into a session-specific function. As a by-product of this enhanced flexibility for Windows programmers, the WinSNMP API can now also be used in some non-Windows operating environments (some examples are given below). This function is a superset of the SnmpOpen() function. That is, when used to create a session with window/message notification, it provides the exact same functionality as SnmpOpen(). (Refer to the descriptive text for SnmpOpen() elsewhere in this alphabetical "Function Reference" chapter for more information.) Developers writing new applications for WinSNMP v2.0 are encouraged to use SnmpCreateSession() for all session creation, even when selecting the window/message notification mode (i.e., instead of using SnmpOpen()). Developers upgrading applications written for earlier versions of WinSNMP to take advantage of other WinSNMP v2.0 features are encouraged to change all SnmpOpen() calls to the equivalent form of SnmpCreateSession(). HSNMP_SESSION SnmpCreateSession (IN HWND hWnd, IN UINT wMsg, IN SNMPAPI_CALLBACK fCallBack, IN LPVOID lpClientData); WINSNMP.DEF category = Communications Functions; ordinal value = 220. Parameter Description hWnd Identifies a notification window. wMsg Identifies a notification message. fCallBack Identifies a notification callback function; may be NULL. lpClientData Identifies a pointer to optional application data to pass to the fCallBack function; may be NULL. Returns: If the SnmpCreateSession() function is successful, the return value is an HSNMP_SESSION handle which identifies the WinSNMP session opened by the implementation on behalf of the calling application. If the function fails, the return value is SNMPAPI_FAILURE and SnmpGetLastError() will be set to return extended error information as follows: SnmpGetLastError() Description "Common Error Codes" See Section 2.10.1. Common Error Codes. SNMPAPI_HWND_INVALID hWnd is not a valid window value. SNMPAPI_MSG_INVALID wMsg is not a valid message value. SNMPAPI_MODE_INVALID The combination of values passed is mutually incompatible or incomplete. SNMPAPI_OPERATION_INVALID The combination of values passed does not identify a valid notification mode for this implementation. As will be explained below, the conditions leading to any of the three specific error codes listed above are somewhat environment-specific. Comments: If fCallBack is NULL, SnmpCreateSession() is equivalent to the SnmpOpen() function. In this window/notification mode, the values of hWnd and wMsg must both be valid in the implementation's operating environment. If the value of hWnd is invalid, then the function returns SNMPAPI_FAILURE, and SnmpGetLastError() is set to return SNMPAPI_HWND_INVALID. Else, if the value of wMsg is invalid, then the function returns SNMPAPI_FAILURE, and SnmpGetLastError() is set to return SNMPAPI_WMSG_INVALID. Else, if both values are individually valid but are mutually incompatible in a given windowing environment, then the function returns SNMPAPI_FAILURE, and SnmpGetLastError() is set to return SNMPAPI_MODE_INVALID. If fCallBack is non-NULL, it represents the address of a function to be called whenever the implementation has a notification to deliver to the session. The notification may signal the presence of an SNMP message for the session or it may signal the existence of an asynchronous error condition (for example, a transport layer timeout error). (Refer to the discussion of "Retransmission and Timeout Notification" in the "Programming with WinSNMP" chapter and the descriptive text for SnmpRecvMsg() elsewhere in this alphabetical "Function Reference" chapter for more information.) When fCallBack is non-NULL, a given operating environment may require valid values for any or all of hWnd, wMsg, and/or lpClientData and should return one of the three function-specific error codes in a manner consistent with that outlined above. The callback function prototype must be: typedef SNMPAPI_STATUS (CALLBACK *SNMPAPI_CALLBACK)( IN HSNMP_SESSION session, IN HWND hWnd, IN UINT wMsg, IN WPARAM wParam, IN LPARAM lParam, IN LPVOID lpClientData); Parameter Description session Identifies the session being notified. hWnd Identifies the session's notification window. wMsg Identifies the session's notification message. wParam Identifies the purpose of the notification. lParam Identifies the RequestID of the subject PDU. lpClientData Identifies a pointer to optional application data, if such a pointer was specified in the session's SnmpCreateSession() call. Note: If fCallBack is non-NULL on a successful call to the SnmpCreateSession() function, then the session operates in callback notification mode and the values of hWnd and wMsg passed to the SnmpCreateSession() function may or may not be significant depending upon the operating environment, but are always passed to the callback function for its possible use. Note: If a callback function has been assigned to a session in this manner, then upon receipt of an SNMP message for the session the implementation will call the callback function-- instead of sending the wMsg notification message to the hWnd as it would in the window/message notification mode--and pass it the session identifier and two values representing the wParam and lParam values that would have been used if operating in the window/message notification mode. (See the descriptive text for the SnmpOpen() function elsewhere in the alphabetical "Function Reference" chapter for additional background information.) Note: The fCallBack function must return SNMPAPI_SUCCESS to indicate continued viability. Any other returned value will be interpreted as SNMPAPI_FAILURE and will result in the implementation doing an implicit SnmpClose() operation on the session. Note: If the fCallBack parameter to SnmpCreateSession() is NULL, any non-NULL value of lpClientData is meaningless and, therefore, will be ignored by the implementation. Note: When the callback function is called for the purpose of notifying the session of the presence of an SNMP message for it, the value passed for wParam must be 0. Otherwise, any non-zero value of wParam will signal an asynchronous error notification for the session. The most common example of such an error notification is a "no response from agent" timeout when the implementation is executing retransmission policy for the application; in which case, the value of wParam will be SNMPAPI_TL_TIMEOUT [108]. The value passed in the lParam parameter will always indicate the RequestID of the affected PDU. (See the descriptive text for the SnmpRecvMsg() function elsewhere in the alphabetical "Function Reference" chapter for more information about the general use of these two parameters.) Following are some sample calling modes for different operating environments: MS-Windows, Window/Message notification mode: hSession = SnmpCreateSession (myWnd, myMsg, NULL, NULL); MS-Windows, Callback notification mode: hSession = SnmpCreateSession (0, 0, myFunc, ); UNIX X-Windows, Callback notification mode: hSession = SnmpCreateSession (myWnd, 0, myFunc, ); Any non-window Command Line Environment, Callback mode: hSession = SnmpCreateSession (0, 0, myFunc, ); Note: The first example above is equivalent to a standard WinSNMP SnmpOpen() call. Note: For non-MS-Windows operating environments, implementors may (and will likely have to) supply definitions for the Windows-specific data types used in the standard WinSNMP.h file, which originate from (which is #include'd in WinSNMP.h). A possible example of a "windows.h" file for a generic X-Windows operating environment follows: // windows.h // #include'd in WinSNMP.h // typedef's for the SnmpCreateSession function typedef XtAppContext HWND; // X-Window id typedef unsigned int UINT; // Not used typedef void *CALLBACK; // Callback function typedef void *LPVOID; // Callback user data // additional typedef's for the fCallBack prototype typedef unsigned int WPARAM; // Notification code typedef unsigned int LPARAM; // RequestID See also: SnmpOpen() and SnmpRecvMsg() in the alphabetical function reference section, and "Retransmission and Timeout Notification" in the "Programming with WinSNMP" section. 2. SnmpCreateEntity() Due to the on-going work in the IETF SNMPv3 WG, this function will be deferred to the WinSNMP v3 time frame. This "placeholder" is being retained here as a signal to interested parties to monitor the SNMPv3 output for future incorporation in WinSNMP v3. 3. SnmpCreateContext() Due to the on-going work in the IETF SNMPv3 WG, this function will be deferred to the WinSNMP v3 time frame. This "placeholder" is being retained here as a signal to interested parties to monitor the SNMPv3 output for future incorporation in WinSNMP v3. 4. SnmpCancelMsg() The SnmpCancelMsg() function requests cancellation of any further retransmissions or timeout notification for the PDU identified by the requestId parameter for the specified session. SNMPAPI_STATUS SnmpCancelMsg (IN HSNMP_SESSION session, IN smiINT32 requestId); WINSNMP.DEF category = Communications Functions; ordinal value = @222. Parameter Description session Identifies the session which submitted the message to be canceled. requestId Identifies the Request-ID value of the hPdu used in the corresponding call to SnmpSendMsg(). Returns: If the function executes successfully, the return value is SNMPAPI_SUCCESS. If the function fails, the return value is SNMPAPI_FAILURE. Use SnmpGetLastError() to obtain extended error information. SnmpGetLastError() Description SNMPAPI_SESSION_INVALID The session parameter is invalid. SNMPAPI_PDU_INVALID The requestId parameter does not identify a message with outstanding retransmissions for the specified session. Comments: Successful execution of this function is analogous to setting RetransmitMode to SNMPAPI_OFF for the affected message. Note: Applications must be aware that--due to transaction queuing at various levels--it is possible that the subject destination entity may still receive and/or respond to a corresponding SNMP message even following successful execution of SnmpCancelMsg(). But the implementation must not transmit any retries or submit a Response-PDU or timeout notification to the application for the subject message following successful execution of this function. Note: Successful execution of this function applies to a single message instance. This point illustrates another reason why applications should use "meaningful" Request-ID values for their respective PDUs. Note: Implementations must effectively execute SnmpCancelMsg() on any outstanding messages for a session when SnmpClose() is called, whether directly or indirectly via SnmpCleanup(). 5. SnmpSetPort() The SnmpSetPort() function permits an application to change the port assignment of a given destination entity. SNMPAPI_STATUS SNMPAPI_CALL SnmpSetPort (IN HSNMP_ENTITY hEntity, IN UINT nPort); WINSNMP.DEF category = Entity/Context Functions; ordinal value = @320. Note: "Destination entity" includes entities used as agent applications via the local WinSNMP implementation (see Section III.6, "SnmpListen()", below). Note: If the hEntity parameter identifies an entity which is already operating in an agent mode for this application (via the new SnmpListen() function outlined below), then this function will return SNMPAPI_FAILURE, with SnmpGetLastError() set to return SNMPAPI_ENTITY_INVALID, since such an entity is already bound to a port. The proper sequence of events for such an entity is: hAgent = SnmpStrToEntity (hSession, ); lStatus = SnmpSetPort (hAgent, ); lStatus = SnmpListen (hAgent, SNMPAPI_ON); The implementation will have "assigned" a port value to the entity as part of the SnmpStrToEntity() operation. This will normally be the standard SNMP request port for the respective protocol family (e.g., UDP 161 or IPX 36879) for an entity created in "untranslated" mode or whatever may be specified in the local database for an entity created in "translated" mode. So, if the agent is to listen on a different port, or just to be safe, the app can use SnmpSetPort() to arrange that. 6. SnmpListen() This new function permits the "attachment" of an agent application using the [local] address and port settings in effect for the hEntity parameter. SNMPAPI_STATUS SNMPAPI_CALL SnmpListen (IN HSNMP_ENTITY hEntity, IN SNMPAPI_STATUS lStatus); WINSNMP.DEF category = Communications Functions; ordinal value = @221. "hEntity" will indicate the session to be notified (via callback or window/message) when an in-coming request is received for this agent application, and the address family, interface address, and port to use for this "agent". Note that all of these attributes already exist as aspects of a WinSNMP "entity". "lStatus" will take either of two values: SNMPAPI_ON or SNMPAPI_OFF. If it is SNMPAPI_ON, all else passing, the "agent" will then bind to its af:addr:port and listen for incoming requests, which will be transferred to it via the normal WinSNMP mechanisms. It will then "do its thing" with the request, form the response, reverse the srcEntity and dstEntity parameters it received on the SnmpRecvMsg() call, and transmit the response back to the requester via SnmpSendMsg(). If the entity's port is already in use, the call to SnmpListen() will fail with an appropriate error via SnmpGetLastError(). When an entity no longer wants to function as an agent, it should call SnmpListen() with an "lStatus" value of SNMPAPI_OFF to release the port (and other resources). Both SnmpClose() for the session and SnmpCleanup() for the app must release all affected agent ports. 7. SnmpGetVendorInfo() This new function returns vendor identification information to the application using a new structure defined in winsnmp.h: #define MAXVENDORINFO 32 typedef struct { char vendorName[MAXVENDORINFO*2]; char vendorContact[MAXVENDORINFO*2]; char vendorVersionId[MAXVENDORINFO]; char vendorVersionDate[MAXVENDORINFO]; smiUINT32 vendorEnterprise; } smiVENDORINFO, FAR *smiLPVENDORINFO; SNMPAPI_STATUS SNMPAPI_CALL SnmpGetVendorInfo (OUT smiLPVENDORINFO vendorInfo); WINSNMP.DEF category = Local Database Functions; ordinal value = @120. If vendorInfo is NULL, the return value is SNMPAPI_FAILURE with SnmpGetLastError() set to return SNMPAPI_NOOP. Upon successful return from this function, the four "char" fields should contain NULL-terminated text strings suitable for output on a display device. The content of these fields is vendor-determined, but should provide information helpful to end-users in the event of a problem, if displayed by an application. For example, "vendorContact" could include a physical or postal address, telephone and/or fax numbers, an e-mail address or a URL. If a vendor has an IANA-issue enterprise number, then it should be returned as the value of vendorEnterprise; otherwise, its value must be zero. 8. SnmpOpen() [Note: Modified for clarity wrt SnmpCreateSession(), which is new for WinSNMP v2.] [Do_Box] Important: WinSNMP v2.0 added the SnmpCreateSession() function which provides a superset of the SnmpOpen() functionality. Developers are encouraged to use SnmpCreateSession() instead of SnmpOpen(). SnmpOpen() is maintained for backwards compatibility with pre-v2.0 WinSNMP applications, but some (non-Windows) implementations may return SNMPAPI_OPERATION_INVALID in response to any SnmpOpen() call, as described below. [End_Box] The SnmpOpen() function enables the implementation to allocate and initialize memory, resources, and/or communications mechanisms and data structures for the application. The application will continue to use the "session identifier" returned by the implementation in subsequent WinSNMP function calls to facilitate resource accounting on a per session basis. This mechanism enables the implementation to perform an orderly release of resources in response to a subsequent SnmpClose() function call for a given session (or in response to a subsequent SnmpCleanup() call for the application). Syntax: HSNMP_SESSION SnmpOpen ( IN HWND hWnd, IN UINT wMsg); Parameter Description hWnd Identifies the application's notification window. wMsg Identifies the application's notification message. Returns: If the function is successful, the return value is a non- zero HSNMP_SESSION value which identifies the WinSNMP session opened by the implementation on behalf of the calling application. If the function fails, the return value is SNMPAPI_FAILURE. Use the SnmpGetLastError() function to obtain extended error information. SnmpGetLastError() Description "Common Error Codes" See Section 2.10.1. Common Error Codes. SNMPAPI_HWND_INVALID The hWnd parameter is not a valid window handle. SNMPAPI_OPERATION_INVALID This implementation does not support the Windows/Message notification scheme (see SnmpCreateSession()). Comments: See Section 2.5. Sessions and Section SnmpCreateSession(). An application can open multiple sessions. Each such session for the same hWnd should provide a different wMsg, but this is not required. A successful SnmpOpen() call always returns a unique HSNMP_SESSION value (with respect to all other currently open sessions for the calling application). The hWnd parameter specifies the window to be notified when an asynchronous request completes or trap/notification occurs and the wMsg parameter specifies the message number that the implementation will send to the window. Upon receipt of this message, - If the wParam component of the notification message is zero (0), the application should call SnmpRecvMsg() to retrieve the subject PDU for immediate or subsequent processing. - If the wParam component of the notification message is non-zero, it will represent a WinSNMP API error code (e.g., SNMPAPI_TL_TIMEOUT) referring to the PDU identified by the Request_Id value in the lParam component. In this case, the application should react to the error condition and should not call SnmpRecvMsg(). In other programming models (e.g., synchronous, CLI-driven, or "curtained" applications), the WinSNMP implementation may interpret hWnd and hMsg differently. Likewise, the session model may be used to facilitate multi-threaded programming in supporting environments. The SnmpCreateSession() function has been added to WinSNMP v2.0 to formalize such usage. Note: A well-behaved WinSNMP application will call SnmpClose() for each session opened with SnmpOpen(). When an emergency exit is required by the application, it must at least call SnmpCleanup(). A well-behaved WinSNMP implementation must react to an SnmpCleanup() call as though it were a series of SnmpClose() calls for each open session allocated to the calling application.