Проблемма следующего содержания:
Через winsocket ловлю приходящие и исходящие пакеты. Под Win2k и win98 все работает отлично.
попробовал на WinXP и ничего у меня не вышло, с одной оговоркой. Если одна из машин находится под управлением win2k или win98,
то пакеты от этих машин лювятся, а пакеты от машины на winXP нет.
Вот код нити по отслеживанию входящих-исходящих пакетов
begin
sUdp := SizeOf(TIpHeader_)+ SizeOf(TUDPHeader);
sTcp := SizeOf(TIpHeader_)+ SizeOf(TTCPHeader);
Fform.Memo1.Clear;
If WSAStartup(MAKEWORD(2,2), wsadata) <> 0 then exit;
s := socket(AF_INET, SOCK_RAW, IPPROTO_IP);
Name := #00;
gethostname(name, sizeof(name));
phe := gethostbyname(name);
ZeroMemory(@sa, sizeof(sa));
sa.sin_family := AF_INET;
sa.sin_addr.s_addr := longint(plongint(phe^.h_addr_list^)^);
sa.sin_port := htons(8080);
idr := bind(s, sa, SizeOf(sa));
flag := 1;
ioctlsocket(s, SIO_RCVALL, flag);
While Not Terminated Do
Begin
Application.ProcessMessages;
FillChar(Buffer,SizeOf(Buffer),#0);
count := recv(s, Buffer, sizeof(Buffer),0);
If (count >= sTcp)or (count >= sUdp)
Then
Begin
ZeroMemory(@hdr,SizeOf(TIPHeader_));
CopyMemory(@hdr,@Buffer,SizeOf(TIPHeader_));
ZeroMemory(@tcphdr,SizeOf(ttcpheader));
ZeroMemory(@udphdr,SizeOf(tUDPheader));
sa1.S_addr := hdr.iph_src;
sa2.S_addr := hdr.iph_dest;
Case hdr.iph_protocol OF
IPPROTO_TCP : Begin
CopyMemory(@tcphdr,@Buffer[sizeof(TIPHeader)],sizeof(TtcpHeader));
Ports := ntohs(tcphdr.th_sport);
Portd := ntohs(tcphdr.th_dport);
// Fform.Memo1.Lines.Add('TCP - '+inet_ntoa(sa1)+'-'+IntToStr(Ports)+'------>'+inet_ntoa(sa2)+'-'+IntToStr(Portd));End;
IPPROTO_UDP : Begin
CopyMemory(@udphdr,@Buffer[sizeof(TIPHeader)],sizeof(TUDPHeader));
Ports := ntohs(udphdr.uh_sport);
Portd := ntohs(udphdr.uh_dport);
// Fform.Memo1.Lines.Add('UDP - '+inet_ntoa(sa1)+'-'+IntToStr(Ports)+'------>'+inet_ntoa(sa2)+'-'+IntToStr(Portd));End;
Else
Ports := 0;
Portd := 0;
End;
if (((sa1.S_addr and inet_addr(PChar(FForm.ipaMask.Text)))= sa1.S_addr) And ((sa2.S_addr and inet_addr(PChar(FForm.ipaMask.Text)))= sa2.S_addr))
and ((sa1.S_addr = inet_addr(PChar(FForm.ipServer.Text)))Or (sa2.S_addr = inet_addr(PChar(FForm.ipServer.Text))))
And (FForm.InPorts(Ports) or FForm.InPorts(Portd))
And (FForm.ClientsWatch(inet_ntoa(sa1)) or FForm.ClientsWatch(inet_ntoa(sa2))) And FForm.isProtocol(hdr.iph_protocol)
Then
Begin
FSum := FSum + ntohs(hdr.iph_length);
FForm.SetBytes(inet_ntoa(sa1),ntohs(hdr.iph_length),False);
FForm.SetBytes(inet_ntoa(sa2),ntohs(hdr.iph_length),True);
FForm.Memo1.Lines.Add(inet_ntoa(sa1)+':'+IntToStr(Ports)+' --> '+inet_ntoa(sa2)+':'+IntToStr(Portd))
End;
Synchronize(DoData);
End;
End;
closesocket(s);
WSACleanup;
Пожалуйста подскажите, в чем дело?
Дункан Маклауд любил ходить в лес и издеваться над кукушками.
138385660
Здравствуйте, Shtirliz, Вы писали:
S>Доброго времени суток.
S>Проблемма следующего содержания: S>Через winsocket ловлю приходящие и исходящие пакеты. Под Win2k и win98 все работает отлично. S>попробовал на WinXP и ничего у меня не вышло, с одной оговоркой. Если одна из машин находится под управлением win2k или win98, S>то пакеты от этих машин лювятся, а пакеты от машины на winXP нет.
S>Вот код нити по отслеживанию входящих-исходящих пакетов
вот этот код непонятен
If (count >= sTcp)or (count >= sUdp)
на мой взгляд нужно иметь локальный буфер
и читать туда все, правильно разбирать длину пакета,
ведь recv() не обязан дать только один пакет?
(можно случайно отбросить длину другого пакета)
но это ИМХО так как этот вопрос я тонко не изучал и не пробовал.
кроме того, судя по Synchronize(DoData); и While Not Terminated Do
это код метода Execute, тогда какого рожна там Application.ProcessMessages; ???
это не только не поможет, это просто неправильно !!!
(ну и всякие там FForm.Memo1. это тоже некорректно)
S>
S>begin
S> sUdp := SizeOf(TIpHeader_)+ SizeOf(TUDPHeader);
S> sTcp := SizeOf(TIpHeader_)+ SizeOf(TTCPHeader);
S> Fform.Memo1.Clear;
S> If WSAStartup(MAKEWORD(2,2), wsadata) <> 0 then exit;
S> s := socket(AF_INET, SOCK_RAW, IPPROTO_IP);
S> Name := #00;
S> gethostname(name, sizeof(name));
S> phe := gethostbyname(name);
S> ZeroMemory(@sa, sizeof(sa));
S> sa.sin_family := AF_INET;
S> sa.sin_addr.s_addr := longint(plongint(phe^.h_addr_list^)^);
S> sa.sin_port := htons(8080);
S> idr := bind(s, sa, SizeOf(sa));
S> flag := 1;
S> ioctlsocket(s, SIO_RCVALL, flag);
S> While Not Terminated Do
S> Begin
S> Application.ProcessMessages;
S> FillChar(Buffer,SizeOf(Buffer),#0);
S> count := recv(s, Buffer, sizeof(Buffer),0);
S> If (count >= sTcp)or (count >= sUdp)
S> Then
S> Begin
S> ZeroMemory(@hdr,SizeOf(TIPHeader_));
S> CopyMemory(@hdr,@Buffer,SizeOf(TIPHeader_));
S> ZeroMemory(@tcphdr,SizeOf(ttcpheader));
S> ZeroMemory(@udphdr,SizeOf(tUDPheader));
S> sa1.S_addr := hdr.iph_src;
S> sa2.S_addr := hdr.iph_dest;
S> Case hdr.iph_protocol OF
S> IPPROTO_TCP : Begin
S> CopyMemory(@tcphdr,@Buffer[sizeof(TIPHeader)],sizeof(TtcpHeader));
S> Ports := ntohs(tcphdr.th_sport);
S> Portd := ntohs(tcphdr.th_dport);
S> // Fform.Memo1.Lines.Add('TCP - '+inet_ntoa(sa1)+'-'+IntToStr(Ports)+'------>'+inet_ntoa(sa2)+'-'+IntToStr(Portd));
S> End;
S> IPPROTO_UDP : Begin
S> CopyMemory(@udphdr,@Buffer[sizeof(TIPHeader)],sizeof(TUDPHeader));
S> Ports := ntohs(udphdr.uh_sport);
S> Portd := ntohs(udphdr.uh_dport);
S> // Fform.Memo1.Lines.Add('UDP - '+inet_ntoa(sa1)+'-'+IntToStr(Ports)+'------>'+inet_ntoa(sa2)+'-'+IntToStr(Portd));
S> End;
S> Else
S> Ports := 0;
S> Portd := 0;
S> End;
S> if (((sa1.S_addr and inet_addr(PChar(FForm.ipaMask.Text)))= sa1.S_addr) And ((sa2.S_addr and inet_addr(PChar(FForm.ipaMask.Text)))= sa2.S_addr))
S> and ((sa1.S_addr = inet_addr(PChar(FForm.ipServer.Text)))Or (sa2.S_addr = inet_addr(PChar(FForm.ipServer.Text))))
S> And (FForm.InPorts(Ports) or FForm.InPorts(Portd))
S> And (FForm.ClientsWatch(inet_ntoa(sa1)) or FForm.ClientsWatch(inet_ntoa(sa2))) And FForm.isProtocol(hdr.iph_protocol)
S> Then
S> Begin
S> FSum := FSum + ntohs(hdr.iph_length);
S> FForm.SetBytes(inet_ntoa(sa1),ntohs(hdr.iph_length),False);
S> FForm.SetBytes(inet_ntoa(sa2),ntohs(hdr.iph_length),True);
S> FForm.Memo1.Lines.Add(inet_ntoa(sa1)+':'+IntToStr(Ports)+' --> '+inet_ntoa(sa2)+':'+IntToStr(Portd))
S> End;
S> Synchronize(DoData);
S> End;
S> End;
S> closesocket(s);
S> WSACleanup;
S>
Здравствуйте, Shtirliz, Вы писали:
S>Доброго времени суток.
S>Проблемма следующего содержания: S>Через winsocket ловлю приходящие и исходящие пакеты. Под Win2k и win98 все работает отлично.
что и под 98 SIO_RCVALL работает? что-то сомневаюсь..
MSDN:
SIO_RCVALL is available in Windows 2000 and later versions of Windows.
S>попробовал на WinXP и ничего у меня не вышло, с одной оговоркой. Если одна из машин находится под управлением win2k или win98, S>то пакеты от этих машин лювятся, а пакеты от машины на winXP нет.
хочешь сказать, что драйвер различает какой пакет пришёл от ХР и не отдаёт тебе его?
а от UNIX'ов пакеты принимает?
S>Пожалуйста подскажите, в чем дело?
могу только посоветовать добавить DEBUG кода, для проверки кодов возврата и посмотреть, может какая-то функция возвратит ошибку..
Здравствуйте, Shtirliz, Вы писали:
NV>вот этот код непонятен NV>
NV> If (count >= sTcp)or (count >= sUdp)
NV>
кстати да, я бы ещё посоветовал тут использовать модель ввода-вывода "Перекрытый ввод-вывод с уведомлениями о событии"
ИМХО — это оптимальная модель для использования в потоке и тогда этот код можно было бы считать корректным, так как событие срабатывает тогда, когда пакет уже прочитан.
NV>ведь recv() не обязан дать только один пакет?
да, он так же не обязан вернуть и полный пакет..
NV>кроме того, судя по Synchronize(DoData); и While Not Terminated Do NV>это код метода Execute, тогда какого рожна там Application.ProcessMessages; ??? NV>это не только не поможет, это просто неправильно !!! NV>(ну и всякие там FForm.Memo1. это тоже некорректно)
Здравствуйте, butcher, Вы писали:
B>Здравствуйте, Shtirliz, Вы писали:
S>>Доброго времени суток.
S>>Проблемма следующего содержания: S>>Через winsocket ловлю приходящие и исходящие пакеты. Под Win2k и win98 все работает отлично.
B> что и под 98 SIO_RCVALL работает? что-то сомневаюсь.. B>
B> MSDN:
B> SIO_RCVALL is available in Windows 2000 and later versions of Windows.
Я имел ввиду, что от 98 пакеты ловятся, а от XP нет.
S>>попробовал на WinXP и ничего у меня не вышло, с одной оговоркой. Если одна из машин находится под управлением win2k или win98, S>>то пакеты от этих машин лювятся, а пакеты от машины на winXP нет.
B>хочешь сказать, что драйвер различает какой пакет пришёл от ХР и не отдаёт тебе его? B>а от UNIX'ов пакеты принимает?
S>>Пожалуйста подскажите, в чем дело?
B>могу только посоветовать добавить DEBUG кода, для проверки кодов возврата и посмотреть, может какая-то функция возвратит ошибку..
Дункан Маклауд любил ходить в лес и издеваться над кукушками.
138385660
Здравствуйте, NeuroVirus, Вы писали:
NV>Здравствуйте, Shtirliz, Вы писали:
S>>Доброго времени суток.
S>>Проблемма следующего содержания: S>>Через winsocket ловлю приходящие и исходящие пакеты. Под Win2k и win98 все работает отлично. S>>попробовал на WinXP и ничего у меня не вышло, с одной оговоркой. Если одна из машин находится под управлением win2k или win98, S>>то пакеты от этих машин лювятся, а пакеты от машины на winXP нет.
S>>Вот код нити по отслеживанию входящих-исходящих пакетов
NV>вот этот код непонятен NV>
NV> If (count >= sTcp)or (count >= sUdp)
NV>
NV>на мой взгляд нужно иметь локальный буфер NV>и читать туда все, правильно разбирать длину пакета, NV>ведь recv() не обязан дать только один пакет? NV>(можно случайно отбросить длину другого пакета) NV>но это ИМХО так как этот вопрос я тонко не изучал и не пробовал.
Попробую...
NV>кроме того, судя по Synchronize(DoData); и While Not Terminated Do NV>это код метода Execute, тогда какого рожна там Application.ProcessMessages; ??? NV>это не только не поможет, это просто неправильно !!! NV>(ну и всякие там FForm.Memo1. это тоже некорректно)
Суть ведь не в этом... Я думаю...
Дункан Маклауд любил ходить в лес и издеваться над кукушками.
138385660