oremanj/python-netfilterqueue

alter ethernet checksum?

Opened this issue · 2 comments

Colleagues, I'm using this great package to modify packets "on the fly" and found an issue.

I'm altering TCP checksum before accepting the packet. While there are no issues with TCP checksum, I see (in tcpdump) that Ethernet frame comes to remote host with incorrect checksum:

23:11:33.982227 52:54:00:b3:33:cd > 72:94:09:84:7b:4e, ethertype IPv4 (0x0800), length 84: (tos 0x0, ttl 63, id 29737, offset 0, flags [DF], proto TCP (6), length 70, bad cksum 7980 (->7972)!)
    203.0.113.2.54118 > 10.9.8.11.443: Flags [P.], cksum 0x2a12 (correct), seq 3045093885:3045093903, ack 2778531205, win 507, options [nop,nop,TS val 127397601 ecr 557607335], length 18
    0x0000:  4500 0046 7429 4000 3f06 7980 cb00 7102  E..Ft)@.?.y...q.
    0x0010:  0a09 080b d366 01bb b580 71fd a59d 0585  .....f....q.....
    0x0020:  8018 01fb 2a12 0000 0101 080a 0797 eee1  ....*...........
    0x0030:  213c 69a7 3132 330a 416c 7465 7265 6420  !<i.123.Altered.
    0x0040:  6461 7461 0a0a                           data..

Is it possible to alter ethernet checksum as well? My code at the moment is simply got from the quickstart where there is nothing about Ethernet headers:

def check_and_modify(pkt):
    packet = pkt.get_payload()
    if <multiple checks>:
        <then modify and >
        pkt.set_payload(packet)
    pkt.accept()

nfqueue = NetfilterQueue()
nfqueue.bind(1, check_and_modify)
try:
    nfqueue.run()
except KeyboardInterrupt:
    print('Ctrl-C!')

Thank you!

The issue behind this is packet drop on ingress of receiving host - the packet with incorrect ethernet frame checksum is silently dropped.

This is what I see on transit host (on egress receiver-facing port):

11:32:52.934009 52:54:00:b3:33:cd > 72:d0:1c:2e:3e:42, ethertype IPv4 (0x0800), length 84: (tos 0x0, ttl 63, id 62499, offset 0, flags [DF], proto TCP (6), length 70, bad cksum f92c (->f91e)!)
    203.0.113.2.33916 > 10.9.8.100.443: Flags [P.], cksum 0x1b4a (correct), seq 2338249475:2338249493, ack 4281749227, win 507, options [nop,nop,TS val 3356499185 ecr 1534377051], length 18
    0x0000:  4500 0046 f423 4000 3f06 f92c cb00 7102  E..F.#@.?..,..q.
    0x0010:  0a09 0864 847c 01bb 8b5e db03 ff36 4eeb  ...d.|...^...6N.
    0x0020:  8018 01fb 1b4a 0000 0101 080a c810 1cf1  .....J..........
    0x0030:  5b74 bc5b 3132 330a 416c 7465 7265 6420  [t.[123.Altered.
    0x0040:  6461 7461 0a0a                           data..

and nothing on ingress of receiving host. In some cases it's possible to switch checksum check off, but not always and I'm the lucky one:

root@sr:~# ethtool -k eth0
Features for eth0:
[ ... ]
rx-checksumming: on [fixed]
rx-fcs: off [fixed]
rx-all: off [fixed]

root@sr:~# ethtool -K eth0 rx-fcs on rx-all on
Could not change any device features

So, I will appreciate any ideas how to solve issue with Ethernet FCS when modifying packet.

Thank you.

My fault. I simply forgotten to update IP Header checksum :)