找回密码
 加入
搜索
查看: 10671|回复: 20

[网络通信] dllcall 调用CreateIpForwardEntry 修改路由应该怎么弄?[已解决]感谢P版

 火.. [复制链接]
发表于 2011-7-14 04:12:08 | 显示全部楼层 |阅读模式
本帖最后由 freedom 于 2011-7-17 02:53 编辑

dllcall  调用 Iphlpapi.dll  中的 CreateIpForwardEntry  函数修改路由表,应该怎么调用。这两天把论坛里关于dllcall的贴子都翻完了。还是没搞懂。。
发表于 2011-7-14 05:51:17 | 显示全部楼层
发表于 2011-7-14 06:54:59 | 显示全部楼层
回复 2# lainline


   
话虽如此说, ip类的结构都极其恶心
 楼主| 发表于 2011-7-14 19:23:36 | 显示全部楼层
就是没搞懂怎么调用。这些资料都是看了的。
发表于 2011-7-14 22:29:25 | 显示全部楼层
写到一下程度可能运行不正确具体哪些参数怎么填我也懒得翻资料了
Local $str =" dword dwForwardDest;dword dwForwardMask;dword dwForwardNextHop;dword dwForwardIfIndex;dword dwForwardType;dword dwForwardProto;dword dwForwardPolicy;dword dwForwardAge;dword dwForwardNextHopAS;dword dwForwardMetric1;dword dwForwardMetric2;dword dwForwardMetric3;dword dwForwardMetric4;dword dwForwardMetric5"
Local $a = DllStructCreate($str)
DllStructSetData($a, "dwForwardDest", inet_addr("1.2.3.4") );目的地址
DllStructSetData($a, "dwForwardMask",  inet_addr("255.255.255.0"));掩码
DllStructSetData($a, "dwForwardNextHop", inet_addr("1.10.10.10") );下一跳
DllStructSetData($a, "dwForwardIfIndex", 1);网卡索引
DllStructSetData($a, "dwForwardType", 4)
DllStructSetData($a, "dwForwardProto",3)
DllStructSetData($a, "dwForwardPolicy ",0)
DllStructSetData($a, "dwForwardAge",0)
DllStructSetData($a, "dwForwardNextHopAS",0)
DllStructSetData($a, "dwForwardMetric1", 10 )
DllStructSetData($a, "dwForwardMetric2", 0xFFFFFFFF)
DllStructSetData($a, "dwForwardMetric3", 0xFFFFFFFF)
DllStructSetData($a, "dwForwardMetric4", 0xFFFFFFFF)
DllStructSetData($a, "dwForwardMetric5", 0xFFFFFFFF)
Local $dll = DllOpen("Iphlpapi.dll")
Local $aResult = DllCall($dll, "dword", "CreateIpForwardEntry", "ptr",DllStructGetPtr($a))
        If @error Then 
        MsgBox (0,"","错误")
Else
        MsgBox(0,"","成功返回结果:"&$aResult[0]&"         "&$aResult[1]);$aResult[0]就是返回值
EndIf
DllClose ($dll)


Func inet_addr($sIP);转换ip格式
$hWs2_32 = DllOpen( "Ws2_32.dll" )
$iRet = DllCall($hWs2_32, "uint", "inet_addr", "str", $sIP)
DllClose($hWs2_32)
If $iRet[ 0 ] = 0xffffffff Then Return False
Return $iRet[ 0 ]
EndFunc
 楼主| 发表于 2011-7-15 02:17:09 | 显示全部楼层
非常感谢!马上测试。
 楼主| 发表于 2011-7-15 03:24:40 | 显示全部楼层
本帖最后由 freedom 于 2011-7-15 03:33 编辑

回复 5# lainline


    好像不行一样。。。  返回值87  传递无效参数。


windows 7
 楼主| 发表于 2011-7-15 04:53:02 | 显示全部楼层
本帖最后由 freedom 于 2011-7-15 04:54 编辑

