1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
| public 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 void PingHost(string strPingHost, int iPingBytes, uint lngPingCount, uint lngPingTimeout)
{
// string strHostToPing = "";
// bool bLoop = false;
// bool bAddressResolve = false;
// iPingBytes = always 32 bytes!! (called in Hoofdscherm)
const int MAX_PACKET_SIZE = 65535;
//Declare the IPHostEntry
IPHostEntry PingTarget, PingSource;
int iBytesReceived = 0;
int dwStart = 0, dwStop = 0;
uint iLoop = 0;
// Get the server endpoint
try
{
PingTarget = Dns.GetHostByName(strPingHost);
}
catch(Exception)
{
MessageBox.Show("Unknown host {0}" , strPingHost); // fail
return;
}
// Convert the server IP_EndPoint to an EndPoint
IPEndPoint ipepServer = new IPEndPoint(PingTarget.AddressList[0],0);
EndPoint epServer = (ipepServer);
// Set the receiving endpoint to the client machine
PingSource = Dns.GetHostByName(Dns.GetHostName());
IPEndPoint ipEndPointFrom = new IPEndPoint(PingSource.AddressList[0],0);
EndPoint EndPointFrom = (ipEndPointFrom);
int iPacketSize = 0;
IcmpPacket PingPacket = new IcmpPacket();
// Construct the packet to send
PingPacket.Type = ICMP_ECHO; //8
PingPacket.SubCode = 0;
PingPacket.CheckSum = UInt16.Parse("0");
PingPacket.Identifier = UInt16.Parse("45");
PingPacket.SequenceNumber = UInt16.Parse("0");
PingPacket.Data = new Byte[iPingBytes];
//Initialize the Packet.Data
for (int iCount = 0; iCount < iPingBytes; iCount++)
{
PingPacket.Data[iCount] = (byte)'#';
}
//Variable to hold the total Packet size
iPacketSize = iPingBytes + 8;
byte [] bytPktBuffer = new byte[iPacketSize];
int iResult = 0;
//Call a Method Serialize which counts
//The total number of Bytes in the Packet
iResult = Serialize(PingPacket, bytPktBuffer, iPacketSize, iPingBytes );
//Error in Packet Size
if( iResult == -1 )
{
MessageBox.Show("Error in Making Packet");
return;
}
/* now get this critter into a ushort array */
ushort [] cksum_buffer = new ushort[Convert.ToInt32( Math.Ceiling( Convert.ToDouble(iResult) / 2))];
//Code to initialize the ushort array
int icmp_header_buffer_index = 0;
for( int iCount = 0; iCount < cksum_buffer.Length; iCount++ )
{
cksum_buffer[iCount] = BitConverter.ToUInt16(bytPktBuffer, icmp_header_buffer_index);
icmp_header_buffer_index += 2;
}
//Call a method which will return a checksum
//Save the checksum to the Packet
PingPacket.CheckSum = CheckSum(cksum_buffer);
// Now that we have the checksum, serialize the packet again
byte [] byteSendBuffer = new byte[ iPacketSize ];
//again check the PingPacket size
iResult = Serialize(PingPacket, byteSendBuffer, iPacketSize, iPingBytes );
//if there is a error report it
if( iResult == -1 )
{
MessageBox.Show("Error in Making Packet");
return;
}
//Loop the ping for IntPingCount times (standard 4, to be lateron (for testing 1))
long lngPacketsSent = 0, lngPacketsReceived = 0, lngTotalTransmitTime = 0;
int iMinTransmitTime = int.MaxValue, iMaxTransmitTime = int.MinValue;
do
{
bool bReceived = false ;
//Initialize a Socket of the Type ICMP
Socket PingSocket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
//Set socket timeout, but this doesn't seem to work...
PingSocket.SetSocketOption( SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, (int) lngPingTimeout);
PingSocket.SetSocketOption( SocketOptionLevel.Socket, SocketOptionName.SendTimeout, (int) lngPingTimeout);
// Initialize the buffers. The receive buffer is the size of the
// ICMP header plus the IP header (20 bytes)
byte [] ReceiveBuffer = new byte [MAX_PACKET_SIZE];
dwStart = System.Environment.TickCount; // Start timing
//Gather stats
lngPacketsSent ++;
//send the Pack over the socket
iResult = PingSocket.SendTo(byteSendBuffer, iPacketSize, SocketFlags.None , epServer);
if ((iResult) == SOCKET_ERROR)
{
MessageBox.Show("Socket Error cannot Send Packet");
}
//Receive the bytes
iBytesReceived = 0;
//loop while waiting checking the time of the server responding
while(!bReceived)
{
try
{
iBytesReceived = PingSocket.ReceiveFrom(ReceiveBuffer, MAX_PACKET_SIZE, SocketFlags.None, ref EndPointFrom);
}
catch//(Exception e)
{
//LOG AS DOWN
MessageBox.Show ("Host not responding to socket connection");
bReceived = false;
iLoop++;
break;
}
if (iBytesReceived == SOCKET_ERROR)
{
// LOG SOCKET ERROR
// LOG AS DOWN
MessageBox.Show("SOCKET ERROR") ;
bReceived = false;
iLoop++;
break;
}
else if (iBytesReceived > 0)
{
bReceived = true;
dwStop = System.Environment.TickCount - dwStart; // stop timing
//Check for timeout
if ( dwStop > lngPingTimeout)
{
// LOG AS DOWN
MessageBox.Show ("Request timed out for "+ipepServer.Address.ToString());
bReceived = false;
System.Threading.Thread.Sleep(System.TimeSpan.FromMilliseconds(1000));
iLoop++;
break;
}
if (dwStop < 10)
{
// LOG AS UP!
MessageBox.Show("Reply from "+ipepServer.Address.ToString()+" <10ms");//, ipepServer.Address.ToString(), iBytesReceived - 28);
iLoop++;
}
else
{
// LOG AS UP!
MessageBox.Show("Reply from "+ipepServer.Address.ToString()+" "+ dwStop+" Seconds"); //, ipepServer.Address.ToString(), iBytesReceived - 28, dwStop
iLoop++;
}
break;
}
}
}
while (iLoop < lngPingCount);
}
/// <summary>
/// This method is used to get the Packet and calculates the total size
/// of the Pack by converting it to byte array
/// </summary>
public static int Serialize(IcmpPacket ThisPacket, byte[] Buffer, int PacketSize, int PingData )
{
int cbReturn = 0;
// serialize the struct into the array
int iIndex = 0;
byte [] b_type = new byte[1];
b_type[0] = ThisPacket.Type;
byte [] b_code = new byte[1];
b_code[0] = ThisPacket.SubCode;
byte [] b_cksum = BitConverter.GetBytes(ThisPacket.CheckSum);
byte [] b_id = BitConverter.GetBytes(ThisPacket.Identifier);
byte [] b_seq = BitConverter.GetBytes(ThisPacket.SequenceNumber);
// MessageBox.Show("Serialize type ");
Array.Copy( b_type, 0, Buffer, iIndex, b_type.Length );
iIndex += b_type.Length;
// MessageBox.Show("Serialize code ");
Array.Copy( b_code, 0, Buffer, iIndex, b_code.Length );
iIndex += b_code.Length;
// MessageBox.Show("Serialize cksum ");
Array.Copy( b_cksum, 0, Buffer, iIndex, b_cksum.Length );
iIndex += b_cksum.Length;
// MessageBox.Show("Serialize id ");
Array.Copy( b_id, 0, Buffer, iIndex, b_id.Length );
iIndex += b_id.Length;
Array.Copy( b_seq, 0, Buffer, iIndex, b_seq.Length );
iIndex += b_seq.Length;
// copy the data
Array.Copy( ThisPacket.Data, 0, Buffer, iIndex, PingData );
iIndex += PingData;
if( iIndex != PacketSize/* sizeof(IcmpPacket) */)
{
cbReturn = -1;
return cbReturn;
}
cbReturn = iIndex;
return cbReturn;
}
/// <summary>
/// Checksum -
/// Algorithm to create a checksup for a buffer
/// </summary>
public static ushort CheckSum( ushort[] BufferToChecksum )
{
int iCheckSum = 0;
for (uint iCount = 0; iCount < BufferToChecksum.Length; iCount++)
{
iCheckSum += Convert.ToInt32( BufferToChecksum[iCount] );
}
iCheckSum = (iCheckSum >> 16) + (iCheckSum & 0xffff);
iCheckSum += (iCheckSum >> 16);
return (ushort)(~iCheckSum);
}
/// <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 ushort CheckSum; // ones complement checksum of struct
public ushort Identifier; // identifier
public ushort SequenceNumber; // sequence number
public byte[] Data; // byte array of data
} // class IcmpPacket
} // class ping |