932 lines
24 KiB
C++
932 lines
24 KiB
C++
/*++
|
||
|
||
Copyright (c) 2001 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
rmALG.cpp
|
||
|
||
Abstract:
|
||
|
||
This module contains routines for the ALG Manager module's
|
||
private interface to be used only by the ALG.exe manager.
|
||
|
||
Author:
|
||
|
||
JPDup 10-Nov-2000
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
|
||
#include "precomp.h"
|
||
|
||
#include <atlbase.h>
|
||
|
||
extern CComModule _Module;
|
||
#include <atlcom.h>
|
||
|
||
#include "Alg.h"
|
||
#include "NatPrivateAPI_Imp.h"
|
||
|
||
#include <MyTrace.h>
|
||
|
||
#include <Rtutils.h>
|
||
|
||
|
||
|
||
extern HANDLE AlgPortReservationHandle; // see rmALG.CPP
|
||
|
||
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// CNat
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//
|
||
// Standard destructor
|
||
//
|
||
CNat::~CNat(void)
|
||
{
|
||
MYTRACE_ENTER("CNat::~CNat(void)");
|
||
|
||
if ( m_hTranslatorHandle )
|
||
NatShutdownTranslator(m_hTranslatorHandle);
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
STDMETHODIMP
|
||
CNat::CreateRedirect(
|
||
IN ULONG Flags,
|
||
IN UCHAR Protocol,
|
||
|
||
IN ULONG DestinationAddress,
|
||
IN USHORT DestinationPort,
|
||
|
||
IN ULONG SourceAddress,
|
||
IN USHORT SourcePort,
|
||
|
||
IN ULONG NewDestinationAddress,
|
||
IN USHORT NewDestinationPort,
|
||
|
||
IN ULONG NewSourceAddress,
|
||
IN USHORT NewSourcePort,
|
||
|
||
IN ULONG RestrictAdapterIndex,
|
||
|
||
IN DWORD_PTR dwAlgProcessId,
|
||
IN HANDLE_PTR hCreateEvent,
|
||
IN HANDLE_PTR hDeleteEvent
|
||
)
|
||
{
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Creates a Redirect PORT
|
||
|
||
Arguments:
|
||
|
||
Flags - Specifies options for the redirect
|
||
Protocol - IP protocol of the session to be redirected
|
||
|
||
DestinationAddress - destination endpoint of the session to be redirected
|
||
DestinationPort - "
|
||
|
||
SourceAddress - source endpoint of the session to be redirected
|
||
SourcePort - "
|
||
|
||
NewDestinationAddress - replacement destination endpoint for the session
|
||
NewDestinationPort - "
|
||
|
||
NewSourceAddress - replacement source endpoint for the session
|
||
NewSourcePort - "
|
||
|
||
RestrictAdapterIndex - optionally specifies the adapter index that this redirect should be restricted to
|
||
|
||
hCreateEvent - optionally specifies an event to be signalled when a session matches the redirect.
|
||
|
||
hDeleteEvent - optionally specifies an event to be signalled when a session is delete.
|
||
|
||
|
||
Return Value:
|
||
|
||
HRESULT - S_OK for success or and HRESULT error
|
||
|
||
Environment:
|
||
|
||
The routine runs in the context of the ALG Manager and cant only be invoke by the ALG.EXE
|
||
|
||
--*/
|
||
|
||
MYTRACE_ENTER("CNat::CreateRedirect");
|
||
|
||
MYTRACE("ProtocolPublic %d, ProtocolInternal %d", Protocol, ProtocolConvertToNT(Protocol));
|
||
MYTRACE("Destination %s:%d", MYTRACE_IP(DestinationAddress), ntohs(DestinationPort));
|
||
MYTRACE("Source %s:%d", MYTRACE_IP(SourceAddress), ntohs(SourcePort));
|
||
MYTRACE("NewDestination %s:%d", MYTRACE_IP(NewDestinationAddress), ntohs(NewDestinationPort));
|
||
MYTRACE("NewSource %s:%d", MYTRACE_IP(NewSourceAddress), ntohs(NewSourcePort));
|
||
|
||
HANDLE hThisEventForCreate=NULL;
|
||
HANDLE hThisEventForDelete=NULL;
|
||
|
||
|
||
//
|
||
// Duplicate the requested Event handles
|
||
//
|
||
if ( dwAlgProcessId )
|
||
{
|
||
|
||
HANDLE hAlgProcess = OpenProcess(
|
||
PROCESS_DUP_HANDLE, // access flag
|
||
false, // handle inheritance option
|
||
(DWORD)dwAlgProcessId // process identifier
|
||
);
|
||
|
||
if ( !hAlgProcess )
|
||
{
|
||
MYTRACE_ERROR("Could not open the Process ID of ALG.exe", 0);
|
||
return HRESULT_FROM_WIN32(GetLastError());
|
||
}
|
||
|
||
|
||
|
||
if ( hCreateEvent )
|
||
{
|
||
|
||
//
|
||
// a create event was requested
|
||
//
|
||
if ( !DuplicateHandle(
|
||
hAlgProcess,
|
||
(HANDLE)hCreateEvent,
|
||
GetCurrentProcess(),
|
||
&hThisEventForCreate,
|
||
0,
|
||
FALSE,
|
||
DUPLICATE_SAME_ACCESS
|
||
)
|
||
)
|
||
{
|
||
MYTRACE_ERROR("DuplicateHandle on the CREATE handle", 0);
|
||
CloseHandle(hAlgProcess);
|
||
return HRESULT_FROM_WIN32(GetLastError());
|
||
}
|
||
|
||
MYTRACE("New DuplicateHandle 'CREATE'=%d base on=%d", hThisEventForCreate, hCreateEvent);
|
||
}
|
||
else
|
||
{
|
||
MYTRACE("No event for Creation requested");
|
||
}
|
||
|
||
|
||
|
||
if ( hDeleteEvent )
|
||
{
|
||
//
|
||
// a delete event was requested
|
||
//
|
||
if ( !DuplicateHandle(
|
||
hAlgProcess,
|
||
(HANDLE)hDeleteEvent,
|
||
GetCurrentProcess(),
|
||
&hThisEventForDelete,
|
||
0,
|
||
FALSE,
|
||
DUPLICATE_SAME_ACCESS
|
||
)
|
||
)
|
||
{
|
||
MYTRACE_ERROR("DuplicateHandle on the DELETE handle", 0);
|
||
|
||
if ( hThisEventForCreate )
|
||
CloseHandle(hThisEventForCreate);
|
||
|
||
CloseHandle(hAlgProcess);
|
||
|
||
return HRESULT_FROM_WIN32(GetLastError());
|
||
}
|
||
|
||
MYTRACE("New DuplicateHandle 'DELETE'=%d base on=%d", hThisEventForDelete, hDeleteEvent);
|
||
|
||
}
|
||
else
|
||
{
|
||
MYTRACE("No event for Delete requested");
|
||
}
|
||
|
||
CloseHandle(hAlgProcess);
|
||
}
|
||
else
|
||
{
|
||
MYTRACE("NO EVENT Requested");
|
||
}
|
||
|
||
|
||
ULONG Error = NatCreateRedirectEx(
|
||
GetTranslatorHandle(),
|
||
Flags,
|
||
ProtocolConvertToNT(Protocol),
|
||
|
||
DestinationAddress,
|
||
DestinationPort,
|
||
|
||
SourceAddress,
|
||
SourcePort,
|
||
|
||
NewDestinationAddress,
|
||
NewDestinationPort,
|
||
|
||
NewSourceAddress,
|
||
NewSourcePort,
|
||
|
||
RestrictAdapterIndex,
|
||
IPNATAPI_SET_EVENT_ON_COMPLETION, // Special constant to use Event vs. a callback to a CompletionRoutine
|
||
(PVOID)hThisEventForDelete, //HANDLE for DELETE sessions
|
||
(HANDLE)hThisEventForCreate //HANDLE NotifyEvent OPTIONAL
|
||
);
|
||
|
||
if ( hThisEventForCreate )
|
||
CloseHandle(hThisEventForCreate);
|
||
|
||
if ( hThisEventForDelete )
|
||
CloseHandle(hThisEventForDelete);
|
||
|
||
if ( ERROR_SUCCESS != Error )
|
||
{
|
||
MYTRACE_ERROR("From NatCreateRedirectEx", Error);
|
||
return HRESULT_FROM_WIN32(Error);
|
||
}
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
|
||
//
|
||
//
|
||
//
|
||
|
||
STDMETHODIMP
|
||
CNat::CancelRedirect(
|
||
IN UCHAR Protocol,
|
||
|
||
IN ULONG DestinationAddress,
|
||
IN USHORT DestinationPort,
|
||
|
||
IN ULONG SourceAddress,
|
||
IN USHORT SourcePort,
|
||
|
||
IN ULONG NewDestinationAddress,
|
||
IN USHORT NewDestinationPort,
|
||
|
||
IN ULONG NewSourceAddress,
|
||
IN USHORT NewSourcePort
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Cancel a Redirect
|
||
|
||
Arguments:
|
||
|
||
Protocol - IP protocol of the session to be redirected eALG_TCP || eALG_UDP
|
||
|
||
DestinationAddress - destination endpoint of the session to be redirected
|
||
DestinationPort - "
|
||
|
||
SourceAddress - source endpoint of the session to be redirected
|
||
SourcePort - "
|
||
|
||
NewDestinationAddress - replacement destination endpoint for the session
|
||
NewDestinationPort - "
|
||
|
||
NewSourceAddress - replacement source endpoint for the session
|
||
NewSourcePort - "
|
||
|
||
|
||
Return Value:
|
||
|
||
HRESULT - S_OK for success or and HRESULT error
|
||
|
||
Environment:
|
||
|
||
The routine runs in the context of the ALG Manager and cant only be invoke by the ALG.EXE
|
||
|
||
--*/
|
||
{
|
||
MYTRACE_ENTER("CNat::CancelRedirect");
|
||
|
||
MYTRACE("Protocol Public %d, Internal %d", Protocol, ProtocolConvertToNT(Protocol));
|
||
MYTRACE("Destination %s:%d", MYTRACE_IP(DestinationAddress), ntohs(DestinationPort));
|
||
MYTRACE("Source %s:%d", MYTRACE_IP(SourceAddress), ntohs(SourcePort));
|
||
MYTRACE("NewDestination %s:%d", MYTRACE_IP(NewDestinationAddress), ntohs(NewDestinationPort));
|
||
MYTRACE("NewSource %s:%d", MYTRACE_IP(NewSourceAddress), ntohs(NewSourcePort));
|
||
|
||
ULONG Error = NatCancelRedirect(
|
||
GetTranslatorHandle(),
|
||
ProtocolConvertToNT(Protocol),
|
||
DestinationAddress,
|
||
DestinationPort,
|
||
SourceAddress,
|
||
SourcePort,
|
||
NewDestinationAddress,
|
||
NewDestinationPort,
|
||
NewSourceAddress,
|
||
NewSourcePort
|
||
);
|
||
|
||
if ( ERROR_SUCCESS != Error )
|
||
{
|
||
MYTRACE_ERROR("From NatCancelRedirect", Error);
|
||
return HRESULT_FROM_WIN32(Error);
|
||
}
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
STDMETHODIMP
|
||
CNat::CreateDynamicRedirect(
|
||
IN ULONG Flags,
|
||
IN ULONG nAdapterIndex,
|
||
IN UCHAR Protocol,
|
||
|
||
IN ULONG DestinationAddress,
|
||
IN USHORT DestinationPort,
|
||
|
||
IN ULONG SourceAddress,
|
||
IN USHORT SourcePort,
|
||
|
||
IN ULONG NewDestinationAddress,
|
||
IN USHORT NewDestinationPort,
|
||
|
||
IN ULONG NewSourceAddress,
|
||
IN USHORT NewSourcePort,
|
||
|
||
OUT HANDLE_PTR* pDynamicRedirectHandle
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Cancel a dynamic Redirect, by seting up a dynamic redirection any time a adapter is created the redirection will be
|
||
applied to that new adapter.
|
||
|
||
Arguments:
|
||
|
||
Flags - Specifies options for the redirect
|
||
nAdapterIndex - Index of the IP adapter (Same as the index found using the cmd line "ROUTE PRINT")
|
||
Protocol - IP protocol of the session to be redirected
|
||
|
||
DestinationAddress - destination endpoint of the session to be redirected
|
||
DestinationPort - "
|
||
|
||
SourceAddress - source endpoint of the session to be redirected
|
||
SourcePort - "
|
||
|
||
NewDestinationAddress - replacement destination endpoint for the session
|
||
NewDestinationPort - "
|
||
|
||
NewSourceAddress - replacement source endpoint for the session
|
||
NewSourcePort - "
|
||
|
||
pDynamicRedirectHandle - This routine will populate this field with the handle (Cookie) for the purpose of canceling
|
||
this DynamicRedirect
|
||
|
||
Return Value:
|
||
|
||
HRESULT - S_OK for success or and HRESULT error
|
||
|
||
Environment:
|
||
|
||
The routine runs in the context of the ALG Manager and cant only be invoke by the ALG.EXE
|
||
and is use via the public api CreatePrimaryControlChannel (See ALG.EXE)
|
||
|
||
--*/
|
||
{
|
||
MYTRACE_ENTER("CNat::CreateDynamicRedirect");
|
||
|
||
ASSERT(pDynamicRedirectHandle!=NULL);
|
||
|
||
#if defined(DBG) || defined(_DEBUG)
|
||
|
||
MYTRACE("Flags %d", Flags);
|
||
|
||
|
||
MYTRACE("Protocol Public %d Internal %d", Protocol, ProtocolConvertToNT(Protocol));
|
||
|
||
if ( Flags & NatRedirectFlagNoTimeout )
|
||
MYTRACE(" NatRedirectFlagNoTimeout");
|
||
|
||
if ( Flags & NatRedirectFlagUnidirectional )
|
||
MYTRACE(" NatRedirectFlagUnidirectional");
|
||
|
||
if ( Flags & NatRedirectFlagRestrictSource )
|
||
MYTRACE(" NatRedirectFlagRestrictSource");
|
||
|
||
if ( Flags & NatRedirectFlagPortRedirect )
|
||
MYTRACE(" NatRedirectFlagPortRedirect");
|
||
|
||
if ( Flags & NatRedirectFlagReceiveOnly )
|
||
MYTRACE(" NatRedirectFlagReceiveOnly");
|
||
|
||
if ( Flags & NatRedirectFlagLoopback )
|
||
MYTRACE(" NatRedirectFlagLoopback");
|
||
|
||
if ( Flags & NatRedirectFlagSendOnly )
|
||
MYTRACE(" NatRedirectFlagSendOnly");
|
||
|
||
if ( Flags & NatRedirectFlagRestrictAdapter )
|
||
MYTRACE(" NatRedirectFlagRestrictAdapter");
|
||
|
||
if ( Flags & NatRedirectFlagSourceRedirect )
|
||
MYTRACE(" NatRedirectFlagSourceRedirect");
|
||
|
||
|
||
MYTRACE("AdapterIndex %d", nAdapterIndex);
|
||
|
||
in_addr tmpAddr;
|
||
tmpAddr.s_addr = DestinationAddress;
|
||
MYTRACE("Destination %s:%d", inet_ntoa(tmpAddr), ntohs(DestinationPort));
|
||
tmpAddr.s_addr = SourceAddress;
|
||
MYTRACE("Source %s:%d", inet_ntoa(tmpAddr), ntohs(SourcePort));
|
||
tmpAddr.s_addr = NewDestinationAddress;
|
||
MYTRACE("NewDestination %s:%d", inet_ntoa(tmpAddr), ntohs(NewDestinationPort));
|
||
tmpAddr.s_addr = NewSourceAddress;
|
||
MYTRACE("NewSource %s:%d", inet_ntoa(tmpAddr), ntohs(NewSourcePort));
|
||
#endif
|
||
|
||
|
||
MYTRACE("About to call NatCreateDynamicFullRedirect");
|
||
|
||
ULONG nRestrictSourceAddress = 0;
|
||
|
||
if ( NatRedirectFlagRestrictSource & Flags )
|
||
{
|
||
MYTRACE("NatRedirectFlagRestrictSource flags is set");
|
||
nRestrictSourceAddress = SourceAddress;
|
||
SourceAddress = 0;
|
||
}
|
||
|
||
ULONG Error = NatCreateDynamicFullRedirect(
|
||
Flags|NatRedirectFlagLoopback,
|
||
ProtocolConvertToNT(Protocol),
|
||
|
||
DestinationAddress,
|
||
DestinationPort,
|
||
|
||
SourceAddress,
|
||
SourcePort,
|
||
|
||
NewDestinationAddress,
|
||
NewDestinationPort,
|
||
|
||
NewSourceAddress,
|
||
NewSourcePort,
|
||
|
||
nRestrictSourceAddress, //ULONG RestrictSourceAddress OPTIONAL,
|
||
nAdapterIndex, //ULONG RestrictAdapterIndex OPTIONAL,
|
||
0, //MinimumBacklog OPTIONAL,
|
||
(PHANDLE)pDynamicRedirectHandle
|
||
);
|
||
|
||
if ( ERROR_SUCCESS != Error )
|
||
{
|
||
MYTRACE_ERROR("Failed NatCreateDynamicFullRedirect", Error);
|
||
return HRESULT_FROM_WIN32(Error);
|
||
}
|
||
|
||
MYTRACE("Call to NatCreateDynamicFullRedirect worked");
|
||
|
||
return S_OK;;
|
||
}
|
||
|
||
|
||
|
||
|
||
STDMETHODIMP
|
||
CNat::CancelDynamicRedirect(
|
||
IN HANDLE_PTR DynamicRedirectHandle
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called to cancel the given dynamic redirect.
|
||
by calling the NatApi version of this function
|
||
|
||
Arguments:
|
||
|
||
DynamicRedirectHandle - the handle to the dynamic redirect to be cancelled
|
||
|
||
Return Value:
|
||
|
||
HRESULT - S_OK for success or and HRESULT error
|
||
|
||
--*/
|
||
|
||
{
|
||
MYTRACE_ENTER("CNat::CancelDynamicRedirect");
|
||
|
||
ULONG Error = NatCancelDynamicRedirect((PHANDLE)DynamicRedirectHandle);
|
||
|
||
if ( ERROR_SUCCESS != Error )
|
||
{
|
||
MYTRACE_ERROR("Failed NatCancelDynamicRedirect", Error);
|
||
return HRESULT_FROM_WIN32(Error);
|
||
}
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
STDMETHODIMP
|
||
CNat::GetBestSourceAddressForDestinationAddress(
|
||
IN ULONG ulDestinationAddress,
|
||
IN BOOL fDemandDial,
|
||
OUT ULONG* pulBestSrcAddress
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
We create a temporary UDP socket, connect the socket to the
|
||
actual client's IP address, extract the IP address to which
|
||
the socket is implicitly bound by the TCP/IP driver, and
|
||
discard the socket. This leaves us with the exact IP address
|
||
that we need to use to contact the client.
|
||
|
||
Arguments:
|
||
|
||
ulDestinationAddress,
|
||
fDemandDial,
|
||
pulBestSrcAddress
|
||
|
||
|
||
Return Value:
|
||
|
||
HRESULT - S_OK for success
|
||
|
||
Environment:
|
||
|
||
ALG module will call this method to:
|
||
|
||
--*/
|
||
|
||
{
|
||
MYTRACE_ENTER("CNat::GetBestSourceAddressForDestinationAddress");
|
||
|
||
if ( !pulBestSrcAddress )
|
||
{
|
||
MYTRACE_ERROR("pulBestSrcAddress not supplied",0);
|
||
return E_INVALIDARG;
|
||
}
|
||
|
||
|
||
SOCKADDR_IN SockAddr;
|
||
|
||
SockAddr.sin_family = AF_INET;
|
||
SockAddr.sin_port = 0;
|
||
SockAddr.sin_addr.s_addr = ulDestinationAddress;
|
||
|
||
|
||
ULONG Length = sizeof(SockAddr);
|
||
|
||
|
||
SOCKET UdpSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||
|
||
if ( INVALID_SOCKET == UdpSocket
|
||
|| SOCKET_ERROR == connect(UdpSocket, (PSOCKADDR)&SockAddr, sizeof(SockAddr))
|
||
|| SOCKET_ERROR == getsockname(UdpSocket, (PSOCKADDR)&SockAddr, (int*)&Length)
|
||
)
|
||
{
|
||
ULONG nError = WSAGetLastError();
|
||
|
||
if ( nError == WSAEHOSTUNREACH )
|
||
{
|
||
if ( fDemandDial )
|
||
nError = RasAutoDialSharedConnection();
|
||
|
||
if ( ERROR_SUCCESS != nError )
|
||
{
|
||
MYTRACE_ERROR(" RasAutoDialSharedConnection failed [%d]", nError);
|
||
|
||
if ( UdpSocket != INVALID_SOCKET )
|
||
{
|
||
closesocket(UdpSocket);
|
||
}
|
||
|
||
return HRESULT_FROM_WIN32(nError);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
MYTRACE_ERROR("error %d routing endpoint %d using UDP", nError);
|
||
|
||
if (UdpSocket != INVALID_SOCKET)
|
||
{
|
||
closesocket(UdpSocket);
|
||
}
|
||
|
||
return HRESULT_FROM_WIN32(nError);
|
||
}
|
||
}
|
||
|
||
*pulBestSrcAddress = SockAddr.sin_addr.s_addr;
|
||
|
||
closesocket(UdpSocket);
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
|
||
|
||
STDMETHODIMP CNat::LookupAdapterPortMapping(
|
||
IN ULONG ulAdapterIndex,
|
||
IN UCHAR Protocol,
|
||
IN ULONG ulDestinationAddress,
|
||
IN USHORT usDestinationPort,
|
||
OUT ULONG* pulRemapAddress,
|
||
OUT USHORT* pusRemapPort
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Call NAT port maping to ge the real destination for the port
|
||
This ofcourse is the use has set some maping in the SharedConnection or Firewalled adapter on the Service Tab.
|
||
|
||
Arguments:
|
||
|
||
ulAdapterIndex - Index of the IP adapter of the session.
|
||
|
||
Protocol - eALG_PROTOCOL_UDP, eALG_PROTOCOL_TCP
|
||
DestinationAddress - the edge public adapter address
|
||
DestinationPort - the edge public adapter port
|
||
|
||
RemapAddres - The address where that the user itended this port to go to (Private computer on the private lan)
|
||
SourcePort - Should be the same as the DestinationPort for future it may be different.
|
||
|
||
|
||
Return Value:
|
||
|
||
HRESULT - S_OK if it worked or E_FAIL if no maping was found
|
||
|
||
--*/
|
||
{
|
||
MYTRACE_ENTER("LookupAdapterPortMapping");
|
||
MYTRACE("AdapterIndex %d Protocol %d DestAddress %s:%d", ulAdapterIndex, ProtocolConvertToNT(Protocol), MYTRACE_IP(ulDestinationAddress), ntohs(usDestinationPort));
|
||
|
||
IP_NAT_PORT_MAPPING PortMapping;
|
||
|
||
ULONG Error = NatLookupPortMappingAdapter(
|
||
ulAdapterIndex,
|
||
ProtocolConvertToNT(Protocol),
|
||
ulDestinationAddress,
|
||
usDestinationPort,
|
||
&PortMapping
|
||
);
|
||
|
||
if ( Error )
|
||
{
|
||
MYTRACE_ERROR("from NatLookupPortMappingAdapter", Error);
|
||
return HRESULT_FROM_WIN32(Error);
|
||
}
|
||
|
||
*pulRemapAddress = PortMapping.PrivateAddress;
|
||
*pusRemapPort = PortMapping.PrivatePort;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
STDMETHODIMP CNat::GetOriginalDestinationInformation(
|
||
IN UCHAR Protocol,
|
||
|
||
IN ULONG ulDestinationAddress,
|
||
IN USHORT usDestinationPort,
|
||
|
||
IN ULONG ulSourceAddress,
|
||
IN USHORT usSourcePort,
|
||
|
||
OUT ULONG* pulOriginalDestinationAddress,
|
||
OUT USHORT* pusOriginalDestinationPort,
|
||
|
||
OUT ULONG* pulAdapterIndex
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Determine the original destination endpoint of a session that is redirected to.
|
||
|
||
Arguments:
|
||
|
||
|
||
DestinationAddress - destination endpoint of the session to be redirected
|
||
DestinationPort - "
|
||
|
||
SourceAddress - source endpoint of the session to be redirected
|
||
SourcePort - "
|
||
|
||
NewDestinationAddress - replacement destination endpoint for the session
|
||
NewDestinationPort - "
|
||
|
||
NewSourceAddress - replacement source endpoint for the session
|
||
NewSourcePort - "
|
||
|
||
pulOriginalDestinationAddress - Returns the original address of the destination (Where the caller realy wanted to go)
|
||
pusOriginalDestinationPort - Returns the original port of the destination
|
||
|
||
pulAdapterIndex - Index of the IP adapter of the session.
|
||
|
||
Return Value:
|
||
|
||
HRESULT - S_OK if it worked or E_FAIL
|
||
|
||
--*/
|
||
{
|
||
MYTRACE_ENTER("CNat::GetOriginalDestinationInformation");
|
||
MYTRACE("Destination %s:%d", MYTRACE_IP(ulDestinationAddress), ntohs(usDestinationPort));
|
||
MYTRACE("Address %s:%d", MYTRACE_IP(ulSourceAddress), ntohs(usSourcePort));
|
||
|
||
ASSERT(pulOriginalDestinationAddress!=NULL);
|
||
ASSERT(pusOriginalDestinationPort!=NULL);
|
||
ASSERT(pulAdapterIndex!=NULL);
|
||
|
||
|
||
IP_NAT_SESSION_MAPPING_KEY_EX Information;
|
||
ULONG ulSizeOfInformation = sizeof(IP_NAT_SESSION_MAPPING_KEY_EX);
|
||
|
||
ULONG Error = NatLookupAndQueryInformationSessionMapping(
|
||
GetTranslatorHandle(),
|
||
ProtocolConvertToNT(Protocol),
|
||
|
||
ulDestinationAddress,
|
||
usDestinationPort,
|
||
|
||
ulSourceAddress,
|
||
usSourcePort,
|
||
|
||
&Information,
|
||
&ulSizeOfInformation,
|
||
NatKeySessionMappingExInformation
|
||
);
|
||
|
||
|
||
if ( ERROR_SUCCESS != Error )
|
||
{
|
||
MYTRACE_ERROR("Call to NatLookupAndQueryInformationMapping", Error);
|
||
return HRESULT_FROM_WIN32(Error);
|
||
}
|
||
|
||
MYTRACE("Original Index %d Address:Port %s:%d", Information.AdapterIndex, MYTRACE_IP(Information.DestinationAddress), ntohs(Information.DestinationPort));
|
||
|
||
*pulOriginalDestinationAddress = Information.DestinationAddress;
|
||
*pusOriginalDestinationPort = Information.DestinationPort;
|
||
*pulAdapterIndex = Information.AdapterIndex;
|
||
|
||
return S_OK;
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
STDMETHODIMP CNat::ReservePort(
|
||
IN USHORT PortCount,
|
||
OUT PUSHORT pReservedPortBase
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Call the into the NAP api to reserve the required port on behave of the ALG module.
|
||
|
||
Arguments:
|
||
|
||
PortCount - Number of port to reserve
|
||
pReservedPortBase - Starting number of the range of port reserved. example ReserePort(3, &) would save 5000,5001,5002 and return 5000 as base
|
||
|
||
Return Value:
|
||
|
||
HRESULT - S_OK if it worked or E_FAIL
|
||
|
||
|
||
Environment:
|
||
|
||
Private interface between rmALG and ALG.EXE
|
||
|
||
ALG expose a more simple interface to reserve at Port
|
||
in turn it call this private interface that end up calling the more complex NatApi
|
||
|
||
--*/
|
||
{
|
||
MYTRACE_ENTER("CNat::ReservePort");
|
||
|
||
ASSERT(pReservedPortBase!=NULL);
|
||
|
||
if ( !AlgPortReservationHandle )
|
||
return E_FAIL; // AlgPortReservationHandle should already have been done
|
||
|
||
|
||
ULONG Error = NatAcquirePortReservation(
|
||
AlgPortReservationHandle,
|
||
PortCount,
|
||
pReservedPortBase
|
||
);
|
||
|
||
if ( ERROR_SUCCESS != Error )
|
||
{
|
||
MYTRACE_ERROR("from NatAcquirePortReservation", Error);
|
||
return HRESULT_FROM_WIN32(Error);
|
||
}
|
||
|
||
MYTRACE("PortBase %d count %d", *pReservedPortBase, PortCount);
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
STDMETHODIMP CNat::ReleasePort(
|
||
IN USHORT ReservedPortBase,
|
||
IN USHORT PortCount
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Private interface between rmALG and ALG.EXE
|
||
|
||
ALG expose a more simple interface to reserve at Port
|
||
in turn it call this private interface that end up calling the more complex NatApi
|
||
|
||
This routine will call the Nat api to release the previously reserved ports
|
||
|
||
Arguments:
|
||
|
||
PortCount - Number of port to reserve
|
||
pReservedPortBase - Starting number of the range of port reserved. example ReserePort(3, &) would save 5000,5001,5002 and return 5000 as base
|
||
|
||
Return Value:
|
||
|
||
HRESULT - S_OK if it worked or E_FAIL
|
||
|
||
Environment:
|
||
|
||
Private interface between rmALG and ALG.EXE
|
||
|
||
ALG expose a more simple interface to reserve at Port
|
||
in turn it call this private interface that end up calling the more complex NatApi
|
||
|
||
--*/
|
||
{
|
||
|
||
MYTRACE_ENTER("CNat::ReleasePort");
|
||
|
||
if ( !AlgPortReservationHandle )
|
||
return E_FAIL; // AlgPortReservationHandle should already have been done
|
||
|
||
ULONG Error = NatReleasePortReservation(
|
||
AlgPortReservationHandle,
|
||
ReservedPortBase,
|
||
PortCount
|
||
);
|
||
|
||
if ( ERROR_SUCCESS != Error )
|
||
{
|
||
MYTRACE_ERROR("from NatReleasePortReservation", Error);
|
||
return HRESULT_FROM_WIN32(Error);
|
||
}
|
||
|
||
MYTRACE("PortBase=%d, Count=%d", ntohs(ReservedPortBase), PortCount);
|
||
|
||
return S_OK;
|
||
}
|
||
|