[原创]逆向分析路由表相关函数(route.exe)
好多年前弄的玩意了,放出来吧。
逆向了路由表相关操作的函数,包含win7 和 xp 平台,临时 和 永久路由表操作的API。
PS: 代码可能有资源泄漏等问题,只经过简单测试。
win 主要是操作 \\\\.\\Nsi (nsi.dll),xp 操作的是 \\\\.\\Tcp (iphlpapi.dll, mprapi.dll)。
贴一下啊WIN7的代码,XP的见
#include "stdafx.h"
#include "NsiFunc.h"
#pragma comment(lib,"Iphlpapi.lib")
namespace ROUTEAPI
{
#ifndef HEAPMALLOC
#define HEAPMALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#endif
#ifndef HEAPFREE
#define HEAPFREE(x) HeapFree(GetProcessHeap(), 0, (x))
#endif
Route::Route()
{
g_NsiAsyncDeviceHandle = INVALID_HANDLE_VALUE;
g_NsiDeviceHandle = INVALID_HANDLE_VALUE;
hNtdll = NULL;
m_NtDeviceIoControlFile = NULL;
m_NtWaitForSingleObject = NULL;
m_RtlIpv4StringToAddressA = NULL;
m_RtlIpv4StringToAddressW = NULL;
m_RtlNtStatusToDosError = NULL;
}
Route::~Route()
{
}
DWORD Route::GetNtdllFuc()
{
hNtdll = LoadLibrary(_T("ntdll.dll"));
if (hNtdll == NULL)
{
return GetLastError();
}
m_NtDeviceIoControlFile = (NtDeviceIoControlFile)GetProcAddress(hNtdll,
"NtDeviceIoControlFile");
m_NtWaitForSingleObject = (NtWaitForSingleObject)GetProcAddress(hNtdll,
"NtWaitForSingleObject");
m_RtlNtStatusToDosError = (RtlNtStatusToDosError)GetProcAddress(hNtdll,
"RtlNtStatusToDosError");
m_RtlIpv4StringToAddressA = (RtlIpv4StringToAddressA)GetProcAddress(hNtdll,
"RtlIpv4StringToAddressA");
m_RtlIpv4StringToAddressW = (RtlIpv4StringToAddressW)GetProcAddress(hNtdll,
"RtlIpv4StringToAddressW");
if (!m_NtDeviceIoControlFile || !m_NtWaitForSingleObject || !m_RtlNtStatusToDosError
||m_RtlIpv4StringToAddressA||m_RtlIpv4StringToAddressW)
{
FreeLibrary(hNtdll);
return GetLastError();
}
return NO_ERROR;
}
DWORD Route::Initialize()
{
return GetNtdllFuc();
}
VOID Route::Clrear()
{
//释放DLL
if (hNtdll)
{
FreeLibrary(hNtdll);
}
hNtdll = NULL;
m_NtDeviceIoControlFile = NULL;
m_NtWaitForSingleObject = NULL;
m_RtlIpv4StringToAddressA = NULL;
m_RtlIpv4StringToAddressW = NULL;
m_RtlNtStatusToDosError = NULL;
}
DWORD Route::NsiOpenDevice(BOOL bAsync)
{
DWORD dwDesiredAccess;
DWORD dwFlagsAndAttributes;
volatile HANDLE * HandlePoint;
HANDLE tempHandle;
DWORD result;
dwDesiredAccess = 0;
dwFlagsAndAttributes = 0;
result = 0;
dwDesiredAccess = 0X100000;
if (bAsync == TRUE)
{
HandlePoint = (volatile HANDLE *)&g_NsiAsyncDeviceHandle;
dwFlagsAndAttributes = FILE_FLAG_OVERLAPPED;
}
else
{
HandlePoint = (volatile HANDLE *)&g_NsiDeviceHandle;
}
if(*HandlePoint == INVALID_HANDLE_VALUE)
{
tempHandle = CreateFile(_T("\\\\.\\Nsi"),
dwDesiredAccess,
FILE_SHARE_WRITE|FILE_SHARE_READ,
NULL,OPEN_EXISTING,
dwFlagsAndAttributes,
NULL
);
if(tempHandle == INVALID_HANDLE_VALUE)
{
result = GetLastError();
}
else
{
if ( InterlockedCompareExchange((volatile LONG *)HandlePoint,(LONG) tempHandle, -1) != -1 )
CloseHandle(tempHandle);
result = 0;
}
}
else
{
result = 0;
}
return result;
}
DWORD Route:: NsiIoctl(DWORD dwIoControlCode,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPVOID lpOutBuffer,
DWORD * nOutBufferSize,
LPOVERLAPPED lpOverlapped
)
{
DWORD result;
DWORD dwOutBufferSize;
HANDLE hevent = INVALID_HANDLE_VALUE;
NTSTATUS m_ntsatus;
IO_STATUS_BLOCK m_status_block;
memset(&m_status_block,0,sizeof(m_status_block));
result = NsiOpenDevice(TRUE);
if (result)
{
return result;
}
dwOutBufferSize = * nOutBufferSize;
if (lpOverlapped)
{
if (DeviceIoControl(
g_NsiAsyncDeviceHandle,
dwIoControlCode,
lpInBuffer,
nInBufferSize,
lpOutBuffer,
dwOutBufferSize,
nOutBufferSize,
lpOverlapped))
{
return NO_ERROR;
}
return GetLastError();
}
hevent = CreateEvent(NULL,FALSE,FALSE,NULL);
if (hevent == NULL)
{
return GetLastError();
}
m_ntsatus = m_NtDeviceIoControlFile(
g_NsiAsyncDeviceHandle,
hevent,
NULL,
NULL,
&m_status_block,
dwIoControlCode,
lpInBuffer,
nInBufferSize,
lpOutBuffer,
dwOutBufferSize
);
if (m_ntsatus == STATUS_PENDING)
{
m_ntsatus = m_NtWaitForSingleObject(hevent,FALSE,0);
if (m_ntsatus >= 0)
{
m_ntsatus = m_status_block.Status;
}
}
CloseHandle(hevent);
if (m_ntsatus >=0 && m_ntsatus != STATUS_MORE_ENTRIES)
{
* nOutBufferSize = 0;
return NO_ERROR;
}
return m_RtlNtStatusToDosError(m_ntsatus& 0xC0000000);
}
DWORD Route:: Ipv4GetAddressA(
__in PCSTR S,
__out IN_ADDR* Addr
)
{
if (m_RtlIpv4StringToAddressA(S,TRUE,(LPSTR *)&Addr,Addr) || *(BYTE *)Addr != 0 )
{
return ERROR_INVALID_PARAMETER;
}
else
{
return NO_ERROR;
}
}
DWORD Route:: Ipv4GetAddressW(
__in PCWSTR S,
__out IN_ADDR* Addr
)
{
if (m_RtlIpv4StringToAddressW == NULL)
{
return GetLastError();
}
if (m_RtlIpv4StringToAddressW(S,TRUE,(LPWSTR *)&Addr,Addr) || *(BYTE *)Addr != 0 )
{
return ERROR_INVALID_PARAMETER;
}
else
{
return NO_ERROR;
}
}
DWORD Route:: Ipv4GetPrefixA(
__in LPCSTR lpDestIpStr,
__out IN_ADDR* Addr,
__out BYTE * PrefixLength
)
{
DWORD dwResult;
BYTE btemp;
LPSTR lpdstIpstr_Copy;
BYTE chPrefix;
BYTE chTemp;
PBYTE lpPoint ;
dwResult = 0;
chPrefix = 0;
lpPoint = NULL;
lpdstIpstr_Copy = (LPSTR)lpDestIpStr;
if (m_RtlIpv4StringToAddressA(lpDestIpStr,TRUE,&lpdstIpstr_Copy,Addr) < 0)
{
dwResult = ERROR_INVALID_PARAMETER;
return dwResult;
}
btemp = *lpdstIpstr_Copy;
lpdstIpstr_Copy ++;
if (btemp != '/')
{
dwResult = ERROR_INVALID_PARAMETER;
return dwResult;
}
for(;isdigit(*lpdstIpstr_Copy);lpdstIpstr_Copy++) //计算输入的前缀
{
chPrefix = 10*chPrefix + *lpdstIpstr_Copy - 48;
if (chPrefix>0xFF) //前缀使用CHAR 表示的,所以必然小于FF
{
dwResult = ERROR_INVALID_PARAMETER;
return dwResult;
}
}
if (*lpdstIpstr_Copy || chPrefix >0x20) //在网络中,前缀最大只可能是32(0X20)
{
dwResult = ERROR_INVALID_PARAMETER;
return dwResult;
}
else
{
chTemp = (chPrefix>>3)+1;
lpPoint = (BYTE *)((BYTE *)Addr+chTemp);
if (chTemp <4)
{
memset(lpPoint,0,sizeof(IN_ADDR)-chTemp);
}
chTemp = (chPrefix>>3);
lpPoint = (BYTE *)((BYTE *)Addr + chTemp);
(*lpPoint) &= -1<<(8-(chPrefix&7));
*PrefixLength = chPrefix;
return 0;
}
}
DWORD Route:: Ipv4GetPrefixW(
__in LPCWSTR lpDestIpStr,
__out IN_ADDR* Addr,
__out BYTE * PrefixLength
)
{
DWORD dwResult;
WCHAR btemp;
LPWSTR lpdstIpstr_Copy;
BYTE chPrefix;
BYTE chTemp;
BYTE * lpPoint ;
dwResult = 0;
chPrefix = 0;
lpPoint = NULL;
lpdstIpstr_Copy = (LPWSTR)lpDestIpStr;
if (m_RtlIpv4StringToAddressW(lpDestIpStr,TRUE,&lpdstIpstr_Copy,Addr) < 0)
{
dwResult = ERROR_INVALID_PARAMETER;
return dwResult;
}
btemp = *lpdstIpstr_Copy;
lpdstIpstr_Copy ++;
if (btemp != '/')
{
dwResult = ERROR_INVALID_PARAMETER;
return dwResult;
}
for(;iswdigit (*lpdstIpstr_Copy);lpdstIpstr_Copy++) //计算输入的前缀
{
chPrefix = 10*chPrefix + *lpdstIpstr_Copy - 48;
if (chPrefix>0xFF) //前缀本来使用CHAR 表示的,因为结构体对齐,改为DWORD ,所以必然小于FF
{
dwResult = ERROR_INVALID_PARAMETER;
return dwResult;
}
}
if (*lpdstIpstr_Copy || chPrefix >0x20) //在网络中,前缀最大只可能是32(0X20)
{
dwResult = ERROR_INVALID_PARAMETER;
return dwResult;
}
else
{
chTemp = (chPrefix>>3)+1;
lpPoint = (BYTE *)((BYTE *)Addr+chTemp);
if (chTemp <4)
{
memset(lpPoint,0,sizeof(IN_ADDR)-chTemp);
}
chTemp = (chPrefix>>3);
lpPoint = (BYTE *)((BYTE *)Addr + chTemp);
(*lpPoint) &= -1<<(8-(chPrefix&7));
*PrefixLength = chPrefix;
return 0;
}
}
DWORD Route::NsiSetAllParameters(DWORD dwStatic,
DWORD dwActionCode,
LPVOID NPI_MS_MODULEID,
DWORD dwIoMainCode, //一般为 16
LPVOID lpNetInfoBuffer,
int SizeofNetInfoBuffer,
LPVOID lpMetricBuffer,
int SizeofMetricBuffer
)
{
ADD_ROUTE_DEV m_route_dev;
DWORD OutBufferSize;
memset(&m_route_dev,0,sizeof(m_route_dev));
m_route_dev.dwReserved1 = 0;
m_route_dev.dwReserved2 = 0;
m_route_dev.lpNpi = NPI_MS_MODULEID;
m_route_dev.dwIoMainCode = 16;
m_route_dev.dwStatic = dwStatic;
m_route_dev.dwIoActionCode = dwActionCode;
m_route_dev.lpdevinfo = (PROUTE_DEV_INFO)lpNetInfoBuffer;
m_route_dev.ElementsSizeOfDev = SizeofNetInfoBuffer;
m_route_dev.lpmertricinfo = (PROUTE_MERTRIC_INFO)lpMetricBuffer;
m_route_dev.ElementsSizeOfMertric = SizeofMetricBuffer;
OutBufferSize = sizeof(m_route_dev);
return NsiIoctl(IOCTL_ROUTE_OPT_REQUEST,
&m_route_dev,
sizeof(m_route_dev),
&m_route_dev,
&OutBufferSize,
0
);
}
DWORD Route::NsiAllocateAndGetTable(DWORD dwStatic,
LPVOID NPI_MS_MODULEID,
DWORD dwIoMainCode, //一般为 16
LPVOID* lpRouteInfoBuffer, //输入的指针,获得一个缓冲区,指向ROUTE_DEV_INFO结构体数组
DWORD ElementsSizeOfDev, //一个ROUTE_DEV_INFO的大小
LPVOID * lpMertricInfoBuffer, //输入的指针,获得一个缓冲区,指向ROUTE_MERTRIC_INFO结构体数组
DWORD ElementsSizeOfMertric, //一个ROUTE_MERTRIC_INFO结构的大小
LPVOID *lpUnknow1,
DWORD dwUnknow1, //未知的结构体大小
LPVOID *lpUnknow2,
DWORD dwUnknow2,
DWORD *dwRouteSize, //路由信息的条数
DWORD dwReserved//未使用的位,保持0
)
{
const DWORD dwZero = 0;
DWORD dwResult;
DWORD dwRouteInfoCount;
DWORD dwTotalSizeOfDev = 0;
LPVOID lpTemp_RouteInfo = NULL;
DWORD dwTotalSizeOfMertric = 0;
LPVOID lpTemp_MerterInfo = NULL;
DWORD dwTotalSizeOfUnknow1 = 0;
LPVOID lpTemp_Unknow1 = NULL;
DWORD dwTotalSizeOfUnknow2 = 0;
LPVOID lpTemp_Unknow2 = NULL;
int i ;
dwResult = 0;
dwRouteInfoCount = 0;
i = 0;
for (;i<3;i++)
{
dwRouteInfoCount = 0;
dwResult = NsiEnumerateObjectsAllParameters(
dwStatic,
1,
NPI_MS_MODULEID,
dwIoMainCode,
dwZero,dwZero,
dwZero,dwZero,
dwZero,dwZero,
dwZero,dwZero,
&dwRouteInfoCount);
if (dwResult !=0 && dwResult != ERROR_MORE_DATA)
{
return dwResult;
}
dwRouteInfoCount +=2;
if (ElementsSizeOfDev > 0)
{
dwTotalSizeOfDev = ElementsSizeOfDev*dwRouteInfoCount;
lpTemp_RouteInfo = (LPVOID)HEAPMALLOC(dwTotalSizeOfDev);
if (lpTemp_RouteInfo == NULL)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
}
if (ElementsSizeOfMertric > 0)
{
dwTotalSizeOfMertric = ElementsSizeOfMertric*dwRouteInfoCount;
lpTemp_MerterInfo = (LPVOID)HEAPMALLOC(dwTotalSizeOfMertric);
if (lpTemp_MerterInfo == NULL)
{
NsiFreeTable(lpTemp_RouteInfo,lpMertricInfoBuffer,NULL,NULL);
return ERROR_NOT_ENOUGH_MEMORY;
}
memset(lpTemp_MerterInfo,0,dwTotalSizeOfMertric);
}
if (dwUnknow1 >0)
{
dwTotalSizeOfUnknow1 = dwUnknow1*dwRouteInfoCount;
lpTemp_Unknow1 = (LPVOID)HEAPMALLOC(dwTotalSizeOfUnknow1);
if (lpTemp_Unknow1 == NULL)
{
NsiFreeTable(lpTemp_RouteInfo,lpMertricInfoBuffer,lpTemp_Unknow1,NULL);
return ERROR_NOT_ENOUGH_MEMORY;
}
}
if (dwUnknow2 >0)
{
dwTotalSizeOfUnknow2 = dwUnknow1*dwRouteInfoCount;
lpTemp_Unknow2 = (LPVOID)HEAPMALLOC(dwTotalSizeOfUnknow2);
if (lpTemp_Unknow2 == NULL)
{
NsiFreeTable(lpTemp_RouteInfo,lpMertricInfoBuffer,lpTemp_Unknow1,lpTemp_Unknow2);
return ERROR_NOT_ENOUGH_MEMORY;
}
}
dwResult = NsiEnumerateObjectsAllParameters(
dwStatic,
1,
NPI_MS_MODULEID,
dwIoMainCode,
lpTemp_RouteInfo,ElementsSizeOfDev,
lpTemp_MerterInfo,ElementsSizeOfMertric,
lpTemp_Unknow1,dwUnknow1,
lpTemp_Unknow2,dwUnknow2,
&dwRouteInfoCount);
if (dwResult != ERROR_MORE_DATA)
{
break;
}
NsiFreeTable(lpTemp_RouteInfo,lpMertricInfoBuffer,lpTemp_Unknow1,lpTemp_Unknow2);
lpTemp_RouteInfo = NULL;
lpTemp_MerterInfo = NULL;
lpTemp_Unknow1 = NULL;
lpTemp_Unknow2 = NULL;
} //end for
if (dwResult !=0)
{
NsiFreeTable(lpTemp_RouteInfo,lpMertricInfoBuffer,lpTemp_Unknow1,lpTemp_Unknow2);
return dwResult;
}
if (i == 3)
{
return STATUS_UNSUCCESSFUL;
}
else
{
*dwRouteSize = dwRouteInfoCount;
if (lpTemp_RouteInfo != NULL)
{
*lpRouteInfoBuffer = lpTemp_RouteInfo;
}
if (lpTemp_MerterInfo != NULL)
{
*lpMertricInfoBuffer = lpTemp_MerterInfo;
}
if (lpTemp_Unknow1 != NULL)
{
*lpUnknow1 = lpTemp_Unknow1;
}
if (lpTemp_Unknow2 != NULL)
{
*lpUnknow2 = lpTemp_Unknow2;
}
dwResult = NO_ERROR;
}
return dwResult;
}
void Route::NsiFreeTable(LPVOID lpRouteInfoBuffer,
LPVOID lpMertricInfoBuffer,
LPVOID lpUnknow1,
LPVOID lpUnknow2
)
{
if (lpRouteInfoBuffer)
{
HEAPFREE(lpRouteInfoBuffer);
}
if (lpMertricInfoBuffer)
{
HEAPFREE(lpMertricInfoBuffer);
}
if (lpUnknow1)
{
HEAPFREE(lpUnknow1);
}
if (lpUnknow2)
{
HEAPFREE(lpUnknow2);
}
}
DWORD Route::NsiEnumerateObjectsAllParameters(
DWORD dwStatic,
DWORD dwUnknow0, //默认是1
LPVOID NPI_MS_MODULEID,
DWORD dwIoMainCode, //一般为 16
LPVOID lpRouteInfoBuffer, //输入的指针,获得一个缓冲区,指向ROUTE_DEV_INFO结构体数组
DWORD ElementsSizeOfDev, //一个ROUTE_DEV_INFO的大小
LPVOID lpMertricInfoBuffer, //输入的指针,获得一个缓冲区,指向ROUTE_MERTRIC_INFO结构体数组
DWORD ElementsSizeOfMertric, //一个ROUTE_MERTRIC_INFO结构的大小
LPVOID lpUnknow1,
DWORD dwUnknow1, //未知的结构体大小
LPVOID lpUnknow2,
DWORD dwUnknow2,
DWORD *dwRouteSize//路由信息的条数
)
{
NSI_REQUEST_QUERY_INFORMATION nsi_buffer;
DWORD dwResult;
DWORD dwOutBufferSize;
memset(&nsi_buffer,0,sizeof(nsi_buffer));
nsi_buffer.lpNpi = NPI_MS_MODULEID;
nsi_buffer.dwIoMainCode = dwIoMainCode;
nsi_buffer.dwStatic = dwStatic;
nsi_buffer.dwIoActionCode = dwUnknow0; // 估计用的ACTIONCODE 1的添加路由信息
nsi_buffer.lpdevinfo = (PROUTE_DEV_INFO )lpRouteInfoBuffer;
nsi_buffer.ElementsSizeOfDev = ElementsSizeOfDev;
nsi_buffer.lpmertricinfo = (PROUTE_MERTRIC_INFO )lpMertricInfoBuffer;
nsi_buffer.ElementsSizeOfMertric = ElementsSizeOfMertric;
nsi_buffer.lpUnknow1 = lpUnknow1;
nsi_buffer.dwUnknow1 = dwUnknow1;
nsi_buffer.lpUnknow2 = lpUnknow2;
nsi_buffer.dwUnknow2 = dwUnknow2;
nsi_buffer.dwRouteSize = *dwRouteSize;
dwOutBufferSize = sizeof(nsi_buffer);
dwResult = NsiIoctl(IOCTL_ROUTE_ENUM_OBJECT,
&nsi_buffer,sizeof(nsi_buffer),
&nsi_buffer,&dwOutBufferSize,
0);
*dwRouteSize = nsi_buffer.dwRouteSize;
return dwResult;
}
DWORD Route::_AddIpv4Route(IN_ADDR DestIp,
BYTE MaskPrefix,
NET_IFINDEX InterfaceIndex,
IN_ADDR GateWay,
int varMetric,
DWORD dwStatic)
{
DWORD dwResult;
ULONG64 ulValue;
ROUTE_DEV_INFO m_dev_buffer;
ROUTE_MERTRIC_INFO m_mertric_buffer;
NET_LUID InterFaceLuid;
InterFaceLuid.Value = 0;
ulValue = 0;
int test = sizeof(m_dev_buffer);
memset(&m_dev_buffer,0,test);
m_dev_buffer.dwIPv4Address = DestIp;
m_dev_buffer.chMaskPrefix = MaskPrefix;
m_dev_buffer.dwGateway = GateWay;
if (InterfaceIndex)
{
dwResult = ConvertInterfaceIndexToLuid(InterfaceIndex,&(InterFaceLuid));
if (dwResult)
{
return dwResult;
}
ulValue = InterFaceLuid.Value;
}
m_dev_buffer.LuidValue1.Value = ulValue & 0X00000000FFFFFFFF ;
m_dev_buffer.LuidValue2.Value = ulValue & 0X00000000FFFFFFFF ;
test = sizeof(m_mertric_buffer);
memset(&m_mertric_buffer,-1,sizeof(m_mertric_buffer));
m_mertric_buffer.Mertric = varMetric;
return NsiSetAllParameters(dwStatic,1,(LPVOID)NPI_MS_IPV4_MODULEID,16,&m_dev_buffer,sizeof(m_dev_buffer),&m_mertric_buffer,sizeof(m_mertric_buffer));
}
DWORD Route::AddIpv4RouteA(LPCSTR lpDestIpStr,
LPCSTR lpMaskStr,
LPCSTR lpGateWayStr,
int MetricNum,
BOOL bStatic,
DWORD * StaticRet,
NET_IFINDEX InterfaceIndex)
{
DWORD dwResult;
IN_ADDR AddrDestIp;
IN_ADDR AddrGateWay;
IN_ADDR AddMask;
BYTE chMaskPrefix;
dwResult = 0;
chMaskPrefix = 0;
dwResult = Ipv4GetPrefixA(lpDestIpStr,&AddrDestIp,&chMaskPrefix);
if(dwResult == ERROR_INVALID_PARAMETER)
{
dwResult = Ipv4GetAddressA(lpDestIpStr,&AddrDestIp);
if (dwResult)
{
dwResult = ERROR_INVALID_PARAMETER;
return dwResult;
}
if (lpMaskStr)
{
dwResult = Ipv4GetAddressA(lpMaskStr,&AddMask);
if (dwResult)
return dwResult;
else
{
dwResult = ConvertIpv4MaskToLength(AddMask.s_addr,(PUINT8)&chMaskPrefix);
if (dwResult != NO_ERROR)
return dwResult;
}
}
}
if (lpGateWayStr)
{
dwResult = Ipv4GetAddressA(lpGateWayStr,&AddrGateWay);
if (dwResult != NO_ERROR)
return dwResult;
}// end
dwResult = _AddIpv4Route(AddrDestIp,chMaskPrefix,InterfaceIndex,AddrGateWay,MetricNum,1);
if(bStatic)
{
dwResult = _AddIpv4Route(AddrDestIp,chMaskPrefix,InterfaceIndex,AddrGateWay,MetricNum,0);
if (StaticRet != NULL)
{
*StaticRet = dwResult;
}
}
return dwResult;
}
DWORD Route::AddIpv4RouteW(LPCWSTR lpDestIpStr,
LPCWSTR lpMaskStr,
LPCWSTR lpGateWayStr,
int MetricNum,
BOOL bStatic,
DWORD * StaticRet,
NET_IFINDEX InterfaceIndex)
{
DWORD dwResult;
IN_ADDR AddrDestIp;
IN_ADDR AddrGateWay;
IN_ADDR AddMask;
BYTE chMaskPrefix;
dwResult = 0;
chMaskPrefix = 0;
dwResult = Ipv4GetPrefixW(lpDestIpStr,&AddrDestIp,&chMaskPrefix);
if(dwResult == ERROR_INVALID_PARAMETER)
{
dwResult = Ipv4GetAddressW(lpDestIpStr,&AddrDestIp);
if (dwResult)
{
dwResult = ERROR_INVALID_PARAMETER;
return dwResult;
}
if (lpMaskStr)
{
dwResult = Ipv4GetAddressW(lpMaskStr,&AddMask);
if (dwResult)
return dwResult;
else
{
dwResult = ConvertIpv4MaskToLength(AddMask.s_addr,(PUINT8)&chMaskPrefix);
if (dwResult != NO_ERROR)
return dwResult;
}
}
}
if (lpGateWayStr)
{
dwResult = Ipv4GetAddressW(lpGateWayStr,&AddrGateWay);
if (dwResult != NO_ERROR)
return dwResult;
}// end
dwResult = _AddIpv4Route(AddrDestIp,chMaskPrefix,InterfaceIndex,AddrGateWay,MetricNum,1);
if(bStatic)
{
dwResult = _AddIpv4Route(AddrDestIp,chMaskPrefix,InterfaceIndex,AddrGateWay,MetricNum,0);
if (StaticRet != NULL)
{
*StaticRet = dwResult;
}
}
return dwResult;
}
DWORD Route::DeleteIpv4RouteA(LPCSTR lpDestIpStr,
LPCSTR lpMaskStr,
LPCSTR lpGateWayStr,
BOOL bStatic, //mustbe TRUE
NET_IFINDEX InterfaceIndex)
{
LPCSTR lpDestIp_Copy;
LPCSTR lpGateWay_Copy;
DWORD dwResult;
IN_ADDR AddrDestIp;
IN_ADDR AddMask;
IN_ADDR AddrGateWay;
NET_LUID InterfaceLuid;
BYTE chMaskPrefix;
DWORD dwCount;
AddMask.s_addr = 0;
AddrDestIp.s_addr = 0;
AddrGateWay.s_addr = 0;
lpDestIp_Copy = lpDestIpStr;
lpGateWay_Copy = lpGateWayStr;
dwResult = 0;
if (InterfaceIndex)
{
dwResult = ConvertInterfaceIndexToLuid(InterfaceIndex,&InterfaceLuid);
if (dwResult)
{
return dwResult;
}
}
if (!lpDestIpStr)
{
chMaskPrefix = -1;
}
else
{
dwResult = Ipv4GetPrefixA(lpDestIp_Copy,&AddrDestIp,&chMaskPrefix);
if (dwResult == ERROR_INVALID_PARAMETER)
{
dwResult = Ipv4GetAddressA(lpDestIp_Copy,&AddrDestIp);
if (dwResult)
{
return dwResult;
}
if (lpMaskStr)
{
dwResult = Ipv4GetAddressA(lpMaskStr,&AddMask);
if (dwResult)
return dwResult;
else
{
dwResult = ConvertIpv4MaskToLength(AddMask.s_addr,(PUINT8)&chMaskPrefix);
if (dwResult != NO_ERROR)
return dwResult;
}
}
else
{
chMaskPrefix = -1;
}
}
}//end else
if (lpGateWay_Copy)
{
dwResult = Ipv4GetAddressA(lpGateWay_Copy,&AddrGateWay);
if (dwResult != NO_ERROR)
return dwResult;
}
dwResult = _DeleteIpv4Route(AddrDestIp,chMaskPrefix,&InterfaceLuid,AddrGateWay,1,&dwCount);
if(bStatic)
{
dwResult = _DeleteIpv4Route(AddrDestIp,chMaskPrefix,&InterfaceLuid,AddrGateWay,0,&dwCount);
}
if (lpDestIp_Copy)
{
if (dwResult)
{
return dwResult;
}
dwResult = (dwCount != 0 ? 0 : ERROR_NOT_FOUND);
return dwResult;
}
else
return NO_ERROR;
}
DWORD Route::DeleteIpv4RouteW(LPCWSTR lpDestIpStr,
LPCWSTR lpMaskStr,
LPCWSTR lpGateWayStr,
BOOL bStatic, //mustbe TRUE
NET_IFINDEX InterfaceIndex)
{
LPCWSTR lpDestIp_Copy;
LPCWSTR lpGateWay_Copy;
DWORD dwResult;
IN_ADDR AddrDestIp;
IN_ADDR AddMask;
IN_ADDR AddrGateWay;
NET_LUID InterfaceLuid;
BYTE chMaskPrefix;
DWORD dwCount;
AddMask.s_addr = 0;
AddrDestIp.s_addr = 0;
AddrGateWay.s_addr = 0;
lpDestIp_Copy = lpDestIpStr;
lpGateWay_Copy = lpGateWayStr;
dwResult = 0;
if (InterfaceIndex)
{
dwResult = ConvertInterfaceIndexToLuid(InterfaceIndex,&InterfaceLuid);
if (dwResult)
{
return dwResult;
}
}
if (!lpDestIpStr)
{
chMaskPrefix = -1;
}
else
{
dwResult = Ipv4GetPrefixW(lpDestIp_Copy,&AddrDestIp,&chMaskPrefix);
if (dwResult == ERROR_INVALID_PARAMETER)
{
dwResult = Ipv4GetAddressW(lpDestIp_Copy,&AddrDestIp);
if (dwResult)
{
return dwResult;
}
if (lpMaskStr)
{
dwResult = Ipv4GetAddressW(lpMaskStr,&AddMask);
if (dwResult)
return dwResult;
else
{
dwResult = ConvertIpv4MaskToLength(AddMask.s_addr,(PUINT8)&chMaskPrefix);
if (dwResult != NO_ERROR)
return dwResult;
}
}
else
{
chMaskPrefix = -1;
}
}
}//end else
if (lpGateWay_Copy)
{
dwResult = Ipv4GetAddressW(lpGateWay_Copy,&AddrGateWay);
if (dwResult != NO_ERROR)
return dwResult;
}
dwResult = _DeleteIpv4Route(AddrDestIp,chMaskPrefix,&InterfaceLuid,AddrGateWay,1,&dwCount);
if(bStatic)
{
dwResult = _DeleteIpv4Route(AddrDestIp,chMaskPrefix,&InterfaceLuid,AddrGateWay,0,&dwCount);
}
if (lpDestIp_Copy)
{
if (dwResult)
{
return dwResult;
}
dwResult = (dwCount != 0 ? 0 : ERROR_NOT_FOUND);
return dwResult;
}
else
return NO_ERROR;
}
DWORD Route::_DeleteIpv4Route(IN_ADDR DestIp,
BYTE MaskPrefix,
PNET_LUID pInterfaceLuid,
IN_ADDR GateWay,
DWORD dwStatic,
DWORD *dwCount
)
{
DWORD dwResult = NO_ERROR;
PROUTE_DEV_INFO pRouteInfo = NULL;
DWORD dwRouteInfoCount = 0;
BOOL bSetNsi = FALSE;
PDWORD pdwTemp1;
PDWORD pdwTemp2;
dwResult = NsiAllocateAndGetTable(
dwStatic,
(LPVOID)NPI_MS_IPV4_MODULEID,
16,
(LPVOID*)&pRouteInfo,sizeof(ROUTE_DEV_INFO),
0,0,0,0,0,0,&dwRouteInfoCount,0
);
if (dwResult == NO_ERROR)
{
for (int i = 0;i<dwRouteInfoCount;i++)
{
if(DestIp.s_addr ==0 || pRouteInfo[i].dwIPv4Address.s_addr == DestIp.s_addr)
{
if (MaskPrefix == -1 || pRouteInfo[i].chMaskPrefix == MaskPrefix)
{
if (GateWay.s_addr == 0 || pRouteInfo[i].dwGateway.s_addr == GateWay.s_addr)
{
if (pInterfaceLuid != 0)
{
bSetNsi = TRUE;
}
else
{
pdwTemp1 =(PDWORD) pInterfaceLuid;
pdwTemp2 = (PDWORD) (&pRouteInfo[i].LuidValue1);
bSetNsi = (pdwTemp1[0] == pdwTemp2[0]);
if (bSetNsi == FALSE)
{
bSetNsi = (pdwTemp1[1] == pdwTemp2[1]);
}
}
if (bSetNsi == TRUE)
{
dwResult = NsiSetAllParameters(dwStatic,
3,(LPVOID)NPI_MS_IPV4_MODULEID,
16,&(pRouteInfo[i]),
sizeof(ROUTE_DEV_INFO),
NULL,0);
if (dwResult == NO_ERROR && DestIp.s_addr != 0)
{
break;
(*dwCount)++;
}
}
}
}
}
}
NsiFreeTable(pRouteInfo,NULL,NULL,NULL);
}
return dwResult;
}
}//end of namespace routeapi详细的代码看附件吧。
