Вопрос

My testing environment

client

  • IP 192.168.0.2/24
  • gateway 192.168.0.1

server

  • IP 192.168.0.1/24
  • http service run on port 80

When I try getting web page hosted on server, everything goes fine.

Then I write a kernel module using netfilter on server, which will change dest IP to 192.168.0.1 if the origin dest IP is 192.168.1.1, and will change source IP to 192.168.1.1 if origin source IP is 192.168.0.1. I think you can understand that I'm just pretending the server to be 192.168.1.1 for the client.(IP header Checksum and TCP Checksum are changed properly)

I use the web browser(chrome, firefox...) on client to visit 192.168.1.1 and capture the packets on the client, results are like:

192.168.0.2:someport_1 -> 192.168.1.1:80 [SYN]
192.168.1.1:80 -> 192.168.0.2:someport_1 [SYN, ACK]
192.168.0.2:someport_2 -> 192.168.1.1:80 [SYN]
192.168.1.1:80 -> 192.168.0.2:someport_2 [SYN, ACK]
192.168.0.2:someport_3 -> 192.168.1.1:80 [SYN]
192.168.1.1:80 -> 192.168.0.2:someport_3 [SYN, ACK]

I don't know why the client will never send the last ACK of TCP handshaking, any ideas?

Edit1:

Now I think that the browser didn't get the [SYN, ACK] packet from the server although wireshark can see it, so maybe it's because that the OS(Windows7) dropped the [SYN, ACK] packet from the server. Now the question becomes that why would windows drop a correct [SYN, ACK] packet?

Это было полезно?

Решение 2

I've made three mistakes.

The first one is that skb can be nonlinear, which will cause the checksum got from csum_partial() be incorrect.

The second one is that I use csum_tcpudp_magic() to get the checksum, but forgot to change skb->ip_summed, so the NIC will use my correct checksum as the partial checksum of tcp pseudo-header to recalculate the checksum, leading checksum incorrect in the packet.

The third mistake is that my wireshark seems to be set to ignore the tcp checksum, and it always shows the packets with wrong checksum as good ones, while tcpdump will tell me incorrect checksums.

Другие советы

You said the IP checksum is OK, but what about the TCP checksum, which is computed from a pseudo-header which includes source and destination IP ?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top