Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Netduino send ICMP Ping ?


  • Please log in to reply
15 replies to this topic

#1 dimeodesign

dimeodesign

    New Member

  • Members
  • Pip
  • 1 posts

Posted 09 May 2011 - 07:53 PM

How can Netduino send an ICMP Ping command?

#2 ColinR

ColinR

    Advanced Member

  • Members
  • PipPipPip
  • 142 posts
  • LocationCape Town, South Africa

Posted 06 June 2011 - 06:53 AM

Did you ever work this out? I'm thinking to ping my gateway to determine if my network on the netduino has died, or if the internet is down. If the network on the Netduino is to blame, I have to request a reboot. But I can't have the Netduino rebooting every minute while the internet is down.

#3 Dixon

Dixon

    Advanced Member

  • Members
  • PipPipPip
  • 32 posts

Posted 13 June 2011 - 08:07 AM

Did you ever work this out?

I'm thinking to ping my gateway to determine if my network on the netduino has died, or if the internet is down. If the network on the Netduino is to blame, I have to request a reboot. But I can't have the Netduino rebooting every minute while the internet is down.


How do you reboot the netduino by code?

#4 ColinR

ColinR

    Advanced Member

  • Members
  • PipPipPip
  • 142 posts
  • LocationCape Town, South Africa

Posted 13 June 2011 - 06:34 PM

How do you reboot the netduino by code?


Microsoft.SPOT.Hardware.PowerState.RebootDevice(false);


#5 ColinR

ColinR

    Advanced Member

  • Members
  • PipPipPip
  • 142 posts
  • LocationCape Town, South Africa

Posted 29 June 2011 - 05:42 AM

Am I correct in saying that ProtocolType.Icmp is not supported?
calling Ping.PingHost(ipAddress) throws an exception at Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp)

Othrewise it looks as if this would allow the use of ping to confirm network stack alive.
As an aside, is there anyway to re-initialise the lwIP stack programatically?

Ping.cs
namespace MyNetduino.ICMP
{
    using System;
    using System.Net;
    using System.Net.Sockets;

    /// <summary>
    ///	 The Main Ping Class
    /// </summary>
    public static class Ping
    {
        //Declare some Constant Variables
        const int SOCKET_ERROR = -1;
        const int ICMP_ECHO = 8;

        /// <summary>
        ///	 This method takes the "hostname" of the server
        ///	 and then it ping's it and shows the response time
        /// </summary>
        public static bool PingHost(string host)
        {
            //Declare the IPHostEntry 
            IPEndPoint ipepServer, ipepLocal;
            int nBytes = 0;
            long dwStart = 0;
            //Initilize a Socket of the Type ICMP
            using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp))
            {

                // Get the server endpoint
                try
                {
                    ipepServer = new IPEndPoint(IPAddress.Parse(Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0].GatewayAddress), 0);
                }
                catch (Exception)
                {
                    return false;
                }

                EndPoint epServer = (ipepServer);

