* Recalculate checksums in netfilter queue
@ 2010-04-21 1:02 Justin Yaple
2010-04-21 2:02 ` Bruno Moreira Guedes
0 siblings, 1 reply; 7+ messages in thread
From: Justin Yaple @ 2010-04-21 1:02 UTC (permalink / raw)
To: netfilter-devel
Hello,
I am having some trouble figuring out how to re-calculate the tcp/ip
checksums after pulling a packet into user space with
libnetfilter_queue. In a netfilter hook I was able to use this:
tcph->check = 0;
tcph->check = tcp_v4_check(tcph, tcplen,
iph->saddr,
iph->daddr,
csum_partial((char *)tcph, tcplen, 0));
iph->check = 0;
ip_send_check(iph); //ip checksum
In user space these functions tcp_v4_check(), csum_partial() and
ip_send_check() do not exists. Are there equivalent functions in user
space so I can recalculate the ip/tcp checksums before passing the new
packet back to the kernel with nfq_set_verdict()?
Thanks.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Recalculate checksums in netfilter queue
2010-04-21 1:02 Recalculate checksums in netfilter queue Justin Yaple
@ 2010-04-21 2:02 ` Bruno Moreira Guedes
2010-04-22 3:15 ` Justin Yaple
0 siblings, 1 reply; 7+ messages in thread
From: Bruno Moreira Guedes @ 2010-04-21 2:02 UTC (permalink / raw)
To: Justin Yaple; +Cc: netfilter-devel
2010/4/20 Justin Yaple <yaplej@gmail.com>:
> Hello,
>
> I am having some trouble figuring out how to re-calculate the tcp/ip
> checksums after pulling a packet into user space with
> libnetfilter_queue. In a netfilter hook I was able to use this:
> tcph->check = 0;
> tcph->check = tcp_v4_check(tcph, tcplen,
> iph->saddr,
> iph->daddr,
> csum_partial((char *)tcph, tcplen, 0));
> iph->check = 0;
> ip_send_check(iph); //ip checksum
>
> In user space these functions tcp_v4_check(), csum_partial() and
> ip_send_check() do not exists. Are there equivalent functions in user
> space so I can recalculate the ip/tcp checksums before passing the new
> packet back to the kernel with nfq_set_verdict()?
>
> Thanks.
> --
> To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
Hello Justin!
If you solve this problem, I'll be too grateful, because I'm looking
for a solution since the last year in order to do NAT in userspace.
Good luck.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Recalculate checksums in netfilter queue
2010-04-21 2:02 ` Bruno Moreira Guedes
@ 2010-04-22 3:15 ` Justin Yaple
2010-04-22 12:43 ` Morgon.J.Kanter
2010-04-22 19:37 ` James King
0 siblings, 2 replies; 7+ messages in thread
From: Justin Yaple @ 2010-04-22 3:15 UTC (permalink / raw)
Cc: netfilter-devel
> If you solve this problem, I'll be too grateful, because I'm looking
> for a solution since the last year in order to do NAT in userspace.
> Good luck.
If I get it figured out I will let you know. Im kind of supprised
that there isnt a function for this in libnetfilter_queue already. It
seems like it would be a pretty common requirement to recalculate the
tcp, and ip checksums. I have spent two days trying to get something
to work without much luck.
My understanding is that the one complement of each 16-bit word is
summed, and then the result of that is bitwise complemented.
So for each word we would do something like this.
for each word{
sum += ~word;
}
then you would take the bitwise complement of that total.
sum = ~sum;
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Recalculate checksums in netfilter queue
2010-04-22 3:15 ` Justin Yaple
@ 2010-04-22 12:43 ` Morgon.J.Kanter
2010-04-22 20:19 ` Justin Yaple
2010-04-22 19:37 ` James King
1 sibling, 1 reply; 7+ messages in thread
From: Morgon.J.Kanter @ 2010-04-22 12:43 UTC (permalink / raw)
To: Justin Yaple; +Cc: netfilter-devel
My understanding is that the one complement of each 16-bit word is
> summed, and then the result of that is bitwise complemented.
>
> So for each word we would do something like this.
> for each word{
> sum += ~word;
> }
>
> then you would take the bitwise complement of that total.
> sum = ~sum;
The RFC for IP contains C code that you can literally copy and paste
for this task.
-- Morgon
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Recalculate checksums in netfilter queue
2010-04-22 12:43 ` Morgon.J.Kanter
@ 2010-04-22 20:19 ` Justin Yaple
[not found] ` <z2o3fdd6ce01004221432yec6c907bz4124144d403be1b4@mail.gmail.com>
0 siblings, 1 reply; 7+ messages in thread
From: Justin Yaple @ 2010-04-22 20:19 UTC (permalink / raw)
To: Morgon.J.Kanter; +Cc: netfilter-devel
> The RFC for IP contains C code that you can literally copy and paste for
> this task.
>
> -- Morgon
Thanks. I finally have both my tcp checksum, and ip checksum
functions working. I found where I was doing some calculations in
reverse order than the example given in the RFC. Would there be any
reason not to add checksum functions to libnetfilter_queue?
unsigned short tcp_sum_calc(unsigned short len_tcp, unsigned short
*src_addr, unsigned short *dest_addr, unsigned short *buff)
{
unsigned short prot_tcp = 6;
long sum = 0;
int i = 0;
/* Check if the tcp length is even or odd. Add padding if odd. */
if((len_tcp % 2) == 1){
buff[len_tcp] = 0; // Empty space in the ip buffer should be 0 anyway.
len_tcp += 1; // increase length to make even.
}
/* add the pseudo header */
sum += ntohs(src_addr[0]);
sum += ntohs(src_addr[1]);
sum += ntohs(dest_addr[0]);
sum += ntohs(dest_addr[1]);
sum += len_tcp; // already in host format.
sum += prot_tcp; // already in host format.
/*
* calculate the checksum for the tcp header and payload
* len_tcp represents number of 8-bit bytes,
* we are working with 16-bit words so divide len_tcp by 2.
*/
for(i=0;i<(len_tcp/2);i++){
sum += ntohs(buff[i]);
}
// keep only the last 16 bits of the 32 bit calculated sum and add the carries
while (sum >> 16){
sum = (sum & 0xFFFF) + (sum >> 16);
}
// Take the bitwise complement of sum
sum = ~sum;
return htons(((unsigned short) sum));
}
unsigned short ip_sum_calc(unsigned short len_ip_header, unsigned short *buff){
long sum = 0;
int i = 0;
for (i=0;i<len_ip_header/2;i++){
sum += ntohs(buff[i]);
}
while (sum >> 16){
sum = (sum & 0xFFFF) + (sum >> 16);
}
sum = ~sum;
return htons(((unsigned short) sum));
}
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Recalculate checksums in netfilter queue
2010-04-22 3:15 ` Justin Yaple
2010-04-22 12:43 ` Morgon.J.Kanter
@ 2010-04-22 19:37 ` James King
1 sibling, 0 replies; 7+ messages in thread
From: James King @ 2010-04-22 19:37 UTC (permalink / raw)
To: Justin Yaple; +Cc: netfilter-devel
On Wed, Apr 21, 2010 at 8:15 PM, Justin Yaple <yaplej@gmail.com> wrote:
> If I get it figured out I will let you know. Im kind of supprised
> that there isnt a function for this in libnetfilter_queue already. It
> seems like it would be a pretty common requirement to recalculate the
> tcp, and ip checksums. I have spent two days trying to get something
> to work without much luck.
>
> My understanding is that the one complement of each 16-bit word is
> summed, and then the result of that is bitwise complemented.
>
> So for each word we would do something like this.
> for each word{
> sum += ~word;
> }
>
> then you would take the bitwise complement of that total.
> sum = ~sum;
For TCP, it's a bit more complicated, as you need to construct an IP
pseudo header first, calculate the checksum for the pseudo header +
segment containing a zeroed checksum field, and then finally insert
the checksum into the TCP header [1]. You also have to pad the
segment into an even number of octets before doing the calculation,
but not include this padding in the transmitted segment [2]. You may
also need to recalculate the IP checksum, depending on what fields
you're modifying. The process is also slightly different for TCP over
IPv6.
I found a thread on this list from last year that contains some helper
functions extracted from tcpdump that may help you, titled "Re: Fwd:
Modifying TCP packets with libnetfilter_queue" [3].
If this works for you, perhaps a patch to include them in
libnetfilter_queue is in order.
[1] http://www.tcpipguide.com/free/t_TCPChecksumCalculationandtheTCPPseudoHeader-2.htm
[2] http://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_checksum_for_IPv4
[3] http://markmail.org/message/auqvblfqenhy4hlz
HTH,
James
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2010-04-22 22:12 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-04-21 1:02 Recalculate checksums in netfilter queue Justin Yaple
2010-04-21 2:02 ` Bruno Moreira Guedes
2010-04-22 3:15 ` Justin Yaple
2010-04-22 12:43 ` Morgon.J.Kanter
2010-04-22 20:19 ` Justin Yaple
[not found] ` <z2o3fdd6ce01004221432yec6c907bz4124144d403be1b4@mail.gmail.com>
2010-04-22 22:12 ` Justin Yaple
2010-04-22 19:37 ` James King
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).