Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2004.06.20;
Скачать: [xml.tar.bz2];

Вниз

Помогите с сокетом   Найти похожие ветки 

 
V@LER@N ©   (2004-04-26 15:39) [0]

Всем доброго времени суток. Есть такая трабла: как смастерить програмулину, которая, работая в ЛАНе (5 компов) на одной из машин, могла бы получать инфу, к-рая приходит на эту машину с других. Пытался писАть на стандартных сокетах - ничего не получилось:(. Смущает такая вещь как "порт" - каков его смысл и где взять его значение я так и не расчехлил. Пробовал переделать один из снифферов (пример Verg"a) - запутался еще сильнее. Сам сниффер у меня работать не стал. Там было сказано, что это только пример, а не рабочая прога, но хоть какие-то признаки жизни он подавать должен был...


 
Digitman ©   (2004-04-26 18:09) [1]


> Пытался писАть на стандартных сокетах


что есть "стандартных сокетах" ?


> Сам сниффер у меня работать не с


программисту, себя таковым считающему, известно такое понятие как "отладка программы" ... Делфи-программисту тем паче известно, что среда Делфи содержит встроенный отладчик , который предназначен для использования отнюдь не Пушкиным А.С.


 
Polevi ©   (2004-04-27 08:18) [2]

снифер он пишет, ты бы еще с TDI начал чтоли


 
имя   (2004-04-27 08:21) [3]

Удалено модератором


 
V@LER@N ©   (2004-04-27 17:29) [4]

Удалено модератором
Примечание: Оффтоп...


 
Digitman ©   (2004-04-27 17:42) [5]

Удалено модератором
Примечание: Оффтоп...


 
VMcL ©   (2004-04-27 17:46) [6]

Удалено модератором
Примечание: Все что ниже удалено - оффтоп...


 
Digitman ©   (2004-04-27 17:48) [7]

Удалено модератором


 
Digitman ©   (2004-04-27 18:00) [8]

Удалено модератором


 
V@LER@N ©   (2004-04-27 18:14) [9]

Удалено модератором


 
Digitman ©   (2004-04-27 18:21) [10]

Удалено модератором


 
Piter ©   (2004-04-27 19:25) [11]

Удалено модератором


 
Verg ©   (2004-04-27 20:56) [12]


> Заново писать не буду, так как сижу в инет-кафе, а по памяти
> написать не смогу... Он у меня зависает на вызове recv.
> Почему?


По памяти, насколько я помню, люди которые на самом деле решили его попробовать обычно спрашивали: "чему равна константа SIO_RCVALL" и кто такой модуль mstсpip, winsock2? Просто интересно, почему у тебя таких вопросов не возникает?

Кстати, ты знаешь, что в сетях Microsoft Windows информация может передаваться не только с применением IP-базирующихся протоколов?
SOCK_RAW, тем временем может принимать (передавать) ТОЛЬКО IP датаграммы.


 
Verg ©   (2004-04-27 21:25) [13]

В качестве развлечения (появился часок другой св. вр.), предлагаю продолжить тему консольных сниферов, т.е. модорнизацию их уже на более кокретные, полезные цели. Считаю себя вправе выбрать тему для такого развлечения и начинаю с метафоры.
Пусть нам хочется узнать интенсивность потребления TCP - трафика некоего хоста в нашей (а в слчаях транзитных сетей возможно и не нашей) сети. Т.е. надо узнать с какой интенсивностью некий хост (Target IP) принимает TCP трафик. Для чего? Ну, например, для того, чтобы предсказать его на будущее и указать, например, на черезмерность. Но главное - иллюстрация работы не столько даже SOCK_RAW, сколько понимание что и где лежит в IP пакетах вместе с надстроенным протоколом верхнего уровня (в данном случае - TCP)
К тому же давайте учтем, что при некоторых условиях пиковая скорость поступления TCP/IP потока (сегментов) очень высока. ..... я думаю, что нужно бы оценить справляется наш "счетчик" или нет.

Итак, первое, что приходит в голову - это необходимость создать модуль, который описывал структуры данных приходящих к нам с SOCK_RAW.

Итак, назовем его IpUtils.pas

unit IPUtils;

interface
uses Windows, WinSock2;

const
 IP_MAXPACKET = high(word);

type
   // IP header
   PIPHeader = ^TIPHeader;
   TIPHeader = packed record
     verlen : byte;      // версия и длина заголовка
     tos    : byte;      // тип сервиса
     length : word;      // длина всего пакета
     id     : word;      // Id
     offset : word;      // флаги и смещения
     ttl    : byte;      // время жизни
     protocol : byte;    // протокол
     xsum   : word;      // контрольная сумма
     src    : TInAddr;   // IP-адрес отправителя
     dst    : TInAddr;   // IP-адрес назначения
   end;

   // TCP Header
   TTCPHeader = packed record
     Source:        word;  //Source Port
     Destination:   word;  //Destination Port
     Seq:           ulong; // порядковый номер передаваемого октета
     Ack:           ulong; // порядковый номер принятого октета
     Rsvd0_Off:     byte;  //Смещение до начала данных
     Flags_Rsvd1:   byte;  //флаги
     Window:        word;  // Размер окна
     Checksum:      word;
     UrgPoint:      word;
   end;
   PTCPHeader = ^TTCPHeader;

   //Флаги TCP (TTCPHeader.Flags_Rsvd1)
   const
     TCP_FLAG_FIN = $01;
     TCP_FLAG_SYN = $02;
     TCP_FLAG_RST = $04;
     TCP_FLAG_PSH = $08;
     TCP_FLAG_ACK = $10;
     TCP_FLAG_URG = $20;

function net_checksum( var data; len : word):word;
function net_chksum_add( S1, S2 : word ) : word;
function PHCheckSumm(Src, Dst : TInAddr;
                    Proto: byte;
                    Len : word):word;

implementation
uses SysUtils;

type
   // Псевдозаголовок
   TPSUHeader = packed record
     Src:        TInAddr;
     Dst:        TInAddr;
     Zero:       byte;
     Protocol:   byte;
     Length:     word;
   end;
   PPSUHeader = ^TPSUHeader;

function net_checksum( var data; len : word):word;
var
  Sum : ulong;
  Dp  : PWORD;
  Words : integer;
begin
   Sum := 0;
   Dp := PWORD(@Data);
   for Words := 1 to Len shr 1 do
   begin
     sum := sum + dp^;
     inc(Dp);
   end;
   if odd(len) then
     Sum := Sum + ord(pchar(Dp)^);
   Sum := (Sum and $FFFF) + LongRec(Sum).Hi;
   Result:= LongRec(sum).Lo + LongRec(Sum).Hi;
   if Result <> $FFFF then
     Result := not Result;
end;

function net_chksum_add( S1, S2 : word ) : word;
var
 Sum : ulong;
begin
 Sum := ulong(s1) + ulong(s2);
 result := Sum;
 if LongRec(Sum).Hi <> 0 then
   Sum := Result + 1
 else
   Sum := Result;
 if (Sum = 0) and ((S1 or S2) <> 0) then
   result := $FFFF
 else
   result := Sum;
end;

function PHCheckSumm(Src, Dst : TInAddr;
                    Proto: byte;
                    Len : word):word;
var pH : TPSUHeader;
begin
 pH.Src := src;
 pH.Dst := dst;
 pH.Protocol := Proto;
 pH.Zero := 0;
 pH.Length := htons(Len);
 result := net_checksum(pH, sizeof(pH));
end;

end.

Думаю, что будет достаточно для модуля такого предназначения...

to be continued...


 
Verg ©   (2004-04-27 21:36) [14]

Теперь, стоит вспонить, что SOCK_RAW может работать в режиме "сковзного приема" (SIO_RCVALL) только с локальным адресом  совпадающим с IP адресом какого-то одного, конкретного, реально физически существующего сетевого интерфейса (сетевого адаптера). Т.е. такому сокету нельзя назначить локальный адрес типа INADDR_ANY (0.0.0.0) или INADDR_LOOPBACK (127.0.0.1).
Т.о., если мы решили "наблюдать" за IP трафиком идущим в сторону конкретоного адрес, то мы должы из, в общем случае, множества сетевых адаптеров на нашем компе определить такой, который быдет в состоянии принимать (слышать) пакеты адресованные Target IP. Я предпочитаю для этого пользоваться замечательной библиотекой iphlpapi.dll, поэтому надо создать минимальный интерфейсный модуль для использования ее возможностями.
unit IPHelper;

interface
uses Windows;
const
 MAX_INTERFACE_NAME_LEN  = 256;
 MAX_TRANSPORT_NAME_LEN  = 40;
 MAX_MEDIA_NAME          = 16;
 MAX_PORT_NAME           = 16;
 MAX_DEVICE_NAME         = 128;
 MAX_PHONE_NUMBER_LEN    = 128;
 MAX_DEVICETYPE_NAME     = 16;
 MAXLEN_IFDESCR          = 256;
 MAXLEN_PHYSADDR         = 8;

type
 TIPAddr = ULONG;     // An IP address.
 TIPMask = ULONG;     // An IP subnet mask.
 TIP_STATUS = ULONG;  // Status code returned from IP APIs.

   TMIB_IFROW = record
           wszName : array[0..MAX_INTERFACE_NAME_LEN-1] of widechar;
           dwIndex,
           dwType,
           dwMtu,
           dwSpeed,
           dwPhysAddrLen : DWORD;
           bPhysAddr : array[0..MAXLEN_PHYSADDR-1] of BYTE;
           dwAdminStatus,
           dwOperStatus,
           dwLastChange,
           dwInOctets,
           dwInUcastPkts,
           dwInNUcastPkts,
           dwInDiscards,
           dwInErrors,
           dwInUnknownProtos,
           dwOutOctets,
           dwOutUcastPkts,
           dwOutNUcastPkts,
           dwOutDiscards,
           dwOutErrors,
           dwOutQLen,
           dwDescrLen : DWORD;
           bDescr : array[0..MAXLEN_IFDESCR-1] of BYTE;
end;

PMIB_IFROW = ^TMIB_IFROW;

const
 MIB_IF_TYPE_OTHER              = 1;
 MIB_IF_TYPE_ETHERNET           = 6;
 MIB_IF_TYPE_TOKENRING          = 9;
 MIB_IF_TYPE_FDDI               = 15;
 MIB_IF_TYPE_PPP                = 23;
 MIB_IF_TYPE_LOOPBACK           = 24;
 MIB_IF_TYPE_SLIP               = 28;

 MIB_IF_ADMIN_STATUS_UP         = 1;
 MIB_IF_ADMIN_STATUS_DOWN       = 2;
 MIB_IF_ADMIN_STATUS_TESTING    = 3;

 MIB_IF_OPER_STATUS_NON_OPERATIONAL =     0;
 MIB_IF_OPER_STATUS_UNREACHABLE     =     1;
 MIB_IF_OPER_STATUS_DISCONNECTED    =     2;
 MIB_IF_OPER_STATUS_CONNECTING      =     3;
 MIB_IF_OPER_STATUS_CONNECTED       =     4;
 MIB_IF_OPER_STATUS_OPERATIONAL     =     5;

type
 
TMIB_IFTABLE = record
   dwNumEntries : DWORD;
   table        : array[0..0] of TMIB_IFROW;
end;
PMIB_IFTABLE = ^TMIB_IFTABLE;

TMIB_IPADDRROW = record
   dwAddr,
   dwIndex,
   dwMask,
   dwBCastAddr,
   dwReasmSize : DWORD;
   unused1,
   unused2 : WORD;
end;
PMIB_IPADDRROW = ^TMIB_IPADDRROW;

TMIB_IPADDRTABLE = record
 dwNumEntries : DWORD;
 table        : array[0..0] of TMIB_IPADDRROW;
end;
PMIB_IPADDRTABLE= ^TMIB_IPADDRTABLE;

TMIB_IPFORWARDROW = record
 dwForwardDest     : DWORD;
 dwForwardMask     : DWORD;
 dwForwardPolicy   : DWORD;
 dwForwardNextHop  : DWORD;
 dwForwardIfIndex  : DWORD;
 dwForwardType     : DWORD;
 dwForwardProto    : DWORD;
 dwForwardAge      : DWORD;
 dwForwardNextHopAS : DWORD;
 dwForwardMetric1   : DWORD;
 dwForwardMetric2   : DWORD;
 dwForwardMetric3   : DWORD;
 dwForwardMetric4   : DWORD;
 dwForwardMetric5   : DWORD;
end;
PMIB_IPFORWARDROW = ^TMIB_IPFORWARDROW;

const
   MIB_IPROUTE_TYPE_OTHER   = 1;
   MIB_IPROUTE_TYPE_INVALID = 2;
   MIB_IPROUTE_TYPE_DIRECT  = 3;
   MIB_IPROUTE_TYPE_INDIRECT= 4;

type
TMIB_IPFORWARDTABLE = record
 dwNumEntries  : DWORD;
 table         : array[0..0] of TMIB_IPFORWARDROW;
end;
PMIB_IPFORWARDTABLE = ^TMIB_IPFORWARDTABLE;

function   GetIfTable(pIfTable : PMIB_IFTABLE; var pdwSize : ULONG; bOrder : BOOL): DWORD; stdcall;

function GetIpAddrTable(pIpAddrTable : PMIB_IPADDRTABLE; var pdwSize : ULONG; bOrder : BOOL): DWORD; stdcall;

function SendARP(DestIP:DWORD;SrcIP:DWORD; var pMacAddr; var PhyAddrLen:DWORD):DWORD;stdcall;

function  SetIfEntry(pIfRow : PMIB_IFROW   // specifies interface and status
): DWORD; stdcall;

function GetIpForwardTable(
 pIpForwardTable : PMIB_IPFORWARDTABLE;  // buffer for routing table
 var pdwSize : ULONG;                       // size of buffer
 bOrder : BOOL                          // sort the table
): DWORD; stdcall;

function GetBestInterface(
 dwDestAddr : DWORD;     // destination IP address
 var pdwBestIfIndex : DWORD // index of interface with the best route
) : DWORD; stdcall;

function GetIfEntry(var pIfRow : TMIB_IFROW ): DWORD; stdcall;  // pointer to interface entry

function NotifyRouteChange(var Handle : THandle; var overlapped : TOverlapped):DWORD; stdcall;

implementation

function   GetIfTable;       external "IPHLPAPI.DLL";
function   GetIpAddrTable;   external "IPHLPAPI.DLL";
function   SendARP;          external "IPHLPAPI.DLL";
function   SetIfEntry;       external "IPHLPAPI.DLL";
function   GetIpForwardTable;external "IPHLPAPI.DLL";
function   GetBestInterface; external "IPHLPAPI.DLL";
function   GetIfEntry;       external "IPHLPAPI.DLL";
function   NotifyRouteChange;external "IPHLPAPI.DLL";

end.


 
Verg ©   (2004-04-27 21:48) [15]

Так, теперя, я думаю, будет полезным иметь возможность считать не просто интенсивность входящего TCP/IP трафика, а с какого-то конкретого,заданного порта. Хм... Представилось,  как некий комп в итрасети (бынальные 192.168......) качает из интернента через прокси (другого пути в интернет у него просто нет). Значит, задав известный порт прокси (например, 3128) мы можем селектировать именно такой трафик....
Впрочем, давайте условимся, что если в качесве порта будет задано значение 0 (ноль), то мы будем считать трафик с любого порта источника без разбору.


 
Verg ©   (2004-04-27 21:56) [16]

Проблемка чисто математического плана: если наш проц достаточно быстр и быстр на столько, что время обработки датаграммы почти не зависит от ее размера, то получится по-моему обман, если мы будем усреднять скорость обработки поступающей информации, складывая их объем и деля на суммароне время обработки каждой в условиях множества малых пакетов.
Ну что ж, введем понятия "малой" датаграммы и не будем учитывать в расчете средней производительности датаграммы "нулевого" размера.


 
Verg ©   (2004-04-27 22:03) [17]

Да, чтобы пока нескучно было :) качайте Winsock2.pas, с молчаливого разрешения (я надеюсь) Alex Konshin-а :)
http://home.earthlink.net/~akonshin/files/ws2rev4a.zip
И еще модуль
unit mstcpip;

