Human readable IP adresses from netfilter
I am writing a simple netfilter kernel module and need to extract and display the IP addresses from incoming packets. In the headers, the address is defined to be __be32 which should be unsigned int. Is there a helper function which can allow me to convert these to a human readable dotted notation string and vice versa? Also, while we are on the subject, when you mangle a packet (change its destination port say) what is the correct way to regenerate the TCP or UDP checksum?
I recommend this tutorial, it contains the answers to both your questions (and lots more): http://jengelh.medozas.de/documents/...er_Modules.pdf
However, here is the solutions.
You use the macro NIPQUAD and feed it the saddr/daddr (for example NIPQUAD(iph->saddr). The matching part in your printk is ("%u.%u.%u.%u). (Found at http://new.linuxfocus.org/English/Fe...ticle367.shtml)
When changing the IP-header, you have to recalculate both IP and transport protocol checksum.
When changing the transport protocol header/payload, you only have to recalculate the transport protocol checksum.
Depending on if the value you changed was a __be16 or __be32, you use csum_replace2 and csum_replace4 respectively.
Calculating transport protocol checksum:
Depending on if the value you changed was a __be16 or __be32, you use inet_proto_csum_replace2 or inet_proto_csum_replace4 respectively
I am not sure what is the most effective way to recalculated the checksum if you have modified more then one field (these functions have to be called for every changed part).
Thanks kristrev. Both your suggestions worked perfectly. I couldn't generate checksums for UDP packets though, but I just change them to 0(for now) since that is allowed.
Glad to hear that it worked. To recalculated the UDP-checksum, you feed &udp->check to either inet...replace2 or inet...replace4. Remember that if you edit something in the IP-header, you have to recalculate the UDP checksum as well.
|All times are GMT -5. The time now is 11:29 AM.|