2013-11-16 3 views
1

Я собрал ICMP-клиент и прослушиватель ICMP. Я могу отправлять пользовательские эхо-запросы слушателю, и слушатель распаковывает их правильно. Теперь я хотел бы, чтобы слушатель ответил - не с точным эхом, а с другим набором данных. Это то, что я пытался до сих пор:Отправка пользовательского ответа эхо-ответа ICMP

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

Таким образом, несмотря на отправку «хороший день» обратно клиенту, кажется, все еще получать «здор`ово паломник». Как я могу вернуть «хороший день» клиенту?

ответ

1

Я полагаю, что это может иметь какое-то отношение к базовой архитектуре TCP/IP. Я думаю, что слой ICMP отсылает обратно пакет ping, прежде чем ваша программа когда-либо получит данные. Попробуйте прокомментировать строку, в которой он отправляет ответ, и посмотреть, не получил ли клиент ответ. Если это так, мое предложение состояло бы в том, чтобы не использовать Ping - вместо этого просто отправляйте TCP-пакет на определенный порт и получите ответ слушателя на это.

ICMP-пакеты очень сложны в .NET. MS хочет обрабатывать все эти вещи для вас, так как с множеством реализаций .NET они не хотят давать вам большой контроль над базовыми протоколами.

+0

Спасибо, ноль. Да, если я прокомментирую строку, ответ все равно будет отправлен обратно. Итак, вы правы - это должна быть какая-то нижняя часть ОС, которая обрабатывает пинги, прежде чем они доберутся до меня. Я мог бы сделать то же самое в TCP очень легко, но я пытаюсь собрать ICMP-туннель. – Fidel

+1

Это совершенно другой IP-протокол. ICMP! = TCP. –

+0

Действительно, Мартин. Идея туннелирования состоит в том, что вы ставите один протокол через другой ... – Fidel

0

Fidel, вы пробовали отключить ответ ICMP в системе? У Linux есть аналогичный параметр, чтобы отключить это под названием «icmp_echo_ignore_all», и это может помешать ответить системному ip стеке, и если вы полностью создаете ответ icmp с помощью своей программы, ответ может не считаться дубликатом в пункте назначения. Я знаю, что вы используете окна для этого, но может быть и альтернатива, и я никогда не пробовал это, но если вам нужно использовать icmp, я думаю, что стоит сделать это

0

Когда вы пингуете на пульте дистанционного управления, вы получите ответ автоматически. Разница между отправленным и полученным пакетом - это просто тип сообщения, которое в случае ping равно 8,3 или 0. 8 - это эхо-запрос, 0 - эхо-ответ, а тип 3 - недоступен, что означает, что ответа не найдено ,

Чтобы получить пользовательский отклик, вам необходимо реализовать прослушиватель, похожий на тот, который у вас есть на вашем сервере, и избавиться от PingReply.

Вам также необходимо создать класс для создания пользовательских ICMP-пакетов и, возможно, изменить их заголовок (Тип и код сообщения), чтобы сервер не отвечал автоматически на эхо-запрос. Затем, когда он получает сообщение, проверьте, имеет ли он правильный тип (объявленный вами отправителем) и отправляет ответ.

Однако, поскольку ICMP-типы определены, не может быть реального решения. (Remote всегда будет отправлять ответ по запросу.Так посылая другое сообщение только)

Редактировать

ICMP сообщение типа 15 (запрос информации) не выскакивает автоматический ответ от сервера. Попытайтесь использовать его как тип сообщения ICMP, которое вы слушаете на сервере, а на клиенте вам также придется прослушивать ICMP.

BTW с использованием метода Ping.Send() при попытке получить ответ от недоступного адресата может вызвать BSOD, когда вы прекратите отладку, пока процесс ждет ответа от удаленного.

Смежные вопросы