#include <WinSock2.h>
#include <IPHlpApi.h>
#include <iostream> 
#include <time.h>
#include <Windows.h>    //Windows.h必须在它们几个下面,否则XX
#pragma comment(lib, "Iphlpapi.lib")
#pragma comment(lib,"Ws2_32.lib")
using namespace std;
;下面是我写的获取路由表的函数:
BOOL GetRouteTable()
{
    PMIB_IPFORWARDTABLE pIpForwardTable = NULL;
    ULONG ulOutBufLen = NULL;
    GetIpForwardTable(pIpForwardTable,&ulOutBufLen,TRUE);
    pIpForwardTable = (PMIB_IPFORWARDTABLE)malloc(ulOutBufLen);
    if (NULL == pIpForwardTable)
     {
        return FALSE;
     }
    if (NO_ERROR == GetIpForwardTable(pIpForwardTable,&ulOutBufLen,TRUE))
     {
        cout<<"Dest"<<"\t\t"<<"Mask"<<"\t\t"<<"NextHop"<<endl;
        for (DWORD dw = 0; dw < pIpForwardTable->dwNumEntries; dw++) 
         {
            IN_ADDR inDest,inMask,inNextHop;
            inDest.S_un.S_addr = pIpForwardTable->table[dw].dwForwardDest;
            inMask.S_un.S_addr = pIpForwardTable->table[dw].dwForwardMask;
            inNextHop.S_un.S_addr = pIpForwardTable->table[dw].dwForwardNextHop;
            if (NULL != inDest.S_un.S_addr && NULL != inMask.S_un.S_addr)
             {
                PCHAR pIP;
                pIP = inet_ntoa(inDest);
                cout<<pIP<<"\t";
                pIP = inet_ntoa(inMask);
                cout<<pIP<<"\t";
                pIP = inet_ntoa(inNextHop);
                cout<<pIP<<"\t";
                cout << endl;
             }
         }
     }
    else 
    {
        return FALSE;
     }
    return TRUE;
}
;下面是我写的添加路由表函数:
DWORD   AddRoutingTable(const char* pIP,const char* pMask)
{
    MIB_IPFORWARDROW IpForwardTable;
    ZeroMemory(&IpForwardTable,sizeof(MIB_IPFORWARDROW));
    IpForwardTable.dwForwardDest = inet_addr(pIP);
    IpForwardTable.dwForwardMask = inet_addr(pMask);
    IpForwardTable.dwForwardPolicy = NULL;
    IpForwardTable.dwForwardNextHop = inet_addr(g_pGateway);
    IpForwardTable.dwForwardIfIndex = g_dwIndex;
    IpForwardTable.dwForwardType = 4;  //路由类型 3是最终目标,4是非最终目标,我们加的路由都是要过网关的,设成4 
    IpForwardTable.dwForwardProto = 3;  //路由协议,这个在这个函数里要设成3 
     //IpForwardTable.dwForwardAge = NULL;
     //IpForwardTable.dwForwardNextHopAS = NULL;
    IpForwardTable.dwForwardMetric1 = 1; 
    IpForwardTable.dwForwardMetric2 = 0xFFFFFFFF;
    IpForwardTable.dwForwardMetric3 = 0xFFFFFFFF;  
    IpForwardTable.dwForwardMetric4 = 0xFFFFFFFF;   
    IpForwardTable.dwForwardMetric5 = 0xFFFFFFFF; 
    DWORD dwRetVal = CreateIpForwardEntry(&IpForwardTable);
    return dwRetVal;
}



这个是在网上找到的代码,看不懂。。
发表于 2011-7-15 08:40:45 | 显示全部楼层
我也纠结了 楼主为什么不用DOS命令解决 这种微软自己编的东西基本上就是对这一函数非常熟悉才能用的好
 楼主| 发表于 2011-7-15 18:53:48 | 显示全部楼层
用批处理,或是au3.如果上千条路由命令.要半小时以上!!!!
 楼主| 发表于 2011-7-17 00:32:00 | 显示全部楼层
本帖最后由 freedom 于 2011-7-17 00:55 编辑


    $WSdll = "ws2_32.dll"
        $IHdll = "iphlpapi.dll"
    $MIB_TCPROW = DllStructCreate("dword;dword;dword;dword;dword;dword;dword;dword") ; connection struct
    DllStructSetData($MIB_TCPROW, 1, 8)
    
    $ret = DllCall($WSdll, "dword", "dwForwardDest", "ptr","222.111.22.11") ; 路由IP,目的地址
        If Not @error Then DllStructSetData($MIB_TCPROW, 2, $ret[0])