interface
uses Winsock2;
type
   _tcp_keepalive  = packed record
      onoff : u_long;
      keepalivetime : u_long;
      keepaliveinterval : u_long;
   end;

const
// New WSAIoctl Options
SIO_RCVALL                           = IOC_IN or IOC_VENDOR or 1;
SIO_RCVALL_MCAST                     = IOC_IN or IOC_VENDOR or 2;
SIO_RCVALL_IGMPMCAST                 = IOC_IN or IOC_VENDOR or 3;
SIO_KEEPALIVE_VALS                   = IOC_IN or IOC_VENDOR or 4;
SIO_ABSORB_RTRALERT                  = IOC_IN or IOC_VENDOR or 5;
SIO_UCAST_IF                         = IOC_IN or IOC_VENDOR or 6;
SIO_LIMIT_BROADCASTS                 = IOC_IN or IOC_VENDOR or 7;
SIO_INDEX_BIND                       = IOC_IN or IOC_VENDOR or 8;
SIO_INDEX_MCASTIF                    = IOC_IN or IOC_VENDOR or 9;
SIO_INDEX_ADD_MCAST                  = IOC_IN or IOC_VENDOR or 10;
SIO_INDEX_DEL_MCAST                  = IOC_IN or IOC_VENDOR or 11;

