public static byte[] CreatePacket(REQUEST req) { Byte[] ByteSend = new Byte[PACKET_SIZE + 8]; //Create Byte array from REQUEST structure ByteSend[0] = req.m_icmp.type; ByteSend[1] = req.m_icmp.code; Array.Copy(BitConverter.GetBytes(req.m_icmp.checksum), 0, ByteSend, 2, 2); Array.Copy(BitConverter.GetBytes(req.m_icmp.id), 0, ByteSend, 4, 2); Array.Copy(BitConverter.GetBytes(req.m_icmp.seq), 0, ByteSend, 6, 2); for (int i = 0; i < req.m_data.Length; i++) { ByteSend[i + 8] = req.m_data[i]; } //calculate checksum int iCheckSum = 0; for (int i = 0; i < ByteSend.Length; i += 2) { iCheckSum += Convert.ToInt32(BitConverter.ToUInt16(ByteSend, i)); } iCheckSum = (iCheckSum >> 16) + (iCheckSum & 0xffff); iCheckSum += (iCheckSum >> 16); //update byte array to reflect checksum Array.Copy(BitConverter.GetBytes((ushort)~iCheckSum), 0, ByteSend, 2, 2); return(ByteSend); }
public static TraceResults TraceHost(string host) { TraceResults results = new TraceResults(); results.Host = host; try { //Create Raw ICMP Socket Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp); //destination IPEndPoint ipdest = new IPEndPoint(Dns.Resolve(host).AddressList[0], 80); //Source IPEndPoint ipsrc = new IPEndPoint(Dns.GetHostByName(Dns.GetHostName()).AddressList[0], 80); EndPoint epsrc = (EndPoint)ipsrc; ICMP ip = new ICMP(); ip.type = ICMPConstants.ICMP_ECHOREQ; ip.code = 0; ip.checksum = 0; ip.id = (ushort)DateTime.Now.Millisecond; //any number you feel is kinda unique :) ip.seq = 0; REQUEST req = new REQUEST(); req.m_icmp = ip; req.m_data = new Byte[PACKET_SIZE]; //Initialize data for (int i = 0; i < req.m_data.Length; i++) { req.m_data[i] = (byte)'S'; } //this function would gets byte array from the REQUEST structure Byte[] ByteSend = CreatePacket(req); //send requests with increasing number of TTL for (int ittl = 1; ittl <= ICMPConstants.MAX_TTL; ittl++) { TraceResult tr = new TraceResult(); tr.TTL = ittl; Byte[] ByteRecv = new Byte[256]; //Socket options to set TTL and Timeouts s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, ittl); s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 10000); s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 10000); //Get current time DateTime dt = DateTime.Now; //Send Request int iRet = s.SendTo(ByteSend, ByteSend.Length, SocketFlags.None, ipdest); //check for Win32 SOCKET_ERROR if (iRet == -1) { tr.HostName = "error sending data"; } //Receive iRet = s.ReceiveFrom(ByteRecv, ByteRecv.Length, SocketFlags.None, ref epsrc); //Calculate time required TimeSpan ts = DateTime.Now - dt;; //check if response is OK if (iRet == -1) { tr.HostName = "error getting data"; } IPAddress addy = ((IPEndPoint)epsrc).Address; tr.IP = addy.ToString(); tr.Time = ts.Milliseconds; results.AddResult(tr); //reply size should be sizeof REQUEST + 20 (i.e sizeof IP header),it should be an echo reply //and id should be same if ((iRet == PACKET_SIZE + 8 + 20) && (BitConverter.ToInt16(ByteRecv, 24) == BitConverter.ToInt16(ByteSend, 4)) && (ByteRecv[20] == ICMPConstants.ICMP_ECHOREPLY)) { break; } //time out if (ByteRecv[20] != ICMPConstants.ICMP_TIMEEXCEEDED) { tr.HostName = "unexpected reply, quitting..."; break; } } } catch (SocketException e) { results.Error = e.ToString(); results.HasError = true; } catch (Exception e) { results.Error = e.ToString(); results.HasError = true; } return(results); }