// 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 ; }