Netduino send ICMP Ping ?
#1
Posted 09 May 2011 - 07:53 PM
#2
Posted 06 June 2011 - 06:53 AM
#3
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
Posted 13 June 2011 - 06:34 PM
How do you reboot the netduino by code?
Microsoft.SPOT.Hardware.PowerState.RebootDevice(false);
#5
Posted 29 June 2011 - 05:42 AM
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
Posted 25 July 2011 - 04:01 AM
#7
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
Posted 29 December 2011 - 04:16 AM
#9
Posted 08 January 2012 - 05:17 AM
#10
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
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
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
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
Posted 06 October 2012 - 05:34 AM
I'll second that
Me too... I'll third that!
#15
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
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