Socket только улавливает исходящие пакеты, а не входящие
Я основал пакетный снифер на этом (часто цитированном) примере проекта. После внедрения пакетов HTTP я заметил, что только HTTP-пакеты, которые я собираю, являются запросами, я не получаю никаких ответов.
Я просмотрел много разных источников, но поскольку используемый код очень часто то же самое, я склонен думать, что он может быть локальным для меня.
Когда я смотрю на свои журналы, я вижу, что каждый пакет имеет свой локальный IP как SourceIP
, как для HTTP-пакетов, так и для пакетов, которые поступают в другие порты.
Я представил рабочий образец здесь, который вы можете скопировать-вставить в LINQPad и должен продемонстрировать проблему (добавьте сборки System.Net
и System.Net.Socket
). Не забудьте выполнить LINQPad как администратор, чтобы иметь доступ к сокету.
Это приводит к сотням/тысячам записей в диапазоне 192.168.0 с 3 исключениями IP-адресов, которые относятся к моему провайдеру хостинга (проверено с помощью nslookup
).
private readonly byte[] _data = new byte[4096];
private Socket _mainSocket;
public void Capture()
{
_mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
_mainSocket.Bind(new IPEndPoint(GetLocalIP(), 0));
var byTrue = new byte[] {1, 0, 0, 0};
var byOut = new byte[] {1, 0, 0, 0};
_mainSocket.IOControl(IOControlCode.ReceiveAll, byTrue, byOut);
_mainSocket.EnableBroadcast = true;
_mainSocket.BeginReceive(_data, 0, _data.Length, SocketFlags.None, OnReceive, null);
}
private void OnReceive(IAsyncResult ar)
{
SocketError error;
var received = _mainSocket.EndReceive(ar, out error);
Parse(_data, received);
_mainSocket.BeginReceive(_data, 0, _data.Length, SocketFlags.None, OnReceive, null);
}
private void Parse(byte[] data, int size)
{
var packet = new IPHeader(data, size);
Console.WriteLine (packet.SourceIP.ToString());
}
- Windows 8.1
-
Гигабитный Ethernet-контроллер Killer e2200 (NDIS 6.30) - Последняя версия драйвера
- Вчера была установлена автономная сетевая карта, она ничего не меняла.
Сообщение, которое ближе всего к моей проблеме, имеет в качестве решения рабочий код, который у меня уже есть.
Почему я могу отслеживать исходящие пакеты?
Ответы
Ответ 1
Как упоминалось как @Saibal и @Saverio: проблема с брандмауэром. В качестве временного решения на данный момент я отключу брандмауэр при запуске пакета папок и включении его обратно, когда он останавливается (не принимая неожиданный выход из учетной записи).
Если вы закончите с такой же проблемой, то ваш первый результат для "отключить брандмауэр С#" может быть этот блогпост. Это не сработало в моем случае и вместо этого выбрало NotImplementedException
. Я предполагаю, что это возможно только в Windows XP как этот документ MSDN.
К счастью, существуют альтернативы для Vista и выше (тестируется только в Windows 8.1, но это, как предполагается, является преемником и упоминает об этом).
Мой код для отключения/включения брандмауэра:
private static readonly Type policyType =
Type.GetTypeFromProgID("HNetCfg.FwPolicy2");
private static readonly INetFwPolicy2 firewall =
(INetFwPolicy2) Activator.CreateInstance(policyType);
private void DisableFirewall()
{
var firewallEnabled = firewall.get_FirewallEnabled(
NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PRIVATE);
if (firewallEnabled)
{
firewall.set_FirewallEnabled(
NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PRIVATE, false);
}
}
Альтернативный способ записи:
firewall.FirewallEnabled[NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PRIVATE] = false;
К сожалению, MSDN предлагает только примеры кода в C/С++, но вы все равно можете отнять суть этого.
Имейте в виду, что вы должны добавить библиотеку Interop.NetFwTypeLib в свой проект. Вы можете найти его в C:\Windows\SysWOW64\FirewallAPI.dll или 32-битном эквиваленте.
Это очень рудиментарно. На более позднем этапе (эта публикация будет обновляться всякий раз, когда я это сделаю). Я рассмотрю просто добавление программы в список исключений из брандмауэра, но прямо сейчас этого будет достаточно.
Ответ 2
Вы пытались заглянуть в ваш брандмауэр OS/Standalone/Router?
Его часто упускают из виду, но у брандмауэров разные правила для входящих и исходящих подключений, и это может быть причиной ваших проблем.
Ответ 3
Проверьте адрес, возвращенный вашим GetLocalIP(). Вы можете получить loopback ip, и в этом случае вы не сможете захватить входящие пакеты. Аналогичная проблема обсуждалась здесь.