public IcmpMessage(UInt32 destinationIPAddress, IcmpMessageType icmpMessageType, IcmpMessageCode icmpMessageCode, byte[] restOfHeader, byte[] data) { this.DestinationIPAddress = destinationIPAddress; this.IcmpMessageType = icmpMessageType; this.IcmpMessageCode = icmpMessageCode; this.RestOfHeader = new byte[4]; if (restOfHeader != null) { Array.Copy(restOfHeader, this.RestOfHeader, System.Math.Min(this.RestOfHeader.Length, restOfHeader.Length)); } if (data != null) { this.Data = data; } else { this.Data = new byte[0]; } }
void SendIcmpMessage(UInt32 destinationIPAddress, IcmpMessageType icmpMessageType, IcmpMessageCode icmpMessageCode, byte[] restOfHeader, byte[] data, Int64 timeoutInMachineTicks) { if (_isDisposed) { return; } lock (_icmpFrameBufferLock) { // configure ICMPv4 frame /* Type */ _icmpFrameBuffer[0] = (byte)icmpMessageType; /* Code (Subtype) */ _icmpFrameBuffer[1] = (byte)icmpMessageCode; /* checksum (clear this for now; we will calculate it shortly) */ Array.Clear(_icmpFrameBuffer, 2, 2); /* restOfHeader */ if (restOfHeader.Length < 4) { Array.Clear(_icmpFrameBuffer, 4, 4); } Array.Copy(restOfHeader, 0, _icmpFrameBuffer, 4, System.Math.Min(4, restOfHeader.Length)); UInt16 checksum; lock (_checksumLock) { // calculate checksum over entire ICMP frame including data _checksumBufferArray[0] = _icmpFrameBuffer; _checksumOffsetArray[0] = 0; _checksumCountArray[0] = ICMP_FRAME_BUFFER_LENGTH; _checksumBufferArray[1] = data; _checksumOffsetArray[1] = 0; _checksumCountArray[1] = data.Length; checksum = Utility.CalculateInternetChecksum(_checksumBufferArray, _checksumOffsetArray, _checksumCountArray, 2); } _icmpFrameBuffer[2] = (byte)((checksum >> 8) & 0xFF); _icmpFrameBuffer[3] = (byte)(checksum & 0xFF); _bufferArray[0] = _icmpFrameBuffer; _indexArray[0] = 0; _countArray[0] = ICMP_FRAME_BUFFER_LENGTH; _bufferArray[1] = data; _indexArray[1] = 0; _countArray[1] = data.Length; _ipv4Layer.Send(1 /* PROTOCOL for ICMP */, _ipv4Layer.IPAddress, destinationIPAddress, _bufferArray, _indexArray, _countArray, timeoutInMachineTicks); } }
void SendIcmpMessageInBackground(UInt32 destinationIPAddress, IcmpMessageType icmpMessageType, IcmpMessageCode icmpMessageCode, byte[] restOfHeader, byte[] data) { IcmpMessage icmpMessage = new IcmpMessage(destinationIPAddress, icmpMessageType, icmpMessageCode, restOfHeader, data); _sendIcmpMessagesInBackgroundQueue.Enqueue(icmpMessage); _sendIcmpMessagesInBackgroundEvent.Set(); }
internal void OnPacketReceived(UInt32 sourceIPAddress, byte[] buffer, Int32 index, Int32 count) { if (count < ICMP_HEADER_LENGTH) { return; } UInt16 verifyChecksum; lock (_checksumLock) { // calculate checksum over entire ICMP frame including data _checksumBufferArray[0] = buffer; _checksumOffsetArray[0] = index; _checksumCountArray[0] = count; verifyChecksum = Utility.CalculateInternetChecksum(_checksumBufferArray, _checksumOffsetArray, _checksumCountArray, 1); } if (verifyChecksum != 0x0000) { return; } /* parse ICMP message */ /* Type */ IcmpMessageType icmpMessageType = (IcmpMessageType)buffer[index + 0]; /* Code (Subtype) */ IcmpMessageCode icmpMessageCode = (IcmpMessageCode)buffer[index + 1]; /* Rest of header */ byte[] restOfHeader = new byte[4]; Array.Copy(buffer, index + 4, restOfHeader, 0, restOfHeader.Length); /* Data */ byte[] data = new byte[count - 8]; Array.Copy(buffer, index + 8, data, 0, data.Length); /* process ICMP message */ switch (icmpMessageType) { case IcmpMessageType.Echo: { SendIcmpMessageInBackground(sourceIPAddress, IcmpMessageType.EchoReply, IcmpMessageCode.None, restOfHeader, data); } break; //case IcmpMessageType.EchoReply: // { // lock (_outstandingEchoRequestsLock) // { // for (int i = 0; i < _outstandingEchoRequests.Count; i++) // { // if (_outstandingEchoRequests[i] != null) // { // // check to see if this request matches // EchoRequest echoRequest = (EchoRequest)_outstandingEchoRequests[i]; // if (echoRequest.DestinationIPAddress == sourceIPAddress) // { // /* parse restOfHeader */ // UInt16 identifier = (UInt16)((restOfHeader[0] << 8) + restOfHeader[1]); // UInt16 sequenceNumber = (UInt16)((restOfHeader[2] << 8) + restOfHeader[3]); // if ((echoRequest.Identifier == identifier) && (echoRequest.SequenceNumber == sequenceNumber) && (echoRequest.Data.Length == data.Length)) // { // bool dataMatches = true; // for (int iData = 0; iData < data.Length; iData++) // { // if (data[iData] != echoRequest.Data[iData]) // { // dataMatches = false; // break; // } // } // if (dataMatches) // echoRequest.SetResponseReceived(); // } // } // } // } // } // } // break; default: break; } }
void SendIcmpMessage(UInt32 destinationIPAddress, IcmpMessageType icmpMessageType, IcmpMessageCode icmpMessageCode, byte[] restOfHeader, byte[] data, Int64 timeoutInMachineTicks) { if (_isDisposed) return; lock (_icmpFrameBufferLock) { // configure ICMPv4 frame /* Type */ _icmpFrameBuffer[0] = (byte)icmpMessageType; /* Code (Subtype) */ _icmpFrameBuffer[1] = (byte)icmpMessageCode; /* checksum (clear this for now; we will calculate it shortly) */ Array.Clear(_icmpFrameBuffer, 2, 2); /* restOfHeader */ if (restOfHeader.Length < 4) Array.Clear(_icmpFrameBuffer, 4, 4); Array.Copy(restOfHeader, 0, _icmpFrameBuffer, 4, System.Math.Min(4, restOfHeader.Length)); UInt16 checksum; lock (_checksumLock) { // calculate checksum over entire ICMP frame including data _checksumBufferArray[0] = _icmpFrameBuffer; _checksumOffsetArray[0] = 0; _checksumCountArray[0] = ICMP_FRAME_BUFFER_LENGTH; _checksumBufferArray[1] = data; _checksumOffsetArray[1] = 0; _checksumCountArray[1] = data.Length; checksum = Utility.CalculateInternetChecksum(_checksumBufferArray, _checksumOffsetArray, _checksumCountArray, 2); } _icmpFrameBuffer[2] = (byte)((checksum >> 8) & 0xFF); _icmpFrameBuffer[3] = (byte)(checksum & 0xFF); _bufferArray[0] = _icmpFrameBuffer; _indexArray[0] = 0; _countArray[0] = ICMP_FRAME_BUFFER_LENGTH; _bufferArray[1] = data; _indexArray[1] = 0; _countArray[1] = data.Length; _ipv4Layer.Send(1 /* PROTOCOL for ICMP */, _ipv4Layer.IPAddress, destinationIPAddress, _bufferArray, _indexArray, _countArray, timeoutInMachineTicks); } }