// Values for use with SIO_RCVALL* options
  RCVALL_OFF             = 0;
  RCVALL_ON              = 1;
  RCVALL_SOCKETLEVELONLY = 2;

implementation

end.


 
Verg ©   (2004-04-27 22:36) [18]

Вот, что получилось. Это, конечно, немного тяжеловато, но оптимизацию предлагаю сделать самим заинтересованным.
program Console;
{$APPTYPE CONSOLE}

{$DEFINE REALTIME}
{$DEFINE CHECKSUMM}

uses
 Windows,
 SysUtils,
 WinSock2 in "WinSock2.pas",
 mstcpip in "mstcpip.pas",
 IPUtils in "IPUtils.pas",
 IPHelper in "IPHelper.pas";

const
 MEGASIZE     = (1024*1024);

 MIN_SPEED_SIZE = 500;

var
 WSAData : TWSAData;
 Sa : TSockAddrIn;
 Rcvd : integer;
 RS   : TSocket;
 flag : DWORD;

 Buffer : array[0..IP_MAXPACKET-1] of byte;
 Iph : TIpHeader absolute Buffer;
 HeaderLen : DWORD;
 IPData    : pchar;

 DstIP   : DWORD;
 DstPort : WORD;
 Trafic0,
 Trafic: Int64;

 Tmv  : TTimeVal;
 StTime : DWORD;
 DGSpeedTimer, DGSpeedTimer2   : Int64;

 DGSpeedTimeSumm,
 DGSpeedCounter : Int64;

 FreqAvail : boolean;
 Freq : Int64;

 StartTime : TDateTime;

