开发者

Retrieving the interface–to–IP address mapping table

开发者 https://www.devze.com 2023-04-07 18:28 出处:网络
I know the index of network interface returned by WinAPI\'s GetBestInterface. How do I get interface properties (IPv4 address) based on interface\'s index?

I know the index of network interface returned by WinAPI's GetBestInterface. How do I get interface properties (IPv4 address) based on interface's index?

Here is the working C++ code, but I need it in C#.

PMIB_IPADDRTABLE    pAddrTable;
PMIB_IPADDRROW      pAddrRow;
in_addr             ia;


CBasePage::OnSetActive();

m_edit1.SetFont(&m_font);
m_edit1.SetWindowText("");

GetIpAddrTable((PMIB_IPADDRTABLE) m_pBuffer, &m_ulSize, TRUE);

m_pBuffer = new BYTE[m_ulSize];
if (NULL != m_pBuffer)
{
    m_dwResult = GetIpAddrTable((PMIB_IPADDRTABLE) m_pBuffer, &m_ulSize, TRUE);
    if (m_dwResult == NO_ERROR)
    {
        pAddrTable = (PMIB_IPADDRTABLE) m_pBuffer;

        for (int x = 0; x < pAddrTable->dwNumEntries; x++)
        {
            pAddr开发者_开发技巧Row = (PMIB_IPADDRROW) &(pAddrTable->table[x]);

            ia.S_un.S_addr = pAddrRow->dwAddr;
            m_strText.Format("       IP address: %s\r\n", inet_ntoa(ia));
            m_edit1.ReplaceSel(m_strText);

            m_strText.Format("  Interface index: %lu\r\n", pAddrRow->dwIndex);
            m_edit1.ReplaceSel(m_strText);

            ia.S_un.S_addr = pAddrRow->dwMask;
            m_strText.Format("      Subnet mask: %s\r\n", inet_ntoa(ia));
            m_edit1.ReplaceSel(m_strText);

            ia.S_un.S_addr = pAddrRow->dwBCastAddr;
            m_strText.Format("Broadcast address: %s\r\n", inet_ntoa(ia));
            m_edit1.ReplaceSel(m_strText);

            m_edit1.ReplaceSel("\r\n");
        }
    }
    else
    {
        m_strText.Format("GetIpAddrTable() failed.  Result = %lu\r\n", m_dwResult);
        m_edit1.ReplaceSel(m_strText);
    }

    delete [] m_pBuffer;
}

I've tried the example on pinvoke but it returns 0.0.0.0 for all the interfaces.


It works for me:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Net;

namespace IpInfo
{
    [StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
    struct MIB_IPADDRROW 
    {
        public int         _address;
        public int         _index;
        public int         _mask;
        public int         _broadcastAddress;
        public int         _reassemblySize;
        public ushort    _unused1;
        public ushort    _type;
    }

    class Program
    {
        [DllImport("iphlpapi.dll", SetLastError=true)]
        public static extern int GetIpAddrTable(IntPtr pIpAddrTable, ref int pdwSize, bool bOrder);

        static void Main(string[] args)
        {
            IntPtr pBuf = IntPtr.Zero;
            int nBufSize = 0;
            // get the required buffer size            
            GetIpAddrTable( IntPtr.Zero, ref nBufSize, false );
            // allocate the buffer
            pBuf = Marshal.AllocHGlobal( nBufSize );

            try
            {
                int r = GetIpAddrTable(pBuf, ref nBufSize, false);
                if (r != 0)
                    throw new System.ComponentModel.Win32Exception(r);

                int entrySize = Marshal.SizeOf(typeof(MIB_IPADDRROW));
                int nEntries = Marshal.ReadInt32(pBuf);
                int tableStartAddr = (int)pBuf + sizeof(int);
                for (int i = 0; i < nEntries; i++)
                {
                    IntPtr pEntry = (IntPtr)(tableStartAddr + i * entrySize);
                    MIB_IPADDRROW addrStruct = (MIB_IPADDRROW)Marshal.PtrToStructure(pEntry, typeof(MIB_IPADDRROW));
                    string ipAddrStr = IPToString(IPAddress.NetworkToHostOrder(addrStruct._address));
                    string ipMaskStr = IPToString(IPAddress.NetworkToHostOrder(addrStruct._mask));
                    Console.WriteLine("IP:" + ipAddrStr + " Mask:" + ipMaskStr);
                }
            }
            finally
            {
                if (pBuf != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pBuf);
                }
            }
        }

        // helper function IPToString
        static string IPToString(int ipaddr)
        {
            return String.Format("{0}.{1}.{2}.{3}",
            (ipaddr >> 24) & 0xFF, (ipaddr >> 16) & 0xFF,
            (ipaddr >> 8) & 0xFF, ipaddr & 0xFF);
        }
    }
}

Produces output like this on my machine:

IP:127.0.0.1 Mask:255.0.0.0
IP:192.168.1.3 Mask:255.255.255.0


Have you tried the functions provided by .NET for this:

  • NetworkInterface.GetAllNetworkInterfaces static function
  • NetworkInterface.GetIPProperties method
  • IPInterfaceProperties.UnicastAddresses property
  • IPInterfaceProperties.GetIPv4Properties method
0

精彩评论

暂无评论...
验证码 换一张
取 消