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.
491 lines
12 KiB
491 lines
12 KiB
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
|
|
/*---------------------------------------------------------
|
|
Filename: tsess.cpp
|
|
Written By: B.Rajeev
|
|
----------------------------------------------------------*/
|
|
|
|
#include "precomp.h"
|
|
#include "common.h"
|
|
#include "error.h"
|
|
#include "encdec.h"
|
|
#include "vblist.h"
|
|
#include "sec.h"
|
|
#include "pdu.h"
|
|
|
|
#include "tsent.h"
|
|
|
|
#include "transp.h"
|
|
#include "tsess.h"
|
|
#include "sync.h"
|
|
|
|
#include "dummy.h"
|
|
#include "flow.h"
|
|
#include "frame.h"
|
|
#include "timer.h"
|
|
#include "message.h"
|
|
#include "ssent.h"
|
|
#include "idmap.h"
|
|
#include "opreg.h"
|
|
|
|
#include "session.h"
|
|
|
|
TransportWindow::TransportWindow (
|
|
|
|
SnmpImpTransport &owner_transport
|
|
|
|
) : owner ( owner_transport ) , m_Session ( NULL )
|
|
{
|
|
smiUINT32 t_MajorVersion = 1 ;
|
|
smiUINT32 t_MinorVersion = 1 ;
|
|
smiUINT32 t_Level = 2 ;
|
|
smiUINT32 t_TranslateMode = SNMPAPI_UNTRANSLATED_V1 ;
|
|
smiUINT32 t_RetransmitMode = SNMPAPI_OFF ;
|
|
|
|
CriticalSectionLock t_CriticalSectionLock ( SnmpEncodeDecode :: s_CriticalSection ) ;
|
|
|
|
t_CriticalSectionLock.GetLock ( INFINITE ) ;
|
|
|
|
SNMPAPI_STATUS t_StartupStatus = SnmpStartup (
|
|
|
|
&t_MajorVersion,
|
|
&t_MinorVersion,
|
|
&t_Level,
|
|
&t_TranslateMode,
|
|
&t_RetransmitMode
|
|
);
|
|
|
|
t_CriticalSectionLock.UnLock () ;
|
|
|
|
if ( t_StartupStatus == SNMPAPI_FAILURE )
|
|
{
|
|
throw GeneralException (
|
|
|
|
Snmp_Error,
|
|
Snmp_Local_Error,
|
|
__FILE__,
|
|
__LINE__
|
|
);
|
|
}
|
|
|
|
m_Session = SnmpOpen (
|
|
|
|
GetWindowHandle (),
|
|
Window :: g_MessageArrivalEvent
|
|
) ;
|
|
|
|
if ( m_Session == SNMPAPI_FAILURE )
|
|
{
|
|
m_Session = NULL;
|
|
DWORD t_LastError = SnmpGetLastError (0) ;
|
|
throw GeneralException (
|
|
|
|
Snmp_Error,
|
|
Snmp_Local_Error,
|
|
__FILE__,
|
|
__LINE__
|
|
);
|
|
}
|
|
|
|
}
|
|
|
|
TransportWindow::~TransportWindow ()
|
|
{
|
|
HSNMP_SESSION t_Session = ( HSNMP_SESSION ) m_Session ;
|
|
if ( t_Session )
|
|
SnmpClose ( t_Session ) ;
|
|
}
|
|
|
|
// over-rides the HandleEvent method provided by the
|
|
// WinSnmpSession. Receives the Pdu and passes it to
|
|
// the owner (SnmpTransport)
|
|
|
|
LONG_PTR TransportWindow::HandleEvent (
|
|
|
|
HWND hWnd ,
|
|
UINT message ,
|
|
WPARAM wParam ,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
LONG rc = 0;
|
|
|
|
try
|
|
{
|
|
// check if the message needs to be handled
|
|
if ( message == Window :: g_MessageArrivalEvent )
|
|
{
|
|
// inform the owner of a successful message receipt
|
|
SnmpPdu t_SnmpPdu ;
|
|
|
|
if ( ReceivePdu ( t_SnmpPdu ) )
|
|
{
|
|
owner.TransportReceiveFrame ( t_SnmpPdu , t_SnmpPdu.GetErrorReport () ) ;
|
|
|
|
delete & t_SnmpPdu.GetVarbindList () ;
|
|
}
|
|
else
|
|
{
|
|
}
|
|
}
|
|
else if ( message == Window :: g_SentFrameEvent )
|
|
{
|
|
// inform the owner of a sent frame event
|
|
// the error report will be ignored in this case
|
|
owner.HandleSentFrame( (TransportFrameId)wParam );
|
|
}
|
|
else
|
|
{
|
|
return Window::HandleEvent(hWnd, message, wParam, lParam);
|
|
}
|
|
}
|
|
catch ( Heap_Exception e_He )
|
|
{
|
|
}
|
|
catch ( GeneralException exception )
|
|
{
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
// sends the specified pdu. it decodes the SnmpPdu to extract
|
|
// parameters needed for SnmpSendMsg. the return value denotes
|
|
// success and failure in transmission
|
|
// we return on encoutering an error from the winsnmp library call
|
|
|
|
BOOL TransportWindow :: SendPdu (
|
|
|
|
IN SnmpPdu &a_SnmpPdu
|
|
)
|
|
{
|
|
WinSnmpVariables t_WinSnmpVariables ;
|
|
|
|
BOOL t_Status ;
|
|
try
|
|
{
|
|
t_Status = owner.session.GetSnmpEncodeDecode ().EncodeFrame ( a_SnmpPdu , &t_WinSnmpVariables ) ;
|
|
if ( ! t_Status )
|
|
{
|
|
throw GeneralException (
|
|
|
|
Snmp_Error,
|
|
Snmp_Local_Error,
|
|
__FILE__,
|
|
__LINE__,
|
|
SnmpGetLastError ((HSNMP_SESSION) m_Session)
|
|
);
|
|
}
|
|
}
|
|
catch ( Heap_Exception e_He )
|
|
{
|
|
throw ;
|
|
}
|
|
catch ( GeneralException exception )
|
|
{
|
|
throw ;
|
|
}
|
|
|
|
HSNMP_CONTEXT t_Context = t_WinSnmpVariables.m_Context ;
|
|
HSNMP_PDU t_Pdu = t_WinSnmpVariables.m_Pdu ;
|
|
HSNMP_VBL t_Vbl = t_WinSnmpVariables.m_Vbl ;
|
|
|
|
char *t_DstAddress = owner.GetTransportAddress ().GetAddress () ;
|
|
|
|
CriticalSectionLock t_CriticalSectionLock ( SnmpEncodeDecode :: s_CriticalSection ) ;
|
|
|
|
t_CriticalSectionLock.GetLock ( INFINITE ) ;
|
|
|
|
owner.session.GetSnmpEncodeDecode ().SetTranslateMode () ;
|
|
|
|
HSNMP_ENTITY t_SrcEntity = SnmpStrToEntity (
|
|
|
|
( HSNMP_SESSION ) m_Session ,
|
|
LOOPBACK_ADDRESS
|
|
) ;
|
|
|
|
if ( t_SrcEntity == SNMPAPI_FAILURE )
|
|
{
|
|
SnmpFreeContext ( t_Context ) ;
|
|
SnmpFreePdu ( t_Pdu ) ;
|
|
SnmpFreeVbl ( t_Vbl ) ;
|
|
|
|
throw GeneralException (
|
|
|
|
Snmp_Error,
|
|
Snmp_Local_Error,
|
|
__FILE__,
|
|
__LINE__,
|
|
SnmpGetLastError ((HSNMP_SESSION) m_Session)
|
|
);
|
|
}
|
|
|
|
HSNMP_ENTITY t_DstEntity = SnmpStrToEntity (
|
|
|
|
( HSNMP_SESSION ) m_Session ,
|
|
t_DstAddress
|
|
) ;
|
|
|
|
t_CriticalSectionLock.UnLock () ;
|
|
|
|
if ( t_DstEntity == SNMPAPI_FAILURE )
|
|
{
|
|
SnmpFreeContext ( t_Context ) ;
|
|
SnmpFreeEntity ( t_SrcEntity ) ;
|
|
SnmpFreePdu ( t_Pdu ) ;
|
|
SnmpFreeVbl ( t_Vbl ) ;
|
|
|
|
throw GeneralException (
|
|
|
|
Snmp_Error,
|
|
Snmp_Local_Error,
|
|
__FILE__,
|
|
__LINE__,
|
|
SnmpGetLastError ((HSNMP_SESSION) m_Session)
|
|
);
|
|
}
|
|
|
|
DebugMacro4(
|
|
|
|
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
|
|
|
|
__FILE__,__LINE__,
|
|
L"Transport::SendPdu: sending %d\r\n\r\n" , t_WinSnmpVariables.m_RequestId
|
|
|
|
) ;
|
|
|
|
smiOCTETS t_Octets ;
|
|
|
|
SnmpSetRetransmitMode ( SNMPAPI_OFF ) ;
|
|
|
|
if ( SnmpEncodeMsg (
|
|
|
|
m_Session,
|
|
t_SrcEntity,
|
|
t_DstEntity,
|
|
t_Context,
|
|
t_Pdu ,
|
|
& t_Octets
|
|
|
|
) != SNMPAPI_FAILURE )
|
|
{
|
|
ULONG t_Len = t_Octets.len ;
|
|
UCHAR *t_Ptr = t_Octets.ptr ;
|
|
|
|
ULONG t_RowLength = t_Len / 16 ;
|
|
ULONG t_Remainder = t_Len % 16 ;
|
|
|
|
ULONG t_Index = 0 ;
|
|
for ( ULONG t_RowIndex = 0 ; t_RowIndex < t_RowLength ; t_RowIndex ++ )
|
|
{
|
|
ULONG t_StoredIndex = t_Index ;
|
|
|
|
for ( ULONG t_ColumnIndex = 0 ; t_ColumnIndex < 16 ; t_ColumnIndex ++ )
|
|
{
|
|
SnmpDebugLog :: s_SnmpDebugLog->Write ( L"%2.2lx " , t_Ptr [ t_Index ++ ] ) ;
|
|
}
|
|
|
|
SnmpDebugLog :: s_SnmpDebugLog->Write ( L" " ) ;
|
|
|
|
for ( t_ColumnIndex = 0 ; t_ColumnIndex < 16 ; t_ColumnIndex ++ )
|
|
{
|
|
if ( ( t_Ptr [ t_StoredIndex ] >= 0x20 ) && ( t_Ptr [ t_StoredIndex ] <= 0x7f ) )
|
|
{
|
|
SnmpDebugLog :: s_SnmpDebugLog->Write ( L"%c" , t_Ptr [ t_StoredIndex ] ) ;
|
|
}
|
|
else
|
|
{
|
|
SnmpDebugLog :: s_SnmpDebugLog->Write ( L"." ) ;
|
|
}
|
|
|
|
t_StoredIndex ++ ;
|
|
}
|
|
|
|
SnmpDebugLog :: s_SnmpDebugLog->Write ( L"\r\n" ) ;
|
|
}
|
|
|
|
ULONG t_StoredIndex = t_Index ;
|
|
for ( ULONG t_ColumnIndex = 0 ; t_ColumnIndex < 16 ; t_ColumnIndex ++ )
|
|
{
|
|
if ( t_ColumnIndex < t_Remainder )
|
|
{
|
|
SnmpDebugLog :: s_SnmpDebugLog->Write ( L"%2.2lx " , t_Ptr [ t_Index ++ ] ) ;
|
|
}
|
|
else
|
|
{
|
|
SnmpDebugLog :: s_SnmpDebugLog->Write ( L" " ) ;
|
|
}
|
|
}
|
|
|
|
SnmpDebugLog :: s_SnmpDebugLog->Write ( L" " ) ;
|
|
|
|
for ( t_ColumnIndex = 0 ; t_ColumnIndex < 16 ; t_ColumnIndex ++ )
|
|
{
|
|
if ( t_ColumnIndex < t_Remainder )
|
|
{
|
|
if ( t_Ptr [ t_StoredIndex ] >= 0x20 && t_Ptr [ t_StoredIndex ] <= 0x7f )
|
|
{
|
|
SnmpDebugLog :: s_SnmpDebugLog->Write ( L"%c" , t_Ptr [ t_StoredIndex ] ) ;
|
|
}
|
|
else
|
|
{
|
|
SnmpDebugLog :: s_SnmpDebugLog->Write ( L"." ) ;
|
|
}
|
|
|
|
t_StoredIndex ++ ;
|
|
}
|
|
}
|
|
|
|
SnmpDebugLog :: s_SnmpDebugLog->Write ( L"\r\n\r\n" ) ;
|
|
|
|
SnmpFreeDescriptor (
|
|
|
|
SNMP_SYNTAX_OCTETS ,
|
|
& t_Octets
|
|
) ;
|
|
}
|
|
)
|
|
|
|
SnmpSetRetransmitMode ( SNMPAPI_OFF ) ;
|
|
|
|
// send message
|
|
t_Status = SnmpSendMsg (
|
|
|
|
m_Session,
|
|
t_SrcEntity,
|
|
t_DstEntity,
|
|
t_Context,
|
|
t_Pdu
|
|
);
|
|
|
|
if ( t_Status == SNMPAPI_FAILURE )
|
|
{
|
|
DebugMacro4(
|
|
|
|
SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
|
|
|
|
__FILE__,__LINE__,
|
|
L"Transport::SendPdu: failed sending %d\r\n\r\n" , t_WinSnmpVariables.m_RequestId
|
|
|
|
) ;
|
|
)
|
|
SnmpFreeContext ( t_Context ) ;
|
|
SnmpFreeEntity ( t_SrcEntity ) ;
|
|
SnmpFreeEntity ( t_DstEntity ) ;
|
|
SnmpFreePdu ( t_Pdu ) ;
|
|
SnmpFreeVbl ( t_Vbl ) ;
|
|
|
|
throw GeneralException (
|
|
|
|
Snmp_Error,
|
|
Snmp_Local_Error,
|
|
__FILE__,
|
|
__LINE__,
|
|
SnmpGetLastError ((HSNMP_SESSION) m_Session)
|
|
) ;
|
|
}
|
|
|
|
SnmpFreeContext ( t_Context ) ;
|
|
SnmpFreeEntity ( t_SrcEntity ) ;
|
|
SnmpFreeEntity ( t_DstEntity ) ;
|
|
SnmpFreePdu ( t_Pdu ) ;
|
|
SnmpFreeVbl ( t_Vbl ) ;
|
|
|
|
if ( t_Status == SNMPAPI_FAILURE )
|
|
return FALSE;
|
|
else
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL TransportWindow :: ReceivePdu (
|
|
|
|
OUT SnmpPdu &a_SnmpPdu
|
|
)
|
|
{
|
|
HSNMP_ENTITY t_SrcEntity = NULL;
|
|
HSNMP_ENTITY t_DstEntity = NULL;
|
|
HSNMP_CONTEXT t_Context;
|
|
HSNMP_PDU t_Pdu;
|
|
|
|
SNMPAPI_STATUS t_Status = SnmpRecvMsg (
|
|
|
|
m_Session ,
|
|
&t_SrcEntity,
|
|
&t_DstEntity ,
|
|
&t_Context,
|
|
&t_Pdu
|
|
);
|
|
|
|
if ( t_SrcEntity )
|
|
{
|
|
SnmpFreeEntity ( t_SrcEntity ) ;
|
|
}
|
|
|
|
if ( t_DstEntity )
|
|
{
|
|
SnmpFreeEntity ( t_DstEntity ) ;
|
|
}
|
|
|
|
if ( t_Status == SNMPAPI_FAILURE )
|
|
{
|
|
if ( SnmpGetLastError ((HSNMP_SESSION) m_Session) == SNMPAPI_NOOP )
|
|
{
|
|
return FALSE ;
|
|
}
|
|
else
|
|
{
|
|
throw GeneralException (
|
|
|
|
Snmp_Error,
|
|
Snmp_Local_Error,
|
|
__FILE__,
|
|
__LINE__,
|
|
SnmpGetLastError ((HSNMP_SESSION) m_Session)
|
|
);
|
|
}
|
|
}
|
|
|
|
CriticalSectionLock t_CriticalSectionLock ( SnmpEncodeDecode :: s_CriticalSection ) ;
|
|
|
|
t_CriticalSectionLock.GetLock ( INFINITE ) ;
|
|
|
|
owner.session.GetSnmpEncodeDecode ().SetTranslateMode () ;
|
|
|
|
t_SrcEntity = SnmpStrToEntity ( (HSNMP_SESSION) m_Session, LOOPBACK_ADDRESS ) ;
|
|
t_DstEntity = SnmpStrToEntity ( (HSNMP_SESSION) m_Session, LOOPBACK_ADDRESS ) ;
|
|
|
|
t_CriticalSectionLock.UnLock () ;
|
|
|
|
WinSnmpVariables t_WinSnmpVariables ;
|
|
|
|
t_WinSnmpVariables.m_SrcEntity = t_SrcEntity ;
|
|
t_WinSnmpVariables.m_DstEntity = t_DstEntity ;
|
|
t_WinSnmpVariables.m_Context = t_Context ;
|
|
t_WinSnmpVariables.m_Pdu = t_Pdu ;
|
|
|
|
t_Status = owner.session.GetSnmpEncodeDecode ().DecodeFrame ( &t_WinSnmpVariables , a_SnmpPdu ) ;
|
|
if ( ! t_Status ||
|
|
SnmpEncodeDecode :: PduType :: RESPONSE != a_SnmpPdu.GetPduType() )
|
|
{
|
|
SnmpFreePdu ( t_Pdu ) ;
|
|
SnmpFreeEntity ( t_SrcEntity ) ;
|
|
SnmpFreeEntity ( t_DstEntity ) ;
|
|
SnmpFreeContext ( t_Context ) ;
|
|
|
|
throw GeneralException (
|
|
|
|
Snmp_Error,
|
|
SnmpEncodeDecode :: PduType :: GETBULK == a_SnmpPdu.GetPduType() ? Snmp_General_Abort : Snmp_Local_Error,
|
|
__FILE__,
|
|
__LINE__,
|
|
SnmpGetLastError ((HSNMP_SESSION) m_Session)
|
|
);
|
|
}
|
|
|
|
SnmpFreePdu ( t_Pdu ) ;
|
|
SnmpFreeEntity ( t_SrcEntity ) ;
|
|
SnmpFreeEntity ( t_DstEntity ) ;
|
|
SnmpFreeContext ( t_Context ) ;
|
|
|
|
return TRUE ;
|
|
}
|
|
|