procedure SaveData;
var Fn : string;
   F  : text;
begin
 Fn := ExtractFilePath(ParamStr(0))+IntToStr(DstIp)+IntToStr(DstPort)+".dat";
 Assign(F, Fn);
 rewrite(F);
 WriteLn(F, StartTime, " ", Trafic);
 Close(F);
end;

procedure LoadData;
var Fn : string;
   F  : text;
begin
 Fn := ExtractFilePath(ParamStr(0))+IntToStr(DstIp)+IntToStr(DstPort)+".dat";
 Assign(F, Fn);
 if FileExists(Fn) then
 begin
   reset(F);
   ReadLn(F, StartTime, Trafic);
   Close(F);
 end else
 begin
   StartTime := now;
   Trafic := 0;
 end;
end;

function CheckIP( DstIP : DWORD ): boolean;
begin
 result := true;
 if (DstIp = htonl(INADDR_ANY)) or
    (DstIp = htonl(INADDR_LOOPBACK)) or
    (DstIp = htonl(INADDR_NONE)) then
   result := false;
end;

function CtrlHandler(dwCtrlType : DWORD):BOOL; stdcall;
var S : TSocket;
begin
 if RS<>INVALID_SOCKET then
 begin
   S:= RS;
   RS := INVALID_SOCKET;
   CloseSocket(S);
 end;
 result := BOOL(true);
