<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=82963&amp;view=findpost&amp;p=608141</guid>
        <pubDate>Thu, 10 Feb 2005 18:29:13 +0000</pubDate>
        <title>Сниффер</title>
        <link>https://forum.sources.ru/index.php?showtopic=82963&amp;view=findpost&amp;p=608141</link>
        <description><![CDATA[Rouse_: <div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">////////////////////////////////////////////////////////////////////////////////</div><div class="code_line">//</div><div class="code_line">// &nbsp;****************************************************************************</div><div class="code_line">// &nbsp;* Project &nbsp; : SnifferDemo</div><div class="code_line">// &nbsp;* Unit Name : uMain</div><div class="code_line">// &nbsp;* Purpose &nbsp; : Демонстрационный пример сниффера.</div><div class="code_line">// &nbsp;* Author &nbsp; &nbsp;: Александр (Rouse_) Багель</div><div class="code_line">// &nbsp;* Version &nbsp; : 1.02</div><div class="code_line">// &nbsp;* Home Page : http://rouse.drkb.ru</div><div class="code_line">// &nbsp;****************************************************************************</div><div class="code_line">//</div><div class="code_line">// &nbsp;Особая благодарность TrefptYc и группе Машина Времени,</div><div class="code_line">// &nbsp;за оказанную моральную поддержку, в процессе написания данного примера :)</div><div class="code_line">//</div><div class="code_line">// &nbsp;**************************************************************************** &nbsp; &nbsp; </div><div class="code_line">// &nbsp;От автора:</div><div class="code_line">// &nbsp;Я не ставил перед собой целью написать что-то революционное,</div><div class="code_line">// &nbsp;просто было желание показать сам принцип написания простейшего сниффера,</div><div class="code_line">// &nbsp;что я и осуществил :)</div><div class="code_line">//</div><div class="code_line">// &nbsp;Да, ну и работает все это бесчинство, только начиная с Windows 2000 :)</div><div class="code_line">// </div><div class="code_line">&nbsp;</div><div class="code_line">unit uMain;</div><div class="code_line">&nbsp;</div><div class="code_line">interface</div><div class="code_line">&nbsp;</div><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,</div><div class="code_line">&nbsp;&nbsp;Dialogs, StdCtrls, WinSock;</div><div class="code_line">&nbsp;</div><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp;MAX_PACKET_SIZE = 000; // 2^16</div><div class="code_line">&nbsp;&nbsp;SIO_RCVALL = 000001;</div><div class="code_line">&nbsp;&nbsp;WSA_VER = 2;</div><div class="code_line">&nbsp;&nbsp;MAX_ADAPTER_NAME_LENGTH &nbsp; &nbsp; &nbsp; &nbsp;= 256;</div><div class="code_line">&nbsp;&nbsp;MAX_ADAPTER_DESCRIPTION_LENGTH = 128;</div><div class="code_line">&nbsp;&nbsp;MAX_ADAPTER_ADDRESS_LENGTH &nbsp; &nbsp; = 8;</div><div class="code_line">&nbsp;&nbsp;IPHelper = &#39;iphlpapi.dll&#39;;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Тип ICMP пакета</div><div class="code_line">&nbsp;&nbsp;ICMP_ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 8; &nbsp; // Запрос</div><div class="code_line">&nbsp;&nbsp;ICMP_ECHOREPLY &nbsp; &nbsp; &nbsp; &nbsp;= 0; &nbsp; // Ответ</div><div class="code_line">&nbsp;</div><div class="code_line">resourcestring</div><div class="code_line">&nbsp;&nbsp;LOG_STR_0 = &#39;==============================================================================&#39; + sLineBreak;</div><div class="code_line">&nbsp;&nbsp;LOG_STR_1 = &#39;Packet ID: %-5d TTL: %d&#39; + sLineBreak;</div><div class="code_line">&nbsp;&nbsp;LOG_STR_2 = &#39;Packet size: %-5d bytes type: %s&#39; + sLineBreak;</div><div class="code_line">&nbsp;&nbsp;LOG_STR_3 = &#39;Source IP &nbsp; &nbsp; &nbsp;: %15s: %d&#39; + sLineBreak;</div><div class="code_line">&nbsp;&nbsp;LOG_STR_4 = &#39;Destination IP : %15s: %d&#39; + sLineBreak;</div><div class="code_line">&nbsp;&nbsp;LOG_STR_5 = &#39;ARP Type: %s, operation: %s&#39; + sLineBreak;</div><div class="code_line">&nbsp;&nbsp;LOG_STR_6 = &#39;ICMP Type: %s&#39; + sLineBreak;</div><div class="code_line">&nbsp;&nbsp;LOG_STR_7 = &#39;------------------------------ Packet dump -----------------------------------&#39; + sLineBreak;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;USHORT = WORD;</div><div class="code_line">&nbsp;&nbsp;ULONG = DWORD;</div><div class="code_line">&nbsp;&nbsp;time_t = Longint;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// ip заголовок</div><div class="code_line">&nbsp;&nbsp;// Более подробно в RFC 791</div><div class="code_line">&nbsp;&nbsp;// http://rtfm.vn.ua/inet/prot/rfc791r.html</div><div class="code_line">&nbsp;&nbsp;TIPHeader = packed record</div><div class="code_line">&nbsp;&nbsp; &nbsp;iph_verlen: &nbsp; UCHAR; &nbsp; &nbsp;// версия и длина заголовка</div><div class="code_line">&nbsp;&nbsp; &nbsp;iph_tos: &nbsp; &nbsp; &nbsp;UCHAR; &nbsp; &nbsp;// тип сервиса</div><div class="code_line">&nbsp;&nbsp; &nbsp;iph_length: &nbsp; USHORT; &nbsp; // длина всего пакета</div><div class="code_line">&nbsp;&nbsp; &nbsp;iph_id: &nbsp; &nbsp; &nbsp; USHORT; &nbsp; // Идентификация</div><div class="code_line">&nbsp;&nbsp; &nbsp;iph_offset: &nbsp; USHORT; &nbsp; // флаги и смещения</div><div class="code_line">&nbsp;&nbsp; &nbsp;iph_ttl: &nbsp; &nbsp; &nbsp;UCHAR; &nbsp; &nbsp;// время жизни пакета</div><div class="code_line">&nbsp;&nbsp; &nbsp;iph_protocol: UCHAR; &nbsp; &nbsp;// протокол</div><div class="code_line">&nbsp;&nbsp; &nbsp;iph_xsum: &nbsp; &nbsp; USHORT; &nbsp; // контрольная сумма</div><div class="code_line">&nbsp;&nbsp; &nbsp;iph_src: &nbsp; &nbsp; &nbsp;ULONG; &nbsp; &nbsp;// IP-адрес отправителя</div><div class="code_line">&nbsp;&nbsp; &nbsp;iph_dest: &nbsp; &nbsp; ULONG; &nbsp; &nbsp;// IP-адрес назначения</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;PIPHeader = ^TIPHeader;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// tcp заголовок</div><div class="code_line">&nbsp;&nbsp;// Более подробно в RFC 793</div><div class="code_line">&nbsp;&nbsp;// http://rtfm.vn.ua/inet/prot/rfc793r.html</div><div class="code_line">&nbsp;&nbsp;TTCPHeader = packed record</div><div class="code_line">&nbsp;&nbsp; &nbsp;sourcePort: USHORT; &nbsp; &nbsp; &nbsp; // порт отправителя</div><div class="code_line">&nbsp;&nbsp; &nbsp;destinationPort: USHORT; &nbsp;// порт назначения</div><div class="code_line">&nbsp;&nbsp; &nbsp;sequenceNumber: ULONG; &nbsp; &nbsp;// номер последовательности</div><div class="code_line">&nbsp;&nbsp; &nbsp;acknowledgeNumber: ULONG; // номер подтверждения</div><div class="code_line">&nbsp;&nbsp; &nbsp;dataoffset: UCHAR; &nbsp; &nbsp; &nbsp; &nbsp;// смещение на область данных</div><div class="code_line">&nbsp;&nbsp; &nbsp;flags: UCHAR; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // флаги</div><div class="code_line">&nbsp;&nbsp; &nbsp;windows: USHORT; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// размер окна</div><div class="code_line">&nbsp;&nbsp; &nbsp;checksum: USHORT; &nbsp; &nbsp; &nbsp; &nbsp; // контрольная сумма</div><div class="code_line">&nbsp;&nbsp; &nbsp;urgentPointer: USHORT; &nbsp; &nbsp;// срочность</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;PTCPHeader = ^TTCPHeader;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// udp заголовок</div><div class="code_line">&nbsp;&nbsp;// Более подробно в RFC 768</div><div class="code_line">&nbsp;&nbsp;// http://rtfm.vn.ua/inet/prot/rfc768r.html</div><div class="code_line">&nbsp;&nbsp;TUDPHeader = packed record</div><div class="code_line">&nbsp;&nbsp; &nbsp;sourcePort: &nbsp; &nbsp; &nbsp; USHORT; &nbsp;// порт отправителя</div><div class="code_line">&nbsp;&nbsp; &nbsp;destinationPort: &nbsp;USHORT; &nbsp;// порт назначения</div><div class="code_line">&nbsp;&nbsp; &nbsp;len: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;USHORT; &nbsp;// длина пакета</div><div class="code_line">&nbsp;&nbsp; &nbsp;checksum: &nbsp; &nbsp; &nbsp; &nbsp; USHORT; &nbsp;// контрольная сумма</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;PUDPHeader = ^TUDPHeader;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// ICMP заголовок</div><div class="code_line">&nbsp;&nbsp;// Более подробно в RFC 792</div><div class="code_line">&nbsp;&nbsp;// http://rtfm.vn.ua/inet/prot/rfc792r.html</div><div class="code_line">&nbsp;&nbsp;TICMPHeader = packed record</div><div class="code_line">&nbsp;&nbsp; IcmpType &nbsp; &nbsp; &nbsp;: BYTE; &nbsp; &nbsp; &nbsp;// Тип пакета</div><div class="code_line">&nbsp;&nbsp; IcmpCode &nbsp; &nbsp; &nbsp;: BYTE; &nbsp; &nbsp; &nbsp;// Код пакета</div><div class="code_line">&nbsp;&nbsp; IcmpChecksum &nbsp;: WORD;</div><div class="code_line">&nbsp;&nbsp; IcmpId &nbsp; &nbsp; &nbsp; &nbsp;: WORD;</div><div class="code_line">&nbsp;&nbsp; IcmpSeq &nbsp; &nbsp; &nbsp; : WORD;</div><div class="code_line">&nbsp;&nbsp; IcmpTimestamp : DWORD;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;PICMPHeader = ^TICMPHeader;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Структуры для выполнения GetAdaptersInfo</div><div class="code_line">&nbsp;&nbsp;IP_ADDRESS_STRING = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;S: array [0..15] of Char;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;IP_MASK_STRING = IP_ADDRESS_STRING;</div><div class="code_line">&nbsp;&nbsp;PIP_MASK_STRING = ^IP_MASK_STRING;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;PIP_ADDR_STRING = ^IP_ADDR_STRING;</div><div class="code_line">&nbsp;&nbsp;IP_ADDR_STRING = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;Next: PIP_ADDR_STRING;</div><div class="code_line">&nbsp;&nbsp; &nbsp;IpAddress: IP_ADDRESS_STRING;</div><div class="code_line">&nbsp;&nbsp; &nbsp;IpMask: IP_MASK_STRING;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Context: DWORD;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;PIP_ADAPTER_INFO = ^IP_ADAPTER_INFO;</div><div class="code_line">&nbsp;&nbsp;IP_ADAPTER_INFO = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;Next: PIP_ADAPTER_INFO;</div><div class="code_line">&nbsp;&nbsp; &nbsp;ComboIndex: DWORD;</div><div class="code_line">&nbsp;&nbsp; &nbsp;AdapterName: array [0..MAX_ADAPTER_NAME_LENGTH + 3] of Char;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Description: array [0..MAX_ADAPTER_DESCRIPTION_LENGTH + 3] of Char;</div><div class="code_line">&nbsp;&nbsp; &nbsp;AddressLength: UINT;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Address: array [0..MAX_ADAPTER_ADDRESS_LENGTH - 1] of BYTE;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Index: DWORD;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Type_: UINT;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DhcpEnabled: UINT;</div><div class="code_line">&nbsp;&nbsp; &nbsp;CurrentIpAddress: PIP_ADDR_STRING;</div><div class="code_line">&nbsp;&nbsp; &nbsp;IpAddressList: IP_ADDR_STRING;</div><div class="code_line">&nbsp;&nbsp; &nbsp;GatewayList: IP_ADDR_STRING;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DhcpServer: IP_ADDR_STRING;</div><div class="code_line">&nbsp;&nbsp; &nbsp;HaveWins: BOOL;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PrimaryWinsServer: IP_ADDR_STRING;</div><div class="code_line">&nbsp;&nbsp; &nbsp;SecondaryWinsServer: IP_ADDR_STRING;</div><div class="code_line">&nbsp;&nbsp; &nbsp;LeaseObtained: time_t;</div><div class="code_line">&nbsp;&nbsp; &nbsp;LeaseExpires: time_t;</div><div class="code_line">&nbsp;&nbsp;end; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Поток сниффера</div><div class="code_line">&nbsp;&nbsp;TSnifferThread = class(TThread)</div><div class="code_line">&nbsp;&nbsp;private</div><div class="code_line">&nbsp;&nbsp; &nbsp;WSA: TWSAData;</div><div class="code_line">&nbsp;&nbsp; &nbsp;hSocket: TSocket;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Addr_in: sockaddr_in;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Packet: array[0..MAX_PACKET_SIZE - 1] of Byte;</div><div class="code_line">&nbsp;&nbsp; &nbsp;LogData: String;</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure ShowPacket;</div><div class="code_line">&nbsp;&nbsp;protected</div><div class="code_line">&nbsp;&nbsp; &nbsp;function InitSocket: Boolean; virtual;</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure DeInitSocket(const ExitCode: Integer); virtual;</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure Execute; override;</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure ParcePacket(const PacketSize: Word); virtual;</div><div class="code_line">&nbsp;&nbsp;public</div><div class="code_line">&nbsp;&nbsp; &nbsp;Host: String;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;TfrmMain = class(TForm)</div><div class="code_line">&nbsp;&nbsp; &nbsp;btnStartStop: TButton;</div><div class="code_line">&nbsp;&nbsp; &nbsp;memReport: TMemo;</div><div class="code_line">&nbsp;&nbsp; &nbsp;cbInterfaces: TComboBox;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Label1: TLabel;</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure FormCreate(Sender: TObject);</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure btnStartStopClick(Sender: TObject);</div><div class="code_line">&nbsp;&nbsp;private</div><div class="code_line">&nbsp;&nbsp; &nbsp;TotalPacketCount: Integer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;FSnifferThread: TSnifferThread;</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure ReadLanInterfaces;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// При помощи данной функции мы определим наличие сетевых интерфейсов</div><div class="code_line">&nbsp;&nbsp;// на локальном компьютере и информацию о них</div><div class="code_line">&nbsp;&nbsp;function GetAdaptersInfo(pAdapterInfo: PIP_ADAPTER_INFO;</div><div class="code_line">&nbsp;&nbsp; &nbsp;var pOutBufLen: ULONG): DWORD; stdcall; external IPHelper;</div><div class="code_line">&nbsp;</div><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp;// Размеры используемых структур</div><div class="code_line">&nbsp;&nbsp;IPHeaderSize = SizeOf(TIPHeader);</div><div class="code_line">&nbsp;&nbsp;ICMPHeaderSize = SizeOf(TICMPHeader);</div><div class="code_line">&nbsp;&nbsp;TCPHeaderSize = SizeOf(TTCPHeader);</div><div class="code_line">&nbsp;&nbsp;UDPHeaderSize = SizeOf(TUDPHeader);</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;frmMain: TfrmMain;</div><div class="code_line">&nbsp;</div><div class="code_line">implementation</div><div class="code_line">&nbsp;</div><div class="code_line">{$R *.dfm}</div><div class="code_line">&nbsp;</div><div class="code_line">{ TSnifferThread }</div><div class="code_line">&nbsp;</div><div class="code_line">// Инициализация слушающего сокета</div><div class="code_line">function TSnifferThread.InitSocket: Boolean;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;PromiscuousMode: Integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// инициализируем WinSock</div><div class="code_line">&nbsp;&nbsp;Result := WSAStartup(WSA_VER, WSA) = NOERROR;</div><div class="code_line">&nbsp;&nbsp;if not Result then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;LogData := &#39;Ошибка: &#39; + SysErrorMessage(WSAGetLastError);</div><div class="code_line">&nbsp;&nbsp; &nbsp;Synchronize(ShowPacket);</div><div class="code_line">&nbsp;&nbsp; &nbsp;Exit;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;// создаем сокет</div><div class="code_line">&nbsp;&nbsp;hSocket := socket(AF_INET, SOCK_RAW, IPPROTO_IP);</div><div class="code_line">&nbsp;&nbsp;if hSocket = INVALID_SOCKET then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;DeInitSocket(WSAGetLastError);</div><div class="code_line">&nbsp;&nbsp; &nbsp;Exit;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;FillChar(Addr_in, SizeOf(sockaddr_in), 0);</div><div class="code_line">&nbsp;&nbsp;Addr_in.sin_family:= AF_INET;</div><div class="code_line">&nbsp;&nbsp;// указываем за каким интерфейсом будем следить</div><div class="code_line">&nbsp;&nbsp;Addr_in.sin_addr.s_addr := inet_addr(PChar(Host));</div><div class="code_line">&nbsp;&nbsp;// связываем сокет с локальным адресом</div><div class="code_line">&nbsp;&nbsp;if bind(hSocket, Addr_in, SizeOf(sockaddr_in)) &#60;&#62; 0 then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;DeInitSocket(WSAGetLastError);</div><div class="code_line">&nbsp;&nbsp; &nbsp;Exit;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;// Переключаем интерфейс на прием всех пакетов проходящих через интерфейс - promiscuous mode.</div><div class="code_line">&nbsp;&nbsp;PromiscuousMode := 1;</div><div class="code_line">&nbsp;&nbsp;if ioctlsocket(hSocket, SIO_RCVALL, PromiscuousMode) &#60;&#62; 0 then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;DeInitSocket(WSAGetLastError);</div><div class="code_line">&nbsp;&nbsp; &nbsp;Exit;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;Result := True;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// Завершение работы сокета</div><div class="code_line">procedure TSnifferThread.DeInitSocket(const ExitCode: Integer);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// Если была ошибка - выводим ее</div><div class="code_line">&nbsp;&nbsp;if ExitCode &#60;&#62; 0 then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;LogData := &#39;Ошибка: &#39; + SysErrorMessage(ExitCode);</div><div class="code_line">&nbsp;&nbsp; &nbsp;Synchronize(ShowPacket);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;// Закрываем сокет</div><div class="code_line">&nbsp;&nbsp;if hSocket &#60;&#62; INVALID_SOCKET then closesocket(hSocket);</div><div class="code_line">&nbsp;&nbsp;// Деинициализируем WinSock</div><div class="code_line">&nbsp;&nbsp;WSACleanup;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// Рабочая процедура потока сниффера</div><div class="code_line">procedure TSnifferThread.Execute;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;PacketSize: Integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// Производим инициализацию</div><div class="code_line">&nbsp;&nbsp;if InitSocket then</div><div class="code_line">&nbsp;&nbsp;try</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Крутим поток до упора</div><div class="code_line">&nbsp;&nbsp; &nbsp;while not Terminated do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Ждем получения пакета (блокирующий режим)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;PacketSize := recv(hSocket, Packet, MAX_PACKET_SIZE, 0);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Если есть данные - производим их разбор</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if PacketSize &#62; SizeOf(TIPHeader) then ParcePacket(PacketSize);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;finally</div><div class="code_line">&nbsp;&nbsp; &nbsp;// В конце освобождаем занятые ресурсы</div><div class="code_line">&nbsp;&nbsp; &nbsp;DeInitSocket(NO_ERROR);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// Процедура разборки пакета</div><div class="code_line">procedure TSnifferThread.ParcePacket(const PacketSize: Word);</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;IPHeader: TIPHeader;</div><div class="code_line">&nbsp;&nbsp;ICMPHeader: TICMPHeader;</div><div class="code_line">&nbsp;&nbsp;TCPHeader: TTCPHeader;</div><div class="code_line">&nbsp;&nbsp;UDPHeader: TUDPHeader;</div><div class="code_line">&nbsp;&nbsp;SrcPort, DestPort: Word;</div><div class="code_line">&nbsp;&nbsp;I, Octets, PartOctets: Integer;</div><div class="code_line">&nbsp;&nbsp;PacketType, DumpData, ExtendedInfo: String;</div><div class="code_line">&nbsp;&nbsp;Addr, A, B: TInAddr;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Inc(frmMain.TotalPacketCount);</div><div class="code_line">&nbsp;&nbsp;// Читаем из буфера IP заголовок</div><div class="code_line">&nbsp;&nbsp;Move(Packet[0], IPHeader, IPHeaderSize);</div><div class="code_line">&nbsp;&nbsp;// Пишем время жизни пакета</div><div class="code_line">&nbsp;&nbsp;LogData := LOG_STR_0 +</div><div class="code_line">&nbsp;&nbsp; &nbsp;Format(LOG_STR_1, [frmMain.TotalPacketCount, IPHeader.iph_ttl]);</div><div class="code_line">&nbsp;&nbsp;SrcPort := 0;</div><div class="code_line">&nbsp;&nbsp;DestPort := 0;</div><div class="code_line">&nbsp;&nbsp;ExtendedInfo := &#39;&#39;;</div><div class="code_line">&nbsp;&nbsp;// определяем тип протокола</div><div class="code_line">&nbsp;&nbsp;case IPHeader.iph_protocol of</div><div class="code_line">&nbsp;&nbsp; &nbsp;IPPROTO_ICMP: // ICMP</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;PacketType := &#39;ICMP&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Читаем ICMP заголовок</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Move(Packet[IPHeaderSize], ICMPHeader, ICMPHeaderSize);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Смотрим тип пакета</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;case ICMPHeader.IcmpCode of</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ICMP_ECHO: ExtendedInfo := Format(LOG_STR_6, [&#39;Echo&#39;]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ICMP_ECHOREPLY: ExtendedInfo := Format(LOG_STR_6, [&#39;Echo reply&#39;]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ExtendedInfo := Format(LOG_STR_6, [&#39;Unknown&#39;]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;IPPROTO_TCP: // TCP</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;PacketType := &#39;TCP&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Читаем ТСР заголовок</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Move(Packet[IPHeaderSize], TCPHeader, TCPHeaderSize);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Смотрим порт отправителя и получателя</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;SrcPort := TCPHeader.sourcePort;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;DestPort := TCPHeader.destinationPort;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;IPPROTO_UDP: // UDP</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;PacketType := &#39;UDP&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Читаем UDP заголовок</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Move(Packet[IPHeaderSize], UDPHeader, UDPHeaderSize);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Смотрим порт отправителя и получателя</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;SrcPort := UDPHeader.sourcePort;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;DestPort := UDPHeader.destinationPort;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;PacketType := &#39;Unsupported (0x&#39; + IntToHex(IPHeader.iph_protocol, 2) + &#39;)&#39;;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;// Пишем размер пакета</div><div class="code_line">&nbsp;&nbsp;LogData := LogData + Format(LOG_STR_2, [PacketSize, PacketType]);</div><div class="code_line">&nbsp;&nbsp;if ExtendedInfo &#60;&#62; &#39;&#39; then</div><div class="code_line">&nbsp;&nbsp; &nbsp;LogData := LogData + ExtendedInfo;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Пишем IP адрес отправителя с портом</div><div class="code_line">&nbsp;&nbsp;Addr.S_addr := IPHeader.iph_src;</div><div class="code_line">&nbsp;&nbsp;LogData := LogData + Format(LOG_STR_3, [inet_ntoa(Addr), htons(SrcPort)]);</div><div class="code_line">&nbsp;&nbsp;// Пишем IP адрес получателя с портом</div><div class="code_line">&nbsp;&nbsp;Addr.S_addr := IPHeader.iph_dest;</div><div class="code_line">&nbsp;&nbsp;LogData := LogData + Format(LOG_STR_4, [inet_ntoa(Addr), htons(DestPort)]) + LOG_STR_7;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Выводим содержимое пакета на экран (парсинг комментировать не буду, там все просто)</div><div class="code_line">&nbsp;&nbsp;// получается что-то вроде этого:</div><div class="code_line">&nbsp;&nbsp;//</div><div class="code_line">&nbsp;&nbsp;// ------------------------------ Packet dump -----------------------------------</div><div class="code_line">&nbsp;&nbsp;// 000000 45 00 00 4E D8 91 00 00 | 80 11 DB 3B C0 A8 02 82 &nbsp; &nbsp; E..N.......;....</div><div class="code_line">&nbsp;&nbsp;// 000010 C0 A8 02 FF 00 89 00 89 | 00 3A AC 6A 83 BD 01 10 &nbsp; &nbsp; .........:.j....</div><div class="code_line">&nbsp;&nbsp;// 000020 00 01 00 00 00 00 00 00 | 20 45 43 46 46 45 49 44 &nbsp; &nbsp; ........ ECFFEID</div><div class="code_line">&nbsp;&nbsp;// 000030 44 43 41 43 41 43 41 43 | 41 43 41 43 41 43 41 43 &nbsp; &nbsp; DCACACACACACACAC</div><div class="code_line">&nbsp;&nbsp;// 000040 41 43 41 43 41 43 41 43 | 41 00 00 20 00 01 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ACACACACA.. ..</div><div class="code_line">&nbsp;&nbsp;I := 0;</div><div class="code_line">&nbsp;&nbsp;Octets := 0;</div><div class="code_line">&nbsp;&nbsp;PartOctets := 0;</div><div class="code_line">&nbsp;&nbsp;while I &#60; PacketSize do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;case PartOctets of</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;0: LogData := LogData + Format(&#39;%.6d &#39;, [Octets]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;9: LogData := LogData + &#39;| &#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;18:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Inc(Octets, 10);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;PartOctets := -1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;LogData := LogData + &#39; &nbsp; &nbsp;&#39; + DumpData + sLineBreak;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;DumpData := &#39;&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;LogData := LogData + Format(&#39;%s &#39;, [IntToHex(Packet[I], 2)]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if Packet[I] in [..F] then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DumpData := DumpData + Chr(Packet[I])</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DumpData := DumpData + &#39;.&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Inc(I);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Inc(PartOctets);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;if PartOctets &#60;&#62; 0 then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;PartOctets := (16 - Length(DumpData)) * 3;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if PartOctets &#62;= 24 then Inc(PartOctets, 2);</div><div class="code_line">&nbsp;&nbsp; &nbsp;Inc(PartOctets, 4);</div><div class="code_line">&nbsp;&nbsp; &nbsp;LogData := LogData + StringOfChar(&#39; &#39;, PartOctets) +</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;DumpData + sLineBreak + sLineBreak</div><div class="code_line">&nbsp;&nbsp;end</div><div class="code_line">&nbsp;&nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;LogData := LogData + sLineBreak + sLineBreak;</div><div class="code_line">&nbsp;&nbsp;// Выводим все что напарсерили в Memo</div><div class="code_line">&nbsp;&nbsp;Synchronize(ShowPacket);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure TSnifferThread.ShowPacket;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;frmMain.memReport.Lines.BeginUpdate;</div><div class="code_line">&nbsp;&nbsp;frmMain.memReport.Text :=</div><div class="code_line">&nbsp;&nbsp; &nbsp;frmMain.memReport.Text + sLineBreak + LogData;</div><div class="code_line">&nbsp;&nbsp;SendMessage(frmMain.memReport.Handle, WM_VSCROLL, SB_BOTTOM, 0);</div><div class="code_line">&nbsp;&nbsp;frmMain.memReport.Lines.EndUpdate;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TfrmMain }</div><div class="code_line">&nbsp;</div><div class="code_line">procedure TfrmMain.FormCreate(Sender: TObject);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;TotalPacketCount := 0;</div><div class="code_line">&nbsp;&nbsp;ReadLanInterfaces;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// Читаем все IP адреса со всех присутствующих</div><div class="code_line">// в системе сетевых интерфейсов</div><div class="code_line">procedure TfrmMain.ReadLanInterfaces;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;InterfaceInfo,</div><div class="code_line">&nbsp;&nbsp;TmpPointer: PIP_ADAPTER_INFO;</div><div class="code_line">&nbsp;&nbsp;IP: PIP_ADDR_STRING;</div><div class="code_line">&nbsp;&nbsp;Len: ULONG;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// Смотрим сколько памяти нам требуется?</div><div class="code_line">&nbsp;&nbsp;if GetAdaptersInfo(nil, Len) = ERROR_BUFFER_OVERFLOW then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Берем нужное кол-во</div><div class="code_line">&nbsp;&nbsp; &nbsp;GetMem(InterfaceInfo, Len);</div><div class="code_line">&nbsp;&nbsp; &nbsp;try</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// выполнение функции</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if GetAdaptersInfo(InterfaceInfo, Len) = ERROR_SUCCESS then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Перечисляем все сетевые интерфейсы</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TmpPointer := InterfaceInfo;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// перечисляем все IP адреса каждого интерфейса</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IP := @TmpPointer.IpAddressList;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbInterfaces.Items.Add(Format(&#39;%s - [%s]&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[IP^.IpAddress.S, TmpPointer.Description]));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IP := IP.Next;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;until IP = nil;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TmpPointer := TmpPointer.Next;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;until TmpPointer = nil;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;finally</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Освобождаем занятую память</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;FreeMem(InterfaceInfo);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;// Смотрим - можем ли мы продолжать работу программы?</div><div class="code_line">&nbsp;&nbsp;if cbInterfaces.Items.Count = 0 then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;memReport.Text := &#39;Сетевые интерфейсы не обнаружены.&#39; + sLineBreak +</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;&#39;Продолжение работы программы не возможно.&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;btnStartStop.Enabled := False;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Exit;</div><div class="code_line">&nbsp;&nbsp;end</div><div class="code_line">&nbsp;&nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;cbInterfaces.ItemIndex := 0;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// Запуск остановка потока</div><div class="code_line">procedure TfrmMain.btnStartStopClick(Sender: TObject);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;if FSnifferThread &#60;&#62; nil then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;FSnifferThread.Terminate;</div><div class="code_line">&nbsp;&nbsp; &nbsp;FSnifferThread := nil;</div><div class="code_line">&nbsp;&nbsp; &nbsp;btnStartStop.Caption := &#39;Start&#39;;</div><div class="code_line">&nbsp;&nbsp;end</div><div class="code_line">&nbsp;&nbsp;else</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;FSnifferThread := TSnifferThread.Create(True);</div><div class="code_line">&nbsp;&nbsp; &nbsp;FSnifferThread.Host := Copy(cbInterfaces.Text, 1, Pos(&#39; &#39;, cbInterfaces.Text));</div><div class="code_line">&nbsp;&nbsp; &nbsp;FSnifferThread.FreeOnTerminate := True;</div><div class="code_line">&nbsp;&nbsp; &nbsp;FSnifferThread.Resume;</div><div class="code_line">&nbsp;&nbsp; &nbsp;btnStartStop.Caption := &#39;Stop&#39;;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">end.</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
<br>
Проект также доступен по адресу: http://rouse.drkb.ru/network.php#sniffer]]></description>
        <author>Rouse_</author>
        <category>Интернет, сети, протоколы</category>
      </item>
	
      </channel>
      </rss>
	