'Sending back custom ICMP echo response
I've put together an ICMP client, and an ICMP listener. I can send custom echo requests to the listener and the listener unpacks them correctly. I would now like the listener to respond - not with an exact echo but with a different set of data. This is what I've tried so far:
ICMP client:
static void Main(string[] args)
{
Ping icmpClient = new Ping();
PingOptions options = new PingOptions();
options.DontFragment = true;
byte[] msg = Encoding.UTF8.GetBytes("howdy pilgrim");
while (true)
{
PingReply reply = icmpClient.Send("192.168.0.3", 60 * 1000, msg, options);
string responseReceived = Encoding.UTF8.GetString(reply.Buffer);
Console.WriteLine(DateTime.Now.ToString() + " Response from server: " + responseReceived);
Thread.Sleep(500);
}
}
ICMP listener:
static void Main(string[] args)
{
while (true)
{
Socket icmpListener = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
icmpListener.Bind(new IPEndPoint(IPAddress.Parse("192.168.0.3"), 0));
icmpListener.IOControl(IOControlCode.ReceiveAll, new byte[] { 1, 0, 0, 0 }, null);
byte[] buffer = new byte[1024*1024];
EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
int bytesRead = icmpListener.ReceiveFrom(buffer, ref remoteEndPoint);
string receivedMsg = Encoding.UTF8.GetString(buffer, 28, bytesRead);
Console.WriteLine(DateTime.Now.ToString() + ": Received " + bytesRead + "B from " + remoteEndPoint + ": " + receivedMsg);
byte[] customResponse = Encoding.UTF8.GetBytes("good day");
int bytesSent = icmpListener.SendTo(customResponse, remoteEndPoint);
}
}
This is what appears on the listener:

This is what appears on the client:

So, despite sending "good day" back to the client, it seems to still be receiving "howdy pilgrim". How can I get "good day" sent back to the client?
Solution 1:[1]
I believe it may have something to do with the underlying TCP/IP architecture. I think the ICMP layer echoes back the ping packet before your program ever even receives the data. Try commenting out the line where it sends the reply and see if the client still receives a reply. If that's the case, my suggestion would be to not use Ping - instead just send a TCP packet on a certain port and have the listener reply to that.
ICMP packets are very tricky in .NET. MS wants to handle all that stuff for you, so as with a lot of .NET implementations, they don't want to give you a lot of control over the underlying protocols.
Solution 2:[2]
Fidel, have you tried disabling ICMP reply on the system? Linux has a similar parameter to disable this called 'icmp_echo_ignore_all', enabling this might prevent the system ip stack from replying and if you are entirely crafting the icmp reply using your program the reply might not be counted as a duplicate at the destination. I know you are using windows for this but there might be an alternative, also I haven never tried this but if you have to use icmp, I think its worth a shot
Solution 3:[3]
When you are pinging remote, you'll receive response automatically. Difference between packet sent and received is just type of the message, which in case of ping is either 8,3 or 0. 8 is echo request, 0 is echo reply, and type 3 is destination unreachable, which means that no response was found.
To receive custom response, you'll have to implement listener similar to to one that you have on your server, and get rid of PingReply.
You'll also have to create a class to generate custom ICMP packets and perhaps change their header (Type and code of message) so server does not respond automatically on echo request. Then when it receives message, check if it has right type (declared by you in sender) and send response.
However - since ICMP types are defined, there might be no real solution. (Remote will always send reply based on request. So sending another message is just)
Edit
ICMP message type 15 (information request) doesn't pop auto-response from server. Try using it as a type of ICMP message that you're listening on server, and on client you'll have to listen for ICMPs as well.
BTW using the Ping.Send() method while trying to get response from unreachable destination may cause BSOD when you stop debugging while process waits for response from remote.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | moz |
| Solution 3 | marc_s |