end;

function ToOem(const S : string):string;
begin
 Result := S;
 if Result<>"" then
   CharToOemBuff(pchar(Result), pchar(Result), length(Result));
end;

function ProcessDGSpeed : double;
begin
 Result := -1;
 if not FreqAvail then
   exit;
 if DGSpeedCounter = 0 then
   DGSpeedCounter := 1;

 Result := ( DGSpeedCounter / (DGSpeedTimeSumm / Freq) ) / MEGASIZE;
 if DGSpeedCounter > 100*MEGASIZE then
 begin
   DGSpeedTimeSumm := 0;
   DGSpeedCounter := 0;
 end;
end;

function ProcessTrafic:boolean;
var MbSec : double;
begin
 Result := false;
 if Trafic0 > 0 then
 begin
   inc(Trafic, Trafic0);
   Trafic0 := 0;

   MbSec := Trafic/((Now - StartTime)*MEGASIZE);

   Write(ToOem("Трф. "+inet_ntoa(TInAddr(DstIP))+
                 " с порта "+IntToStr(ntohs(DstPort))+" = "),
            Trafic, #9,
            "(", MbSec:3:1, toOem(" МБ/сут)"));
   if FreqAvail then
     WriteLn(" ", ProcessDGSpeed:3:1, ToOem("МБ/с"))
   else
     WriteLn;
   SaveData;
   Result := true;
 end;
