背景: 需求源于为ST测试人员所要实现的一个自动化工具,从PPPOE拨号到自动添加路由,最后到发包。
相关知识:
(1)添加路由的主要函数:CreateIpForwardEntry
MSDN的描述如下:
The CreateIpForwardEntry function creates a route in the local computer's IPv4 routing table.
语法:
DWORD CreateIpForwardEntry(
__in PMIB_IPFORWARDROW pRoute
);
A pointer to a MIB_IPFORWARDROW structure that specifies the information for the new route. The caller must specify values for all members of this structure. The caller must specify MIB_IPPROTO_NETMGMT for the dwForwardProto member of MIB_IPFORWARDROW .
The function returns NO_ERROR (zero) if the function is successful.
更多消息查看:
http://msdn.microsoft.com/en-us/library/aa365860(VS.85).aspx
The MIB_IPFORWARDROW structure contains information that describes an IPv4 network route.
typedef struct _MIB_IPFORWARDROW {
DWORD dwForwardDest;
DWORD dwForwardMask;
DWORD dwForwardPolicy;
DWORD dwForwardNextHop;
DWORD dwForwardIfIndex;
DWORD dwForwardType;
DWORD dwForwardProto;
DWORD dwForwardAge;
DWORD dwForwardNextHopAS;
DWORD dwForwardMetric1;
DWORD dwForwardMetric2;
DWORD dwForwardMetric3;
DWORD dwForwardMetric4;
DWORD dwForwardMetric5;
} MIB_IPFORWARDROW, *PMIB_IPFORWARDROW;
更多信息查看 http://msdn.microsoft.com/en-us/library/aa366850(VS.85).aspx
具体实现代码 :
DWORD AddRoutingTable(const char* pIP,const char* pMask,CString getway)
{
MIB_IPFORWARDROW IpForwardTable={0};
ZeroMemory(&IpForwardTable,sizeof(MIB_IPFORWARDROW));
//const char *FWDESTADDR="219.138.39.150";
//IpForwardTable.dwForwardDest=inet_addr(FWDESTADDR);
//for test code
IpForwardTable.dwForwardDest=inet_addr(pIP);
//const char*FWMASK="255.255.255.255";
//IpForwardTable.dwForwardMask=inet_addr(FWMASK);
//需要注意的地方:如果子网掩码为255.255.255.255,则使用inet_addr会出现错误 。
//由于本需求实现中子网掩码固定,所以直接写成了 0XFFFFFFFF,否则可以使用inet_aton进行转换
IpForwardTable.dwForwardMask=0xFFFFFFFF;
// IpForwardTable.dwForwardPolicy;
// Unused value by CreateIpForwardEntry Function based on MSDN
//const char *FWNEXTHOP="172.31.12.1";
//IpForwardTable.dwForwardNextHop=inet_addr(FWNEXTHOP);
// for test code
IpForwardTable.dwForwardNextHop=inet_addr((LPTSTR)(LPCTSTR)getway);
//IpForwardTable.dwForwardIfIndex=getindex("172.31.12.213");
//for test
//下面这个是一个比较重要的参数,当时为了这个参数纠结了很久 。需要通过定外一种方法获取。
IpForwardTable.dwForwardIfIndex=getindex(pIP);
// IpForwardTable.dwForwardType;
// Unused value by CreateIpForwardEntry Function based on MSDN
IpForwardTable.dwForwardProto=MIB_IPPROTO_NETMGMT;
//MIB_IPPROTO_NETMGMT indicates static appended
// IpForwardTable.dwForwardAge;
// Unused value by CreateIpForwardEntry Function based on MSDN
// IpForwardTable.dwForwardNextHopAS;
// Unused value by CreateIpForwardEntry Function based on MSDN
IpForwardTable.dwForwardMetric1=1;
//1 indicated highest prority
// IpForwardTable.dwForwardMetric2;
// Unused value by CreateIpForwardEntry Function based on MSDN
// IpForwardTable.dwForwardMetric3;
// Unused value by CreateIpForwardEntry Function based on MSDN
// IpForwardTable.dwForwardMetric4;
// Unused value by CreateIpForwardEntry Function based on MSDN
// IpForwardTable.dwForwardMetric5;
// Unused value by CreateIpForwardEntry Function based on MSDN
DWORD dwRetVal;
if(&IpForwardTable!=NULL)
{
dwRetVal = CreateIpForwardEntry(&IpForwardTable);
/ / dwRetVal = SetIpForwardEntry(&IpForwardTable);
}
if (dwRetVal == NO_ERROR)
{
//AfxMessageBox("Gateway changed successfully/n");
printf("Gateway changed successfully/n");
}
else if (dwRetVal == ERROR_INVALID_PARAMETER)
{
AfxMessageBox("Invalid parameter./n");
}
else
{
AfxMessageBox("Error: %d/n", dwRetVal);
}
return dwRetVal;
}
//获取index的具体方法: 其中dwForwardIfIndex 定义为 :
The index of the local interface through which the next hop of this route should be reached.
下面的函数要获取的就是这个值 。
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);
}