                // Set the receiving endpoint to the client machine
                ipepLocal = new IPEndPoint(IPAddress.Parse(Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0].IPAddress), 0);
                EndPoint epLocal = (ipepLocal);

                int PacketSize = 0;
                IcmpPacket packet = new IcmpPacket();
                // Construct the packet to send
                packet.Type = ICMP_ECHO; //8
                packet.SubCode = 0;
                packet.CheckSum = UInt16.Parse("0");
                packet.Identifier = UInt16.Parse("45");
                packet.SequenceNumber = UInt16.Parse("0");
                int PingData = 32; // sizeof(IcmpPacket) – 8;
                packet.Data = new Byte[PingData];
                //Initilize the Packet.Data
                for (int i = 0; i < PingData; i++)
                {
                    packet.Data[i] = (byte)'#';
                }

                //Variable to hold the total Packet size
                PacketSize = PingData + 8;
                Byte[] icmp_pkt_buffer = new Byte[PacketSize];
                Int32 Index = 0;
                //Call a Method Serialize which counts
                //The total number of Bytes in the Packet
                Index = Serialize(
                packet,
                icmp_pkt_buffer,
                PacketSize,
                PingData);
                //Error in Packet Size
                if (Index == -1)
                {
                    return false;
                }

                // now get this critter into a UInt16 array

                //Get the Half size of the Packet
                Double double_length = (double)Index;
                Double dtemp = Math.Ceiling(double_length / 2);
                int cksum_buffer_length = (int)dtemp;
                //Create a Byte Array
                UInt16[] cksum_buffer = new UInt16[cksum_buffer_length];
                //Code to initialize the Uint16 array 
                int icmp_header_buffer_index = 0;
                for (int i = 0; i < cksum_buffer_length; i++)
                {
                    cksum_buffer[i] =
                    BitConverter.ToUInt16(icmp_pkt_buffer, icmp_header_buffer_index);
                    icmp_header_buffer_index += 2;
                }
                //Call a method which will return a checksum 
                UInt16 u_cksum = checksum(cksum_buffer, cksum_buffer_length);
                //Save the checksum to the Packet
                packet.CheckSum = u_cksum;

                // Now that we have the checksum, serialize the packet again
                Byte[] sendbuf = new Byte[PacketSize];
                //again check the packet size
                Index = Serialize(packet, sendbuf, PacketSize, PingData);
                //if there is a error report it
                if (Index == -1)
                {
                    return false;
                }

                dwStart = DateTime.Now.Ticks; // Start timing and send the Pack over the socket
                if ((nBytes = socket.SendTo(sendbuf, PacketSize, 0, epServer)) == SOCKET_ERROR)
                {
                    return false;
                }

                // Initialize the buffers. The receive buffer is the size of the
                // ICMP header plus the IP header (20 bytes)
                Byte[] ReceiveBuffer = new Byte[256];
                nBytes = 0;
                long timeout = 0;
                while (true)
                {
                    nBytes = socket.ReceiveFrom(ReceiveBuffer, 256, 0, ref epLocal);
                    if (nBytes == SOCKET_ERROR)
                    {
                        return false;
                    }
                    else if (nBytes > 0)
                    {
                        return true;
                    }

                    timeout = DateTime.Now.Ticks - dwStart;
                    if (timeout > 1000)
                    {
                        return false;
                    }
                }
            }
        }

        /// <summary>
        /// This method get the Packet and calculates the total size 
        /// of the Pack by converting it to byte array
        /// </summary>
        public static Int32 Serialize(IcmpPacket packet, Byte[] Buffer,
        Int32 PacketSize, Int32 PingData)
        {
            Int32 cbReturn = 0;
            // serialize the struct into the array
            int Index = 0;

            Byte[] b_type = new Byte[1];
            b_type[0] = (packet.Type);

            Byte[] b_code = new Byte[1];
            b_code[0] = (packet.SubCode);

            Byte[] b_cksum = BitConverter.GetBytes(packet.CheckSum);
            Byte[] b_id = BitConverter.GetBytes(packet.Identifier);
            Byte[] b_seq = BitConverter.GetBytes(packet.SequenceNumber);

            // Console.WriteLine("Serialize type ");
            Array.Copy(b_type, 0, Buffer, Index, b_type.Length);
            Index += b_type.Length;

            // Console.WriteLine("Serialize code ");
            Array.Copy(b_code, 0, Buffer, Index, b_code.Length);
            Index += b_code.Length;

            // Console.WriteLine("Serialize cksum ");
            Array.Copy(b_cksum, 0, Buffer, Index, b_cksum.Length);
            Index += b_cksum.Length;

            // Console.WriteLine("Serialize id ");
            Array.Copy(b_id, 0, Buffer, Index, b_id.Length);
            Index += b_id.Length;

            Array.Copy(b_seq, 0, Buffer, Index, b_seq.Length);
            Index += b_seq.Length;

            // copy the data	
            Array.Copy(packet.Data, 0, Buffer, Index, PingData);
            Index += PingData;
            if (Index != PacketSize/* sizeof(IcmpPacket) */)
            {
                cbReturn = -1;
                return cbReturn;
            }

            cbReturn = Index;
            return cbReturn;
        }

        /// <summary>
        ///	 This Method has the algorithm to make a checksum 
        /// </summary>
        public static UInt16 checksum(UInt16[] buffer, int size)
        {
            Int32 cksum = 0;
            int counter;
            counter = 0;

            while (size > 0)
            {
                UInt16 val = buffer[counter];

                cksum += (int)buffer[counter];
                counter += 1;
                size -= 1;
            }

            cksum = (cksum >> 16) + (cksum & 0xffff);
            cksum += (cksum >> 16);
            return (UInt16)(~cksum);
        }
    }    
}

