Тема: Сниффер
Показать сообщение отдельно
Старый 23.06.2010, 00:24   #73
user456
Новичок
 
Регистрация: 31.03.2010
Сообщений: 22
Сказал(а) спасибо: 2
Поблагодарили 23 раз(а) в 8 сообщениях
user456 На верном пути
По умолчанию обработка пакетов

Вот собсно raw сокеты в 2-х словах. Код на Дельфи, но винапи он и в Африке винапи. PChar соответственно в си char*. Элементарного типа WSAStartup не касаюсь.
Инициализация
Код:
//декларация обработки ивента
const
  WM_ListenSocketEvent = WM_User+1;
....
procedure WMListenSocketEventHandler(var Msg:TMessage);message WM_ListenSocketEvent;

....

function TfrmMain.InitSocket: Boolean;
var
  PromiscuousMode: dword;
  temp: integer;
  BufSize: dword;
begin
     result:=false;
     // создаем сокет
     hSocket := socket(AF_INET, SOCK_RAW, IPPROTO_IP);
     if hSocket = INVALID_SOCKET then begin
        DeInitSocket(WSAGetLastError);
        AddToLog('Raw sockets not supported');
        Exit;
     end;
     FillChar(Addr_in, SizeOf(sockaddr_in), 0);
     Addr_in.sin_family:= AF_INET;
     // указываем за каким интерфейсом будем следить
     Addr_in.sin_addr.s_addr := inet_addr(PChar(Host));
     // связываем сокет с локальным адресом
     if ScktErrorCheck(bind(hSocket, @Addr_in, SizeOf(sockaddr_in))) = SOCKET_ERROR then exit;
     BufSize:=MAX_PACKET_SIZE;
     if ScktErrorCheck(SetSockOpt(hSocket, SOL_SOCKET, SO_RCVBUF, PChar(@BufSize), sizeof(BufSize))) = SOCKET_ERROR then exit;
     temp:=sizeof(integer);
     if ScktErrorCheck(GetSockOpt(hSocket, SOL_SOCKET, SO_RCVBUF, PChar(@BufSize), temp)) = SOCKET_ERROR then exit
     else AddToLog('Buffer size = '+IntToHex(BufSize,4));
     if ScktErrorCheck(WSAAsyncSelect(hSocket,frmMain.Handle,WM_ListenSocketEvent,FD_READ or FD_CLOSE)) = SOCKET_ERROR then exit;

     // Переключаем интерфейс на прием всех пакетов проходящих через интерфейс - promiscuous mode.
     PromiscuousMode := 1;
     if ScktErrorCheck(ioctlsocket(hSocket, SIO_RCVALL, PromiscuousMode)) = SOCKET_ERROR then exit;
     Result := True;
end;
обработчик ивента
Код:
procedure TfrmMain.WMListenSocketEventHandler(var Msg:TMessage);
var
   Sock: TSocket;
   SockError,PacketSize: integer;
begin
     Sock:=TSocket(Msg.WParam);
     SockError:=WSAGetSelectError(Msg.lParam);
     if SockError <> 0 then begin
        CloseSocket(Sock);
        Exit;
     end;
     case WSAGetSelectEvent(Msg.lParam) of
          FD_Read:   begin
             CS.Enter;
             PacketSize := recv(hSocket, Packet, MAX_PACKET_SIZE, 0);
             // Если есть данные - производим их разбор
             ParcePacket(PacketSize);
             CS.Leave;
          end;
          FD_Close: begin
             AddToLog('FD_CLOSE');
          end;
     end;
end;
далее разбор пакета
Код:
     if PacketSize <= SizeOf(TIPHeader) then exit;

     pIpHdr:=PIPHeader(@Packet[0]);
     ipHdrLen:=GetIPHeaderLen(pIpHdr);
     pTcpHdr:=PTCPHeader(@Packet[ipHdrLen]);
     // определяем тип протокола
     if pIpHdr.iph_protocol = IPPROTO_TCP then begin
         PacketType := 'TCP';
     	    // Смотрим порт отправителя и получателя
         SrcPort := pTcpHdr.sourcePort;
         DestPort := pTcpHdr.destinationPort;
     end
     else exit;

     SrcPort := htons(SrcPort);
     DestPort := htons(DestPort);
     if (SrcPort <> frmMain.FListenPort)and(DestPort <> frmMain.FListenPort) then exit;

     // Пишем IP адрес отправителя с портом
     AddrSrc.S_addr := pIpHdr.iph_src;
     // Пишем IP адрес получателя с портом
     AddrDst.S_addr := pIpHdr.iph_dest;

     tcpHdrDataOffs:=ipHdrLen + GetTCPDataOffset(@Packet[ipHdrLen]);

     PacketFlags:=ntohs(pTcpHdr.flags);
...
в общем на основе структур ip и tcp хедеров разбираем, если что читаем доку "RFC793 - Transmission Control Protocol".

продолжение ниже...
user456 вне форума   Ответить с цитированием
2 пользователя(ей) сказали cпасибо:
Konctantin (23.06.2010), zergtmn (23.06.2010)