* performing dnat from userspace with libnetfilter_conntrack
@ 2010-09-27 10:09 Steven Ayre
2010-09-28 13:35 ` Pablo Neira Ayuso
0 siblings, 1 reply; 2+ messages in thread
From: Steven Ayre @ 2010-09-27 10:09 UTC (permalink / raw)
To: netfilter-devel
I'm trying to perform DNAT from within my userspace program to a dynamic host.
I have in nat PREROUTING a NFQUEUE rule that gives the packet to my
program. I am trying to setup a conntrack rule at this time before
accepting the packet. The NFQUEUE part works just fine. However I am
having trouble adding the conntrack entry.
I also have a SNAT rule in POSTROUTING that ensures all reply packets
come via the server performing the DNAT.
This is the code I currently have:
/* Pseudocode showing data types */
/* All IPs and ports are in network byte order */
struct iphdr *ip = (struct iphdr*)payload; // payload is
char* from nfq_get_payload
struct tcphdr *tcp = (struct tcphdr*)(ip + ip->ihl*4);
uint32_t new_daddr;
uint16_t new_dport;
inet_pton(AF_INET, "a.b.c.d", &new_daddr);
new_dport = htons(e);
/* Add a new conntrack entry */
if (!(ct = nfct_new())) {
perror("nfct_new");
return -1;
}
nfct_set_attr_u8(ct, ATTR_ORIG_L3PROTO, AF_INET);
nfct_set_attr_u8(ct, ATTR_ORIG_L4PROTO, IPPROTO_TCP);
nfct_set_attr_u32(ct, ATTR_ORIG_IPV4_SRC, ip->saddr);
nfct_set_attr_u32(ct, ATTR_ORIG_IPV4_DST, ip->daddr);
nfct_set_attr_u16(ct, ATTR_ORIG_PORT_SRC, tcp->source);
nfct_set_attr_u16(ct, ATTR_ORIG_PORT_SRC, tcp->dest);
nfct_setobjopt(ct, NFCT_SOPT_SETUP_REPLY);
nfct_set_attr_u32(ct, ATTR_REPL_IPV4_SRC, ip->saddr);
nfct_set_attr_u16(ct, ATTR_REPL_PORT_SRC, ip->daddr);
nfct_set_attr_u32(ct, ATTR_DNAT_IPV4, new_daddr);
nfct_set_attr_u16(ct, ATTR_DNAT_PORT, new_dport);
nfct_set_attr_u32(ct, ATTR_TIMEOUT, 120);
if (nfct_query(globals.cth, NFCT_Q_CREATE, ct) < 0) {
perror("nfct_query");
return -1;
}
nfct_destroy(ct);
When the above code runs I get the following event:
[NEW] tcp 6 120 src=81.27.101.233 dst=81.27.101.231
sport=52357 dport=1720 [UNREPLIED] src=81.27.101.231 dst=81.27.101.233
sport=1720 dport=52357
But when using the DNAT target I get the following:
[NEW] tcp 6 120 SYN_SENT src=81.27.101.233 dst=81.27.101.231
sport=39591 dport=1720 [UNREPLIED] src=81.27.101.232 dst=81.27.101.231
sport=1721 dport=39591
There's a difference in the events, and while the DNAT target works my
conntrack entry does not. The event when I create the conntrack entry
doesn't actually show the DNAT destination at all!
Does anyone know what I'm doing wrong?
Also, do I need to manually mangle the first packet to perform the
DNAT or will netfilter do this for me after I accept the packet due to
the conntrack entry? I have working code to do this if it's required.
-Steve
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: performing dnat from userspace with libnetfilter_conntrack
2010-09-27 10:09 performing dnat from userspace with libnetfilter_conntrack Steven Ayre
@ 2010-09-28 13:35 ` Pablo Neira Ayuso
0 siblings, 0 replies; 2+ messages in thread
From: Pablo Neira Ayuso @ 2010-09-28 13:35 UTC (permalink / raw)
To: Steven Ayre; +Cc: netfilter-devel
Hi Steven,
On 27/09/10 12:09, Steven Ayre wrote:
> I'm trying to perform DNAT from within my userspace program to a dynamic host.
>
> I have in nat PREROUTING a NFQUEUE rule that gives the packet to my
> program. I am trying to setup a conntrack rule at this time before
> accepting the packet. The NFQUEUE part works just fine. However I am
> having trouble adding the conntrack entry.
>
> I also have a SNAT rule in POSTROUTING that ensures all reply packets
> come via the server performing the DNAT.
>
> This is the code I currently have:
>
> /* Pseudocode showing data types */
> /* All IPs and ports are in network byte order */
> struct iphdr *ip = (struct iphdr*)payload; // payload is
> char* from nfq_get_payload
> struct tcphdr *tcp = (struct tcphdr*)(ip + ip->ihl*4);
> uint32_t new_daddr;
> uint16_t new_dport;
> inet_pton(AF_INET, "a.b.c.d",&new_daddr);
> new_dport = htons(e);
>
> /* Add a new conntrack entry */
> if (!(ct = nfct_new())) {
> perror("nfct_new");
> return -1;
> }
> nfct_set_attr_u8(ct, ATTR_ORIG_L3PROTO, AF_INET);
> nfct_set_attr_u8(ct, ATTR_ORIG_L4PROTO, IPPROTO_TCP);
> nfct_set_attr_u32(ct, ATTR_ORIG_IPV4_SRC, ip->saddr);
> nfct_set_attr_u32(ct, ATTR_ORIG_IPV4_DST, ip->daddr);
> nfct_set_attr_u16(ct, ATTR_ORIG_PORT_SRC, tcp->source);
> nfct_set_attr_u16(ct, ATTR_ORIG_PORT_SRC, tcp->dest);
> nfct_setobjopt(ct, NFCT_SOPT_SETUP_REPLY);
> nfct_set_attr_u32(ct, ATTR_REPL_IPV4_SRC, ip->saddr);
> nfct_set_attr_u16(ct, ATTR_REPL_PORT_SRC, ip->daddr);
> nfct_set_attr_u32(ct, ATTR_DNAT_IPV4, new_daddr);
> nfct_set_attr_u16(ct, ATTR_DNAT_PORT, new_dport);
> nfct_set_attr_u32(ct, ATTR_TIMEOUT, 120);
> if (nfct_query(globals.cth, NFCT_Q_CREATE, ct)< 0) {
> perror("nfct_query");
> return -1;
> }
> nfct_destroy(ct);
>
> When the above code runs I get the following event:
> [NEW] tcp 6 120 src=81.27.101.233 dst=81.27.101.231
> sport=52357 dport=1720 [UNREPLIED] src=81.27.101.231 dst=81.27.101.233
> sport=1720 dport=52357
>
> But when using the DNAT target I get the following:
> [NEW] tcp 6 120 SYN_SENT src=81.27.101.233 dst=81.27.101.231
> sport=39591 dport=1720 [UNREPLIED] src=81.27.101.232 dst=81.27.101.231
> sport=1721 dport=39591
>
> There's a difference in the events, and while the DNAT target works my
> conntrack entry does not. The event when I create the conntrack entry
> doesn't actually show the DNAT destination at all!
>
> Does anyone know what I'm doing wrong?
It seems that the ATTR_TCP_STATE attribute is missing. Don't forget to
use NFQUEUE in the raw table in PREROUTING chain.
> Also, do I need to manually mangle the first packet to perform the
> DNAT or will netfilter do this for me after I accept the packet due to
> the conntrack entry? I have working code to do this if it's required.
No.
BTW, you have to set TCP_LIBERAL flag as well to skip the TCP tracking
(you will have to wait until 2.6.36 to avoid this, and you'll have to
use the WSCALE attributes instead of setting liberal to inject the
window scale factor).
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-09-28 13:34 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-27 10:09 performing dnat from userspace with libnetfilter_conntrack Steven Ayre
2010-09-28 13:35 ` Pablo Neira Ayuso
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).