BitConverter.cs
using System;
using Microsoft.SPOT;

namespace MyNetduino.ICMP
{
    public static class BitConverter
    {
        public static unsafe long DoubleToInt64Bits(double value)
        {
            return *(((long*)&value));
        }
        public static unsafe double Int64BitsToDouble(long value)
        {
            return *(((double*)&value));
        }
        public static byte[] GetBytes(bool value)
        {
            return new byte[] { (value ? ((byte)1) : ((byte)0)) };
        }
        public static byte[] GetBytes(char value)
        {
            return new byte[2] { (byte)(value & 0xFF), (byte)((value >> 8) & 0xFF) };
        }
        public static byte[] GetBytes(short value)
        {
            return new byte[2] { (byte)(value & 0xFF), (byte)((value >> 8) & 0xFF) };
        }
        public static byte[] GetBytes(ushort value)
        {
            return new byte[2] { (byte)(value & 0xFF), (byte)((value >> 8) & 0xFF) };
        }
        public static byte[] GetBytes(int value)
        {
            return new byte[4] { 
                    (byte)(value & 0xFF), 
                    (byte)((value >> 8) & 0xFF), 
                    (byte)((value >> 16) & 0xFF), 
                    (byte)((value >> 24) & 0xFF) };
        }
        public static byte[] GetBytes(uint value)
        {
            return new byte[4] { 
                    (byte)(value & 0xFF), 
                    (byte)((value >> 8) & 0xFF), 
                    (byte)((value >> 16) & 0xFF), 
                    (byte)((value >> 24) & 0xFF) };
        }
        public static byte[] GetBytes(long value)
        {
            return new byte[8] { 
                    (byte)(value & 0xFF), 
                    (byte)((value >> 8) & 0xFF), 
                    (byte)((value >> 16) & 0xFF), 
                    (byte)((value >> 24) & 0xFF),
                    (byte)((value >> 32) & 0xFF),
                    (byte)((value >> 40) & 0xFF),
                    (byte)((value >> 48) & 0xFF),
                    (byte)((value >> 56) & 0xFF)};
        }
        public static byte[] GetBytes(ulong value)
        {
            return new byte[8] { 
                    (byte)(value & 0xFF), 
                    (byte)((value >> 8) & 0xFF), 
                    (byte)((value >> 16) & 0xFF), 
                    (byte)((value >> 24) & 0xFF),
                    (byte)((value >> 32) & 0xFF),
                    (byte)((value >> 40) & 0xFF),
                    (byte)((value >> 48) & 0xFF),
                    (byte)((value >> 56) & 0xFF)};
        }
        public static unsafe byte[] GetBytes(float value)
        {
            int val = *((int*)&value);
            return GetBytes(val);
        }
        public static unsafe byte[] GetBytes(double value)
        {
            long val = *((long*)&value);
            return GetBytes(val);
        }