;~     MsgBox (0,0,$ret[0])
        $ret = DllCall($WSdll, "dword", "dwForwardMask",  "ptr","255.255.255.255") ; 子网掩码
    If Not @error Then DllStructSetData($MIB_TCPROW, 3, $ret[0])

    $ret = DllCall($WSdll, "dword", "dwForwardNextHop", "ptr","192.168.1.254") ; 网关,下一跳地址
    If Not @error Then DllStructSetData($MIB_TCPROW, 4, $ret[0])
    $ret = DllCall($WSdll, "dword", "dwForwardIfIndex", "ptr", 1) ; 网卡索引
    If Not @error Then DllStructSetData($MIB_TCPROW, 5, $ret[0])
    $ret = DllCall($WSdll, "dword", "dwForwardType", "ptr", 4) ; 
    If Not @error Then DllStructSetData($MIB_TCPROW, 6, $ret[0])
    $ret = DllCall($WSdll, "dword", "dwForwardProto", "ptr", 3) ; 
    If Not @error Then DllStructSetData($MIB_TCPROW, 7, $ret[0])
    $ret = DllCall($WSdll, "dword", "dwForwardMetric1", "ptr",30) ; 优先级
    If Not @error Then DllStructSetData($MIB_TCPROW, 8, $ret[0])

    $ret = DllCall($IHdll, "dword", "CreateIpForwardEntry", "ptr", DllStructGetPtr($MIB_TCPROW)) ;

            MsgBox(0,"","返回结果:"&$ret[0]&"         "&$ret[1])



还是不行啊,谁帮我看看啊?返回值87,提交了无效参数。。

MIB_IPFORWARDROW IpForwardTable 这两个又是个什么情况?
发表于 2011-7-17 02:10:26 | 显示全部楼层

Const $IPHLPAPI = DllOpen("iphlpapi.dll")
Const $tagMIB_IPFORWARDROW = "long Destination;long NetworkMask;long Policy;long NextHop;long IfIndex;long Type;long Proto;long Age;long NextHopAS;long Metric1;long Metric2;long Metric3;long Metric4;long Metric5"

Func _EnumIpForwordEntries()
        Local $iResult, $tBuffer, $tBinary, $pBinary, $tNumberofEntries, $aResult[1][14] = [[0]]

        $iResult = DllCall($IPHLPAPI, "long", "GetIpForwardTable", "ptr", 0, "long*", 0, "bool", 1)
        If ($iResult[2] < 4) Then Return SetError($iResult[0], 0, $aResult)

        $tBinary = DllStructCreate("ubyte Binary[" & $iResult[2] & "]")
        $pBinary = DllStructGetPtr($tBinary)

        $iResult = DllCall($IPHLPAPI, "long", "GetIpForwardTable", "ptr", $pBinary, "long*", $iResult[2], "bool", 1)
        If ($iResult[0]) Then Return SetError($iResult[0], 0, $aResult)

        $tNumberofEntries = DllStructCreate("long NumberofEntries", $pBinary)
        $aResult[0][0] = DllStructGetData($tNumberofEntries, "NumberofEntries")
        Redim $aResult[$aResult[0][0] + 1][14]

        For $i = 1 To $aResult[0][0]
                $tBuffer = DllStructCreate($tagMIB_IPFORWARDROW, $pBinary + 4 + ($i - 1) * 56)

                For $j = 0 To 13
                        $aResult[$i][$j] = DllStructGetData($tBuffer, $j + 1)
                Next
                $aResult[$i][0] = _ConvertUlongToChars($aResult[$i][0])
                $aResult[$i][1] = _ConvertUlongToChars($aResult[$i][1])
                $aResult[$i][3] = _ConvertUlongToChars($aResult[$i][3])
        Next

        Return $aResult
EndFunc        ;==>_EnumIpForwordEntries

Func _ConvertUlongToChars($iUlong)
        Local $iResult = DllCall("Ws2_32.dll", "str", "inet_ntoa", "ulong", $iUlong)
        Return $iResult[0]
EndFunc        ;==>_ConvertUlongToChars

Func _ConvertCharsToUlong($sChars)
        Local $iResult = DllCall("Ws2_32.dll", "long", "inet_addr", "str", $sChars)
        Return $iResult[0]
