Re-routing TCP packets

Home Forums Discussions Support Re-routing TCP packets

Viewing 15 posts - 1 through 15 (of 21 total)
  • Author
    Posts
  • #4839
    Voxen
    Participant

      Hello,

      I’m writting a filter that has to re-route outgoing POP3 packets to a local POP3 server so the mailer actually connects to the local server instead of the real one. I’m very new to TCP/IP programming.

      Here is my thread’s loop:

      // Loop filtering packets
      while (!Terminated)
      ..{
      ..WaitForSingleObject(hEvent, INFINITE);
      ..ResetEvent(hEvent);

      ..while (!Terminated && NdisApi.ReadPacket(&Request))
      ….{
      ….if (PacketBuffer.m_dwDeviceFlags == PACKET_FLAG_ON_SEND)
      ……{
      ……// Sent packet
      ……ether_header* pEthHeader = (ether_header*)PacketBuffer.m_IBuffer;
      ……if (ntohs(pEthHeader->h_proto) == ETH_P_IP)
      ……..{
      ……..// IP
      ……..iphdr_ptr pIp = (iphdr_ptr)&PacketBuffer.m_IBuffer[sizeof(ether_header)];
      ……..if (pIp->ip_p == IPPROTO_TCP)
      ……….{
      ……….// TCP
      ……….tcphdr_ptr pTcp = (tcphdr_ptr)(((PUCHAR)pIp) + sizeof(DWORD)*pIp->ip_hl);
      ……….in_addr IPs = pIp->ip_src;
      ……….in_addr IPd = pIp->ip_dst;
      ……….if (ntohs(pTcp->th_dport) == 110)
      …………{
      …………if (!strcmp(inet_ntoa(IPd), “211.182.33.20”))
      …………..{
      …………..// Change destination IP and port
      …………..pIp->ip_dst.S_un.S_addr = inet_addr(“192.168.0.3”);
      …………..pTcp->th_dport = 115;
      …………..RecalculateIPChecksum(&PacketBuffer);
      …………..RecalculateTCPChecksum(&PacketBuffer);
      …………..}
      …………}
      ……….}
      ……..}

      ……..// Place packet on the network interface
      ……..NdisApi.SendPacketToAdapter(&Request);
      ……..}
      ……else
      ……..{
      ……..// Indicate packet to MSTCP
      ……..NdisApi.SendPacketToMstcp(&Request);
      ……..}
      ……}
      ….}

      Of course this doesn’t work. All the code seems correct, because if I disable the IP and port modification, the filter runs ok (checksum calculation methods are correct).
      I belive something is missing, but what?

      Thanks for your help!

      #5521
      bk
      Participant

        Why don’t you install ethereal and check if the checksums are really correct (perhaps thew work correctly if you don’t change the data)?

        #5522
        Voxen
        Participant

          I captured the packets with Ethereal, the checksum are both correct.
          The mail client loops sending SYN but gets no reply.

          Do I need to modify the destination MAC address as well (copy source MAC address to destination)?

          #5523
          Vadim Smirnov
          Keymaster

            After outgoing packet modification I would indicate it to MSTCP instead sending it over the network.

            Hope it helps…

            #5524
            Voxen
            Participant

              You mean calling NdisApi.SendPacketToMstcp(&Request) instead of NdisApi.SendPacketToAdapter(&Request) in my example above?

              I’ve just tried this and it doesn’t work any better.
              Should I modify something else in the packet?
              Or should I switch this “sent” packet into a “receive” one?

              Sorry but I’m a bit lost…

              #5525
              bk
              Participant

                @Voxen wrote:

                Do I need to modify the destination MAC address as well (copy source MAC address to destination)?

                Yes, if the destination host is not the same machine as the original destination you need to change the mac address, unless you are using a gateway and the destination is not the gateway itself.

                If you are sending packets through a gateway, the destination MAC address should be the MAC of the gateway. If both the (original and changed) destination IP are reachable through the GW, then you should not need to change the dest MAC since the destination MAC is the same.

                But since the original IP seems to be on the internet while the new destination seems to be on the local net, you must change the MAC to the one of the new host.

                Let me explain: the MAC address is the low level address of a host on a local net. The IP address is a higher level address, and may be outside the local net.

                If you send a packet through different nets, the IP address can be the true destination across networks, while the MAC address must be the destination of the next step on the local net. As an example, suppose you have a local host with IP 192.168.0.2 and MAC address “MACa”, a local gateway with IP 192.168.0.1 and “MACb”. Your destination is an external host with IP 212.144.155.166. Since the destination is not on the local net, the packets must be routed through the local gateway. You don’t need and don’t know the real destination MAC address. You packet should then have IP destination 212.144.155.166 BUT MAC address MACb. If you change the destination IP BUT the next step along the path is still the gateway, then the MAC address is still MACb since the next step is still the GW on the local net.
                Let’s suppose that you change the destination to a local IP address, then if you don’t change the MAC address to the MAC of the new local destination the packets will still be sent to the GW, which can route the packets or throw them away, depending on how it’s configured.
                The best bet is to send the packets to the real destination host, and since it’s on the local net, you can set the correct MAC address to reach it.
                Btw, the CORRECT thing to do is to set the MAC address to the MAC of the next host along the router. Also notice that if the destination is on a different network interface, you must send the packet to the correct one.

                Suppose you have this config:

                A is connected to the internet through a local net, with gateway B
                A il also conneted to another local net, using another ethernet card, with the host C.

                If you send a packet to the internet, then your OS will use the first interface, set the IP destination to the destination host on the internet and MAC address of B, since B is the next step on the path.
                When you catch the outgoing packets with winpkfilter, then routing has already been done: the OS has already chosen the first interface, MAC of B.
                If you want to route the packet to C, then you must change the IP to the IP address of B, the MAC to the MAC address of B, AND QUEUE THE PACKET on the SECOND interface.

                #5526
                Voxen
                Participant

                  Thank you bk for this very clear explanation.

                  As I’m running both the mail client, the POP3 server and the packet filter on the same PC, I guess that what I must do is:
                  – capture the outgoing packet
                  – change its IP and port to localhost/110
                  – change its MAC address to PC’s MAC address
                  – recalculate checksums
                  – send the packet to MSTCP (as stated by SerpentFly above) and not Adapter

                  So, since the packet originator is the mail client running on the same PC, the source MAC address it the one I should set as MAC destination, right?

                  #5527
                  bk
                  Participant

                    @Voxen wrote:

                    As I’m running both the mail client, the POP3 server and the packet filter on the same PC, I guess that what I must do is:
                    – capture the outgoing packet
                    – change its IP and port to localhost/110
                    – change its MAC address to PC’s MAC address
                    – recalculate checksums
                    – send the packet to MSTCP (as stated by SerpentFly above) and not Adapter

                    So, since the packet originator is the mail client running on the same PC, the source MAC address it the one I should set as MAC destination, right?

                    Ehm, this is a kind of a special case. You can’t catch internal packets with winpkfilter, so I’m not sure you can also send localhost packets to windows that way. The steps above are correct, but I’m not sure you can inject a packet with localhost destination using winpkfilter. Windows might decide to throw your packets away.. 😕

                    #5528
                    bk
                    Participant

                      If changing to localhost does not work, try with the IP address of the ethernet card you are catching the packets from (and make up a fake source IP address if source == destination does not work). This way your packets should appear as coming from an external host to the adapter and should work.

                      #5529
                      Voxen
                      Participant

                        I’ll try that! Thanks again bk.

                        #5530
                        Voxen
                        Participant

                          Well I’ve not been able to make it work within the same machine 😥

                          I’ve been able to reroute to another PC in the local area network but it doesn’t totally work either. This is roughly what Ethereal reports:
                          PCA -> SYN -> PCB
                          PCA <- SYN/ACK <- PCB
                          PCA <- SYN/ACK <- PCB
                          PCA -> RST -> PCB (ZeroWindow)

                          #5531
                          Vadim Smirnov
                          Keymaster

                            It looks that something was wrong when processing the packets below:
                            PCA <- SYN/ACK <- PCB
                            PCA <- SYN/ACK <- PCB
                            and connection was terminated due to time out. I would try to check what happens there.

                            #5532
                            Voxen
                            Participant

                              SerpentFly, could you tell me if WinpkFilter is able to process internal packets as bk said it probably doesn’t? I need to reroute packets sent from local machine to local machine instead of Internet.

                              #5533
                              Vadim Smirnov
                              Keymaster

                                If you mean packet sent to localhost (127.X.X.X) then the answer is NO. These packets (actually they never have the form of packets with IP and TCP headers, just chunks of data) are processed internally by TCP/IP and never reach NDIS level.

                                #5534
                                bk
                                Participant

                                  Voxen, I’ve seen now your post:

                                  PCA -> SYN -> PCB
                                  PCA <- SYN/ACK <- PCB
                                  PCA <- SYN/ACK <- PCB
                                  PCA -> RST -> PCB (ZeroWindow)

                                  From what I understand, PCA does not respond to the SYN/ACK packet coming from PCB. I could help you better if you describe me exactly what you do, but I have a hint.
                                  PCA generates a packet, you change the destination and PCB receives it.
                                  PCB responds to the packet, sending the answer to PCA. But since PCA is not expeting an ACK from PCB (he thinks he’s talking with the original host you substituted) it will throw the packet away.
                                  When you receive a packet from PCB, you must reverse what you’ve done before: substitute che source from PCB to the original destination.

                                  I.e:

                                  1) PCA sends a packet to PCX. You change the destination to PCB.
                                  2) PCB answers to PCA, but PCA is expecting an answer from PCX, NOT PCB!
                                  So you must reverse the changes you’ve done in step 1, reverting the sender from PCB to PCX.

                                  I’m not sure it’s your problem, since you don’t describe exactly what you do. Btw, you are trying to NAT che packets, try reading some papers on this subject.

                                Viewing 15 posts - 1 through 15 (of 21 total)
                                • You must be logged in to reply to this topic.