title: Delphi hook to redirect to different ip
body: <p>What is the best way to redirect ANY browser to a different ip for specific sites?
  For example if the user will type www.facebook.com in any browser he will be redirected to 127.0.0.1. Also the same should happen if he will type 66.220.146.11.</p>
  
  <p>What I have until now is this:
  using the <a href="http://ntkernel.com/w&amp;p.php?id=7" rel="nofollow noreferrer">winpkfilter</a> I am able to intercept all the traffic on port 80, with type(in or out), source ip, destination ip and packet. My problem is to modify somehow the packet so the browser will be redirected. </p>
  
  <p>This is the code that i have right now:</p>
  
  <pre><code>program Pass;
  
  {$APPTYPE CONSOLE}
  
  uses
    SysUtils,
    Windows,
    Winsock,
    winpkf,
    iphlp;
  
  var
    iIndex, counter : DWORD;
    hFilt : THANDLE;
    Adapts : TCP_AdapterList;
    AdapterMode : ADAPTER_MODE;
    Buffer, ParsedBuffer : INTERMEDIATE_BUFFER;
    ReadRequest : ETH_REQUEST;
    hEvent : THANDLE;
    hAdapter : THANDLE;
    pEtherHeader : TEtherHeaderPtr;
    pIPHeader : TIPHeaderPtr;
    pTcpHeader : TTCPHeaderPtr;
    pUdpHeader : TUDPHeaderPtr;
    SourceIP, DestIP : TInAddr;
  
    thePacket : PChar;
  
    f : TextFile;
  
    SourceIpString, DestinationIpString : string;
    SourceName, DestinationName : string;
  
  function IPAddrToName(IPAddr : string) : string;
  var
    SockAddrIn : TSockAddrIn;
    HostEnt : PHostEnt;
    WSAData : TWSAData;
  begin
    WSAStartup($101, WSAData);
    SockAddrIn.sin_addr.s_addr := inet_addr(PChar(IPAddr));
    HostEnt := gethostbyaddr(@SockAddrIn.sin_addr.S_addr, 4, AF_INET);
    if HostEnt &lt;&gt; nil then
      begin
        result := StrPas(Hostent^.h_name)
      end
    else
      begin
        result := '';
      end;
  end;
  
  procedure ReleaseInterface();
  begin
    // Restore default mode
    AdapterMode.dwFlags := 0;
    AdapterMode.hAdapterHandle := hAdapter;
    SetAdapterMode(hFilt, @AdapterMode);
  
    // Set NULL event to release previously set event object
    SetPacketEvent(hFilt, hAdapter, 0);
  
    // Close Event
    if hEvent &lt;&gt; 0 then
      CloseHandle(hEvent);
  
    // Close driver object
    CloseFilterDriver(hFilt);
  
    // Release NDISAPI
    FreeNDISAPI();
  end;
  
  begin
  
    // Check the number of parameters
    if ParamCount() &lt; 2 then
      begin
        Writeln('Command line syntax:');
        Writeln('   PassThru.exe index num');
        Writeln('   index - network interface index.');
        Writeln('   num - number or packets to filter');
        Writeln('You can use ListAdapters to determine correct index.');
        Exit;
      end;
  
    // Initialize NDISAPI
    InitNDISAPI();
  
    // Create driver object
    hFilt := OpenFilterDriver('NDISRD');
  
    if IsDriverLoaded(hFilt) then
      begin
  
        // Get parameters from command line
        iIndex := StrToInt(ParamStr(1));
        counter := StrToInt(ParamStr(2));
  
        // Set exit procedure
        ExitProcessProc := ReleaseInterface;
  
        // Get TCP/IP bound interfaces
        GetTcpipBoundAdaptersInfo(hFilt, @Adapts);
  
        // Check paramer values
        if iIndex &gt; Adapts.m_nAdapterCount then
          begin
            Writeln('There is no network interface with such index on this system.');
            Exit;
          end;
  
        hAdapter := Adapts.m_nAdapterHandle[iIndex];
  
        AdapterMode.dwFlags := MSTCP_FLAG_SENT_TUNNEL or MSTCP_FLAG_RECV_TUNNEL;
        AdapterMode.hAdapterHandle := hAdapter;
  
        // Create notification event
        hEvent := CreateEvent(nil, TRUE, FALSE, nil);
  
        if hEvent &lt;&gt; 0 then
          if SetPacketEvent(hFilt, hAdapter, hEvent) &lt;&gt; 0 then
            begin
              // Initialize request
              ReadRequest.EthPacket.Buffer := @Buffer;
              ReadRequest.hAdapterHandle := hAdapter;
  
              SetAdapterMode(hFilt, @AdapterMode);
              counter := 0;
              //while counter &lt;&gt; 0 do
              while true do
                begin
                  WaitForSingleObject(hEvent, INFINITE);
                  while ReadPacket(hFilt, @ReadRequest) &lt;&gt; 0 do
                    begin
                      //dec(counter);
  
                      pEtherHeader := TEtherHeaderPtr(@Buffer.m_IBuffer);
  
                      if ntohs(pEtherHeader.h_proto) = ETH_P_IP then
                        begin
                          pIPHeader := TIPHeaderPtr(Integer(pEtherHeader) +
                            SizeOf(TEtherHeader));
                          SourceIP.S_addr := pIPHeader.SourceIp;
                          DestIP.S_addr := pIPHeader.DestIp;
                          if pIPHeader.Protocol = IPPROTO_TCP then
                            begin
                              pTcpHeader := TTCPHeaderPtr(Integer(pIPHeader) +
                                (pIPHeader.VerLen and $F) * 4);
                              if (pTcpHeader.SourcePort = htons(80)) or
                                (pTcpHeader.DestPort = htons(80)) then
                                begin
                                  inc(counter);
                                  if Buffer.m_dwDeviceFlags = PACKET_FLAG_ON_SEND
                                    then
                                    Writeln(counter, ') - MSTCP --&gt; Interface')
                                  else
                                    Writeln(counter, ') - Interface --&gt; MSTCP');
                                  Writeln('     Packet size =    ',
                                    Buffer.m_Length);
                                  Writeln(Format('     IP %.3u.%.3u.%.3u.%.3u --&gt; %.3u.%.3u.%.3u.%.3u PROTOCOL: %u',
                                    [byte(SourceIP.S_un_b.s_b1),
                                    byte(SourceIP.S_un_b.s_b2),
                                      byte(SourceIP.S_un_b.s_b3),
                                      byte(SourceIP.S_un_b.s_b4),
                                      byte(DestIP.S_un_b.s_b1),
                                      byte(DestIP.S_un_b.s_b2),
                                      byte(DestIP.S_un_b.s_b3),
                                      byte(DestIP.S_un_b.s_b4),
                                      byte(pIPHeader.Protocol)]
                                      ));
                                  Writeln(Format('     TCP SRC PORT: %d DST PORT: %d',
                                    [ntohs(pTcpHeader.SourcePort),
                                    ntohs(pTcpHeader.DestPort)]));
  
                                  //get the data
                                  thePacket := pchar(pEtherHeader) +
                                    (sizeof(TEtherHeaderPtr) + pIpHeader.VerLen * 4
                                    + pTcpHeader.Offset * 4);
                                  {
                                  SourceIpString :=
                                    IntToStr(byte(SourceIP.S_un_b.s_b1)) + '.' +
                                    IntToStr(byte(SourceIP.S_un_b.s_b2)) + '.' +
                                    IntToStr(byte(SourceIP.S_un_b.s_b3)) + '.' +
                                    IntToStr(byte(SourceIP.S_un_b.s_b4));
                                  DestinationIpString :=
                                    IntToStr(byte(DestIP.S_un_b.s_b1)) + '.' +
                                    IntToStr(byte(DestIP.S_un_b.s_b2)) + '.' +
                                    IntToStr(byte(DestIP.S_un_b.s_b3)) + '.' +
                                    IntToStr(byte(DestIP.S_un_b.s_b4));
                                  }
  
                                end;
                            end;
  
                        end;
  
                      // if ntohs(pEtherHeader.h_proto) = ETH_P_RARP then
                      //   Writeln('     Reverse Addr Res packet');
  
                      // if ntohs(pEtherHeader.h_proto) = ETH_P_ARP then
                      //   Writeln('     Address Resolution packet');
  
                      //Writeln('__');
  
                      if Buffer.m_dwDeviceFlags = PACKET_FLAG_ON_SEND then
                        // Place packet on the network interface
                        SendPacketToAdapter(hFilt, @ReadRequest)
                      else
                        // Indicate packet to MSTCP
                        SendPacketToMstcp(hFilt, @ReadRequest);
                      {
                      if counter = 0 then
                        begin
                          Writeln('Filtering complete');
                          readln;
                          break;
                        end;
                      }
                    end;
                  ResetEvent(hEvent);
                end;
            end;
      end;
  end.
  </code></pre>