« | August 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | |
| 公告 |
戒除浮躁,读好书,交益友 |
Blog信息 |
blog名称:邢红瑞的blog 日志总数:523 评论数量:1142 留言数量:0 访问次数:9691706 建立时间:2004年12月20日 |

| |
[c++]用IP Helper API动态修改路由  文章收藏, 软件技术, 电脑与网络
邢红瑞 发表于 2006/10/15 17:08:07 |
win2000以后版本的Persistent Route,在TCP/IP启动的时候就自动加载的路由表信息,这些信息是存贮在注册表中的,位于HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\PersistentRoutes\下面,保存的键名是 [网络地址],[子网掩码],[网关],[metric]构成的串,值是REG_SZ类型的空字符串。有时候必须要动态添加路由,但是使用route命令确实麻烦。 添加路由信息:CreateIpForwardEntry(PMIB_IPFORWARDROW pIpForwardRow) 这个就是添加一条路由信息的函数,参数是一个指向MIB_IPFORWARDROW的指针,返回0就是成功,要做的主要的工作就是设置这个结构的各个必要的属性值。
typedef struct _MIB_IPFORWARDROW { DWORD dwForwardDest; //路由到的目标网络地址 DWORD dwForwardMask; //路由到的目标网络子网掩码 DWORD dwForwardPolicy; //现在没用 DWORD dwForwardNextHop; //下一跳的地址,即网关地址 DWORD dwForwardIfIndex; //使用的网络设备接口索引值 DWORD dwForwardType; //路由类型 3是最终目标,4是非最终目标 DWORD dwForwardProto; //路由协议,这个在这个函数里要设成3 DWORD dwForwardAge; //路由生命周期,没用 DWORD dwForwardNextHopAS; //没用,设成0 DWORD dwForwardMetric1; //路由优先级,正数,最小优先级越高 DWORD dwForwardMetric2; //下面这几个暂时不用,设成0xFFFFFFFF DWORD dwForwardMetric3; DWORD dwForwardMetric4; DWORD dwForwardMetric5; } MIB_IPFORWARDROW, *PMIB_IPFORWARDROW; 例:
MIB_IPFORWARDROW ipfr={0}; ipfr.dwForwardAge=0; ipfr.dwForwardDest=inet_addr(ip); ipfr.dwForwardIfIndex=m_interface; ipfr.dwForwardMask=inet_addr(mask); ipfr.dwForwardMetric1=1; ipfr.dwForwardMetric2=0xFFFFFFFF; ipfr.dwForwardMetric3=0xFFFFFFFF; ipfr.dwForwardMetric4=0xFFFFFFFF; ipfr.dwForwardMetric5=0xFFFFFFFF; ipfr.dwForwardNextHop=inet_addr((LPCTSTR)m_gateway); ipfr.dwForwardNextHopAS=0; ipfr.dwForwardPolicy=0; ipfr.dwForwardProto=3; ipfr.dwForwardType=4; //路由都是要过网关的,设成4 ,最终路由设为3DWORD dwRet=CreateIpForwardEntry(&ipfr); 如果路由的目标是通过本机一个IP就可以到达的话dwForwardType要设成3,不然不能加,如何确定dwForwardIfIndex是一个重要问题,这个是根据dwForwardNextHop和本机的网络设置情况而定的,要用到另一个函数DWORD GetAdaptersInfo( PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen)来取得网络配置信息,这个函数将把所有的网络配置放在pAdapterInfo指向的内存单元里。 pAdapterInfo是一个指向IP_ADAPTER_INFO结构的指针,定义是这样的:
typedef struct _IP_ADAPTER_INFO { struct _IP_ADAPTER_INFO* Next; //指向下一个单元的指针 DWORD ComboIndex; //没用 char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4]; //适配器名 char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4]; //适配器描述 UINT AddressLength; //硬件地址长度 BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH]; //硬件地址 DWORD Index; //适配器索引值 UINT Type; //适配器类型 UINT DhcpEnabled; //是否启用DHCP PIP_ADDR_STRING CurrentIpAddress;//没用 IP_ADDR_STRING IpAddressList; //这个适配器的IP列表 IP_ADDR_STRING GatewayList; //这个适配器的网关列表 IP_ADDR_STRING DhcpServer; //DHCP服务器地址 BOOL HaveWins; //是否使用WINS IP_ADDR_STRING PrimaryWinsServer; //主WINS服务器地址 IP_ADDR_STRING SecondaryWinsServer; //备用WINS服务器地址 time_t LeaseObtained; //DHCP地址使用时间 time_t LeaseExpires; //DHCP地址到期时间 } IP_ADAPTER_INFO, *PIP_ADAPTER_INFO; typedef struct _IP_ADDR_STRING { struct _IP_ADDR_STRING* Next; IP_ADDRESS_STRING IpAddress; //IP地址字符串 IP_MASK_STRING IpMask; //子网掩码字符串 DWORD Context; //Netword table entry } IP_ADDR_STRING, *PIP_ADDR_STRING; 要确定应该用哪个值做dwForwardIfIndex只要比较每个适配器中配置的IP地址和要添加路由的dwForwardNextHop是不是在同一子网里,在的话就取这个适配器的Index作为dwForwardIfIndex。 取得适配器信息的代码:
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); if(nError==0) { //做相关的操作 }else { if(nError==ERROR_NO_DATA) AfxMessageBox("请检查您的计算机是否安装了网卡"); if(nError==ERROR_NOT_SUPPORTED) AfxMessageBox("请更新你的操作系统为Win98/Me/2000/XP/2003"); } free( pinfo); 删除路由信息:DeleteIpForwardEntry(PMIB_IPFORWARDROW pRoute) 这里必须要指定dwForwardIfIndex, dwForwardDest, dwForwardMask,dwForwardNextHop, and dwForwardPolicy 值,不过删除路由肯定是要在已经有的里面删除,所以更一般的用法是遍历整个路由表,把其中感兴趣的路由删除掉。 整个路由表是由DWORD GetIpForwardTable(PMIB_IPFORWARDTABLE pIpForwardTable, PULONG pdwSize, BOOL bOrder)得到的。 PMIB_IPFORWARDTABLE定义如下:
typedef struct _MIB_IPFORWARDTABLE { DWORD dwNumEntries; //路由信息的条目数 MIB_IPFORWARDROW table[ANY_SIZE]; //路由表 } MIB_IPFORWARDTABLE, *PMIB_IPFORWARDTABLE; 例:
DWORD dwRet=0; for(DWORD i=0;i<ipftbl->dwNumEntries;i++) { if(ipftbl->table.dwForwardDest==inet_addr(ip)) { dwRet=DeleteIpForwardEntry(&ipftbl->table); } } 其中ipftbl类型是PMIB_IPFORWARDTABLE。 |
|
回复:用IP Helper API动态修改路由 文章收藏, 软件技术, 电脑与网络
Q(游客)发表评论于2009/2/26 18:37:16 |
if(ipftbl->table.dwForwardDest==inet_addr(ip))
少个i? |
|
» 1 »
|