1 module app; 2 import std.stdio; 3 import std.string; 4 import std.socket; 5 import core.thread; 6 import std.datetime.stopwatch; 7 import ipcmp; 8 import utils; 9 10 const int PING_PKT_S = 64; 11 12 struct PingPacket 13 { 14 icmp_hdr hdr; 15 ubyte[PING_PKT_S - icmp_hdr.sizeof] msg; 16 } 17 18 struct PingReply 19 { 20 ubyte type; // ICMP message type (should be 0x00 for Echo Reply) 21 ubyte code; // ICMP message code (should be 0x00 for Echo Reply) 22 ushort checksum; // ICMP header checksum 23 ushort identifier; // Identifier field (16 bits) 24 ushort sequence; // Sequence number field (16 bits) 25 int timestamp; // Use this field to store the timestamp 26 } 27 28 ushort checksum(void* data, size_t len) 29 { 30 ushort* buf = cast(ushort*) data; 31 uint sum = 0; 32 33 while (len > 1) 34 { 35 sum += *buf++; 36 len -= 2; 37 } 38 39 if (len == 1) 40 { 41 sum += *cast(ubyte*) buf; 42 } 43 44 while (sum >> 16) 45 { 46 sum = (sum & 0xFFFF) + (sum >> 16); 47 } 48 49 return cast(ushort)(~sum); 50 } 51 52 void main(string[] args) 53 { 54 if (args.length < 2) 55 { 56 writeln("Supply a hostname as parameter"); 57 return; 58 } 59 60 string host = args[1]; 61 62 int seq = 0; 63 64 PingPacket packet = PingPacket(); 65 packet.hdr.type = 8; 66 packet.hdr.code = 0; 67 packet.hdr.un.echo.id = cast(ushort)(getpid() & 0xFFFF); 68 69 packet.hdr.un.echo.sequence = cast(ushort)(seq++); 70 71 packet.hdr.checksum = checksum(&packet, PingPacket.sizeof); 72 73 Address[] addresses = getAddress(host); 74 75 Socket s = new Socket(AddressFamily.INET, SocketType.RAW, ProtocolType.ICMP); 76 77 StopWatch sw = StopWatch(AutoStart.yes); 78 s.sendTo((cast(ubyte*)&packet)[0 .. packet.sizeof], addresses[0]); 79 80 ubyte[64] recvBuf; 81 s.receiveFrom(recvBuf); 82 83 long time = sw.peek.total!"msecs"; 84 85 // PingReply reply; 86 87 // // Parse the fields from recvBuf 88 // reply.type = recvBuf[0]; 89 // reply.code = recvBuf[1]; 90 // reply.checksum = recvBuf[2 .. 4].toType!ushort; 91 // reply.identifier = recvBuf[4 .. 6].toType!ushort; 92 // reply.sequence = recvBuf[6 .. 8].toType!ushort; 93 // reply.timestamp = recvBuf[8 .. 12].toType!int; 94 95 writeln("Reply from ", host, " in ", time , "ms"); 96 }