Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

1254 lines
33 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
Abstract:
Revision History:
Amritansh Raghav
--*/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <ntioapi.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <crt\stddef.h>
#include <ntosp.h>
#include <ndis.h>
#include <windef.h>
//#include <ntddk.h>
#include <ipexport.h>
#include "defs.h"
#include <cxport.h>
#include <ip.h>
#include "ipfltdrv.h"
//#include "filter.h"
#include <winsock.h>
#include <ipinfo.h>
#include <llinfo.h>
#include <tcpinfo.h>
#include <tdiinfo.h>
#include <ntddtcp.h>
#include <ntddip.h>
#define is ==
#define isnot !=
#define and &&
#define or ||
DWORD InitializeFilter();
VOID DoAddInterface();
VOID DoSetFilters();
VOID DoFilterPacket();
VOID DoGetInfo();
VOID DoDeleteInterface();
VOID DoStopFilter();
VOID DoAddRoute();
VOID DoAddForwarderIf();
DWORD GetIpStatsFromStack(IPSNMPInfo *IPSnmpInfo);
DWORD GetIpAddrTableFromStack(IPAddrEntry *lpipaeTable, LPDWORD lpdwNumEntries);
VOID CloseHandles();
typedef struct _USER_IF
{
LIST_ENTRY ifLink;
PVOID pvIfContext;
CHAR pszName[80];
}USER_IF, *PUSER_IF;
LIST_ENTRY g_ifList;
HANDLE g_FilterDriverHandle;
HANDLE g_IpDriverHandle;
HANDLE g_TcpDriverHandle;
INT _cdecl main()
{
NTSTATUS ntStatus;
WORD wVersion = MAKEWORD(1,1);
WSADATA wsaData;
if(WSAStartup(wVersion,&wsaData) isnot NO_ERROR)
{
printf("WSAStartup failed\n");
return(1);
}
ntStatus = InitializeFilter();
if(ntStatus isnot STATUS_SUCCESS)
{
printf("Couldnt init filter - error %x\n",ntStatus);
exit(1);
}
InitializeListHead(&g_ifList);
while(TRUE)
{
CHAR cInput[10];
printf("\n----- USER MODE IP FILTER DRIVER TEST -----\n");
printf("1.\tAdd Interface\n");
printf("2.\tSet Filters\n");
printf("3.\tFilter Packet\n");
printf("4.\tGet Info\n");
printf("5.\tDelete Interface\n");
printf("6.\tStop Filter\n");
printf("7.\tAdd Route to Forwarder\n");
printf("8.\tAdd Interface to Forwarder\n");
printf("99.\tQuit\n");
printf("Selection:\t");
gets(cInput);
printf("\n");
switch(atoi(cInput))
{
case 1:
{
DoAddInterface();
break;
}
case 2:
{
DoSetFilters();
break;
}
case 3:
{
DoFilterPacket();
break;
}
case 4:
{
DoGetInfo();
break;
}
case 5:
{
DoDeleteInterface();
break;
}
case 6:
{
DoStopFilter();
break;
}
case 7:
{
DoAddRoute();
break;
}
case 8:
{
DoAddForwarderIf();
break;
}
case 99:
{
DoStopFilter();
WSACleanup();
return(0);
}
default:
{
continue;
}
}
}
return(0);
}
VOID
DoAddInterface()
{
NTSTATUS ntStatus;
IO_STATUS_BLOCK IoStatusBlock;
CHAR cName[70];
FILTER_DRIVER_CREATE_INTERFACE inBuffer;
DWORD dwInBufLen = sizeof(FILTER_DRIVER_CREATE_INTERFACE);
PUSER_IF pIf;
if((pIf = HeapAlloc(GetProcessHeap(),0,sizeof(USER_IF))) is NULL)
{
printf("Couldnt allocate memory\n");
}
printf("Enter new interface name: ");
gets(pIf->pszName);
printf("\n");
InitializeListHead(&pIf->ifLink);
inBuffer.dwIfIndex = 0;
inBuffer.pvRtrMgrContext = NULL;
ntStatus = NtDeviceIoControlFile(g_FilterDriverHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_CREATE_INTERFACE,
(PVOID)&inBuffer,
dwInBufLen,
(PVOID)&inBuffer,
dwInBufLen);
if (!NT_SUCCESS(ntStatus))
{
printf("IOCTL failed - status %x \n", ntStatus);
HeapFree(GetProcessHeap(),0,pIf);
return;
}
printf("Added interface, context %x\n",(UINT_PTR)inBuffer.pvDriverContext);
pIf->pvIfContext = inBuffer.pvDriverContext;
InsertHeadList(&g_ifList,&(pIf->ifLink));
return;
}
VOID
DoSetFilters()
{
NTSTATUS ntStatus;
IO_STATUS_BLOCK IoStatusBlock;
PFILTER_INFO pInfo;
PFILTER_DRIVER_SET_FILTERS pIo;
DWORD i,dwNumInFilters = 0,dwNumOutFilters = 0,dwInBufLen;
PLIST_ENTRY currentList;
BYTE cAddr[50];
PUSER_IF pIf;
BOOL bSetInput,bSetOutput,bDelInput,bDelOutput;
FORWARD_ACTION faOutAction,faInAction;
DWORD dwInIndex,dwOutIndex;
currentList = g_ifList.Flink;
i = 1;
printf("\nCurrent Interfaces\n");
while(currentList isnot &g_ifList)
{
pIf = CONTAINING_RECORD(currentList,USER_IF,ifLink);
printf("\t%d. %s\n",i++,pIf->pszName);
currentList = currentList->Flink;
}
printf("Input Interface index: ");
gets(cAddr);
printf("\n");
currentList = g_ifList.Flink;
i = 1;
pIf = NULL;
while(currentList isnot &g_ifList)
{
if(i is (DWORD)atoi(cAddr))
{
pIf = CONTAINING_RECORD(currentList,USER_IF,ifLink);
break;
}
i++;
currentList = currentList->Flink;
}
if(pIf is NULL)
{
printf("Couldnt find interface block\n");
return;
}
printf("Setting filters for %s with context %#08x\n",pIf->pszName,
(UINT_PTR)pIf->pvIfContext);
dwInBufLen = sizeof(FILTER_DRIVER_SET_FILTERS) - sizeof(RTR_TOC_ENTRY);
printf("Do you want to modify input filters? (0/1): ");
gets(cAddr);
printf("\n");
if(atoi(cAddr) is 1)
{
dwInBufLen += sizeof(RTR_TOC_ENTRY);
bSetInput = TRUE;
}
else
{
bSetInput = FALSE;
}
printf("Do you want to modify output filters? (0/1): ");
gets(cAddr);
printf("\n");
if(atoi(cAddr) is 1)
{
dwInBufLen += sizeof(RTR_TOC_ENTRY);
bSetOutput = TRUE;
}
else
{
bSetOutput = FALSE;
}
if(bSetInput)
{
printf("Do you want to delete all in filters?(0/1): ");
gets(cAddr);
printf("\n");
if(atoi(cAddr) is 0)
{
printf("How many input filters (0 will remove filters but allow a default action)?: ");
gets(cAddr);
printf("\n");
dwNumInFilters = atoi(cAddr);
printf("Default in action (0 - FORWARD, 1 - DROP): ");
gets(cAddr);
printf("\n");
faInAction = (FORWARD_ACTION)atoi(cAddr);
dwInBufLen += sizeof(FILTER_DESCRIPTOR) - sizeof(FILTER_INFO);
bDelInput = FALSE;
}
else
{
bDelInput = TRUE;
}
}
if(bSetOutput)
{
printf("Do you want to delete all out filters?(0/1): ");
gets(cAddr);
printf("\n");
if(atoi(cAddr) is 0)
{
printf("How many out filters (0 will remove filters but allow a default action)?: ");
gets(cAddr);
printf("\n");
dwNumInFilters = atoi(cAddr);
printf("Default in action (0 - FORWARD, 1 - DROP): ");
gets(cAddr);
printf("\n");
faOutAction = (FORWARD_ACTION)atoi(cAddr);
dwInBufLen += sizeof(FILTER_DESCRIPTOR) - sizeof(FILTER_INFO);
bDelOutput = FALSE;
}
else
{
bDelOutput = TRUE;
}
}
if(!(bSetInput or bSetOutput) )
{
return;
}
dwInBufLen += ((dwNumInFilters + dwNumOutFilters -1) * sizeof(FILTER_INFO));
pIo = HeapAlloc(GetProcessHeap(),0,dwInBufLen);
if(pIo is NULL)
{
printf("Couldnt allocate memory\n");
return;
}
pIo->pvDriverContext = (PVOID)pIf;
dwInIndex = 0;
dwOutIndex = 1;
if(!bSetInput)
{
dwOutIndex = 0;
}
pIo->ribhInfoBlock.Version = IP_FILTER_DRIVER_VERSION;
pIo->ribhInfoBlock.Size = dwInBufLen - FIELD_OFFSET(FILTER_DRIVER_SET_FILTERS,
ribhInfoBlock);
pIo->ribhInfoBlock.TocEntriesCount = 0;
if(bSetInput)
{
pIo->ribhInfoBlock.TocEntry[dwInIndex].InfoType = IP_FILTER_DRIVER_IN_FILTER_INFO;
if(bDelInput)
{
pIo->ribhInfoBlock.TocEntry[dwInIndex].InfoSize = 0;
pIo->ribhInfoBlock.TocEntry[dwInIndex].Offset = 0;
pIo->ribhInfoBlock.TocEntry[dwInIndex].Count = 0;
}
else
{
pIo->ribhInfoBlock.TocEntry[dwInIndex].InfoSize = sizeof(FILTER_DESCRIPTOR) -
sizeof(FILTER_INFO) + (dwNumInFilters * sizeof(FILTER_INFO));
if(bSetOutput)
{
pIo->ribhInfoBlock.TocEntry[dwInIndex].Offset = (ULONG) (((PBYTE)&pIo->ribhInfoBlock.TocEntry[2] - (PBYTE)&pIo->ribhInfoBlock));
}
else
{
pIo->ribhInfoBlock.TocEntry[dwInIndex].Offset = (ULONG) (((PBYTE)&pIo->ribhInfoBlock.TocEntry[1] - (PBYTE)&pIo->ribhInfoBlock));
}
pIo->ribhInfoBlock.TocEntry[dwInIndex].Count = 1;
}
}
if(bSetOutput)
{
pIo->ribhInfoBlock.TocEntry[dwOutIndex].InfoType = IP_FILTER_DRIVER_OUT_FILTER_INFO;
if(bDelOutput)
{
pIo->ribhInfoBlock.TocEntry[dwOutIndex].InfoSize = 0;
pIo->ribhInfoBlock.TocEntry[dwOutIndex].Offset = 0;
pIo->ribhInfoBlock.TocEntry[dwOutIndex].Count = 0;
}
else
{
pIo->ribhInfoBlock.TocEntry[dwOutIndex].InfoSize = sizeof(FILTER_DESCRIPTOR) -
sizeof(FILTER_INFO) + (dwNumOutFilters * sizeof(FILTER_INFO));
if(bSetInput)
{
pIo->ribhInfoBlock.TocEntry[dwOutIndex].Offset = (ULONG) (((PBYTE)&pIo->ribhInfoBlock.TocEntry[2] + pIo->ribhInfoBlock.TocEntry[1].InfoSize - (PBYTE)&pIo->ribhInfoBlock));
}
else
{
pIo->ribhInfoBlock.TocEntry[dwOutIndex].Offset = (ULONG) (((PBYTE)&pIo->ribhInfoBlock.TocEntry[1] - (PBYTE)&pIo->ribhInfoBlock));
}
pIo->ribhInfoBlock.TocEntry[dwOutIndex].Count = 1;
}
}
if(bSetInput and !bDelInput)
{
pInfo = ((PFILTER_DESCRIPTOR)((PBYTE)&pIo->ribhInfoBlock + pIo->ribhInfoBlock.TocEntry[dwInIndex].Offset))->fiFilter;
((PFILTER_DESCRIPTOR)((PBYTE)&pIo->ribhInfoBlock + pIo->ribhInfoBlock.TocEntry[dwInIndex].Offset))->dwVersion = IP_FILTER_DRIVER_VERSION;
((PFILTER_DESCRIPTOR)((PBYTE)&pIo->ribhInfoBlock + pIo->ribhInfoBlock.TocEntry[dwInIndex].Offset))->dwNumFilters = dwNumInFilters;
((PFILTER_DESCRIPTOR)((PBYTE)&pIo->ribhInfoBlock + pIo->ribhInfoBlock.TocEntry[dwInIndex].Offset))->faDefaultAction = faInAction;
printf("Input Filters - addresses and mask in dotted decimal\n");
for(i = 0; i < dwNumInFilters; i++)
{
printf("Enter source addr: ");
gets(cAddr);
printf("\n");
pInfo[i].dwSrcAddr = inet_addr(cAddr);
printf("Enter source mask: ");
gets(cAddr);
printf("\n");
pInfo[i].dwSrcMask = inet_addr(cAddr);
printf("Enter dest addr: ");
gets(cAddr);
printf("\n");
pInfo[i].dwDstAddr = inet_addr(cAddr);
printf("Enter dest mask: ");
gets(cAddr);
printf("\n");
pInfo[i].dwDstMask = inet_addr(cAddr);
printf("Enter protocol id - 0 for any: ");
gets(cAddr);
printf("\n");
pInfo[i].dwProtocol = atoi(cAddr);
pInfo[i].wSrcPort = pInfo[i].wDstPort = 0x00000000;
switch(pInfo[i].dwProtocol)
{
case 1:
{
printf("Enter type - 255 for any");
gets(cAddr);
printf("\n");
pInfo[i].wSrcPort = (BYTE)atoi(cAddr);
printf("Enter code - 255 for any");
gets(cAddr);
printf("\n");
pInfo[i].wDstPort = (BYTE)atoi(cAddr);
break;
}
case 6:
case 17:
{
printf("Enter source port - 0 for any: ");
gets(cAddr);
printf("\n");
pInfo[i].wSrcPort = htons((WORD)atoi(cAddr));
printf("Enter Dst Port - 0 for any: ");
gets(cAddr);
printf("\n");
pInfo[i].wDstPort = htons((WORD)atoi(cAddr));
break;
}
}
}
}
if(bSetOutput and !bDelOutput)
{
pInfo = ((PFILTER_DESCRIPTOR)((PBYTE)&pIo->ribhInfoBlock + pIo->ribhInfoBlock.TocEntry[dwOutIndex].Offset))->fiFilter;
((PFILTER_DESCRIPTOR)((PBYTE)&pIo->ribhInfoBlock + pIo->ribhInfoBlock.TocEntry[dwOutIndex].Offset))->dwVersion = IP_FILTER_DRIVER_VERSION;
((PFILTER_DESCRIPTOR)((PBYTE)&pIo->ribhInfoBlock + pIo->ribhInfoBlock.TocEntry[dwOutIndex].Offset))->dwNumFilters = dwNumOutFilters;
((PFILTER_DESCRIPTOR)((PBYTE)&pIo->ribhInfoBlock + pIo->ribhInfoBlock.TocEntry[dwOutIndex].Offset))->faDefaultAction = faOutAction;
printf("Output Filters - addresses and mask in dotted decimal\n");
for(i = 0; i < dwNumOutFilters; i++)
{
printf("Enter source addr: ");
gets(cAddr);
printf("\n");
pInfo[i].dwSrcAddr = inet_addr(cAddr);
printf("Enter source mask: ");
gets(cAddr);
printf("\n");
pInfo[i].dwSrcMask = inet_addr(cAddr);
printf("Enter dest addr: ");
gets(cAddr);
printf("\n");
pInfo[i].dwDstAddr = inet_addr(cAddr);
printf("Enter dest mask: ");
gets(cAddr);
printf("\n");
pInfo[i].dwDstMask = inet_addr(cAddr);
printf("Enter protocol id - 0 for any: ");
gets(cAddr);
printf("\n");
pInfo[i].dwProtocol = atoi(cAddr);
pInfo[i].wSrcPort = pInfo[i].wDstPort = 0x00000000;
switch(pInfo[i].dwProtocol)
{
case 1:
{
printf("Enter type - 255 for any");
gets(cAddr);
printf("\n");
pInfo[i].wSrcPort = (BYTE)atoi(cAddr);
printf("Enter code - 255 for any");
gets(cAddr);
printf("\n");
pInfo[i].wDstPort = (BYTE)atoi(cAddr);
break;
}
case 6:
case 17:
{
printf("Enter source port - 0 for any: ");
gets(cAddr);
printf("\n");
pInfo[i].wSrcPort = htons((WORD)atoi(cAddr));
printf("Enter Dst Port - 0 for any: ");
gets(cAddr);
printf("\n");
pInfo[i].wDstPort = htons((WORD)atoi(cAddr));
}
}
}
}
ntStatus = NtDeviceIoControlFile(g_FilterDriverHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_SET_INTERFACE_FILTERS,
(PVOID)pIo,
dwInBufLen,
NULL,
0);
if (!NT_SUCCESS(ntStatus))
{
printf("IOCTL failed - status %x \n", ntStatus);
}
printf("Filters set\n");
HeapFree(GetProcessHeap(),0,pIo);
return;
}
VOID
DoFilterPacket()
{
NTSTATUS ntStatus;
IO_STATUS_BLOCK IoStatusBlock;
DWORD i,dwInBufLen;
BYTE cAddr[40];
PFILTER_DRIVER_TEST_PACKET pTest;
IPHeader *pIph;
PWORD pwPort;
PLIST_ENTRY currentList;
PUSER_IF pInIf = NULL, pOutIf = NULL, pIf;
dwInBufLen = sizeof(FILTER_DRIVER_TEST_PACKET) + sizeof(IPHeader) + 2*sizeof(DWORD);
pTest = HeapAlloc(GetProcessHeap(),0,dwInBufLen);
if(pTest is NULL)
{
printf("Couldnt allocate memory for the packet\n");
return;
}
pIph = (IPHeader*)(pTest->bIpPacket);
pwPort = (PWORD)((PBYTE)pIph + sizeof(IPHeader));
currentList = g_ifList.Flink;
i=1;
printf("\nCurrent Interfaces\n");
while(currentList isnot &g_ifList)
{
pIf = CONTAINING_RECORD(currentList,USER_IF,ifLink);
printf("\t%d. %s\n",i++,pIf->pszName);
currentList = currentList->Flink;
}
printf("Index of input Interface <enter for none>: ");
gets(cAddr);
printf("\n");
if(strlen(cAddr) isnot 0)
{
DWORD dwInIf = atoi(cAddr);
currentList = g_ifList.Flink;
i = 1;
while(currentList isnot &g_ifList)
{
if(i is dwInIf)
{
pInIf = CONTAINING_RECORD(currentList,USER_IF,ifLink);
break;
}
i++;
currentList = currentList->Flink;
}
}
printf("Index of output Interface <enter for none>: ");
gets(cAddr);
printf("\n");
if(strlen(cAddr) isnot 0)
{
DWORD dwOutIf = atoi(cAddr);
currentList = g_ifList.Flink;
i = 1;
while(currentList isnot &g_ifList)
{
if(i is dwOutIf)
{
pOutIf = CONTAINING_RECORD(currentList,USER_IF,ifLink);
break;
}
i++;
currentList = currentList->Flink;
}
}
printf("Input if is %s and output if is %s\n",
(pInIf is NULL)? "NULL":pInIf->pszName,
(pOutIf is NULL)?"NULL":pOutIf->pszName);
pTest->pvInInterfaceContext = (pInIf is NULL)?NULL:pInIf->pvIfContext;
pTest->pvOutInterfaceContext = (pOutIf is NULL)?NULL:pOutIf->pvIfContext;
printf("Enter packet header\n\n");
printf("Enter source addr: ");
gets(cAddr);
printf("\n");
pIph->iph_src = (IPAddr)inet_addr(cAddr);
printf("Enter dest addr: ");
gets(cAddr);
printf("\n");
pIph->iph_dest = (IPAddr)inet_addr(cAddr);
printf("Enter Protocol id - 0 for any: ");
gets(cAddr);
printf("\n");
pIph->iph_protocol = (UCHAR)LOBYTE(atoi(cAddr));
printf("Is this a fragment? (1 - yes 0 - no): ");
gets(cAddr);
printf("\n");
if(atoi(cAddr) is 0)
{
printf("Enter source port - 0 for any: ");
gets(cAddr);
printf("\n");
pwPort[0] = htons((WORD)atoi(cAddr));
printf("Enter Dst Port - 0 for any: ");
gets(cAddr);
printf("\n");
pwPort[1] = htons((WORD)atoi(cAddr));
pIph->iph_offset = 0x0000; // no flags , no fragment
}
else
{
// Lets give it a frag offset of 100 - 64h
pIph->iph_offset = 0x6400;
}
//
// Fill up the rest of the packet with some meaningful info
//
pIph->iph_verlen = '\x45'; //Version = 4 Hdr Len = 5*4bytes
pIph->iph_tos = '\x0f'; //TOS signature for mem dumps
pIph->iph_length = htons((WORD)(sizeof(IPHeader)+2*sizeof(DWORD))); //Length in bytes
pIph->iph_id = 0xcdab; //ID another signature
pIph->iph_ttl = 0xef; // TTL
pIph->iph_xsum = 0xcdab; //Checksum;
ntStatus = NtDeviceIoControlFile(g_FilterDriverHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_TEST_PACKET,
(PVOID)pTest,
dwInBufLen,
(PVOID)pTest,
dwInBufLen);
if (!NT_SUCCESS(ntStatus))
{
printf("IOCTL failed - status %x \n", ntStatus);
return;
}
if(pTest->eaResult is DROP)
{
printf("Packet rejected\n");
}
else
{
printf("Packet accepted\n");
}
HeapFree(GetProcessHeap(),0,pTest);
return;
}
VOID
DoDeleteInterface()
{
}
VOID
DoStopFilter()
{
CloseHandles();
}
VOID
DoGetInfo()
{
}
VOID
DoAddRoute()
{
TDIObjectID *lpObject;
IPRouteEntry *lpentry;
NTSTATUS ntStatus;
IO_STATUS_BLOCK IoStatusBlock;
CHAR szIPAddr[20];
DWORD dwInBufLen;
TCP_REQUEST_SET_INFORMATION_EX *lptrsiBuffer;
BYTE buffer[sizeof(TCP_REQUEST_SET_INFORMATION_EX) + sizeof(IPRouteEntry)];
lptrsiBuffer = (TCP_REQUEST_SET_INFORMATION_EX *)buffer;
lptrsiBuffer->BufferSize = sizeof(IPRouteEntry);
lpObject = &lptrsiBuffer->ID;
lpObject->toi_id = IP_MIB_RTTABLE_ENTRY_ID;
lpObject->toi_type = INFO_TYPE_PROVIDER;
lpObject->toi_class = INFO_CLASS_PROTOCOL;
lpObject->toi_entity.tei_entity = CL_NL_ENTITY;
lpObject->toi_entity.tei_instance = 0;
lpentry = (IPRouteEntry *)lptrsiBuffer->Buffer;
dwInBufLen = sizeof(TCP_REQUEST_SET_INFORMATION_EX) + sizeof(IPRouteEntry) - 1;
printf("Enter Address (Dotted Decimal Form): ");
gets(szIPAddr);
printf("\n");
lpentry->ire_dest = inet_addr(szIPAddr);
printf("Enter IF (numerical):");
gets(szIPAddr);
printf("\n");
lpentry->ire_index = atoi(szIPAddr);
printf("Enter Next Hop (Dotted Decimal Form): ");
gets(szIPAddr);
printf("\n");
lpentry->ire_nexthop = inet_addr(szIPAddr);
printf("Enter Mask (Dotted Decimal Form): ");
gets(szIPAddr);
printf("\n");
lpentry->ire_mask = inet_addr(szIPAddr);
printf("Enter Metric 1: ");
gets(szIPAddr);
printf("\n");
lpentry->ire_metric1 = atoi(szIPAddr);
lpentry->ire_metric2 =
lpentry->ire_metric3 =
lpentry->ire_metric4 =
lpentry->ire_metric5 = IRE_METRIC_UNUSED;
lpentry->ire_age = 0;
printf("Enter type 2 - invalid 3 - direct 4 - indirect: ");
gets(szIPAddr);
printf("\n");
lpentry->ire_type = atoi(szIPAddr);
lpentry->ire_proto = IRE_PROTO_LOCAL;
ntStatus = NtDeviceIoControlFile(g_TcpDriverHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_TCP_SET_INFORMATION_EX,
(PVOID)lptrsiBuffer,
dwInBufLen,
NULL,
0);
if(ntStatus is STATUS_PENDING)
{
ntStatus = NtWaitForSingleObject(g_TcpDriverHandle, FALSE, NULL );
ntStatus = IoStatusBlock.Status;
}
if (!NT_SUCCESS(ntStatus))
{
printf("IOCTL failed to get set route - error %x\n",ntStatus);
}
}
VOID
DoAddForwarderIf()
{
NTSTATUS ntStatus;
IO_STATUS_BLOCK IoStatusBlock;
DWORD dwResult;
DWORD dwSpace,dwId,dwIf,i;
IPSNMPInfo ipsiInfo;
IPAddrEntry *pAddrTable;
PLIST_ENTRY currentList;
PUSER_IF pIf;
IP_SET_IF_CONTEXT_INFO info;
CHAR cAddr1[20],cAddr2[20];
dwResult = GetIpStatsFromStack(&ipsiInfo);
if(dwResult isnot NO_ERROR)
{
printf("Couldnt get Ip Snmp info from stack for num addr error %x\n",dwResult);
return;
}
dwSpace = ipsiInfo.ipsi_numaddr + 10;
pAddrTable = HeapAlloc(GetProcessHeap(),0,dwSpace * sizeof(IPAddrEntry));
if(pAddrTable is NULL)
{
printf("Couldnt allocate space for ipAddr table\n");
return;
}
dwResult = GetIpAddrTableFromStack(pAddrTable,&dwSpace);
if(dwResult isnot NO_ERROR)
{
printf("Couldnt get addr table from stack %x\n",dwResult);
HeapFree(GetProcessHeap(),0,pAddrTable);
return;
}
printf("\nForwarder Interfaces\n");
printf("Index\tAddress\t\tMask\n");
for(i = 0; i < dwSpace; i++)
{
struct in_addr addr;
addr.s_addr = pAddrTable[i].iae_addr;
strcpy(cAddr1,inet_ntoa(addr));
addr.s_addr = pAddrTable[i].iae_mask;
strcpy(cAddr2,inet_ntoa(addr));
printf("%d.\t%s\t\t%s\n",pAddrTable[i].iae_index,cAddr1,cAddr2);
}
printf("\nFilter Interfaces\n");
currentList = g_ifList.Flink;
i = 1;
while(currentList isnot &g_ifList)
{
pIf = CONTAINING_RECORD(currentList,USER_IF,ifLink);
printf("\t%d. %s\n",i++,pIf->pszName);
currentList = currentList->Flink;
}
while(TRUE)
{
printf("Enter Forwarder index (99 to exit): ");
gets(cAddr1);
printf("\n");
dwId = atoi(cAddr1);
if(dwId is 99)
break;
printf("Enter Interface Index to associate with: ");
gets(cAddr1);
printf("\n");
dwIf = atoi(cAddr1);
currentList = g_ifList.Flink;
i = 1;
pIf = NULL;
while(currentList isnot &g_ifList)
{
if(i is dwIf)
{
pIf = CONTAINING_RECORD(currentList,USER_IF,ifLink);
break;
}
i++;
currentList = currentList->Flink;
}
if(pIf is NULL)
{
printf("Couldnt find filter interface\n");
continue;
}
info.Index = dwId;
info.Context = pIf->pvIfContext;
ntStatus = NtDeviceIoControlFile(g_IpDriverHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_IP_SET_IF_CONTEXT,
(PVOID)&info,
sizeof(IP_SET_IF_CONTEXT_INFO),
NULL,
0);
if(!NT_SUCCESS(ntStatus))
{
printf("Couldnt set context\n");
}
else
{
printf("Set context successfully\n");
}
}
HeapFree(GetProcessHeap(),0,pAddrTable);
return;
}
DWORD
InitializeFilter()
{
NTSTATUS status;
UNICODE_STRING nameString;
IO_STATUS_BLOCK ioStatusBlock;
OBJECT_ATTRIBUTES objectAttributes;
RtlInitUnicodeString(&nameString,DD_IPFLTRDRVR_DEVICE_NAME);
InitializeObjectAttributes(&objectAttributes, &nameString,
OBJ_CASE_INSENSITIVE, NULL, NULL);
status = NtCreateFile(&g_FilterDriverHandle,
SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
&objectAttributes,
&ioStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN_IF,
0,
NULL,
0);
if(!NT_SUCCESS(status))
{
printf("Couldnt create filter driver handle\n");
return(status);
}
RtlInitUnicodeString(&nameString, DD_IP_DEVICE_NAME);
InitializeObjectAttributes(&objectAttributes, &nameString,
OBJ_CASE_INSENSITIVE, NULL, NULL);
status = NtCreateFile(&g_IpDriverHandle,
SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
&objectAttributes,
&ioStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN_IF,
0,
NULL,
0);
if(!NT_SUCCESS(status))
{
printf("Couldnt create ip driver handle\n");
return(status);
}
RtlInitUnicodeString(&nameString, DD_TCP_DEVICE_NAME);
InitializeObjectAttributes(&objectAttributes, &nameString,
OBJ_CASE_INSENSITIVE, NULL, NULL);
status = NtCreateFile(&g_TcpDriverHandle,
SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
&objectAttributes,
&ioStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN_IF,
0,
NULL,
0);
if(!NT_SUCCESS(status))
{
printf("Couldnt create tcp driver handle\n");
}
return (status);
}
//* CloseHandles()
//
// Function: Close TCPIP stack handle.
//
// Returns: 0
//*
VOID
CloseHandles ()
{
CloseHandle(g_FilterDriverHandle);
CloseHandle(g_IpDriverHandle);
CloseHandle(g_TcpDriverHandle);
}
DWORD
GetIpAddrTableFromStack(IPAddrEntry *lpipaeTable, LPDWORD lpdwNumEntries)
{
DWORD dwResult;
DWORD dwInBufLen;
DWORD dwOutBufLen;
DWORD i,j;
TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
TDIObjectID *ID;
BYTE *Context;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;
dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
dwOutBufLen = (*lpdwNumEntries) * sizeof( IPAddrEntry );
ID = &(trqiInBuf.ID);
ID->toi_entity.tei_entity = CL_NL_ENTITY;
ID->toi_entity.tei_instance = 0;
ID->toi_class = INFO_CLASS_PROTOCOL;
ID->toi_type = INFO_TYPE_PROVIDER;
ID->toi_id = IP_MIB_ADDRTABLE_ENTRY_ID;
Context = (BYTE *) &(trqiInBuf.Context[0]);
ZeroMemory( Context, CONTEXT_SIZE );
Status = NtDeviceIoControlFile(g_TcpDriverHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_TCP_QUERY_INFORMATION_EX,
(PVOID)&trqiInBuf,
dwInBufLen,
lpipaeTable,
dwOutBufLen);
if(Status is STATUS_PENDING)
{
Status = NtWaitForSingleObject(g_TcpDriverHandle, FALSE, NULL );
Status = IoStatusBlock.Status;
}
if (!NT_SUCCESS( Status ))
{
printf("IOCTL failed to get address table\n");
*lpdwNumEntries = 0;
return ( Status );
}
*lpdwNumEntries = (ULONG)(((UINT_PTR)IoStatusBlock.Information / sizeof(IPAddrEntry)));
return (NO_ERROR);
}
DWORD
GetIpStatsFromStack(IPSNMPInfo *IPSnmpInfo)
{
DWORD dwResult;
DWORD dwInBufLen;
DWORD dwOutBufLen;
TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
TDIObjectID *ID;
BYTE *Context;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;
dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
dwOutBufLen = sizeof(IPSNMPInfo);
ID = &(trqiInBuf.ID);
ID->toi_entity.tei_entity = CL_NL_ENTITY;
ID->toi_entity.tei_instance = 0;
ID->toi_class = INFO_CLASS_PROTOCOL;
ID->toi_type = INFO_TYPE_PROVIDER;
ID->toi_id = IP_MIB_STATS_ID;
Context = (BYTE *) &(trqiInBuf.Context[0]);
ZeroMemory(Context, CONTEXT_SIZE);
Status = NtDeviceIoControlFile(g_TcpDriverHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_TCP_QUERY_INFORMATION_EX,
(PVOID)&trqiInBuf,
sizeof(TCP_REQUEST_QUERY_INFORMATION_EX),
IPSnmpInfo,
dwOutBufLen);
if(Status is STATUS_PENDING)
{
Status = NtWaitForSingleObject(g_TcpDriverHandle, FALSE, NULL);
Status = IoStatusBlock.Status;
}
if (!NT_SUCCESS(Status))
{
printf("IOCTL failed to get SNMP info\n");
return (Status);
}
return (NO_ERROR);
}