Search code examples
c#.netpingarp

Pinging using ARP always return host offline


I'm trying to check if computer on the net is online by using code which supposedly to check it by using ARP packets.

I am always getting message that host is offline even when I'm sure that it's online. I have checked on my localhost IP and on some always working IPs such as google.

That could be wrong with this code?

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

private byte[] macAddr = new byte[6];
private uint macAddrLen;

private void Ping(IPAddress address)
{
    if (SendARP(address, 0, new byte[6], ref macAddrLen) == 0)
    {
        open++;
        txtDisplay.AppendText("Host " + address + " is open." + Environment.NewLine);
    }
    else
    {
        closed++;
        txtDisplay.AppendText("Host " + address + " is closed." + Environment.NewLine);
    }
}

By using previous code I'm basically trying to do something like following code. But the problem with this code is that when host is closed that it takes like 2 seconds to get the respond which I want to eliminate. Someone suggested to use ARP ping:

private void Ping(IPAddress address)
{
    Ping pingSender = new Ping();
    PingOptions options = new PingOptions();
    if (cbDontFragment.Checked) options.DontFragment = true;
    else options.DontFragment = false;
    string dataa = string.Empty;
    int dataCounter = 0;
    options.Ttl = (int)nudTTL.Value;

    for (int i = 0; i < nudData.Value; i++)
    {
        dataCounter++;
        if (dataCounter == 10) dataCounter = 0;
        dataa += dataCounter.ToString();
    }

    byte[] buffer = Encoding.ASCII.GetBytes(dataa);
    int timeout = 120;
    try
    {
        PingReply reply = pingSender.Send(address, timeout, buffer, options);

        if (reply.Status == IPStatus.Success)
        {
            open++;
            txtDisplay.AppendText("Host " + address + " is open. ");
            if (cbDontFragment.Checked) txtDisplay.AppendText(" Don't fragment. ");
            txtDisplay.AppendText(" TTL: " + options.Ttl.ToString() + " ");
            txtDisplay.AppendText(" Bytes: " + nudData.Value + " ");
            txtDisplay.AppendText(Environment.NewLine);
        }
        else
        {
            closed++;
            txtDisplay.AppendText("Host " + address + " is closed. ");
            if (cbDontFragment.Checked) txtDisplay.AppendText(" Don't fragment. ");
            txtDisplay.AppendText(" TTL: " + options.Ttl.ToString() + " ");
            txtDisplay.AppendText(" Bytes: " + nudData.Value + " ");
            txtDisplay.AppendText(Environment.NewLine);
        }
    }
    catch (Exception ex)
    {
        txtDisplay.SelectedText += Environment.NewLine + ex.Message;
    }
}

Solution

  • ARP cannot be used for what you are trying to do. It only works over a local network.

    It's purpose is to resolve an IP address (which is routed) to a MAC address (which is not). It is never sent beyond a network segment (a lan)