1: /// <summary>
2: /// Class used to ping another computer
3: /// </summary>
4: public static class Ping
5: {
6: #region Public Static Functions
7:
8: /// <summary>
9: /// Does a ping against the host specified
10: /// </summary>
11: /// <param name="Address">Address of the host</param>
12: /// <returns>True if a response is received, false otherwise</returns>
13: public static bool PingHost(string Address)
14: {
15: IPHostEntry Server, From;
16: Socket Socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
17: Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 1000);
18: try
19: {
20: Server = Dns.GetHostEntry(Address);
21: From = Dns.GetHostEntry(Dns.GetHostName());
22: }
23: catch (Exception)
24: {
25: Socket.Close();
26: throw new Exception("Can't find host");
27: }
28:
29: EndPoint EndPoint = new IPEndPoint(Server.AddressList[0], 0);
30: EndPoint EndPointFrom = new IPEndPoint(From.AddressList[0], 0);
31:
32: int PacketSize = 40;
33: Packet Packet = new Packet();
34: Packet.Type = 8;
35: Packet.SubCode = 0;
36: Packet.Check = 0;
37: Packet.ID = 45;
38: Packet.SequenceNumber = 0;
39: int DataSize = 32;
40: Packet.Data = new byte[DataSize];
41: for (int x = 0; x < DataSize; ++x)
42: {
43: Packet.Data[x] = (byte)'#';
44: }
45:
46: byte[] Buffer = Serialize(PacketSize, Packet);
47: double CheckSumSize=System.Math.Ceiling((double)PacketSize/2);
48:
49: ushort []CheckSumBuffer=new ushort[(int)CheckSumSize];
50:
51: int BufferIndex=0;
52: for(int x=0;x<(int)CheckSumSize;++x)
53: {
54: CheckSumBuffer[x]=BitConverter.ToUInt16(Buffer,BufferIndex);
55: BufferIndex+=2;
56: }
57: Packet.Check = CheckSum(CheckSumBuffer);
58:
59: Buffer = Serialize(PacketSize, Packet);
60:
61: if (Socket.SendTo(Buffer, PacketSize, 0, EndPoint) == -1)
62: {
63: Socket.Close();
64: throw new Exception("Couldn't send packet");
65: }
66: Buffer=new byte[256];
67: int NumBytes = Socket.ReceiveFrom(Buffer, 256, SocketFlags.None, ref EndPointFrom);
68: if (NumBytes == -1)
69: {
70: Socket.Close();
71: throw new Exception("Host not responding");
72: }
73: else if (NumBytes > 0)
74: {
75: Socket.Close();
76: return true;
77: }
78:
79: Socket.Close();
80: return false;
81: }
82:
83: #endregion
84:
85: #region Private Static Functions
86:
87: /// <summary>
88: /// Does a check sum of an array
89: /// </summary>
90: /// <param name="CheckSumBuffer">Buffer to do a check sum on</param>
91: /// <returns>The check sum of the buffer</returns>
92: private static ushort CheckSum(ushort[] CheckSumBuffer)
93: {
94: Int32 Sum = 0;
95: for (int x = 0; x < CheckSumBuffer.Length; ++x)
96: {
97: Sum += Convert.ToInt32(CheckSumBuffer[x]);
98: }
99: Sum = (Sum >> 16) + (Sum & 0xffff);
100: Sum += (Sum >> 16);
101: return (UInt16)(~Sum);
102: }
103:
104: /// <summary>
105: /// Serializes the packet into an array
106: /// </summary>
107: /// <param name="PacketSize">Size of the packet</param>
108: /// <param name="Packet">Packet to serialize</param>
109: /// <returns>The packet in byte array form</returns>
110: private static byte[] Serialize(int PacketSize, Packet Packet)
111: {
112: byte[] Buffer = new byte[PacketSize];
113: int x = 2;
114: Buffer[0] = Packet.Type;
115: Buffer[1] = Packet.SubCode;
116:
117: byte[] TempArray = BitConverter.GetBytes(Packet.Check);
118: Array.Copy(TempArray, 0, Buffer, x, TempArray.Length);
119: x += TempArray.Length;
120:
121: TempArray = BitConverter.GetBytes(Packet.ID);
122: Array.Copy(TempArray, 0, Buffer, x, TempArray.Length);
123: x += TempArray.Length;
124:
125: TempArray = BitConverter.GetBytes(Packet.SequenceNumber);
126: Array.Copy(TempArray, 0, Buffer, x, TempArray.Length);
127: x += TempArray.Length;
128:
129: Array.Copy(Packet.Data, 0, Buffer, x, Packet.Data.Length);
130:
131: return Buffer;
132: }
133:
134: #endregion
135:
136: #region Private Classes
137:
138: /// <summary>
139: /// Acts as a packet holder
140: /// </summary>
141: private class Packet
142: {
143: public byte Type;
144: public byte SubCode;
145: public ushort Check;
146: public ushort ID;
147: public ushort SequenceNumber;
148: public byte[] Data;
149: }
150:
151: #endregion
152: }