mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
934 lines
22 KiB
934 lines
22 KiB
/*++
|
|
|
|
Copyright (c) 1992-1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
pduapi.c
|
|
|
|
Abstract:
|
|
|
|
Performs all functions to encode/decode a RFC 1157 PDU and trap.
|
|
|
|
Environment:
|
|
|
|
User Mode - Win32
|
|
|
|
Revision History:
|
|
|
|
10-May-1996 DonRyan
|
|
Removed banner from Technology Dynamics, Inc.
|
|
|
|
--*/
|
|
|
|
//--------------------------- WINDOWS DEPENDENCIES --------------------------
|
|
|
|
//--------------------------- STANDARD DEPENDENCIES -- #include<xxxxx.h> ----
|
|
|
|
#include <stdlib.h>
|
|
|
|
//--------------------------- MODULE DEPENDENCIES -- #include"xxxxx.h" ------
|
|
|
|
#include <snmp.h>
|
|
#include <snmputil.h>
|
|
|
|
#include "berapi.h"
|
|
|
|
//--------------------------- SELF-DEPENDENCY -- ONE #include"module.h" -----
|
|
|
|
#include "pduapi.h"
|
|
|
|
//--------------------------- PUBLIC VARIABLES --(same as in module.h file)--
|
|
|
|
//--------------------------- PRIVATE CONSTANTS -----------------------------
|
|
|
|
#define PDU_ERRORSTATUS_LAST SNMP_ERRORSTATUS_GENERR
|
|
#define PDU_GENERICTRAP_LAST SNMP_GENERICTRAP_ENTERSPECIFIC
|
|
|
|
//--------------------------- PRIVATE STRUCTS -------------------------------
|
|
|
|
//--------------------------- PRIVATE VARIABLES -----------------------------
|
|
|
|
//--------------------------- PRIVATE PROTOTYPES ----------------------------
|
|
|
|
void PDU_ReleasePDU(
|
|
RFC1157Pdu *pdu // PDU to release
|
|
);
|
|
|
|
void PDU_ReleaseTrap(
|
|
RFC1157TrapPdu *pdu // Trap to release
|
|
);
|
|
|
|
//--------------------------- PRIVATE PROCEDURES ----------------------------
|
|
|
|
//--------------------------- PUBLIC PROCEDURES -----------------------------
|
|
|
|
//
|
|
// SnmpPduEncodePdu:
|
|
// Encode a RFC1157 PDU.
|
|
//
|
|
// Notes:
|
|
// The encoded PDU is left in reverse order so the rest of the message
|
|
// information can be appended to the buffer, and then reversed.
|
|
//
|
|
// The buffer information must be initialized prior to calling this routine.
|
|
//
|
|
// If an error occurs, the entire buffer is freed, and set to NULL.
|
|
//
|
|
// Return Codes:
|
|
// SNMPAPI_NOERROR
|
|
// SNMPAPI_ERROR
|
|
//
|
|
// Error Codes:
|
|
// SNMP_PDUAPI_INVALID_ES
|
|
//
|
|
SNMPAPI SnmpPduEncodePdu(
|
|
IN BYTE nType, // Type of RFC 1157 PDU to encode
|
|
IN RFC1157Pdu *pdu, // RFC 1157 PDU to encode into stream buffer
|
|
IN OUT BYTE **pBuffer, // Stream buffer to accept encoding
|
|
IN OUT UINT *nLength // Length of stream buffer
|
|
)
|
|
|
|
{
|
|
SNMPAPI nResult;
|
|
UINT nBufStart;
|
|
int I;
|
|
|
|
|
|
// Check for valid error status
|
|
if ( pdu->errorStatus > PDU_ERRORSTATUS_LAST )
|
|
{
|
|
SetLastError( SNMP_PDUAPI_INVALID_ES );
|
|
nResult = SNMPAPI_ERROR;
|
|
|
|
goto Exit;
|
|
}
|
|
|
|
// Save start position of buffer
|
|
nBufStart = *nLength;
|
|
|
|
// Encode var binds
|
|
for ( I=pdu->varBinds.len-1;I >= 0;I-- )
|
|
{
|
|
UINT nSeqStart;
|
|
|
|
|
|
// Save starting point of sequence
|
|
nSeqStart = *nLength;
|
|
|
|
// Encode variable value
|
|
if ( SNMPAPI_ERROR ==
|
|
SnmpBerEncodeAsnAny(&pdu->varBinds.list[I].value,
|
|
pBuffer, nLength) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Encode variable name
|
|
if ( SNMPAPI_ERROR ==
|
|
SnmpBerEncodeAsnObjectId(ASN_OBJECTIDENTIFIER,
|
|
&pdu->varBinds.list[I].name,
|
|
pBuffer, nLength) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Encode the entire variable info. as a sequence
|
|
if ( SNMPAPI_ERROR ==
|
|
SnmpBerEncodeAsnSequence(*nLength - nSeqStart,
|
|
pBuffer, nLength) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
// Encode the var bind list as a sequence of 'sequence's
|
|
if ( SNMPAPI_ERROR ==
|
|
SnmpBerEncodeAsnImplicitSeq(ASN_SEQUENCEOF, *nLength - nBufStart,
|
|
pBuffer, nLength) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Encode error-index
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerEncodeAsnInteger(ASN_INTEGER,
|
|
pdu->errorIndex,
|
|
pBuffer, nLength)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Encode error-status
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerEncodeAsnInteger(ASN_INTEGER,
|
|
pdu->errorStatus,
|
|
pBuffer, nLength)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Encode request-id
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerEncodeAsnInteger(ASN_INTEGER,
|
|
pdu->requestId,
|
|
pBuffer, nLength)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Encode entire pdu as Implicit Sequence
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerEncodeAsnImplicitSeq(nType, *nLength - nBufStart,
|
|
pBuffer, nLength)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
if ( nResult == SNMPAPI_ERROR )
|
|
{
|
|
SnmpUtilMemFree( *pBuffer );
|
|
|
|
*pBuffer = NULL;
|
|
*nLength = 0;
|
|
}
|
|
|
|
return nResult;
|
|
} // SnmpPduEncodePdu
|
|
|
|
|
|
|
|
//
|
|
// SnmpPduDecodePdu
|
|
// Decode a PDU.
|
|
//
|
|
// Notes:
|
|
//
|
|
// Return Codes:
|
|
// SNMPAPI_NOERROR
|
|
// SNMPAPI_ERROR
|
|
//
|
|
// Error Codes:
|
|
// SNMP_MEM_ALLOC_ERROR
|
|
// SNMP_PDUAPI_INVALID_ES
|
|
//
|
|
SNMPAPI SnmpPduDecodePdu(
|
|
IN BYTE nType, // Type of RFC 1157 PDU to decode
|
|
OUT RFC1157Pdu *pdu, // RFC 1157 PDU to accept decoding
|
|
IN OUT BYTE **pBuffer, // Stream buffer to decode
|
|
IN OUT UINT *nLength // Length of stream buffer
|
|
)
|
|
|
|
{
|
|
UINT BufLen;
|
|
BYTE *BufPtr;
|
|
AsnAny pResult;
|
|
SNMPAPI nResult;
|
|
|
|
|
|
// Initialize variable bindings' list
|
|
pdu->varBinds.list = NULL;
|
|
pdu->varBinds.len = 0;
|
|
|
|
// process the sequence encapsuling the PDU
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerDecodeAsnStream(nType, pBuffer, nLength, &pResult)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Make copy of sequence information
|
|
BufPtr = pResult.asnValue.sequence.stream;
|
|
BufLen = pResult.asnValue.sequence.length;
|
|
|
|
// Decode request-id
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerDecodeAsnStream(ASN_INTEGER, &BufPtr,
|
|
&BufLen, &pResult)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Save request-id
|
|
pdu->requestId = pResult.asnValue.number;
|
|
|
|
// Decode error-status
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerDecodeAsnStream(ASN_INTEGER, &BufPtr,
|
|
&BufLen, &pResult)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Save error-status
|
|
pdu->errorStatus = pResult.asnValue.number;
|
|
|
|
// Check for valid error status
|
|
if ( pdu->errorStatus > PDU_ERRORSTATUS_LAST )
|
|
{
|
|
SetLastError( SNMP_PDUAPI_INVALID_ES );
|
|
nResult = SNMPAPI_ERROR;
|
|
|
|
goto Exit;
|
|
}
|
|
|
|
// Decode error-index
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerDecodeAsnStream(ASN_INTEGER, &BufPtr,
|
|
&BufLen, &pResult)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Save error-status
|
|
pdu->errorIndex = pResult.asnValue.number;
|
|
|
|
// Decode variable-bindings' sequence
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerDecodeAsnStream(ASN_SEQUENCEOF, &BufPtr,
|
|
&BufLen, &pResult)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Make temps of sequence data
|
|
BufLen = pResult.asnValue.sequence.length;
|
|
BufPtr = pResult.asnValue.sequence.stream;
|
|
|
|
// Gather variables and save in pdu list
|
|
while ( BufLen )
|
|
{
|
|
BYTE *VarBufPtr;
|
|
UINT VarBufLen;
|
|
|
|
|
|
// Alloc space for variable binding
|
|
pdu->varBinds.list = (RFC1157VarBind *) SnmpUtilMemReAlloc( pdu->varBinds.list,
|
|
((pdu->varBinds.len+1)*sizeof(RFC1157VarBind)) );
|
|
|
|
// Check for errors on alloc
|
|
if ( pdu->varBinds.list == NULL )
|
|
{
|
|
SetLastError( SNMP_MEM_ALLOC_ERROR );
|
|
|
|
nResult = SNMPAPI_ERROR;
|
|
goto Exit;
|
|
}
|
|
|
|
// Decode sequence of info
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerDecodeAsnStream(ASN_SEQUENCE,
|
|
&BufPtr, &BufLen, &pResult)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Setup variable bindings' buffer
|
|
VarBufPtr = pResult.asnValue.sequence.stream;
|
|
VarBufLen = pResult.asnValue.sequence.length;
|
|
|
|
// Decode name
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerDecodeAsnStream(ASN_OBJECTIDENTIFIER, &VarBufPtr,
|
|
&VarBufLen, &pResult)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Save name of variable
|
|
// This is a non-standard copy - MS C specific
|
|
pdu->varBinds.list[pdu->varBinds.len].name = pResult.asnValue.object;
|
|
|
|
// Get ASN Type
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerQueryAsnType(VarBufPtr, VarBufLen)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Decode value
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerDecodeAsnStream( (BYTE)nResult,
|
|
&VarBufPtr, &VarBufLen,
|
|
&pdu->varBinds.list[pdu->varBinds.len++].value)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
if ( nResult == SNMPAPI_ERROR )
|
|
{
|
|
PDU_ReleasePDU( pdu );
|
|
}
|
|
|
|
return nResult;
|
|
} // SnmpPduDecodePdu
|
|
|
|
|
|
|
|
//
|
|
// SnmpPduEncodeTrap:
|
|
// The encoded TRAP is left in reverse order so the rest of the message
|
|
// information can be appended to the buffer, and then reversed.
|
|
//
|
|
// Notes:
|
|
// The buffer information must be initialized prior to calling this routine.
|
|
//
|
|
// If an error occurs, the entire buffer is freed and set to NULL.
|
|
//
|
|
// Return Codes:
|
|
// SNMPAPI_NOERROR
|
|
// SNMPAPI_ERROR
|
|
//
|
|
// Error Codes:
|
|
// SNMP_PDUAPI_INVALID_GT
|
|
//
|
|
SNMPAPI SnmpPduEncodeTrap(
|
|
IN BYTE nType, // Type of RFC 1157 TRAP to encode
|
|
IN RFC1157TrapPdu *pdu, // RFC 1157 Trap to encode into stream buffer
|
|
IN OUT BYTE **pBuffer, // Stream buffer to accept encoding
|
|
IN OUT UINT *nLength // Length of stream buffer
|
|
)
|
|
|
|
{
|
|
SNMPAPI nResult;
|
|
UINT nBufStart;
|
|
int I;
|
|
|
|
|
|
// Check for valid generic trap
|
|
if ( pdu->genericTrap > PDU_GENERICTRAP_LAST )
|
|
{
|
|
SetLastError( SNMP_PDUAPI_INVALID_GT );
|
|
nResult = SNMPAPI_ERROR;
|
|
|
|
goto Exit;
|
|
}
|
|
|
|
// Save start position of buffer
|
|
nBufStart = *nLength;
|
|
|
|
// Encode var binds
|
|
for( I=pdu->varBinds.len-1;I >= 0;I-- )
|
|
{
|
|
UINT nSeqStart;
|
|
|
|
|
|
// Save starting point of sequence
|
|
nSeqStart = *nLength;
|
|
|
|
// Encode variable value
|
|
if ( SNMPAPI_ERROR ==
|
|
SnmpBerEncodeAsnAny(&pdu->varBinds.list[I].value,
|
|
pBuffer, nLength) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Encode variable name
|
|
if ( SNMPAPI_ERROR ==
|
|
SnmpBerEncodeAsnObjectId(ASN_OBJECTIDENTIFIER,
|
|
&pdu->varBinds.list[I].name,
|
|
pBuffer, nLength) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Encode the entire variable info. as a sequence
|
|
if ( SNMPAPI_ERROR ==
|
|
SnmpBerEncodeAsnSequence(*nLength - nSeqStart,
|
|
pBuffer, nLength) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
// Encode the var bind list as a sequence of 'sequence's
|
|
if ( SNMPAPI_ERROR ==
|
|
SnmpBerEncodeAsnImplicitSeq(ASN_SEQUENCEOF, *nLength - nBufStart,
|
|
pBuffer, nLength) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Encode time-stamp
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerEncodeAsnInteger(ASN_RFC1155_TIMETICKS,
|
|
pdu->timeStamp,
|
|
pBuffer, nLength)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Encode specific-trap
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerEncodeAsnInteger(ASN_INTEGER,
|
|
pdu->specificTrap,
|
|
pBuffer, nLength)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Encode generic-trap
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerEncodeAsnInteger(ASN_INTEGER,
|
|
pdu->genericTrap,
|
|
pBuffer, nLength)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Encode agent-addr
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerEncodeAsnOctetStr(ASN_RFC1155_IPADDRESS,
|
|
&pdu->agentAddr,
|
|
pBuffer, nLength)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Encode enterprise
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerEncodeAsnObjectId(ASN_OBJECTIDENTIFIER,
|
|
&pdu->enterprise,
|
|
pBuffer, nLength)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Encode entire pdu as Implicit Sequence
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerEncodeAsnImplicitSeq(nType,
|
|
*nLength - nBufStart,
|
|
pBuffer, nLength)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
if ( nResult == SNMPAPI_ERROR )
|
|
{
|
|
SnmpUtilMemFree( *pBuffer );
|
|
|
|
*pBuffer = NULL;
|
|
*nLength = 0;
|
|
}
|
|
|
|
return nResult;
|
|
} // SnmpPduEncodeTrap
|
|
|
|
|
|
|
|
//
|
|
// SnmpPduDecodeTrap:
|
|
// Decode a TRAP.
|
|
//
|
|
// Notes:
|
|
//
|
|
// Return Codes:
|
|
// SNMPAPI_NOERROR
|
|
// SNMPAPI_ERROR
|
|
//
|
|
// Error Codes:
|
|
// SNMP_MEM_ALLOC_ERROR
|
|
// SNMP_PDUAPI_INVALID_GT
|
|
//
|
|
SNMPAPI SnmpPduDecodeTrap(
|
|
IN BYTE nType, // Type of RFC 1157 TRAP to decode
|
|
OUT RFC1157TrapPdu *pdu, // RFC 1157 Trap to accept decoding
|
|
IN OUT BYTE **pBuffer, // Stream buffer to decode
|
|
IN OUT UINT *nLength // Length of stream buffer
|
|
)
|
|
|
|
{
|
|
UINT BufLen;
|
|
BYTE *BufPtr;
|
|
AsnAny pResult;
|
|
SNMPAPI nResult;
|
|
|
|
|
|
// Initialize variable bindings' list
|
|
pdu->enterprise.ids = NULL;
|
|
pdu->varBinds.list = NULL;
|
|
pdu->varBinds.len = 0;
|
|
|
|
// process the sequence encapsuling the PDU
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerDecodeAsnStream(nType, pBuffer, nLength, &pResult)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Make copy of sequence information
|
|
BufPtr = pResult.asnValue.sequence.stream;
|
|
BufLen = pResult.asnValue.sequence.length;
|
|
|
|
// Decode enterprise
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerDecodeAsnStream(ASN_OBJECTIDENTIFIER, &BufPtr,
|
|
&BufLen, &pResult)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// This is a non-standard structure copy
|
|
pdu->enterprise = pResult.asnValue.object;
|
|
|
|
// Decode agent-addr
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerDecodeAsnStream(ASN_RFC1155_IPADDRESS, &BufPtr,
|
|
&BufLen, &pResult)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// This is a non-standard structure copy
|
|
pdu->agentAddr = pResult.asnValue.string;
|
|
|
|
// Decode generic-trap
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerDecodeAsnStream(ASN_INTEGER, &BufPtr,
|
|
&BufLen, &pResult)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
pdu->genericTrap = pResult.asnValue.number;
|
|
|
|
// Check for valid generic trap
|
|
if ( pdu->genericTrap > PDU_GENERICTRAP_LAST )
|
|
{
|
|
SetLastError( SNMP_PDUAPI_INVALID_GT );
|
|
nResult = SNMPAPI_ERROR;
|
|
|
|
goto Exit;
|
|
}
|
|
|
|
// Decode specific-trap
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerDecodeAsnStream(ASN_INTEGER, &BufPtr,
|
|
&BufLen, &pResult)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
pdu->specificTrap = pResult.asnValue.number;
|
|
|
|
// Decode time-stamp
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerDecodeAsnStream(ASN_RFC1155_TIMETICKS, &BufPtr,
|
|
&BufLen, &pResult)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
pdu->timeStamp = pResult.asnValue.number;
|
|
|
|
// Decode variable-bindings' sequence
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerDecodeAsnStream(ASN_SEQUENCEOF, &BufPtr,
|
|
&BufLen, &pResult)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Make temps of sequence data
|
|
BufLen = pResult.asnValue.sequence.length;
|
|
BufPtr = pResult.asnValue.sequence.stream;
|
|
|
|
// Gather variables and save in pdu list
|
|
while ( BufLen )
|
|
{
|
|
BYTE *VarBufPtr;
|
|
UINT VarBufLen;
|
|
|
|
|
|
// Alloc space for variable binding
|
|
pdu->varBinds.list = (RFC1157VarBind *) SnmpUtilMemReAlloc( pdu->varBinds.list,
|
|
((pdu->varBinds.len+1)*sizeof(RFC1157VarBind)) );
|
|
|
|
// Check for errors on alloc
|
|
if ( pdu->varBinds.list == NULL )
|
|
{
|
|
SetLastError( SNMP_MEM_ALLOC_ERROR );
|
|
|
|
nResult = SNMPAPI_ERROR;
|
|
goto Exit;
|
|
}
|
|
|
|
// Decode sequence of info
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerDecodeAsnStream(ASN_SEQUENCE,
|
|
&BufPtr, &BufLen, &pResult)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Setup variable bindings' buffer
|
|
VarBufPtr = pResult.asnValue.sequence.stream;
|
|
VarBufLen = pResult.asnValue.sequence.length;
|
|
|
|
// Decode name
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerDecodeAsnStream(ASN_OBJECTIDENTIFIER, &VarBufPtr,
|
|
&VarBufLen, &pResult)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Save name of variable
|
|
// This is a non-standard copy - MS C specific
|
|
pdu->varBinds.list[pdu->varBinds.len].name = pResult.asnValue.object;
|
|
|
|
// Decode value
|
|
if ( SNMPAPI_ERROR ==
|
|
(nResult = SnmpBerDecodeAsnStream(
|
|
(BYTE)SnmpBerQueryAsnType(VarBufPtr, VarBufLen),
|
|
&VarBufPtr, &VarBufLen,
|
|
&pdu->varBinds.list[pdu->varBinds.len++].value)) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
if ( nResult == SNMPAPI_ERROR )
|
|
{
|
|
PDU_ReleaseTrap( pdu );
|
|
}
|
|
|
|
return nResult;
|
|
} // SnmpPduDecodePdu
|
|
|
|
|
|
|
|
//
|
|
// SnmpPduEncodeAnyPdu
|
|
// Determines the type of PDU to encode (PDU or TRAP) and calls the
|
|
// appropriate routine to do it.
|
|
//
|
|
// Notes:
|
|
// If the pdu type is unrecognized, this is an error and the buffer info.
|
|
// is freed.
|
|
//
|
|
// Return Codes:
|
|
// SNMPAPI_NOERROR
|
|
// SNMPAPI_ERROR
|
|
//
|
|
// Error Codes:
|
|
// SNMP_PDUAPI_UNRECOGNIZED_PDU
|
|
//
|
|
SNMPAPI SnmpPduEncodeAnyPdu(
|
|
RFC1157Pdus *pdu, // PDU/TRAP to Encode
|
|
IN OUT BYTE **pBuffer, // Buffer to accept encoding
|
|
IN OUT UINT *nLength // Length of buffer
|
|
)
|
|
|
|
{
|
|
SNMPAPI nResult;
|
|
|
|
|
|
// Encode PDU/TRAP
|
|
switch ( pdu->pduType )
|
|
{
|
|
case ASN_RFC1157_GETREQUEST:
|
|
case ASN_RFC1157_GETNEXTREQUEST:
|
|
case ASN_RFC1157_GETRESPONSE:
|
|
case ASN_RFC1157_SETREQUEST:
|
|
nResult = SnmpPduEncodePdu( pdu->pduType, &pdu->pduValue.pdu,
|
|
pBuffer, nLength );
|
|
break;
|
|
|
|
case ASN_RFC1157_TRAP:
|
|
nResult = SnmpPduEncodeTrap( pdu->pduType, &pdu->pduValue.trap,
|
|
pBuffer, nLength );
|
|
break;
|
|
|
|
default:
|
|
SetLastError( SNMP_PDUAPI_UNRECOGNIZED_PDU );
|
|
|
|
nResult = SNMPAPI_ERROR;
|
|
}
|
|
|
|
if ( nResult == SNMPAPI_ERROR )
|
|
{
|
|
SnmpUtilMemFree( *pBuffer );
|
|
|
|
*pBuffer = NULL;
|
|
*nLength = 0;
|
|
}
|
|
|
|
return nResult;
|
|
} // SnmpPduEncodeAnyPdu
|
|
|
|
|
|
|
|
//
|
|
// SnmpPduDecodeAnyPdu
|
|
// Determines and sets the type of PDU to decode (PDU or TRAP) and calls the
|
|
// appropriate routine to do it.
|
|
//
|
|
// Notes:
|
|
//
|
|
// Return Codes:
|
|
// SNMPAPI_NOERROR
|
|
// SNMPAPI_ERROR
|
|
//
|
|
// Error Codes:
|
|
// SNMP_PDUAPI_UNRECOGNIZED_PDU
|
|
//
|
|
SNMPAPI SnmpPduDecodeAnyPdu(
|
|
OUT RFC1157Pdus *pdu, // Will accept PDU or TRAP as result
|
|
IN OUT BYTE **pBuffer, // Stream buffer to decode
|
|
IN OUT UINT *nLength // Length of stream buffer
|
|
)
|
|
|
|
{
|
|
SNMPAPI nResult;
|
|
|
|
|
|
// Get pdu type
|
|
if ( SNMPAPI_ERROR ==
|
|
(pdu->pduType = (BYTE)(nResult = SnmpBerQueryAsnType(*pBuffer, *nLength))) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
switch ( nResult )
|
|
{
|
|
case ASN_RFC1157_GETREQUEST:
|
|
case ASN_RFC1157_GETNEXTREQUEST:
|
|
case ASN_RFC1157_GETRESPONSE:
|
|
case ASN_RFC1157_SETREQUEST:
|
|
nResult = SnmpPduDecodePdu( pdu->pduType, &pdu->pduValue.pdu,
|
|
pBuffer, nLength );
|
|
break;
|
|
|
|
case ASN_RFC1157_TRAP:
|
|
nResult = SnmpPduDecodeTrap( pdu->pduType, &pdu->pduValue.trap,
|
|
pBuffer, nLength );
|
|
break;
|
|
|
|
default:
|
|
SetLastError( SNMP_PDUAPI_UNRECOGNIZED_PDU );
|
|
|
|
nResult = SNMPAPI_ERROR;
|
|
}
|
|
|
|
Exit:
|
|
return nResult;
|
|
} // SnmpPduDecodeAnyPdu
|
|
|
|
|
|
|
|
//
|
|
// PDU_ReleasePDU
|
|
// Frees all memory associated with a pdu, including a call to
|
|
// SnmpUtilVarBindListFree to free the var binds list.
|
|
//
|
|
// Notes:
|
|
// The dynamic memory associated with a pdu must be set before calling
|
|
// this routine.
|
|
//
|
|
// Return Codes:
|
|
// None.
|
|
//
|
|
// Error Codes:
|
|
// None.
|
|
//
|
|
void PDU_ReleasePDU(
|
|
RFC1157Pdu *pdu // PDU to release
|
|
)
|
|
|
|
{
|
|
SnmpUtilVarBindListFree( &pdu->varBinds );
|
|
} // PDU_ReleasePDU
|
|
|
|
|
|
|
|
//
|
|
// PDU_ReleaseTrap
|
|
// Frees all memory associated with a trap, including a call to
|
|
// SnmpUtilVarBindListFree to free the var binds list.
|
|
//
|
|
// Notes:
|
|
// The dynamic memory associated with a trap pdu must be set before calling
|
|
// this routine.
|
|
//
|
|
// Return Codes:
|
|
// None.
|
|
//
|
|
// Error Codes:
|
|
// None.
|
|
//
|
|
void PDU_ReleaseTrap(
|
|
RFC1157TrapPdu *pdu // Trap to release
|
|
)
|
|
|
|
{
|
|
SnmpUtilOidFree( &pdu->enterprise );
|
|
|
|
// Free network address if dynamic
|
|
if ( pdu->agentAddr.dynamic )
|
|
{
|
|
SnmpUtilMemFree( pdu->agentAddr.stream );
|
|
}
|
|
|
|
SnmpUtilVarBindListFree( &pdu->varBinds );
|
|
} // PDU_ReleaseTrap
|
|
|
|
|
|
|
|
//
|
|
// PDU_ReleaseAnyPdu
|
|
// Determines what type of PDU it is and calls the appropriate routine
|
|
// to release it.
|
|
//
|
|
// Notes:
|
|
//
|
|
// Return Codes:
|
|
// SNMPAPI_NOERROR
|
|
// SNMPAPI_ERROR
|
|
//
|
|
// Error Codes:
|
|
// SNMP_PDUAPI_UNRECOGNIZED_PDU
|
|
//
|
|
SNMPAPI PDU_ReleaseAnyPDU(
|
|
IN OUT RFC1157Pdus *Pdu
|
|
)
|
|
|
|
{
|
|
SNMPAPI nResult;
|
|
|
|
|
|
// Encode PDU/TRAP
|
|
switch ( Pdu->pduType )
|
|
{
|
|
case ASN_RFC1157_GETREQUEST:
|
|
case ASN_RFC1157_GETNEXTREQUEST:
|
|
case ASN_RFC1157_GETRESPONSE:
|
|
case ASN_RFC1157_SETREQUEST:
|
|
PDU_ReleasePDU( &Pdu->pduValue.pdu );
|
|
break;
|
|
|
|
case ASN_RFC1157_TRAP:
|
|
PDU_ReleaseTrap( &Pdu->pduValue.trap );
|
|
break;
|
|
|
|
default:
|
|
SetLastError( SNMP_PDUAPI_UNRECOGNIZED_PDU );
|
|
|
|
nResult = SNMPAPI_ERROR;
|
|
goto Exit;
|
|
}
|
|
|
|
nResult = SNMPAPI_NOERROR;
|
|
|
|
Exit:
|
|
return nResult;
|
|
} // PDU_ReleaseAnyPDU
|
|
|
|
//-------------------------------- END --------------------------------------
|
|
|