I'm using scapy and NetFilterQueue to manipulate IP packets between client and server.
I would like to remove the last option in the TCP header option field list. Removing an option in the TCP header changes the size of the packet and whenever I change the size packet leads to packet drop at both client and server-side.
I tried to recalculate the length of both IP & TCP but still doesn't work. Here is my complete code and I'm using scapy version 2.4.5.
#! /usr/bin/env python2.7
from scapy.all import *
from netfilterqueue import NetfilterQueue
import os
iptablesr = "iptables -A FORWARD -j NFQUEUE --queue-num 1"
os.system(iptablesr)
os.system("sysctl net.ipv4.ip_forward=1")
def check_mptcp_option(option_list):
for option in option_list:
if option[0] == 30:
return True
return False
def modify(packet):
ip_pkt = IP(packet.get_payload())
try:
ip_tcp = ip_pkt.getlayer(TCP)
if check_mptcp_option(ip_tcp.options):
payload_before = len(ip_pkt[TCP])
ip_pkt[TCP].options = ip_pkt[TCP].options[:-1] # remove last option
payload_after = len(ip_pkt[TCP])
payload_dif = payload_after - payload_before
ip_pkt[IP].len = ip_pkt[IP].len + payload_dif
del ip_pkt[IP].chksum
del ip_pkt[TCP].chksum
packet.set_payload(str(ip_pkt))
packet.accept()
except Exception as e:
print(e)
packet.accept() #just skip the packet unmodified.
def main():
nfqueue = NetfilterQueue()
nfqueue.bind(1, modify)
try:
print "[*] waiting for data"
nfqueue.run()
except KeyboardInterrupt:
nfqueue.unbind()
print "Flushing iptables."
os.system('iptables -F')
os.system('iptables -X')
if __name__ == "__main__":
main()
Note: If I do anything without changing the size of the packet it works (for example modifying the TCP option instead of removing it).