end;

procedure PrintErr(Err : DWORD; Wt : boolean);
begin
 Writeln(ToOem(SysErrorMessage(Err)));
 if Wt then ReadLn;
end;

procedure ExitErr;
begin
 if (WSAGetLastError<>NO_ERROR) and
    (WSAGetLastError<>WSAENOTSOCK) and
    (WSAGetLastError<>WSAEINTR) then
   PrintErr(WSAGetLastError, true)
 else
   if ProcessTrafic then
     ReadLn;
 if Rs<> INVALID_SOCKET then
   CloseSocket(RS);
 if WSAData.wVersion <> 0 then
   WSACleanup;
 halt(0);
end;

function checksocket(Ret : integer):integer;
begin
 Result := Ret;
 if Result = SOCKET_ERROR then
 begin
   if WSAGetLastError <> WSAETIMEDOUT then
    ExitErr
   else
    result :=0;
 end;
end;

function InterfaceTo( DstIp : DWORD; var IntIP : DWORD) : integer;
var Table : PMIB_IPADDRTABLE;
   TableSize : ulong;
   Bi : DWORD;
   I : integer;
   Res : DWORD;

   procedure CheckIPHLP(R: DWORD);
   begin
     if R<>NO_ERROR then
     begin
       WSASetLastError(R);
       ExitErr;
     end;
   end;

