windows使用接口添加路由

场景:windows需要添加大量的主机路由时,使用route add命令执行会很慢,于是考虑使用windows系统接口进行路由添加。

接口函数:

CreateIpForwardEntry

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <windows.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib,"ws2_32.lib")

/*
获取接口对应的十六进制的序号
*/
ULONG getindex(const char* ip)
{

	PIP_ADAPTER_INFO pinfo = NULL;
	unsigned long len = 0;
	unsigned long nError;
	nError = GetAdaptersInfo(pinfo, &len); //这里nError肯定是ERROR_BUFFER_OVERFLOW,但是                  //我们得到了要用多少长的字节来存它。
	pinfo = (PIP_ADAPTER_INFO)malloc(len);
	nError = GetAdaptersInfo(pinfo, &len);

	//char *ip="172.31.12.213";
	if (nError == 0)
	{
		PIP_ADAPTER_INFO adapterPointer = pinfo;
		while (adapterPointer != NULL)
		{
			PIP_ADDR_STRING ipAddressListPointer = &(adapterPointer->IpAddressList);
			while (ipAddressListPointer != NULL) {
				if (strcmp((char*)(ipAddressListPointer->IpAddress).String, ip) == 0)
				{
					return(adapterPointer->Index);
				}
				else {
					ipAddressListPointer = ipAddressListPointer->Next;
				}
				adapterPointer = adapterPointer->Next;
			}
		}
		//做相关的操作
	}
	else
	{
		if (nError == ERROR_NO_DATA) printf("请检查您的计算机是否安装了网卡");
		if (nError == ERROR_NOT_SUPPORTED) printf("请更新你的操作系统为Win98/Me/2000/XP/2003");
	}
	free(pinfo);
}

/*
添加路由函数
入参:主机IP,子网掩码,接口IP
主体逻辑:先获取路由表中默认路由的信息,
再将其中的主机IP、子网掩码、接口等替换成自己需要的,
再使用CreateIpForwardEntry函数进行添加。
注意,struct _MIB_IPFORWARDROW 这个结构体是路由信息的结构体
*/
void addRoute(const char* dst_ip, const char* net_mask, 
const char* interface_ip)
{
	PMIB_IPFORWARDTABLE pIpForwardTable = NULL;
	PMIB_IPFORWARDROW pRow = NULL;
	DWORD dwSize = 0;
	BOOL bOrder = FALSE;
	DWORD dwStatus = 0;

	unsigned int i;

	// Find out how big our buffer needs to be.
	dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
	if (dwStatus == ERROR_INSUFFICIENT_BUFFER) {
		// Allocate the memory for the table
		if (!(pIpForwardTable = (PMIB_IPFORWARDTABLE)malloc(dwSize))) {
			printf("Malloc failed. Out of memory.\n");
			return;
		}
		// Now get the table.
		dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
	}

	if (dwStatus != ERROR_SUCCESS) {
		printf("getIpForwardTable failed.\n");
		if (pIpForwardTable)
			free(pIpForwardTable);
		return;
	}

	for (i = 0; i < pIpForwardTable->dwNumEntries; i++)
	{
		if (pIpForwardTable->table[i].dwForwardDest == 0)
		{
			if (!pRow)
			{
				pRow = (PMIB_IPFORWARDROW)malloc(sizeof(MIB_IPFORWARDROW));
				if (!pRow) 
				{
					printf("Malloc failed. Out of memory.\n");
					return;
				}
				// Copy the row
				memcpy(pRow, &(pIpForwardTable->table[i]), sizeof(MIB_IPFORWARDROW));
			}
		}
	}
	/*printf("dwForwardDest:%0x dwForwardMask:%0x dwForwardNextHop:%0x, dwForwardIfIndex:%0x\n",
		pIpForwardTable->table[1].dwForwardDest,
		pIpForwardTable->table[1].dwForwardMask,
		pIpForwardTable->table[1].dwForwardNextHop,
		pIpForwardTable->table[1].dwForwardIfIndex);*/

	pRow->dwForwardNextHop = inet_addr(interface_ip);
	pRow->dwForwardDest = inet_addr(dst_ip);
	pRow->dwForwardMask = inet_addr(net_mask);
	pRow->dwForwardIfIndex = getindex(interface_ip);

	// Create a new route entry for the default gateway.
	dwStatus = CreateIpForwardEntry(pRow);

	if (dwStatus == NO_ERROR)
		printf("Gateway changed successfully\n");
	else if (dwStatus == ERROR_INVALID_PARAMETER)
		printf("Invalid parameter.\n");
	else if (ERROR_ACCESS_DENIED == dwStatus)
	{
		printf("ERROR_ACCESS_DENIED\n");
	}
	else
		printf("Error: %d\n", dwStatus);

	// Free resources
	if (pIpForwardTable)
		free(pIpForwardTable);
	if (pRow)
		free(pRow);

	return;
}
int main()
{
	addRoute("1.1.1.1", "255.255.255.255", "192.168.100.10");
	return 0;
}

注意,程序执行时,需要使用管理员权限执行,否则执行可能不生效。

参考:

https://docs.microsoft.com/zh-cn/windows/win32/api/iphlpapi/nf-iphlpapi-createipforwardentry

https://docs.microsoft.com/zh-cn/windows/win32/api/ipmib/ns-ipmib-mib_ipforwardrow

https://bbs.csdn.net/topics/360168672?list=lz

https://bbs.csdn.net/topics/390169429#post-392113140

https://bbs.csdn.net/topics/390321525?page=1

 

 

おすすめ

転載: blog.csdn.net/xiadeliang1111/article/details/112287746