GetIpForwardTable возвращает мусор в Windows CE с помощью PInvoke - PullRequest
1 голос
/ 20 января 2011

У меня следующая проблема.Я создал PInvoke в управляемом проекте Windows CE .NET для функции GetIpForwardTable.Когда я вызываю функцию, возвращает результат, но результаты отличаются от результата, возвращаемого командой route.В таблице есть больше записей, Маска и Место назначения изменились, и NextHop всегда установлен на 0.0.0.0

Вот класс (нужно вызвать IPForwardEntry.GetIpForwardTable ()).

public class IPForwardEntry
{
    public enum ForwardType
    {
        Other = 1,
        Invalid = 2,
        Direct = 3,
        Indirect = 4
    }

    public enum ForwardProtocol
    {
        Other = 1,
        Local = 2,
        NetMGMT = 3,
        ICMP = 4,
        EGP = 5,
        GGP = 6,
        Hello = 7,
        RIP = 8,
        IS_IS = 9,
        ES_IS = 10,
        CISCO = 11,
        BBN = 12,
        OSPF = 13,
        BGP = 14,
        NT_AUTOSTATIC = 10002,
        NT_STATIC = 10006,
        NT_STATIC_NON_DOD = 10007
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct MIB_IPFORWARDROW
    {
        public uint dwForwardDest;
        public uint dwForwardMask;
        public int dwForwardPolicy;
        public uint dwForwardNextHop;
        public int dwForwardIfIndex;
        public ForwardType dwForwardType;
        public ForwardProtocol dwForwardProto;
        public int dwForwardAge;
        public int dwForwardNextHopAS;
        public int dwForwardMetric1;
        public int dwForwardMetric2;
        public int dwForwardMetric3;
        public int dwForwardMetric4;
        public int dwForwardMetric5;
    }

    private IPForwardEntry(MIB_IPFORWARDROW forwardRow)
    {
        myForwardRow = forwardRow;
    }

    private MIB_IPFORWARDROW myForwardRow;

    private const int NO_ERROR = 0;

    [DllImport("Iphlpapi.dll")]
    private static extern int CreateIpForwardEntry(MIB_IPFORWARDROW[] pRoute);

    [DllImport("Iphlpapi.dll")]
    private static extern int GetIpForwardTable(MIB_IPFORWARDROW[] pIpForwardTable, ref long pdwSize, bool bOrder);

    public static IPForwardEntry[] GetIpForwardTable()
    {
        long tableSize = 0;
        GetIpForwardTable(null, ref tableSize, true);

        MIB_IPFORWARDROW[] forwardTable = new MIB_IPFORWARDROW[tableSize / Marshal.SizeOf(typeof(MIB_IPFORWARDROW)) + 1];

        long tableSizeOld = tableSize;

        if (GetIpForwardTable(forwardTable, ref tableSize, false) != NO_ERROR)
            throw new SystemException();

        if (tableSizeOld != tableSize)
            throw new SystemException();


        IPForwardEntry[] result = new IPForwardEntry[forwardTable.Length];

        for (int i = 0; i < forwardTable.Length; i++)
            result[i] = new IPForwardEntry(forwardTable[i]);

        return result;

    }

    #region members

    public IPAddress FordwardDestination
    {
        get
        {
            return new IPAddress(myForwardRow.dwForwardDest);
        }
        set
        {
            myForwardRow.dwForwardDest = (uint) value.Address;
        }
    }

    public IPAddress ForwardMask
    {
        get
        {
            return new IPAddress(myForwardRow.dwForwardMask);
        }
        set
        {
            myForwardRow.dwForwardMask = (uint) value.Address;
        }
    }

    public int ForwardPolicy
    {
        get
        {
            return myForwardRow.dwForwardPolicy;
        }
        set
        {
            myForwardRow.dwForwardPolicy = value;
        }
    }

    public IPAddress ForwardNextHop
    {
        get
        {
            return new IPAddress(myForwardRow.dwForwardNextHop);
        }
        set
        {
            myForwardRow.dwForwardNextHop = (uint) value.Address;
        }
    }

    public int ForwardInterfaceIndex
    {
        get
        {
            return myForwardRow.dwForwardIfIndex;
        }
        set
        {
            myForwardRow.dwForwardIfIndex = value;
        }
    }


    public ForwardType ForwrdType
    {
        get
        {
            return myForwardRow.dwForwardType;
        }
        set
        {
            myForwardRow.dwForwardType = value;
        }
    }

    public ForwardProtocol Protocol
    {
        get
        {
            return myForwardRow.dwForwardProto;
        }
        set
        {
            myForwardRow.dwForwardProto = value;
        }
    }


    public int ForwardAge
    {
        get
        {
            return myForwardRow.dwForwardAge;
        }
        set
        {
            myForwardRow.dwForwardAge = value;
        }
    }

    public int ForwardNextHopAS
    {
        get
        {
            return myForwardRow.dwForwardNextHopAS;
        }
        set
        {
            myForwardRow.dwForwardNextHopAS = value;
        }
    }

    public int ForwardMetric1
    {
        get
        {
            return myForwardRow.dwForwardMetric1;
        }
        set
        {
            myForwardRow.dwForwardMetric1 = value;
        }
    }

    public int ForwardMetric2
    {
        get
        {
            return myForwardRow.dwForwardMetric2;
        }
        set
        {
            myForwardRow.dwForwardMetric2 = value;
        }
    }

    public int ForwardMetric3
    {
        get
        {
            return myForwardRow.dwForwardMetric3;
        }
        set
        {
            myForwardRow.dwForwardMetric3 = value;
        }
    }

    public int ForwardMetric4
    {
        get
        {
            return myForwardRow.dwForwardMetric4;
        }
        set
        {
            myForwardRow.dwForwardMetric4 = value;
        }
    }

    public int ForwardMetric5
    {
        get
        {
            return myForwardRow.dwForwardMetric5;
        }
        set
        {
            myForwardRow.dwForwardMetric5 = value;
        }
    }

    #endregion

}

Ответы [ 2 ]

2 голосов
/ 20 января 2011

GetIpForwardTable не возвращает массив объектов MIB_IPFORWARDROW, он возвращает MIB_IPFORWARDTABLE, который содержит массив строк и числа.Так что это как минимум одна проблема.Вероятно, есть и другие, поскольку это не простой набор P / Invoke для маршалинга.

Для чего бы я ни был, я уже реализовал весь этот код в Smart Device Framework , в частностив OpenNETCF.Net.NetworkInformation.IPRoutingTable class

0 голосов
/ 20 января 2011

Я не знаю, как работает эта функция, но выглядит очень подозрительно:

new MIB_IPFORWARDROW[tableSize / Marshal.SizeOf(typeof(MIB_IPFORWARDROW)) + 1]

Почему вы делите на sizeof?

...