Home › Forums › Discussions › General › How to get source IP address in TDI filter driver?
- This topic has 4 replies, 2 voices, and was last updated 17 years, 1 month ago by kokos.
-
AuthorPosts
-
November 20, 2007 at 5:36 pm #5150
Hello gurus.
I am writing a TDI filter driver which is using IoAttachDevice to attach to
protocol devices. In my filter driver, I handle TDI_CONNECT and
TDI_SEND_DATAGRAM and do some logics.The problem is, I need to get the source IP address and source port which is
initiating a connection. I can easially get the remote IP and port by
accessing PIO_STACK_LOCATION->Parameters field. But how can I get the source
IP and port?I did a massive googling regarding this problem. And I found only solution
regarding source port. The solution is posted by Jeff Runaway:
http://groups.google.com/group/microsoft.public.development.device.drivers/browse_thread/thread/6ecb94f4b27b480e/d612e6caa47e8376?lnk=gst&q=TDI_QUERY_INFORMATIONHowever, his code only retrievies the source port, not the IP address. How
to solve the problem with source IP? Thanks.November 21, 2007 at 5:30 pm #6491TDI_QUERY_INFORMATION allows getting both IP address and port. Refer the structures below in the DDK docs or MSDN.
typedef struct _TA_ADDRESS {
USHORT AddressLength;
USHORT AddressType;
UCHAR Address[1];
} TA_ADDRESS, *PTA_ADDRESS;
typedef struct _TA_ADDRESS_IP {
LONG TAAddressCount;
struct _AddrIp {
USHORT AddressLength;
USHORT AddressType;
TDI_ADDRESS_IP Address[1];
} Address [1];
} TA_IP_ADDRESS, *PTA_IP_ADDRESS;
typedef struct _TDI_ADDRESS_IP {
USHORT sin_port;
ULONG in_addr;
UCHAR sin_zero[8];
} TDI_ADDRESS_IP, *PTDI_ADDRESS_IP;November 22, 2007 at 8:34 am #6492Hello, thank you for reply.
Unfortunatly, TDI_QUERY_INFORMATION does not obtain the actual source IP address in 100 % of cases. I tried to obtain it using TDI_QUERY_INFORMATION and TDI_QUERY_ADDRESS_INFO but in 99 % of cases I get zero for source IP (you can take a look at the code I am using at the end of this message).
I also tried get the adapter info (TDI_QUERY_ADAPTER_STATUS) when I handle TDI_CONNECT and once I succeed I will be able to get the adapter address, but the TDI_QUERY_ADAPTER_STATUS is not implemented – IoCallDriver returns me STATUS_NOT_IMPLEMENTED.
When all my attempts failed, I downloaded the open source TDI firewall – tdi_fw to check how it detects the local IP address, and I noticed, that in major cases it detects the source IP as 0 (this can easially be seen in the logs).
OK then, I did again some googling, and found an interesting reply of DDK MVP: http://tech.groups.yahoo.com/group/discussion-pcausa/message/1516
Maybe, his reply explains why I always get the 0.0.0.0 – because the application specifies INADDR_ANY as a source address and TDI subsystem just gives me a hint that I can treat the source address, as any address of the currently running adapters. But I need to obtain the real source IP address …The code I am using to obtain the source IP (source port is correctly obtained):
USHORT GetPortFromAddressInfo(PDEVICE_OBJECT pDeviceObject, PFILE_OBJECT
pAddressObject)
{
NTSTATUS status ;
PIRP pIrp = NULL ;
PMDL pMDL = NULL ;
TDI_ADDRESS_INFO *pAddrInfo = NULL ;
TDI_ADDRESS_IP TDI_IP ;
USHORT usPort ;
IO_STATUS_BLOCK IoStatusBlock ;
pIrp = TdiBuildInternalDeviceControlIrp (TDI_QUERY_INFORMATION,
pDeviceObject,
pAddressObject,
NULL,
&IoStatusBlock
);
if(!pIrp)
{
DebugPrint("pIrp not allocated") ;
return 0 ;
}
if(!pAddrInfo) //not yet allocated
pAddrInfo = (TDI_ADDRESS_INFO*)ExAllocatePool(NonPagedPool , 2048) ;
if(!pAddrInfo) //not allocated
{
return 0 ;
}
{
pMDL = IoAllocateMdl(
pAddrInfo,
2048,
FALSE,
TRUE,
pIrp
);
}
if(!pMDL)
{
DebugPrint("MDL not allocated") ;
goto CLEANUP ;
}
//__try
{
MmProbeAndLockPages(pMDL, KernelMode, IoWriteAccess) ;
}
//__except(EXCEPTION_EXECUTE_HANDLER){
//DebugPrint("MDL not locked") ;
//bSuccess = 0 ;
//}
TdiBuildQueryInformation (
pIrp,
pDeviceObject,
pAddressObject,
NULL, //QUERY_COMPLETION_ROUTINE,
NULL,
TDI_QUERY_ADDRESS_INFO,
pMDL );
status = IoCallDriver(pDeviceObject, pIrp);
if( status == STATUS_SUCCESS )
{ in_addr *p_inetAddr ;
//DebugPrint("Connection State [%u]", pAddrInfo->ActivityCount) ;
TRANSPORT_ADDRESS *pTAddress = &pAddrInfo->Address ;
TA_ADDRESS *pTA = &pTAddress->Address[0] ;
RtlCopyMemory(&TDI_IP, (TDI_ADDRESS_IP*)pTA->Address,
TDI_ADDRESS_LENGTH_IP) ;
p_inetAddr = (in_addr*)&TDI_IP.in_addr ;
}
else
{
DebugPrint("Connection State - CallDriver failed") ;
}
usPort = TDI_IP.sin_port ;
CLEANUP:
if(pAddrInfo)
ExFreePool(pAddrInfo) ;
return usPort ;
}
November 23, 2007 at 9:50 am #6493Once the connection is established you can query the IP it was done from, but NOT before.
November 23, 2007 at 3:07 pm #6494Yes. I was trying to get the source IP before I pass the IRP processing down to the stack. So at that moment, the source IP was not formed.
So, now if I am obtaining the source IP after I pass IRP to next handler in the stack (via IoCallDriver) I get the correct value. But … This works only on XP and 2k. On Vista I continue to obtain the 0, however the port is correctly obtained.
What to do with Vista? 😥
-
AuthorPosts
- You must be logged in to reply to this topic.