场景: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