// write an ICMP echo request public static int WriteIcmpEchoRequest(byte[] !pkt, int offset, ref IcmpEchoRequest request) { int o = offset; // write the common header o = WriteIcmpHeader(pkt, offset, ref request.header); // dump the data (endian doesn't matter, since it is a user data) Array.Copy(request.data, 0, pkt, o, request.data.Length); // calc the checksum ushort chk = IPFormat.Checksum(pkt, offset, request.GetSize()); pkt[offset + 2] = (byte)(((ushort)chk) >> 8); pkt[offset + 3] = (byte)(((ushort)chk) & 0xff); request.header.chksum = chk; return(o); }
// a fast method that uses that modified the ECHO request // packet to an ECHO reply. // return true if success public static void CreateFastEchoReply(byte[] !pkt, int icmpPacketSize) { // 1. switch the source IP and destination IP // 2. change ICMP code to IcmpFormat.IcmpType.ECHO_REPLY // 3. should use ARP table to find out the mac address of the target // (if it is on the local network) // CURRENTLY: just switch MAC addresses as well. // 4. recompute ICMP and IP checksums int ipStart = EthernetFormat.Size; int icmpStart = ipStart + IPFormat.Size; pkt[icmpStart] = (byte)IcmpFormat.IcmpType.ECHO_REPLY; // zero checksum pkt[icmpStart + 2] = 0; pkt[icmpStart + 3] = 0; ushort chk = IPFormat.Checksum(pkt, icmpStart, icmpPacketSize); pkt[icmpStart + 2] = (byte)(chk >> 8); pkt[icmpStart + 3] = (byte)chk; // switch IPs byte[] tmp = new byte[6]; Array.Copy(pkt, ipStart + 16, tmp, 0, 4); // dest->tmp Array.Copy(pkt, ipStart + 12, pkt, ipStart + 16, 4); // src->dest Array.Copy(tmp, 0, pkt, ipStart + 12, 4); // tmp->src // zero the checksum pkt[ipStart + 10] = 0; pkt[ipStart + 11] = 0; // calculate checksum chk = IPFormat.Checksum(pkt, ipStart, IPFormat.Size); pkt[ipStart + 10] = (byte)(((ushort)chk) >> 8); pkt[ipStart + 11] = (byte)(((ushort)chk) & 0xff); // TBC: currently just switch mac addresses Array.Copy(pkt, 6, tmp, 0, 6); // src -> temp Array.Copy(pkt, 0, pkt, 6, 6); // dest -> src Array.Copy(tmp, 0, pkt, 0, 6); // tmp -> dest }