Модераторы: Snowy, Poseidon, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Неправильно считается трафик 
:(
    Опции темы
Felan
Дата 15.1.2008, 16:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 284
Регистрация: 2.8.2007
Где: Самара

Репутация: нет
Всего: 7



В моей программе надо сделать учет трафика.
Я взял за основу пример снифера от Rouse.
Вроде все заработало, но вот размер трафика который считается программой не совпадает с фактически преданным. Причем на порядки не совпадает. Закономерность несовпадения мне выявить неудалось :(

Т.е. если я, например, запускаю программу и копирую по сети файл порядка 700мб, то она мне показывает порядка 60мб.
Если я гружу HTML страницу, то она мне показывает порядка 45кб, хотя полностью сохраненная эта же страница занимает порядка 270кб.

Посему прошу помощи! Подскажите, где я чего не так делаю, или может быть у кого готовый пример найдется?

Вот, на мой взгляд, важные моменты. Хотя это пока тестовый вариант, и обработка ошибок будет добавлена позже...
Открытие сокета:
Код

  // инициализируем WinSock
  Result := WSAStartup(WSA_VER, fWSA) = NOERROR;
  if not Result then
    raise ETrafficSniffer.Create( SysErrorMessage(WSAGetLastError) );
  // создаем сокет
  fhSocket := socket(AF_INET, SOCK_RAW, IPPROTO_IP);
  if fhSocket = INVALID_SOCKET then
    begin
      vErr := WSAGetLastError();
      DeInitSocket( vErr );
      raise ETrafficSniffer.Create( SysErrorMessage(WSAGetLastError) );
    end;

  FillChar(fAddr_in, SizeOf(sockaddr_in), 0);
  fAddr_in.sin_family:= PF_INET;
  // указываем за каким интерфейсом будем следить
  fAddr_in.sin_addr.s_addr := inet_addr( PChar( getProperties.Host ) );
  // связываем сокет с локальным адресом
  if bind(fhSocket, fAddr_in, SizeOf(sockaddr_in)) <> 0 then
    begin
      vErr := WSAGetLastError();
      DeInitSocket( vErr );
      raise ETrafficSniffer.Create( SysErrorMessage(WSAGetLastError) );
    end;
  // Переключаем интерфейс на прием всех пакетов проходящих через интерфейс - promiscuous mode.
  PromiscuousMode := 1;
  if ioctlsocket(fhSocket, SIO_RCVALL, PromiscuousMode) <> 0 then
    begin
      vErr := WSAGetLastError();
      DeInitSocket( vErr );
      raise ETrafficSniffer.Create( SysErrorMessage(WSAGetLastError) );
    end;
  Result := True;


Поточная процедура:
Код

var
  vPacketSize: Integer;
begin
  // Ждем получения пакета (блокирующий режим)
  vPacketSize := recv(fhSocket, fPacket, MAX_PACKET_SIZE, 0);
  // Если есть данные - производим их разбор
  if vPacketSize > SizeOf(TIPHeader) then
    ParcePacket( vPacketSize );


Процедура парсера
Код

var
  IPHeader: TIPHeader;
  ICMPHeader: TICMPHeader;
  TCPHeader: TTCPHeader;
  UDPHeader: TUDPHeader;
  SrcPort, DestPort: Word;
  I, Octets, PartOctets: Integer;
  PacketType, DumpData, ExtendedInfo: String;
  Addr: TInAddr;
  vLogData: String;
  fLocalIP: TInAddr;
begin
  Inc( fTotalPacketCount );
  // Читаем из буфера IP заголовок
  Move( fPacket[0], IPHeader, SizeOf(TIPHeader) );

  // Пишем время жизни пакета
  vLogData := LOG_STR_0 +
    Format(LOG_STR_1, [fTotalPacketCount, IPHeader.iph_ttl]);

  SrcPort := 0;
  DestPort := 0;
  ExtendedInfo := '';
  // определяем тип протокола
  case IPHeader.iph_protocol of
    IPPROTO_ICMP: // ICMP
    begin
      PacketType := 'ICMP';
        // Читаем ICMP заголовок
      Move( fPacket[SizeOf(TIPHeader)], ICMPHeader, SizeOf(TICMPHeader) );
        // Смотрим тип пакета
      case ICMPHeader.IcmpCode of
        ICMP_ECHO: ExtendedInfo := Format(LOG_STR_6, ['Echo']);
        ICMP_ECHOREPLY: ExtendedInfo := Format(LOG_STR_6, ['Echo reply']);
      else
        ExtendedInfo := Format(LOG_STR_6, ['Unknown']);
      end;
    end;
    IPPROTO_TCP: // TCP
    begin
      PacketType := 'TCP';
        // Читаем ТСР заголовок
      Move( fPacket[SizeOf(TIPHeader)], TCPHeader, SizeOf(TTCPHeader) );
        // Смотрим порт отправителя и получателя
      SrcPort := TCPHeader.sourcePort;
      DestPort := TCPHeader.destinationPort;
    end;
    IPPROTO_UDP: // UDP
    begin
      PacketType := 'UDP';
        // Читаем UDP заголовок
      Move(fPacket[SizeOf(TIPHeader)], UDPHeader, SizeOf(TUDPHeader));
        // Смотрим порт отправителя и получателя
      SrcPort := UDPHeader.sourcePort;
      DestPort := UDPHeader.destinationPort;
    end;
  else
    PacketType := 'Unsupported (0x' + IntToHex(IPHeader.iph_protocol, 2) + ')';
  end;
  // Пишем размер пакета
  vLogData := vLogData + Format(LOG_STR_2, [PacketSize, PacketType]);
  if ExtendedInfo <> '' then
    vLogData := vLogData + ExtendedInfo;
    
  SrcPort := htons(SrcPort);
  DestPort := htons(DestPort);

  // Пишем IP адрес отправителя с портом
  Addr.S_addr := IPHeader.iph_src;
  vLogData := vLogData + Format(LOG_STR_3, [inet_ntoa(Addr), SrcPort]);
  // Пишем IP адрес получателя с портом
  Addr.S_addr := IPHeader.iph_dest;
  vLogData := vLogData + Format(LOG_STR_4, [inet_ntoa(Addr), DestPort]) + LOG_STR_7;

  fLocalIP.S_addr := inet_addr( PChar( getProperties.Host ) ); //ПОлучение собственного IP на который привязан сокет

  //изменение счетчиков
  if IPHeader.iph_src = fLocalIP.S_addr then
    setOutBytesCount( getOutBytesCount + PacketSize );

  if IPHeader.iph_dest = fLocalIP.S_addr then
    setInBytesCount( getInBytesCount + PacketSize );



--------------------
// Любая сложная система - это темный лес. Каждый в этом лесу протаптывает свои тропинки, по ним и бегает. Лишь изредка, сходя с них, мы находим много интересного, а порою и страшного.
PM MAIL WWW ICQ   Вверх
MetalFan
Дата 15.1.2008, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 14
Всего: 128



хм... выложи тестовое приложение... на первый взгляд упущений не вижу


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Felan
Дата 16.1.2008, 09:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 284
Регистрация: 2.8.2007
Где: Самара

Репутация: нет
Всего: 7



Вот тестовое приложение. Немного некрасиво внутри, но пришлось из рабочего приложения модули выдирать.
Вобщем и целом, кроме обвязки, там все то же самое.

Присоединённый файл ( Кол-во скачиваний: 5 )
Присоединённый файл  _____________.rar 24,99 Kb


--------------------
// Любая сложная система - это темный лес. Каждый в этом лесу протаптывает свои тропинки, по ним и бегает. Лишь изредка, сходя с них, мы находим много интересного, а порою и страшного.
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Сети"
Snowy
Poseidon
MetalFan

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0452 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.