Leaked source code of windows server 2003
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.
 
 
 
 
 
 

584 lines
19 KiB

/*****************************************************************************
*
* $Workfile: SnmpMgr.cpp $
*
* Copyright (C) 1997 Hewlett-Packard Company.
* Copyright (C) 1997 Microsoft Corporation.
* All rights reserved.
*
* 11311 Chinden Blvd.
* Boise, Idaho 83714
*
*****************************************************************************/
#include "precomp.h"
#include "stdoids.h"
#include "snmpmgr.h"
///////////////////////////////////////////////////////////////////////////////
// CSnmpMgr::CSnmpMgr()
CSnmpMgr::CSnmpMgr() :
m_pAgent(NULL), m_pCommunity(NULL),m_pSession(NULL),
m_iLastError(NO_ERROR), m_iRetries(DEFAULT_RETRIES),
m_iTimeout(DEFAULT_TIMEOUT),
m_bRequestType(DEFAULT_SNMP_REQUEST)
{
} // ::CSnmpMgr()
///////////////////////////////////////////////////////////////////////////////
// CSnmpMgr::CSnmpMgr() -- establishes a session w/ a given agent
// uses the default request type (get) & community name (public)
CSnmpMgr::CSnmpMgr( const char in *pHost,
const char in *pCommunity,
DWORD dwDevIndex ) :
m_pAgent(NULL), m_pCommunity(NULL),m_pSession(NULL),
m_iLastError(NO_ERROR), m_iRetries(DEFAULT_RETRIES),
m_iTimeout(DEFAULT_TIMEOUT),
m_bRequestType(DEFAULT_SNMP_REQUEST)
{
size_t cchAgent = strlen(pHost) + 1;
m_pAgent = (LPSTR)SNMP_malloc(cchAgent * sizeof m_pAgent [0]); // copy the agent
if( m_pAgent != NULL )
{
StringCchCopyA (m_pAgent, cchAgent, pHost);
}
size_t cchCommunity = strlen(pCommunity) + 1;
m_pCommunity = (LPSTR)SNMP_malloc(cchCommunity * sizeof m_pCommunity [0]); // copy the community name
if( m_pCommunity != NULL )
{
StringCchCopyA (m_pCommunity, cchCommunity, pCommunity);
}
m_bRequestType = DEFAULT_SNMP_REQUEST; // set the default request type == GET request
m_pSession = NULL;
if ( !Open() ) // establish a session w/ the agent
{
m_iLastError = GetLastError();
}
} // ::CSnmpMgr()
///////////////////////////////////////////////////////////////////////////////
// CSnmpMgr::CSnmpMgr() -- establishes a session w/ a given agent
// uses the default request type (get) & community name (public)
CSnmpMgr::CSnmpMgr( const char in *pHost,
const char in *pCommunity,
DWORD in dwDevIndex,
AsnObjectIdentifier in *pMibObjId,
RFC1157VarBindList out *pVarBindList) :
m_pAgent(NULL), m_pCommunity(NULL),m_pSession(NULL),
m_iLastError(NO_ERROR), m_iRetries(DEFAULT_RETRIES),
m_iTimeout(DEFAULT_TIMEOUT),
m_bRequestType(DEFAULT_SNMP_REQUEST)
{
DWORD dwRetCode = SNMPAPI_NOERROR;
size_t cchAgent = strlen(pHost) + 1;
m_pAgent = (LPSTR)SNMP_malloc(cchAgent * sizeof m_pAgent [0]); // copy the agent
if( m_pAgent != NULL )
{
StringCchCopyA (m_pAgent, cchAgent, pHost);
}
size_t cchCommunity = strlen(pCommunity) + 1;
m_pCommunity = (LPSTR)SNMP_malloc(cchCommunity * sizeof m_pCommunity [0]); // copy the community name
if( m_pCommunity != NULL )
{
StringCchCopyA (m_pCommunity, cchCommunity, pCommunity);
}
m_bRequestType = DEFAULT_SNMP_REQUEST; // set the default request type == GET request
dwRetCode = BldVarBindList(pMibObjId, pVarBindList);
if (dwRetCode == SNMPAPI_NOERROR)
{
m_pSession = NULL;
if ( !Open() ) // establish a session w/ the agent
{
m_iLastError = GetLastError();
}
}
} // ::CSnmpMgr()
///////////////////////////////////////////////////////////////////////////////
// CSnmpMgr::~CSnmpMgr()
CSnmpMgr::~CSnmpMgr()
{
if (m_pSession) Close(); // close the session
// delete the allocated memory from community & agent names
if (m_pAgent) SNMP_free(m_pAgent);
if (m_pCommunity) SNMP_free(m_pCommunity);
} // ::~CSnmpMgr()
///////////////////////////////////////////////////////////////////////////////
// Open() -- establishes a session
// Error Codes:
// SNMPAPI_NOERROR if successful
// SNMPAPI_ERROR if fails
BOOL
CSnmpMgr::Open()
{
m_iLastError = SNMPAPI_NOERROR;
m_pSession = SnmpMgrOpen(m_pAgent, m_pCommunity, m_iTimeout, m_iRetries);
if ( m_pSession == NULL )
{
m_iLastError = SNMPAPI_ERROR;
m_pSession = NULL;
return FALSE;
}
return TRUE;
} // ::Open()
///////////////////////////////////////////////////////////////////////////////
// Close() -- closes the previously established session
void
CSnmpMgr::Close()
{
_ASSERTE( m_pSession != NULL);
if ( !SnmpMgrClose(m_pSession) )
{
m_iLastError = GetLastError();
}
m_pSession = NULL;
} // ::Close()
///////////////////////////////////////////////////////////////////////////////
// Get() -- does an SNMP command (m_bRequestType) given a set of OIDs
// Error Codes:
// SNMP_ERRORSTATUS_NOERROR if no error
// SNMP_ERRORSTATUS_TOOBIG if the packet returned is big
// SNMP_ERRORSTATUS_NOSUCHNAME if the OID isn't supported
// SNMP_ERRORSTATUS_BADVALUE
// SNMP_ERRORSTATUS_READONLY
// SNMP_ERRORSTATUS_GENERR
// SNMP_MGMTAPI_TIMEOUT -- set by GetLastError()
// SNMP_MGMTAPI_SELECT_FDERRORS -- set by GetLastError()
int
CSnmpMgr::Get( RFC1157VarBindList in *pVariableBindings)
{
int iRetCode = SNMP_ERRORSTATUS_NOERROR;
AsnInteger errorStatus;
AsnInteger errorIndex;
if ( !SnmpMgrRequest( m_pSession, m_bRequestType, pVariableBindings, &errorStatus, &errorIndex) )
{
iRetCode = m_iLastError = GetLastError();
}
else
{
if (errorStatus > 0)
{
iRetCode = errorStatus;
}
else // return the result of the variable bindings?
{
// variableBindings->list[x]->value contains the return value
}
}
return iRetCode;
} // ::Get()
///////////////////////////////////////////////////////////////////////////////
// Walk -- given an object, it walks until the tree is done
// Error Codes:
// SNMP_ERRORSTATUS_TOOBIG if the packet returned is big
// SNMP_ERRORSTATUS_NOSUCHNAME if the OID isn't supported
// SNMP_ERRORSTATUS_BADVALUE
// SNMP_ERRORSTATUS_READONLY
// SNMP_ERRORSTATUS_GENERR
// SNMP_MGMTAPI_TIMEOUT -- set by GetLastError()
// SNMP_MGMTAPI_SELECT_FDERRORS -- set by GetLastError()
int
CSnmpMgr::Walk( RFC1157VarBindList inout *pVariableBindings)
{
int iRetCode = SNMP_ERRORSTATUS_NOERROR;
RFC1157VarBindList variableBindings;
UINT numElements=0;
LPVOID pTemp;
variableBindings.len = 0;
variableBindings.list = NULL;
variableBindings.len++;
if ( (variableBindings.list = (RFC1157VarBind *)SNMP_realloc(variableBindings.list,
sizeof(RFC1157VarBind) * variableBindings.len)) == NULL)
{
iRetCode = ERROR_NOT_ENOUGH_MEMORY;
return iRetCode;
}
if ( !SnmpUtilVarBindCpy(&(variableBindings.list[variableBindings.len -1]), &(pVariableBindings->list[0])) )
{
iRetCode = ERROR_NOT_ENOUGH_MEMORY;
return iRetCode;
}
AsnObjectIdentifier root;
AsnObjectIdentifier tempOid;
AsnInteger errorStatus;
AsnInteger errorIndex;
if (!SnmpUtilOidCpy(&root, &variableBindings.list[0].name))
{
iRetCode = ERROR_NOT_ENOUGH_MEMORY;
goto CleanUp;
}
m_bRequestType = ASN_RFC1157_GETNEXTREQUEST;
while(1) // walk the MIB tree (or sub-tree)
{
if (!SnmpMgrRequest(m_pSession, m_bRequestType, &variableBindings,
&errorStatus, &errorIndex))
{
// The API is indicating an error.
iRetCode = m_iLastError = GetLastError();
break;
}
else
{
// The API succeeded, errors may be indicated from the remote agent.
// Test for end of subtree or end of MIB.
if (errorStatus == SNMP_ERRORSTATUS_NOSUCHNAME ||
SnmpUtilOidNCmp(&variableBindings.list[0].name, &root, root.idLength))
{
iRetCode = SNMP_ERRORSTATUS_NOSUCHNAME;
break;
}
// Test for general error conditions or sucesss.
if (errorStatus > 0)
{
iRetCode = errorStatus;
break;
}
numElements++;
} // end if()
// append the variableBindings to the pVariableBindings
_ASSERTE(pVariableBindings->len != 0);
if ( ( pTemp = (RFC1157VarBind *)SNMP_realloc(pVariableBindings->list,
sizeof(RFC1157VarBind) * (pVariableBindings->len + 1))) == NULL)
{
iRetCode = ERROR_NOT_ENOUGH_MEMORY;
break;
}
else
{
pVariableBindings->list = (SnmpVarBind *)pTemp;
pVariableBindings->len++;
}
if ( !SnmpUtilVarBindCpy(&(pVariableBindings->list[pVariableBindings->len -1]), &(variableBindings.list[0])) )
{
iRetCode = ERROR_NOT_ENOUGH_MEMORY;
break;
}
// Prepare for the next iteration. Make sure returned oid is
// preserved and the returned value is freed
if( SnmpUtilOidCpy(&tempOid, &variableBindings.list[0].name) )
{
SnmpUtilVarBindFree(&variableBindings.list[0]);
if ( SnmpUtilOidCpy(&variableBindings.list[0].name, &tempOid))
{
variableBindings.list[0].value.asnType = ASN_NULL;
SnmpUtilOidFree(&tempOid);
}
else
{
iRetCode = SNMP_ERRORSTATUS_GENERR;
goto CleanUp;
}
}
else
{
iRetCode = SNMP_ERRORSTATUS_GENERR;
goto CleanUp;
}
} // end while()
CleanUp:
// Free the variable bindings that have been allocated.
SnmpUtilVarBindListFree(&variableBindings);
SnmpUtilOidFree(&root);
if (iRetCode == SNMP_ERRORSTATUS_NOSUCHNAME)
if (numElements != 0) // list is full; iRetCode indicates the end of the MIB
iRetCode = SNMP_ERRORSTATUS_NOERROR;
return (iRetCode);
} // Walk()
///////////////////////////////////////////////////////////////////////////////
// WalkNext -- given object(s), it walks until the table has no more object
// entries. The end of the table is determined by the first item in the list.
// Error Codes:
// SNMP_ERRORSTATUS_TOOBIG if the packet returned is big
// SNMP_ERRORSTATUS_NOSUCHNAME if the OID isn't supported
// SNMP_ERRORSTATUS_BADVALUE
// SNMP_ERRORSTATUS_READONLY
// SNMP_ERRORSTATUS_GENERR
// SNMP_MGMTAPI_TIMEOUT -- set by GetLastError()
// SNMP_MGMTAPI_SELECT_FDERRORS -- set by GetLastError()
int
CSnmpMgr::WalkNext( RFC1157VarBindList inout *pVariableBindings)
{
int iRetCode = SNMP_ERRORSTATUS_NOERROR;
RFC1157VarBindList variableBindings;
UINT numElements=0;
UINT len=0, i=0;
LPVOID pTemp;
variableBindings.len = 0;
variableBindings.list = NULL;
variableBindings.len = pVariableBindings->len;
if ( (variableBindings.list = (RFC1157VarBind *)SNMP_realloc(variableBindings.list,
sizeof(RFC1157VarBind) * variableBindings.len)) == NULL)
{
iRetCode = ERROR_NOT_ENOUGH_MEMORY;
return iRetCode;
}
for (i=0; i<variableBindings.len; i++)
{
if ( !SnmpUtilVarBindCpy(&(variableBindings.list[i]), &(pVariableBindings->list[i])) )
{
iRetCode = ERROR_NOT_ENOUGH_MEMORY;
return iRetCode;
}
}
AsnObjectIdentifier root;
AsnObjectIdentifier tempOid;
AsnInteger errorStatus;
AsnInteger errorIndex;
if (!SnmpUtilOidCpy(&root, &variableBindings.list[0].name))
{
iRetCode = ERROR_NOT_ENOUGH_MEMORY;
goto CleanUp;
}
m_bRequestType = ASN_RFC1157_GETNEXTREQUEST;
while(1) // get the object(s) in the MIB table
{
if (!SnmpMgrRequest(m_pSession, m_bRequestType, &variableBindings,
&errorStatus, &errorIndex))
{
// The API is indicating an error.
iRetCode = m_iLastError = GetLastError();
break;
}
else
{
// The API succeeded, errors may be indicated from the remote agent.
// Test for end of subtree or end of MIB.
if (errorStatus == SNMP_ERRORSTATUS_NOSUCHNAME ||
SnmpUtilOidNCmp(&variableBindings.list[0].name, &root, root.idLength))
{
iRetCode = SNMP_ERRORSTATUS_NOSUCHNAME;
break;
}
// Test for general error conditions or sucesss.
if (errorStatus > 0)
{
iRetCode = errorStatus;
break;
}
numElements++;
} // end if()
// append the variableBindings to the pVariableBindings
_ASSERTE(pVariableBindings->len != 0);
len = pVariableBindings->len;
if ( (pTemp = (RFC1157VarBind *)SNMP_realloc(pVariableBindings->list,
sizeof(RFC1157VarBind) * (pVariableBindings->len + variableBindings.len))) == NULL)
{
iRetCode = ERROR_NOT_ENOUGH_MEMORY;
break;
}
else
{
pVariableBindings->list = (SnmpVarBind *)pTemp;
pVariableBindings->len += variableBindings.len;
}
int j=0;
for ( i=len; i < pVariableBindings->len; i++, j++)
{
if ( !SnmpUtilVarBindCpy(&(pVariableBindings->list[i]), &(variableBindings.list[j])) )
{
iRetCode = ERROR_NOT_ENOUGH_MEMORY;
break;
}
}
// Prepare for the next iteration. Make sure returned oid is
// preserved and the returned value is freed
for (i=0; i<variableBindings.len; i++)
{
if ( SnmpUtilOidCpy(&tempOid, &variableBindings.list[i].name) )
{
SnmpUtilVarBindFree(&variableBindings.list[i]);
if( SnmpUtilOidCpy(&variableBindings.list[i].name, &tempOid))
{
variableBindings.list[i].value.asnType = ASN_NULL;
SnmpUtilOidFree(&tempOid);
}
else
{
iRetCode = SNMP_ERRORSTATUS_GENERR;
goto CleanUp;
}
}
else
{
iRetCode = SNMP_ERRORSTATUS_GENERR;
goto CleanUp;
}
}
} // end while()
CleanUp:
// Free the variable bindings that have been allocated.
SnmpUtilVarBindListFree(&variableBindings);
SnmpUtilOidFree(&root);
if (iRetCode == SNMP_ERRORSTATUS_NOSUCHNAME)
if (numElements != 0) // list is full; iRetCode indicates the end of the MIB
iRetCode = SNMP_ERRORSTATUS_NOERROR;
return (iRetCode);
} // WalkNext()
///////////////////////////////////////////////////////////////////////////////
// GetNext -- does an SNMP GetNext command on the set of OID(s)
// Error Codes:
// SNMP_ERRORSTATUS_TOOBIG if the packet returned is big
// SNMP_ERRORSTATUS_NOSUCHNAME if the OID isn't supported
// SNMP_ERRORSTATUS_BADVALUE
// SNMP_ERRORSTATUS_READONLY
// SNMP_ERRORSTATUS_GENERR
// SNMP_MGMTAPI_TIMEOUT -- set by GetLastError()
// SNMP_MGMTAPI_SELECT_FDERRORS -- set by GetLastError()
int
CSnmpMgr::GetNext( RFC1157VarBindList inout *pVariableBindings)
{
int iRetCode = SNMP_ERRORSTATUS_NOERROR;
AsnInteger errorStatus;
AsnInteger errorIndex;
m_bRequestType = ASN_RFC1157_GETNEXTREQUEST;
if ( !SnmpMgrRequest( m_pSession, m_bRequestType, pVariableBindings, &errorStatus, &errorIndex) )
{
iRetCode = m_iLastError = GetLastError();
}
else
{
if (errorStatus > 0)
{
iRetCode = errorStatus;
}
else // return the result of the variable bindings?
{
// variableBindings->list[x]->value contains the return value
}
}
return (iRetCode);
} // GetNext()
///////////////////////////////////////////////////////////////////////////////
// BldVarBindList -- given a category, it retuns the RFC1157VarBindList
// Error Codes:
// NO_ERROR if successful
// ERROR_NOT_ENOUGH_MEMORY if memory allocation failes
// ERROR_INVALID_HANDLE if can't build the variable bindings
DWORD
CSnmpMgr::BldVarBindList( AsnObjectIdentifier in *pMibObjId, // group identifier
RFC1157VarBindList inout *pVarBindList)
{
DWORD dwRetCode = SNMPAPI_NOERROR;
LPVOID pTemp;
m_iLastError = SNMPAPI_NOERROR;
while (pMibObjId->idLength != 0)
{
// setup the variable bindings
CONST UINT uNewLen = pVarBindList->len + 1;
if ( (pTemp = (RFC1157VarBind *)SNMP_realloc(pVarBindList->list,
sizeof(RFC1157VarBind) * uNewLen)) == NULL)
{
m_iLastError = ERROR_NOT_ENOUGH_MEMORY;
return ERROR_NOT_ENOUGH_MEMORY;
}
else
{
pVarBindList->list = (SnmpVarBind *)pTemp;
pVarBindList-> len = uNewLen;
}
AsnObjectIdentifier reqObject;
if ( !SnmpUtilOidCpy(&reqObject, pMibObjId) )
{
m_iLastError = ERROR_INVALID_HANDLE;
return ERROR_INVALID_HANDLE;
}
pVarBindList->list[pVarBindList->len -1].name = reqObject;
pVarBindList->list[pVarBindList->len -1].value.asnType = ASN_NULL;
pMibObjId++;
}
return dwRetCode;
} // BldVarBindList