        public static bool ToBoolean(byte[] value, int index = 0)
        {
            return value[index] != 0;
        }
        public static char ToChar(byte[] value, int index = 0)
        {
            return (char)(value[0 + index] << 0 | value[1 + index] << 8);
        }
        public static short ToInt16(byte[] value, int index = 0)
        {
            return (short)(
                value[0 + index] << 0 |
                value[1 + index] << 8);
        }
        public static int ToInt32(byte[] value, int index = 0)
        {
            return (
                value[0 + index] << 0 |
                value[1 + index] << 8 |
                value[2 + index] << 16 |
                value[3 + index] << 24);
        }
        public static long ToInt64(byte[] value, int index = 0)
        {
            return (
                (long)value[0 + index] << 0) |
                (long)value[1 + index] << 8 |
                (long)value[2 + index] << 16 |
                (long)value[3 + index] << 24 |
                (long)value[4 + index] << 32 |
                (long)value[5 + index] << 40 |
                (long)value[6 + index] << 48 |
                (long)value[7 + index] << 56;
        }
        public static ushort ToUInt16(byte[] value, int index = 0)
        {
            return (ushort)(
                value[0 + index] << 0 |
                value[1 + index] << 8);
        }
        public static uint ToUInt32(byte[] value, int index = 0)
        {
            return (uint)(
                value[0 + index] << 0 |
                value[1 + index] << 8 |
                value[2 + index] << 16 |
                value[3 + index] << 24);
        }
        public static ulong ToUInt64(byte[] value, int index = 0)
        {
            return (ulong)(
                value[0 + index] << 0 |
                value[1 + index] << 8 |
                value[2 + index] << 16 |
                value[3 + index] << 24 |
                value[4 + index] << 32 |
                value[5 + index] << 40 |
                value[6 + index] << 48 |
                value[7 + index] << 56);
        }

        public static unsafe float ToSingle(byte[] value, int index = 0)
        {
            int i = ToInt32(value);
            return *(((float*)&i));
        }
        public static unsafe double ToDouble(byte[] value, int index = 0)
        {
            long l = ToInt64(value);
            return *(((double*)&l));
        }

        public static string ToString(byte[] value, int index = 0)
        {
            return ToString(value, index, value.Length - index);
        }
        public static string ToString(byte[] value, int index, int length)
        {
            char[] c = new char[length * 3];
            byte b;

            for (int y = 0, x = 0; y < length; ++y, ++x)
            {
                b = (byte)(value[index + y] >> 4);
                c[x] = (char)(b > 9 ? b + 0x37 : b + 0x30);
                b = (byte)(value[index + y] & 0xF);
                c[++x] = (char)(b > 9 ? b + 0x37 : b + 0x30);
                c[++x] = '-';
            }
            return new string(c, 0, c.Length - 1);
        }
    }
}

IcmpPacket.cs
using System;
using Microsoft.SPOT;

namespace MyNetduino.ICMP
{
    // class ping
    /// <summary>
    ///	 Class that holds the Pack information
    /// </summary>
    public class IcmpPacket
    {
        public Byte Type; // type of message
        public Byte SubCode; // type of sub code
        public UInt16 CheckSum; // ones complement checksum of struct
        public UInt16 Identifier; // identifier
        public UInt16 SequenceNumber; // sequence number 
        public Byte[] Data;

    } // class IcmpPacket
}


#6 chedemefedeme

chedemefedeme

    New Member

  • Members
  • Pip
  • 8 posts

Posted 25 July 2011 - 04:01 AM

I'd like to bring this back to life. Can someone please give an example of pinging another host on the network using Netduino Plus in c#?

#7 ColinR

ColinR

    Advanced Member

  • Members
  • PipPipPip
  • 142 posts
  • LocationCape Town, South Africa

Posted 25 July 2011 - 02:02 PM

I'd like to bring this back to life. Can someone please give an example of pinging another host on the network using Netduino Plus in c#?


I'll second that :)

#8 samjones

samjones

    Advanced Member

  • Members
  • PipPipPip
  • 105 posts