begin
 Result := -1;
 IntIp := INADDR_NONE;
 CheckIPHLP(GetBestInterface(DstIp, Bi) );
 TableSize := 0;
 Res := GetIpAddrTable(nil, TableSize, false);
 if TableSize <> 0 then
 begin
   GetMem(Table, TableSize);
   try
     CheckIPHLP(GetIpAddrTable(Table, TableSize, false));
     for I:= 0 to Table^.dwNumEntries-1 do
     if Table^.table[I].dwIndex = Bi then
     begin
       Result := 0;
       IntIP := Table^.table[I].dwAddr;
       if IntIP = htonl(INADDR_LOOPBACK) then
       begin
         // Получлось, что задан собственно один из адресов нашего хоста
         result := 1;
         IntIp := DstIP;
         Break;
       end;
       if  (IntIP and Table^.table[I].dwMask) =
           (DstIp and Table^.table[I].dwMask) then
       begin
         Result := 1;
         break;
       end;
     end;
   finally
     FreeMem(Table);
   end;
 end else
   CheckIPHLP(Res);
end;


 
Verg ©   (2004-04-27 22:37) [19]

procedure RealTime;
begin
 if not SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS) or
    not SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL) then
 begin
   WSASetLastError(GetLastError);
   ExitErr;
 end;
end;

function TCPInput(Iph: PIPHeader; TCPPacket : PTCPHeader; Size : word): boolean;
begin
 Result := false;
 if Size < sizeof(TTCPHeader) then exit;
 if DstPort<>0 then
   if TCPPacket^.Source <> DstPort then exit;      //Только нужный порт
 //SOCK_RAW гарантирует, что IP заголовок имеет правильную КС,
 // но на все остальные уровни он плевал, поэтому придется расчитать
 // КС TCP пакета самим
{$IFDEF CHECKSUMM}
 if net_chksum_add(PHCheckSumm(Iph^.src, Iph^.dst, IPPROTO_TCP, Size),
                   net_checksum(TCPPacket^, Size)
                  ) <> $FFFF then
   exit;
{$ENDIF}
 Inc(Trafic0, ntohs(Iph^.length));
 Result := true;
end;

