I am trying to figure out how to modify packets as they pass from LAN to WAN (and back again).
Specifically I need to modify a UDP packet on a specific port such that the changes made require calculating a custom checksum and writing this back to the packet.
I've managed to build and install a custom app on the OpenWRT firmware - this is where I would like to pass the packet and have it modified ready to send out.
The bit I'm struggling with is how to know when the packets I'm interested in have arrived, and how to call my app to modify them.
I thought iptables might have been the answer, but I can't see how to call an app to make the changes.
Anyone have any thoughts on how to implement this?
Typically there is only one checksum that is correct for a given packet[1]. Perhaps you could enlighten us as to what you are trying to achieve so that a reasonable approach could be suggested.
Checksum is the 16-bit one's complement of the one's complement sum of a
pseudo header of information from the IP header, the UDP header, and the
data, padded with zero octets at the end (if necessary) to make a
multiple of two octets.
The pseudo header conceptually prefixed to the UDP header contains the
source address, the destination address, the protocol, and the UDP
length. This information gives protection against misrouted datagrams.
This checksum procedure is the same as is used in TCP.
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| source address |
+--------+--------+--------+--------+
| destination address |
+--------+--------+--------+--------+
| zero |protocol| UDP length |
+--------+--------+--------+--------+
If the computed checksum is zero, it is transmitted as all ones (the
equivalent in one's complement arithmetic). An all zero transmitted
checksum value means that the transmitter generated no checksum (for
debugging or for higher level protocols that don't care).
Thanks for the quick reply. The checksum per se is irrelevant. I only mentioned it to indicate the changes that I need to make to the packet are non-trivial and can't be done by a script. The checksum I'm referring to is different to the IP packet one.
Thus I need to write an app to handle all the calculations and changes.
That makes sense. So once I've finished modifying the packet, should my app also then send the modified packet to a specific port and again iptables would forward it to the WAN?
So I managed to write a filter and got it to compile and capture packets on my Debian 9 dev system.
After much fighting with the OpenWrt SDK I also managed to build a package and install it on the target OpenWrt device.
Now came the big moment to test it...
root@OpenWRT:~# iptables -I INPUT -d 192.168.1.0/24 -j NFQUEUE --queue-num 0 --q
ueue-bypass
iptables v1.8.2 (legacy): unknown option "--queue-num"
Try `iptables -h' or 'iptables --help' for more information.
After all that it appears the version of iptables doesn't know about NFQUEUE.
Is there something else I need to do to enable my filter hook?
Or as you compiling with the SDK, just compile also those packages...
But make sure that you are using the exactly correct SDK, which matches you firmware and kernel 4.14.87. that is especially important for compiling kernel packages.
Possibly you need to download a new firmware and the SDK at the same time. Then flash the new firmware and use that SDK to compile your packages.
So I figured building the latest kernel would be the best way forward. I have just finished building and wrote the image to an SD card. When I boot I see:
root@OpenWrt:/# uname -r
4.14.115
Great. So now I try to install the iptables module:
root@OpenWrt:/# opkg install iptables-mod-nfqueue
Installing iptables-mod-nfqueue (1.8.2-3) to root...
Downloading http://downloads.openwrt.org/snapshots/targets/sunxi/cortexa7/packages/iptables-mod-nfqueue_1.8.2-3_arm_cortex-a7_neon-vfpv4.ipk
Collected errors:
* satisfy_dependencies_for: Cannot satisfy the following dependencies for iptables-mod-nfqueue:
* kernel (= 4.14.115-1-9bcd561448ae0d9d6f516e5662947645)
* opkg_install_cmd: Cannot install package iptables-mod-nfqueue.
You need to flash your own packages, not those from the OpenWrt repo.
The easiest is to add them to your build directly.
Enabling ccache under developer options will speed your builds.
Other options include building them as modules yourself and either uploading them to the OpenWrt instance and installing them, or running your own HTTP server with the packages available there and modifying the opkg config to use your repo. Since you've got to select and build them yourself anyway, might as well add them to the image.