Posted 29 December 2011 - 04:16 AM

I have big need of ping for two reasons: #1: Ping is an important part of getting started with netduino networking. I can't ping the netduino (cause it has no full stack running), so I want to ping from netduino to the network. #2: I would like to build a little network monitor, that runs at work, and if it can't ping the server for some period of time, it sends me an sms message (out of band, in case the inet connection is down) Gotta have ping on netduino to do this!

#9 Brettski

Brettski

    New Member

  • Members
  • Pip
  • 5 posts
  • LocationChicago, Illinois

Posted 08 January 2012 - 05:17 AM

My netduino seems to respond fine to ICMP ping requests, not sure why you are having an issue. @ColinR instead of using ICMP ping, connect using HTTP to determine if the internet is available or not. It should give you the same results. Response time can be used for latency... @samejones I am not sure what services are running on your server to see if there is another way to test it other that ICMP ping packets. Other than as a toy, not sure how useful a netduino "monitor" would be. Parking a regular app on a machine seems much more feasible and flexible.

#10 ColinR

ColinR

    Advanced Member

  • Members
  • PipPipPip
  • 142 posts
  • LocationCape Town, South Africa

Posted 08 January 2012 - 06:17 AM

@ColinR instead of using ICMP ping, connect using HTTP to determine if the internet is available or not. It should give you the same results. Response time can be used for latency...


My application logs data via http once a minute. I was wanting to test ping for the occasions when the http connection fails - but the netduino is still connected to the internet. If http fail, and ping succeeds: force reboot.

#11 Brettski

Brettski

    New Member

  • Members
  • Pip
  • 5 posts
  • LocationChicago, Illinois

Posted 09 January 2012 - 01:01 AM

My application logs data via http once a minute. I was wanting to test ping for the occasions when the http connection fails - but the netduino is still connected to the internet. If http fail, and ping succeeds: force reboot.


OK, but what is the difference than connecting to something local via http or using ping? Both will test if it's the netduino or internet which is down.

I agree, it would be great if a icmp ping was available.

#12 ColinR

ColinR

    Advanced Member

  • Members
  • PipPipPip
  • 142 posts
  • LocationCape Town, South Africa

Posted 09 January 2012 - 05:08 AM

OK, but what is the difference than connecting to something local via http or using ping? Both will test if it's the netduino or internet which is down.


I didn't want to make the assumption that the gateway (the address I was going to ping) would always have an http interface.

#13 Brettski

Brettski

    New Member

  • Members
  • Pip
  • 5 posts
  • LocationChicago, Illinois

Posted 10 January 2012 - 06:47 PM

I didn't want to make the assumption that the gateway (the address I was going to ping) would always have an http interface.



Sorry, I assumed the solution was more specific than general.

#14 David_G

David_G

    New Member

  • Members
  • Pip
  • 3 posts

Posted 06 October 2012 - 05:34 AM

I'll second that :)


Me too... I'll third that!

#15 Daniel Minnaar

Daniel Minnaar

    Advanced Member

  • Members
  • PipPipPip
  • 46 posts
  • LocationJohannesburg, South Africa

Posted 01 April 2014 - 08:40 AM

To get back to this issue, I've tested Colin's 3 source files he posted above on the Netduino Plus 2, and it works. However, when the network is not available, an exception gets thrown instead of a false being returned.

 

Successful pings return a true though, so this is definitely a solution.



#16 ColinR

ColinR

    Advanced Member

  • Members
  • PipPipPip
  • 142 posts
  • LocationCape Town, South Africa

Posted 01 April 2014 - 09:02 AM

To get back to this issue, I've tested Colin's 3 source files he posted above on the Netduino Plus 2, and it works. However, when the network is not available, an exception gets thrown instead of a false being returned.

 

Successful pings return a true though, so this is definitely a solution.

 

Perfect, so we'll know:

 

I'm alive, remote dead
I'm alive, remote alive,

I'm dead






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.