begin
 Trafic  := 0;
 Trafic0 := 0;
 SetConsoleTitle("SOCK_RAW usage demo.");
 RS := INVALID_SOCKET;
 if ParamCount <> 2 then
 begin
   Writeln("Usage: "+ExtractFileName(ParamStr(0))+" <Target IP> <Target port>");
   Readln;
   Exit;
 end;

 DstIp := inet_addr(pchar(ParamStr(1)));
 if not CheckIP(DstIp) then
 begin
   Writeln("Invalid Target IP");
   Readln;
   Exit;
 end;
 DstPort := htons( StrToIntDef(ParamStr(2), 0) );

 if WSAStartup(MAKEWORD(2, 2), WSAData)<> NO_ERROR then
    ExitErr;
 try
   RS := socket(PF_INET, SOCK_RAW, IPPROTO_IP);
   if RS = INVALID_SOCKET then
     ExitErr;
   try
     ZeroMemory( @sa, sizeof(sa) );
     sa.sin_family := AF_INET;
     case InterfaceTo(DstIp, sa.sin_addr.S_addr) of
       -1 : ExitErr;
       0  : writeln(ToOem("Пакеты Target IP могут не приходить на наш хост."));
     end;
     checksocket(bind(RS, @sa, sizeof(sa)));
     Tmv.tv_sec  := 2;
     Tmv.tv_usec := 0;
     checksocket( setsockopt(RS, SOL_SOCKET, SO_RCVTIMEO,
                             pchar(@Tmv), sizeof(Tmv) ));
     flag:= 1;
     checksocket( ioctlsocket(RS, SIO_RCVALL , flag) );

     Tmv.tv_sec  := Tmv.tv_sec * 1000;
     SetconsoleCtrlHandler(@CtrlHandler, LongBool(TRUE));
     LoadData;
{$IFDEF REALTIME}
     RealTime;
{$ENDIF}

     StTime := GetTickCount;
     DGSpeedCounter := 0;
     FreqAvail :=QueryPerformanceFrequency(Freq);
     repeat
       if GetTickCount - StTime > DWORD(Tmv.tv_sec) then
         Rcvd := 0
       else
         Rcvd := checksocket( recv(RS, Buffer, sizeof(Buffer), 0) );
       if Rcvd > 0 then
       begin
         if FreqAvail then QueryPerformanceCounter( DGSpeedTimer );
         if Iph.dst.S_addr = DstIp then // Только нужный IP
         begin
           HeaderLen := (Iph.verlen and $F) shl 2;  // Длина IP заголовка
           IPData := pchar(@Iph)+HeaderLen;
           if Rcvd <> ntohs( Iph.length ) then
             WriteLn("Error: IP.LENGTH mismatch!");
           case Iph.protocol of
             IPPROTO_TCP : if TCPInput(@Iph,
                                       PTCPHeader( IPData ),
                                       DWORD(Rcvd) - HeaderLen) then
                              StTime := GetTickCount;
           end;
         end;
         if FreqAvail and (Rcvd > MIN_SPEED_SIZE) then
         begin
           QueryPerformanceCounter( DGSpeedTimer2 );
           Inc(DGSpeedTimeSumm, DGSpeedTimer2 - DGSpeedTimer);
           Inc(DgSpeedCounter, Rcvd);
         end;
       end else
       begin
         ProcessTrafic;
         StTime := GetTickCount;
       end;
     until false;
   finally
     closesocket(RS);
   end;
 finally
   WSACleanup;
 end;
end.


 
Rouse_ ©   (2004-04-27 23:05) [20]

> Digitman ©  
Сергей, большая просьба...
Я очень уважительно отношусь к Вашим знаниям и ни в коем случае не умаляю их, но большая просьба:
Пожалуйста, будьте более выдержанны к участникам форумов, я не могу пропускать посты с таким содержанием и приходится их удалять... :(
Я очень не хочу продолжать такую профилактику в будующем...


 
Verg ©   (2004-04-27 23:28) [21]

Ну вот, за приемлимое время у меня получилось:
Условия:
Win2K Pro RUS SP4 P4 1.5G 512M

За прошедшее с запуска время - потрябляемый моим адресом трафик через мой прокси - 20,6 МБ/сут. Средняя производительность счетчик в режиме REALTIME с расчетом конрольной суммы - 203 МБ/с.
Для сети  100 bps предельная производительность д.б ~12 МБ/c. Т.о. запас более чем достаточный.

Можно сделать NT-сервис с "предохранителем", например, чтобы верещала, если среднее потребление трафика превысило некоторый порог. Впрочем, наверняка это где-ниубдь, в каких-нибудь утилитах давно сделано :) в лучшем виде :))))


 
Digitman ©   (2004-04-28 08:01) [22]


> Rouse_ ©   (27.04.04 23:05) [20]


Ok.
Приношу извинения



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2004.06.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.58 MB
Время: 0.028 c
1-1086315999
Funnymind
2004-06-04 06:26
2004.06.20
Про форму


1-1086453802
qwertqwert
2004-06-05 20:43
2004.06.20
Помогите утопающему


4-1084421624
Vitt_lay
2004-05-13 08:13
2004.06.20
Синхронные прием-передача на LPT


1-1086257109
Сашка
2004-06-03 14:05
2004.06.20
Перехват сообщений из dll


14-1086115649
YurikGL
2004-06-01 22:47
2004.06.20
Сегодня пропала строка статуса в IE





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский