Socket ReceiveAll - PullRequest
       1

Socket ReceiveAll

4 голосов
/ 02 мая 2010

Я пытаюсь перехватить IP-пакеты в c #. Все работает нормально, за исключением того, что я получаю только исходящие пакеты.

Мой код:

using (Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP))
{
    sock.Bind(new IPEndPoint(MYADDRESS, 0));
    sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);
    sock.IOControl(IOControlCode.ReceiveAll, BitConverter.GetBytes(1), null);

    while (true)
    {
        byte[] buffer = new byte[sock.ReceiveBufferSize];
        int count = sock.Receive(buffer);

        // ...
    }
}

Проблема определенно в моем компьютере! Но, возможно, есть обходной путь ...

Ответы [ 5 ]

4 голосов
/ 30 октября 2012

Вероятно, что брандмауэр Windows блокирует входящие пакеты. Добавьте вашу программу в исключения брандмауэра.

3 голосов
/ 02 мая 2010

А как насчет другого подхода, такого как использование WinPcap для .Net с SharpPcap ( больше информации )

Он предоставляет API для захвата, внедрения, анализа и построения пакетов с использованием любого языка .NET, такого как C # и VB.NET

.... звучит более многообещающе

3 голосов
/ 02 мая 2010

Я считаю, что проблема заключается в том, что вы привязываетесь к IP-шлейфу, предполагая, что в вашем коде 'LOCALHOST' подразумевается 127.0.0.1.Попробуйте связать с IP-адресом интерфейса, для которого вы хотите перехватить пакеты.

Я взял ваш код и провел быстрый тест, и определенно вижу, как данные текут в обоих направлениях, используя Windows 7. NB Я использую это как администратор, не уверен, насколько хорошо это работает в противном случае.

  using (Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP))
  {
    sock.Bind(new IPEndPoint(IPAddress.Parse("192.168.0.121"), 0));

    sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);

    sock.IOControl(IOControlCode.ReceiveAll, BitConverter.GetBytes(1), null);

    while (true)
    {
      byte[] buffer = new byte[sock.ReceiveBufferSize];

      int count = sock.Receive(buffer);
      IpHeader hdr = IpHeader.FromPacket(buffer, count);
      if ((ProtocolType)hdr.Protocol == ProtocolType.Tcp)
      {
        Console.WriteLine("{0} : {1} -> {2}", (ProtocolType)hdr.Protocol, new IPAddress(hdr.SrcAddr).ToString(), new IPAddress(hdr.DestAddr).ToString());
      }
    }
  }

IpHeader из библиотеки, которую я написал несколько лет назад , я использовал это для быстрого декодированияпакеты, чтобы убедиться, что я видел данные в обоих направлениях.

Вот быстрый захват из кода выше для проверки (AA.BB.CC.DD - мой публичный IP)

Tcp : 83.221.14.72 -> AA.BB.CC.DD
Tcp : AA.BB.CC.DD -> 83.221.14.72
Tcp : 83.221.14.72 -> AA.BB.CC.DD
Tcp : 83.221.14.72 -> AA.BB.CC.DD
Tcp : AA.BB.CC.DD -> 83.221.14.72
Tcp : 83.221.14.72 -> AA.BB.CC.DD
Tcp : 83.221.14.72 -> AA.BB.CC.DD
Tcp : AA.BB.CC.DD -> 83.221.14.72
Tcp : AA.BB.CC.DD -> 83.221.14.72
Tcp : AA.BB.CC.DD -> 83.221.14.72
Tcp : 83.221.14.72 -> AA.BB.CC.DD
Tcp : 83.221.14.72 -> AA.BB.CC.DD
Tcp : AA.BB.CC.DD -> 83.221.14.72
2 голосов
/ 12 марта 2014

В моем случае мне пришлось разрешить vshost.exe в брандмауэре Windows

0 голосов
/ 02 мая 2010

Я думаю, что проблема в вызове IOControl. Если честно, я не совсем понимаю документацию, предоставленную MSDN об этой функции, но в codeproject есть пример ( здесь ) по этой теме, и я предполагаю, что, передав null в последнем параметре вы не получаете входящие пакеты. Попробуйте вместо этого:

byte[] byTrue = new byte[4]{1, 0, 0, 0};
byte[] byOut = new byte[4];

sock.IOControl(IOControlCode.ReceiveAll, byTrue, byOut);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...