发送回自定义ICMP回应响应

时间:2013-11-16 13:33:05

标签: c# sockets network-programming icmp

我已经组建了一个ICMP客户端和一个ICMP监听器。我可以向侦听器发送自定义echo请求,并且侦听器正确解压缩它们。我现在希望听众能够做出回应 - 不是使用精确的回声,而是使用不同的数据集。这是我到目前为止所尝试的:

ICMP客户端:

    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听众:

    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);        
        }
    }

这是听众出现的内容: enter image description here

这是客户端上显示的内容: enter image description here

所以,尽管将“美好的一天”送回给客户,但似乎仍然在接受“你好的朝圣者”。如何将“好日子”送回客户手中?

3 个答案:

答案 0 :(得分:1)

我认为它可能与底层TCP / IP架构有关。我认为ICMP层会在程序甚至收到数据之前回显ping数据包。尝试评论它发送回复的行,看看客户端是否仍然收到回复。如果是这种情况,我的建议是不使用Ping - 而只是在某个端口上发送TCP数据包并让监听器回复。

ICMP数据包在.NET中非常棘手。 MS希望为您处理所有这些内容,因此,与许多.NET实现一样,他们并不想让您对底层协议进行大量控制。

答案 1 :(得分:0)

菲德尔,您是否尝试在系统上禁用ICMP回复? Linux有一个类似的参数来禁用这个名为'icmp_echo_ignore_all',启用这可能会阻止系统IP堆栈回复,如果您使用您的程序完全制作icmp回复,则回复可能不会被视为目的地的重复。我知道你正在使用Windows,但可能有另一种选择,我也从未尝试过这个但是如果你必须使用icmp,我认为它值得一试

答案 2 :(得分:0)

当你ping远程时,你会自动收到回复。发送和接收的数据包之间的差异只是消息的类型,在ping的情况下是8,3或0. 8是回应请求,0是回复应答,类型3是目的地不可达,这意味着没有找到响应

要接收自定义响应,您必须实现类似于服务器上的侦听器,并摆脱PingReply。

您还必须创建一个类来生成自定义ICMP数据包,并可能更改其标题(消息的类型和代码),以便服务器不会自动响应echo请求。然后当它收到消息时,检查它是否具有正确的类型(由发件人声明)并发送响应。

但是 - 由于定义了ICMP类型,因此可能没有真正的解决方案。 (远程总是根据请求发送回复。所以发送另一条消息就是这样)

修改

ICMP消息类型15(信息请求)不会从服务器弹出自动响应。尝试将它用作您在服务器上监听的一种ICMP消息,并且在客户端上您也必须监听ICMP。

BTW使用Ping.Send()方法尝试从无法到达目的地获取响应时可能会在进程等待远程响应时停止调试时导致BSOD。