EndFunc        ;==>_ConvertCharsToUlong

Func _CreateIpForwardEntry($sDestination, $sNetworkMask, $sNextHop, $iIfIndex, $iType, $iMetric)
        Local $tBuffer, $iResult

        If $iIfIndex = -1 Then $iIfIndex = _GetBestInterface($sNextHop)

        $tBuffer = DllStructCreate($tagMIB_IPFORWARDROW)
        DllStructSetData($tBuffer, "Destination", _ConvertCharsToUlong($sDestination))
        DllStructSetData($tBuffer, "NetworkMask", _ConvertCharsToUlong($sNetworkMask))
        DllStructSetData($tBuffer, "NextHop", _ConvertCharsToUlong($sNextHop))
        DllStructSetData($tBuffer, "IfIndex", $iIfIndex)
        DllStructSetData($tBuffer ,"Type", $iType)
        DllStructSetData($tBuffer, "Proto", 3)
        DllStructSetData($tBuffer, "Policy", 0)
        DllStructSetData($tBuffer, "Age", 0)
        DllStructSetData($tBuffer, "NextHopAS", 0)
        DllStructSetData($tBuffer, "Metric1", $iMetric)
        DllStructSetData($tBuffer ,"Metric2", -1)
        DllStructSetData($tBuffer ,"Metric3", -1)
        DllStructSetData($tBuffer ,"Metric4", -1)
        DllStructSetData($tBuffer ,"Metric5", -1)

        $iResult = DllCall($IPHLPAPI, "long", "CreateIpForwardEntry", "ptr", DllStructGetPtr($tBuffer))
        Return SetError($iResult[0], 0, $iResult[0] = 0)
EndFunc        ;==>_CreateIpForwardEntry

Func _DeleteIpForwardEntry($sDestination, $sNetworkMask, $sNextHop, $iIfIndex, $iProto = 3)
        Local $iResult, $tBuffer

        If $iIfIndex = -1 Then $iIfIndex = _GetBestInterface($sNextHop)

        $tBuffer = DllStructCreate($tagMIB_IPFORWARDROW)
        DllStructSetData($tBuffer, "Destination", _ConvertCharsToUlong($sDestination))
        DllStructSetData($tBuffer, "NetworkMask", _ConvertCharsToUlong($sNetworkMask))
        DllStructSetData($tBuffer, "NextHop", _ConvertCharsToUlong($sNextHop))
        DllStructSetData($tBuffer, "IfIndex", $iIfIndex)
        DllStructSetData($tBuffer, "Proto", $iProto)

        $iResult = DllCall($IPHLPAPI, "long", "DeleteIpForwardEntry", "ptr", DllStructGetPtr($tBuffer))
        Return SetError($iResult[0], 0, $iResult[0] = 0)
EndFunc        ;==>_DeleteIpForwardEntry

Func _GetBestInterface($sAddress)
        Local $iResult

        $iResult = DllCall($IPHLPAPI, "long", "GetBestInterface", "long", _ConvertCharsToUlong($sAddress), "long*", 0)
        Return SetError($iResult[0], 0, $iResult[2])
EndFunc        ;==>_GetBestInterface

If _CreateIpForwardEntry("1.2.3.4", "255.255.255.255", "1.2.3.0", -1, 3, 60) Then
        MsgBox(48, "OK", "Done")
Else
        MsgBox(48, "Error", "Failed with error " & @error)
EndIf

If _DeleteIpForwardEntry("1.2.3.4", "255.255.255.255", "1.2.3.0", -1) Then
        MsgBox(48, "OK", "Done")
Else
        MsgBox(48, "Error", "Failed with error " & @error)
EndIf


注意目标地址、网络掩码、网关地址 这3个参数要相互匹配。
 楼主| 发表于 2011-7-17 02:39:19 | 显示全部楼层
回复 12# pusofalse


谢谢版主,问题已解决,你是哪人啊?不远的话,我请你吃饭。
发表于 2011-7-20 10:31:22 | 显示全部楼层
看了大半天,收获太大了
发表于 2011-9-5 20:59:31 | 显示全部楼层
很好的东西,谢谢收藏了!
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-16 20:17 , Processed in 0.075703 second(s), 19 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表