SendARP返回错误的MAC地址

时间:2014-05-12 17:25:41

标签: c# mac-address arp

我正在尝试使用SendARP函数和此代码获取另一台设备的MAC地址:

[DllImport("iphlpapi.dll", ExactSpelling = true)]
public static extern int SendARP(System.Net.IPAddress DestIP, int SrcIP, byte[] pMacAddr, ref uint PhyAddrLen);

private void btnMAC_Click(object sender, EventArgs e)
{
    string mac = "";
    IPHostEntry hostEntry = Dns.GetHostEntry(IPaddress);

    byte[] macAddr = new byte[6];
    uint macAddrLen = (uint)macAddr.Length;

    int dwRetVal = SendARP(hostEntry.AddressList[0], 0, macAddr, ref macAddrLen);

    if (dwRetVal == 0)
    {
        StringBuilder macAddressString = new StringBuilder();
        for (int i = 0; i < macAddr.Length; i++)
        {
            if (macAddressString.Length > 0)
                macAddressString.Append(":");

            macAddressString.AppendFormat("{0:x2}", macAddr[i]);
        }

        mac = macAddressString.ToString();
    }
    else
    {
        lblMACaddress.Text = "Invalid";
    }
}

它返回的MAC地址完全错误。我引用了这个问题,C++ SendARP returns wrong mac address? 但是这个问题的答案实际上似乎是关于退出函数时缓存的返回堆栈,但我正在我的函数中做所有事情。

我必须遗漏一些基本概念,我不理解其他参考文献。

--- --- EDIT 由于可能的错误参数类型,我的功能更改为:

        string ip = txtIP1.Text + "." + txtIP2.Text + "." + txtIP3.Text + "." + txtIP4.Text;
        IPAddress dst = IPAddress.Parse(ip);
        int intAddress = BitConverter.ToInt32(dst.GetAddressBytes(), 0);

        byte[] macAddr = new byte[6];
        uint macAddrLen = (uint)macAddr.Length;

        if (SendARP(intAddress, 0, macAddr, ref macAddrLen) != 0)
        {
            lblMACaddress.Text = "SendARP failed.";
            return;
        }

        string[] str = new string[(int)macAddrLen];

        for (int i = 0; i < macAddrLen; i++)
            str[i] = macAddr[i].ToString("x2");

        string mac = string.Join(":", str);

现在的问题是,当我使用自己的计算机的IP时,我得到了正确的MAC但是当我在局域网上使用不同计算机的IP时,我得到了SendARP失败的异常。任何想法为什么会发生这种情况?

1 个答案:

答案 0 :(得分:0)

我认为你的p调用是错误的。此函数的WINAPI定义传递

typedef struct {
  union {
    struct {
      u_char s_b1,s_b2,s_b3,s_b4;
    } S_un_b;
    struct {
      u_short s_w1,s_w2;
    } S_un_w;
    u_long S_addr;
  } S_un;
} IPAddr;

我非常怀疑它与IPAddress类具有相同的内存布局。

以下是开始的要点:

http://www.pinvoke.net/default.aspx/iphlpapi.sendarp

如果这不起作用,您可以使用显式内存布局自己对结构进行编组,或者只使用IntPtr。