В общем. При переходе на Windows 10 (да, именно 10) обнаружилось, что моя любимая программа для мониторинга сетевого трафика BWMeter
начала глючить. То скорость обрежет, то вообще интернет заблочит. Но если на Windows 10 её хоть как-то можно заставить работать, то на Windows 11 всё плохо. Вероятно, это сильно зависит от драйверов на сетевуху и у кого-то на его сетевухе будет нормально работать, но на моём ноутбуке - всё плохо. Пробовал ставить другие программы, но они все либо не удобные, либо функционал не тот, либо фаервола нет, либо рисуют график не так как я хочу. По сравнению с ними, BWMeter
был идеален. Уже очень давно его юзаю.
Недавно я решил погулить, как же на винде осуществляется перехват трафика и что в этом такого сложного. Все примеры кода (если таковые и есть) используют WinPCap
. Это что-то типа библиотеки для перехвата сетевых пакетов. На его сайте написано, что авторы забили на проект и, сорян, но обновлений больше не будет. Вероятно, есть ещё подобные библиотеки, но так ведь не интересно
Гулил дальше и нашел пример простейшего сниффера (без WinPCap
):
Попробовал запустить - работает (и, вроде, даже правильно ). Конечно, так никакого фаервола не получится (для этого надо писать какой-то драйвер в режиме ядра), но даже так можно написать простую отображалку трафика.
Однако, остались непонятны две вещи:
- Как отличить входящий пакет от исходящего?
При запуске предлагается выбрать интерфейс, который будем снифферить:
Initialising Winsock...Initialised
Creating RAW Socket...Created.
Host name : MIKROSHA
Available Network Interfaces :
Interface Number : 0 Address : 192.168.121.1
Interface Number : 1 Address : 26.37.131.105
Interface Number : 2 Address : 192.168.118.1
Interface Number : 3 Address : 192.168.88.250
Enter the interface number you would like to sniff :
Потом каждый пакет выводится в лог:
fprintf(logfile," |-Source IP : %s\n",inet_ntoa(source.sin_addr));
fprintf(logfile," |-Destination IP : %s\n",inet_ntoa(dest.sin_addr));
Source IP
всегда равен IP-адресу интерфейса, который был выбран. Не пойму, почему так А Destination IP
отображается, видимо, правильно
- Вот у нас есть бесконечный цикл прослушивания сокета:
do
{
mangobyte = recvfrom(sniffer , Buffer , 65536 , 0 , 0 , 0);
if(mangobyte > 0)
{
ProcessPacket(Buffer, mangobyte); //тут обработка и выхлоп
}
else
{
printf( "recvfrom() failed.\n");
}
}
while (mangobyte > 0);
Когда проект консольный - всё нормально. А как прикрутить это к окну? У окна же свой цикл. Если запустить цикл прослушивания - окно зависнет. Через потоки? А окно не задохнётся от синхронизации на каждый пакет?
Сейчас ещё потестил. Так только у TCP
протокола. У UDP
меняется. Как будто у TCP
ловится только исходящий трафик Но почему?