[netfilter-cvslog] r4093 - in
trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11:
include/linux/netfilter_ipv4 net/ipv4/netfilter
laforge at netfilter.org
laforge at netfilter.org
Mon Jul 4 20:44:45 CEST 2005
Author: laforge at netfilter.org
Date: 2005-07-04 20:44:44 +0200 (Mon, 04 Jul 2005)
New Revision: 4093
Modified:
trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/include/linux/netfilter_ipv4/ip_conntrack_pptp.h
trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h
trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_pptp.c
trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_proto_gre.c
trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_nat_pptp.c
Log:
major update. fixed a couple of bugs in preliminary conntrack support, added port of NAT code. works fine now on 2.6.12.1
Modified: trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/include/linux/netfilter_ipv4/ip_conntrack_pptp.h
===================================================================
--- trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/include/linux/netfilter_ipv4/ip_conntrack_pptp.h 2005-07-04 15:35:34 UTC (rev 4092)
+++ trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/include/linux/netfilter_ipv4/ip_conntrack_pptp.h 2005-07-04 18:44:44 UTC (rev 4093)
@@ -33,6 +33,10 @@
enum pptp_ctrlcall_state cstate; /* call state */
u_int16_t pac_call_id; /* call id of PAC, host byte order */
u_int16_t pns_call_id; /* call id of PNS, host byte order */
+
+ /* in pre-2.6.11 this used to be per-expect. Now it is per-conntrack
+ * and therefore imposes a fixed limit on the number of maps */
+ struct ip_ct_gre_keymap *keymap_orig, *keymap_reply;
};
/* conntrack_expect private member */
@@ -45,6 +49,7 @@
#ifdef __KERNEL__
+
#include <linux/netfilter_ipv4/lockhelp.h>
DECLARE_LOCK_EXTERN(ip_pptp_lock);
@@ -306,5 +311,26 @@
struct PptpSetLinkInfo setlink;
};
+extern int
+(*ip_nat_pptp_hook_outbound)(struct sk_buff **pskb,
+ struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo,
+ struct PptpControlHeader *ctlh,
+ union pptp_ctrl_union *pptpReq);
+
+extern int
+(*ip_nat_pptp_hook_inbound)(struct sk_buff **pskb,
+ struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo,
+ struct PptpControlHeader *ctlh,
+ union pptp_ctrl_union *pptpReq);
+
+extern int
+(*ip_nat_pptp_hook_exp_gre)(struct ip_conntrack_expect *exp_orig,
+ struct ip_conntrack_expect *exp_reply);
+
+extern void
+(*ip_nat_pptp_hook_expectfn)(struct ip_conntrack *ct,
+ struct ip_conntrack_expect *exp);
#endif /* __KERNEL__ */
#endif /* _CONNTRACK_PPTP_H */
Modified: trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h
===================================================================
--- trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h 2005-07-04 15:35:34 UTC (rev 4092)
+++ trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h 2005-07-04 18:44:44 UTC (rev 4093)
@@ -69,14 +69,11 @@
struct ip_ct_gre {
unsigned int stream_timeout;
unsigned int timeout;
-
- /* in pre-2.6.11 this used to be per-expect. Now it is per-conntrack
- * and therefore imposes a fixed limit on the number of maps */
- struct ip_ct_gre_keymap *keymap_orig, *keymap_reply;
};
#ifdef __KERNEL__
struct ip_conntrack_expect;
+struct ip_conntrack;
/* structure for original <-> reply keymap */
struct ip_ct_gre_keymap {
@@ -85,16 +82,11 @@
struct ip_conntrack_tuple tuple;
};
-
/* add new tuple->key_reply pair to keymap */
int ip_ct_gre_keymap_add(struct ip_conntrack *ct,
struct ip_conntrack_tuple *t,
int reply);
-/* change an existing keymap entry */
-void ip_ct_gre_keymap_change(struct ip_ct_gre_keymap *km,
- struct ip_conntrack_tuple *t);
-
/* delete keymap entries */
void ip_ct_gre_keymap_destroy(struct ip_conntrack *ct);
Modified: trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_pptp.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_pptp.c 2005-07-04 15:35:34 UTC (rev 4092)
+++ trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_pptp.c 2005-07-04 18:44:44 UTC (rev 4093)
@@ -17,9 +17,9 @@
* - We blindly assume that control connections are always
* established in PNS->PAC direction. This is a violation
* of RFFC2673
+ * - We can only support one single call within each session
*
- * TODO: - finish support for multiple calls within one session
- * (needs expect reservations in newnat)
+ * TODO:
* - testing of incoming PPTP calls
*
* Changes:
@@ -52,6 +52,8 @@
#include <net/tcp.h>
#include <linux/netfilter_ipv4/lockhelp.h>
+#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <linux/netfilter_ipv4/ip_conntrack_core.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
@@ -64,6 +66,28 @@
DECLARE_LOCK(ip_pptp_lock);
+int
+(*ip_nat_pptp_hook_outbound)(struct sk_buff **pskb,
+ struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo,
+ struct PptpControlHeader *ctlh,
+ union pptp_ctrl_union *pptpReq);
+
+int
+(*ip_nat_pptp_hook_inbound)(struct sk_buff **pskb,
+ struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo,
+ struct PptpControlHeader *ctlh,
+ union pptp_ctrl_union *pptpReq);
+
+int
+(*ip_nat_pptp_hook_exp_gre)(struct ip_conntrack_expect *expect_orig,
+ struct ip_conntrack_expect *expect_reply);
+
+void
+(*ip_nat_pptp_hook_expectfn)(struct ip_conntrack *ct,
+ struct ip_conntrack_expect *exp);
+
#if 0
#include "ip_conntrack_pptp_priv.h"
#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, __FUNCTION__, ## args)
@@ -82,91 +106,95 @@
static void pptp_expectfn(struct ip_conntrack *ct,
struct ip_conntrack_expect *exp)
{
- struct ip_conntrack *master;
+ DEBUGP("increasing timeouts\n");
- DEBUGP("increasing timeouts\n");
/* increase timeout of GRE data channel conntrack entry */
ct->proto.gre.timeout = PPTP_GRE_TIMEOUT;
ct->proto.gre.stream_timeout = PPTP_GRE_STREAM_TIMEOUT;
- master = master_ct(ct);
- if (!master) {
- DEBUGP(" no master!!!\n");
- return 0;
- }
+ /* Can you see how rusty this code is, compared with the pre-2.6.11
+ * one? That's what happened to my shiny newnat of 2002 ;( -HW */
- DEBUGP("completing tuples with ct info\n");
- /* we can do this, since we're unconfirmed */
- if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.gre.key ==
- htons(master->help.ct_pptp_info.pac_call_id)) {
- /* assume PNS->PAC */
- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key =
- htons(master->help.ct_pptp_info.pns_call_id);
- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key =
- htons(master->help.ct_pptp_info.pns_call_id);
+ if (!ip_nat_pptp_hook_expectfn) {
+ struct ip_conntrack_tuple inv_t;
+ struct ip_conntrack_expect *exp_other;
+
+ /* obviously this tuple inversion only works until you do NAT */
+ invert_tuplepr(&inv_t, &exp->tuple);
+ DEBUGP("trying to unexpect other dir: ");
+ DUMP_TUPLE(&inv_t);
+
+ exp_other = __ip_conntrack_exp_find(&inv_t);
+ if (exp_other) {
+ /* delete other expectation. */
+ DEBUGP("found\n");
+ ip_conntrack_unexpect_related(exp_other);
+ } else {
+ DEBUGP("not found\n");
+ }
} else {
- /* assume PAC->PNS */
- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key =
- htons(master->help.ct_pptp_info.pac_call_id);
- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key =
- htons(master->help.ct_pptp_info.pac_call_id);
+ /* we need more than simple inversion */
+ ip_nat_pptp_hook_expectfn(ct, exp);
}
-
-#ifdef FIXME_LATER
- /* delete other expectation */
- if (exp->expected_list.next != &exp->expected_list) {
- struct ip_conntrack_expect *other_exp;
- struct list_head *cur_item, *next;
+}
- for (cur_item = master->sibling_list.next;
- cur_item != &master->sibling_list; cur_item = next) {
- next = cur_item->next;
- other_exp = list_entry(cur_item,
- struct ip_conntrack_expect,
- expected_list);
- /* remove only if occurred at same sequence number */
- if (other_exp != exp && other_exp->seq == exp->seq) {
- DEBUGP("unexpecting other direction\n");
- ip_ct_gre_keymap_destroy(other_exp);
- ip_conntrack_unexpect_related(other_exp);
- }
+static int timeout_ct_or_exp(const struct ip_conntrack_tuple *t)
+{
+ struct ip_conntrack_tuple_hash *h;
+ struct ip_conntrack_expect *exp;
+
+ DEBUGP("trying to timeout ct or exp for tuple ");
+ DUMP_TUPLE(t);
+
+ h = __ip_conntrack_find(t, NULL);
+ if (h) {
+ struct ip_conntrack *sibling = tuplehash_to_ctrack(h);
+ DEBUGP("setting timeout of conntrack %p to 0\n", sibling);
+ sibling->proto.gre.timeout = 0;
+ sibling->proto.gre.stream_timeout = 0;
+ /* refresh_acct will not modify counters if skb == NULL */
+ ip_ct_refresh_acct(sibling, 0, NULL, 0);
+ return 1;
+ } else {
+ exp = __ip_conntrack_exp_find(t);
+ if (exp) {
+ DEBUGP("unexpect_related of expect %p\n", exp);
+ ip_conntrack_unexpect_related(exp);
+ return 1;
}
}
-#endif
return 0;
}
+
/* timeout GRE data connections */
static int pptp_timeout_related(struct ip_conntrack *ct)
{
- struct list_head *cur_item, *next;
- struct ip_conntrack_expect *exp;
+ struct ip_conntrack_tuple t;
+ int ret;
-#ifdef FIXME_LATER
- /* FIXME: do we have to lock something ? */
- for (cur_item = ct->sibling_list.next;
- cur_item != &ct->sibling_list; cur_item = next) {
- next = cur_item->next;
- exp = list_entry(cur_item, struct ip_conntrack_expect,
- expected_list);
+ /* Since ct->sibling_list has literally rusted away in 2.6.11,
+ * we now need another way to find out about our sibling
+ * contrack and expects... -HW */
- ip_ct_gre_keymap_destroy(exp);
- if (!exp->sibling) {
- ip_conntrack_unexpect_related(exp);
- continue;
- }
+ /* try original (pns->pac) tuple */
+ memcpy(&t, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, sizeof(t));
+ t.dst.protonum = IPPROTO_GRE;
+ t.src.u.gre.key = htons(ct->help.ct_pptp_info.pns_call_id);
+ t.dst.u.gre.key = htons(ct->help.ct_pptp_info.pac_call_id);
- DEBUGP("setting timeout of conntrack %p to 0\n",
- exp->sibling);
- exp->sibling->proto.gre.timeout = 0;
- exp->sibling->proto.gre.stream_timeout = 0;
- /* refresh_acct will not modify counters if skb == NULL */
- ip_ct_refresh_acct(exp->sibling, 0, NULL, 0);
- }
-#endif
+ ret = timeout_ct_or_exp(&t);
- return 0;
+ /* try reply (pac->pns) tuple */
+ memcpy(&t, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, sizeof(t));
+ t.dst.protonum = IPPROTO_GRE;
+ t.src.u.gre.key = htons(ct->help.ct_pptp_info.pac_call_id);
+ t.dst.u.gre.key = htons(ct->help.ct_pptp_info.pns_call_id);
+
+ ret += timeout_ct_or_exp(&t);
+
+ return ret;
}
/* expect GRE connections (PNS->PAC and PAC->PNS direction) */
@@ -196,64 +224,93 @@
.protonum = IPPROTO_GRE
},
}
- }, *exp_tuple;
+ };
- for (exp_tuple = exp_tuples; exp_tuple < &exp_tuples[2]; exp_tuple++) {
- struct ip_conntrack_expect *exp;
- struct ip_ct_pptp_expect exp_pptp_info;
+ struct ip_conntrack_expect *exp_orig, *exp_reply;
- exp = ip_conntrack_expect_alloc();
- if (exp == NULL)
+ exp_orig = ip_conntrack_expect_alloc();
+ if (exp_orig == NULL)
+ return 1;
+
+ exp_reply = ip_conntrack_expect_alloc();
+ if (exp_reply == NULL) {
+ ip_conntrack_expect_free(exp_orig);
+ return 1;
+ }
+
+ memcpy(&exp_orig->tuple, &exp_tuples[0], sizeof(exp_orig->tuple));
+
+ exp_orig->mask.src.ip = 0xffffffff;
+ exp_orig->mask.src.u.all = 0;
+ exp_orig->mask.dst.u.all = 0;
+ exp_orig->mask.dst.u.gre.key = 0xffff;
+ exp_orig->mask.dst.ip = 0xffffffff;
+ exp_orig->mask.dst.protonum = 0xff;
+
+ exp_orig->master = master;
+ exp_orig->expectfn = pptp_expectfn;
+
+ exp_orig->dir = IP_CT_DIR_ORIGINAL;
+
+ /* both expectations are identical apart from tuple */
+ memcpy(exp_reply, exp_orig, sizeof(*exp_reply));
+ memcpy(&exp_reply->tuple, &exp_tuples[1], sizeof(exp_reply->tuple));
+
+ exp_reply->dir = !exp_orig->dir;
+
+ if (ip_nat_pptp_hook_exp_gre)
+ return ip_nat_pptp_hook_exp_gre(exp_orig, exp_reply);
+ else {
+
+ DEBUGP("calling expect_related PNS->PAC");
+ DUMP_TUPLE(&exp_orig->tuple);
+
+ if (ip_conntrack_expect_related(exp_orig) != 0) {
+ ip_conntrack_expect_free(exp_orig);
+ ip_conntrack_expect_free(exp_reply);
+ DEBUGP("cannot expect_related()\n");
return 1;
+ }
- memcpy(&exp->tuple, exp_tuple, sizeof(exp->tuple));
+ DEBUGP("calling expect_related PAC->PNS");
+ DUMP_TUPLE(&exp_reply->tuple);
- exp->mask.src.ip = 0xffffffff;
- exp->mask.src.u.all = 0;
- exp->mask.dst.u.all = 0;
- exp->mask.dst.u.gre.key = 0xffff;
- exp->mask.dst.ip = 0xffffffff;
- exp->mask.dst.protonum = 0xff;
-
- exp->master = master;
- exp->expectfn = pptp_expectfn;
+ if (ip_conntrack_expect_related(exp_reply) != 0) {
+ ip_conntrack_unexpect_related(exp_orig);
+ ip_conntrack_expect_free(exp_reply);
+ DEBUGP("cannot expect_related()\n");
+ return 1;
+ }
- exp_pptp_info.pac_call_id = ntohs(callid);
- exp_pptp_info.pns_call_id = ntohs(peer_callid);
-
- DEBUGP("calling expect_related ");
- DUMP_TUPLE(&exp->tuple);
-
/* Add GRE keymap entries */
- if (ip_ct_gre_keymap_add(master, &exp->tuple, 0) != 0) {
- ip_conntrack_expect_free(exp);
+ if (ip_ct_gre_keymap_add(master, &exp_reply->tuple, 0) != 0) {
+ ip_conntrack_unexpect_related(exp_orig);
+ ip_conntrack_unexpect_related(exp_reply);
+ DEBUGP("cannot keymap_add() exp\n");
return 1;
}
- invert_tuplepr(&inv_tuple, &exp->tuple);
+ invert_tuplepr(&inv_tuple, &exp_reply->tuple);
if (ip_ct_gre_keymap_add(master, &inv_tuple, 1) != 0) {
+ ip_conntrack_unexpect_related(exp_orig);
+ ip_conntrack_unexpect_related(exp_reply);
ip_ct_gre_keymap_destroy(master);
- ip_conntrack_expect_free(exp);
+ DEBUGP("cannot keymap_add() exp_inv\n");
return 1;
}
- if (ip_conntrack_expect_related(exp) != 0) {
- ip_ct_gre_keymap_destroy(master);
- ip_conntrack_expect_free(exp);
- DEBUGP("cannot expect_related()\n");
- return 1;
- }
}
return 0;
}
static inline int
-pptp_inbound_pkt(struct sk_buff *skb,
+pptp_inbound_pkt(struct sk_buff **pskb,
struct tcphdr *tcph,
unsigned int ctlhoff,
size_t datalen,
- struct ip_conntrack *ct)
+ struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo)
{
struct PptpControlHeader _ctlh, *ctlh;
unsigned int reqlen;
@@ -262,14 +319,14 @@
u_int16_t msg, *cid, *pcid;
u_int32_t seq;
- ctlh = skb_header_pointer(skb, ctlhoff, sizeof(_ctlh), &_ctlh);
+ ctlh = skb_header_pointer(*pskb, ctlhoff, sizeof(_ctlh), &_ctlh);
if (unlikely(!ctlh)) {
DEBUGP("error during skb_header_pointer\n");
return NF_ACCEPT;
}
reqlen = datalen - sizeof(struct pptp_pkt_hdr) - sizeof(_ctlh);
- pptpReq = skb_header_pointer(skb, ctlhoff+sizeof(_ctlh),
+ pptpReq = skb_header_pointer(*pskb, ctlhoff+sizeof(_ctlh),
reqlen, &_pptpReq);
if (unlikely(!pptpReq)) {
DEBUGP("error during skb_header_pointer\n");
@@ -446,16 +503,22 @@
break;
}
+
+ if (ip_nat_pptp_hook_inbound)
+ return ip_nat_pptp_hook_inbound(pskb, ct, ctinfo, ctlh,
+ pptpReq);
+
return NF_ACCEPT;
}
static inline int
-pptp_outbound_pkt(struct sk_buff *skb,
+pptp_outbound_pkt(struct sk_buff **pskb,
struct tcphdr *tcph,
unsigned int ctlhoff,
size_t datalen,
- struct ip_conntrack *ct)
+ struct ip_conntrack *ct,
+ enum ip_conntrack_info ctinfo)
{
struct PptpControlHeader _ctlh, *ctlh;
unsigned int reqlen;
@@ -463,12 +526,12 @@
struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
u_int16_t msg, *cid, *pcid;
- ctlh = skb_header_pointer(skb, ctlhoff, sizeof(_ctlh), &_ctlh);
+ ctlh = skb_header_pointer(*pskb, ctlhoff, sizeof(_ctlh), &_ctlh);
if (!ctlh)
return NF_ACCEPT;
reqlen = datalen - sizeof(struct pptp_pkt_hdr) - sizeof(_ctlh);
- pptpReq = skb_header_pointer(skb, ctlhoff+sizeof(_ctlh), reqlen,
+ pptpReq = skb_header_pointer(*pskb, ctlhoff+sizeof(_ctlh), reqlen,
&_pptpReq);
if (!pptpReq)
return NF_ACCEPT;
@@ -560,6 +623,10 @@
/* unknown: no need to create GRE masq table entry */
break;
}
+
+ if (ip_nat_pptp_hook_outbound)
+ return ip_nat_pptp_hook_outbound(pskb, ct, ctinfo, ctlh,
+ pptpReq);
return NF_ACCEPT;
}
@@ -610,7 +677,7 @@
if (tcp_v4_check(tcph, tcplen, (*pskb)->nh.iph->saddr,
(*pskb)->nh.iph->daddr,
csum_partial((char *) tcph, tcplen, 0))) {
- printk(KERN_NOTICE __FILE__ ": bad csum\n");
+ DEBUGP(" bad csum\n");
/* W2K PPTP server sends TCP packets with wrong checksum :(( */
//return NF_ACCEPT;
}
@@ -651,10 +718,12 @@
* established from PNS->PAC. However, RFC makes no guarantee */
if (dir == IP_CT_DIR_ORIGINAL)
/* client -> server (PNS -> PAC) */
- ret = pptp_outbound_pkt(*pskb, tcph, nexthdr_off, datalen, ct);
+ ret = pptp_outbound_pkt(pskb, tcph, nexthdr_off, datalen, ct,
+ ctinfo);
else
/* server -> client (PAC -> PNS) */
- ret = pptp_inbound_pkt(*pskb, tcph, nexthdr_off, datalen, ct);
+ ret = pptp_inbound_pkt(pskb, tcph, nexthdr_off, datalen, ct,
+ ctinfo);
DEBUGP("sstate: %d->%d, cstate: %d->%d\n",
oldsstate, info->sstate, oldcstate, info->cstate);
UNLOCK_BH(&ip_pptp_lock);
@@ -694,7 +763,7 @@
{
int retcode;
- DEBUGP(__FILE__ ": registering helper\n");
+ DEBUGP(" registering helper\n");
if ((retcode = ip_conntrack_helper_register(&pptp))) {
printk(KERN_ERR "Unable to register conntrack application "
"helper for pptp: %d\n", retcode);
@@ -715,3 +784,7 @@
module_exit(fini);
EXPORT_SYMBOL(ip_pptp_lock);
+EXPORT_SYMBOL(ip_nat_pptp_hook_outbound);
+EXPORT_SYMBOL(ip_nat_pptp_hook_inbound);
+EXPORT_SYMBOL(ip_nat_pptp_hook_exp_gre);
+EXPORT_SYMBOL(ip_nat_pptp_hook_expectfn);
Modified: trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_proto_gre.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_proto_gre.c 2005-07-04 15:35:34 UTC (rev 4092)
+++ trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_proto_gre.c 2005-07-04 18:44:44 UTC (rev 4093)
@@ -80,18 +80,17 @@
static u_int32_t gre_keymap_lookup(struct ip_conntrack_tuple *t)
{
struct ip_ct_gre_keymap *km;
- u_int32_t key;
+ u_int32_t key = 0;
READ_LOCK(&ip_ct_gre_lock);
km = LIST_FIND(&gre_keymap_list, gre_key_cmpfn,
struct ip_ct_gre_keymap *, t);
- if (!km) {
- READ_UNLOCK(&ip_ct_gre_lock);
- return 0;
- }
-
- key = km->tuple.src.u.gre.key;
+ if (km)
+ key = km->tuple.src.u.gre.key;
READ_UNLOCK(&ip_ct_gre_lock);
+
+ DEBUGP("lookup src key 0x%x up key for ", key);
+ DUMP_TUPLE_GRE(t);
return key;
}
@@ -101,8 +100,13 @@
ip_ct_gre_keymap_add(struct ip_conntrack *ct,
struct ip_conntrack_tuple *t, int reply)
{
- struct ip_ct_gre_keymap *km;
+ struct ip_ct_gre_keymap *km, *old;
+ if (!ct->helper || strcmp(ct->helper->name, "pptp")) {
+ DEBUGP("refusing to add GRE keymap to non-pptp session\n");
+ return -1;
+ }
+
km = kmalloc(sizeof(*km), GFP_ATOMIC);
if (!km)
return -1;
@@ -112,11 +116,42 @@
memcpy(&km->tuple, t, sizeof(*t));
- if (!reply)
- ct->proto.gre.keymap_orig = km;
- else
- ct->proto.gre.keymap_reply = km;
+ if (!reply) {
+ if (ct->help.ct_pptp_info.keymap_orig) {
+ kfree(km);
+ /* check whether it's a retransmission */
+ old = LIST_FIND(&gre_keymap_list, gre_key_cmpfn,
+ struct ip_ct_gre_keymap *, t);
+ if (old == ct->help.ct_pptp_info.keymap_orig) {
+ DEBUGP("retransmission\n");
+ return 0;
+ }
+
+ DEBUGP("trying to override keymap_orig for ct %p\n",
+ ct);
+ return -2;
+ }
+ ct->help.ct_pptp_info.keymap_orig = km;
+ } else {
+ if (ct->help.ct_pptp_info.keymap_reply) {
+ kfree(km);
+
+ /* check whether it's a retransmission */
+ old = LIST_FIND(&gre_keymap_list, gre_key_cmpfn,
+ struct ip_ct_gre_keymap *, t);
+ if (old == ct->help.ct_pptp_info.keymap_reply) {
+ DEBUGP("retransmission\n");
+ return 0;
+ }
+
+ DEBUGP("trying to override keymap_reply for ct %p\n",
+ ct);
+ return -2;
+ }
+ ct->help.ct_pptp_info.keymap_reply = km;
+ }
+
DEBUGP("adding new entry %p: ", km);
DUMP_TUPLE_GRE(&km->tuple);
@@ -127,34 +162,30 @@
return 0;
}
-/* change the tuple of a keymap entry (used by nat helper) */
-void ip_ct_gre_keymap_change(struct ip_ct_gre_keymap *km,
- struct ip_conntrack_tuple *t)
-{
- DEBUGP("changing entry %p to: ", km);
- DUMP_TUPLE_GRE(t);
-
- WRITE_LOCK(&ip_ct_gre_lock);
- memcpy(&km->tuple, t, sizeof(km->tuple));
- WRITE_UNLOCK(&ip_ct_gre_lock);
-}
-
/* destroy the keymap entries associated with specified master ct */
void ip_ct_gre_keymap_destroy(struct ip_conntrack *ct)
{
DEBUGP("entering for ct %p\n", ct);
+
+ if (!ct->helper || strcmp(ct->helper->name, "pptp")) {
+ DEBUGP("refusing to destroy GRE keymap to non-pptp session\n");
+ return;
+ }
+
WRITE_LOCK(&ip_ct_gre_lock);
- if (ct->proto.gre.keymap_orig) {
- DEBUGP("removing %p from list\n", ct->proto.gre.keymap_orig);
- list_del(&ct->proto.gre.keymap_orig->list);
- kfree(ct->proto.gre.keymap_orig);
- ct->proto.gre.keymap_orig = NULL;
+ if (ct->help.ct_pptp_info.keymap_orig) {
+ DEBUGP("removing %p from list\n",
+ ct->help.ct_pptp_info.keymap_orig);
+ list_del(&ct->help.ct_pptp_info.keymap_orig->list);
+ kfree(ct->help.ct_pptp_info.keymap_orig);
+ ct->help.ct_pptp_info.keymap_orig = NULL;
}
- if (ct->proto.gre.keymap_reply) {
- DEBUGP("removing %p from list\n", ct->proto.gre.keymap_reply);
- list_del(&ct->proto.gre.keymap_reply->list);
- kfree(ct->proto.gre.keymap_reply);
- ct->proto.gre.keymap_reply = NULL;
+ if (ct->help.ct_pptp_info.keymap_reply) {
+ DEBUGP("removing %p from list\n",
+ ct->help.ct_pptp_info.keymap_reply);
+ list_del(&ct->help.ct_pptp_info.keymap_reply->list);
+ kfree(ct->help.ct_pptp_info.keymap_reply);
+ ct->help.ct_pptp_info.keymap_reply = NULL;
}
WRITE_UNLOCK(&ip_ct_gre_lock);
}
@@ -271,9 +302,6 @@
ct->proto.gre.stream_timeout = GRE_STREAM_TIMEOUT;
ct->proto.gre.timeout = GRE_TIMEOUT;
- ct->proto.gre.keymap_orig = NULL;
- ct->proto.gre.keymap_reply = NULL;
-
return 1;
}
@@ -281,9 +309,13 @@
* and is about to be deleted from memory */
static void gre_destroy(struct ip_conntrack *ct)
{
+ struct ip_conntrack *master = ct->master;
DEBUGP(" entering\n");
- ip_ct_gre_keymap_destroy(ct);
+ if (!master)
+ DEBUGP("no master !?!\n");
+ else
+ ip_ct_gre_keymap_destroy(master);
}
/* protocol helper struct */
@@ -331,7 +363,6 @@
}
EXPORT_SYMBOL(ip_ct_gre_keymap_add);
-EXPORT_SYMBOL(ip_ct_gre_keymap_change);
EXPORT_SYMBOL(ip_ct_gre_keymap_destroy);
module_init(init);
Modified: trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_nat_pptp.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_nat_pptp.c 2005-07-04 15:35:34 UTC (rev 4092)
+++ trunk/patch-o-matic-ng/patchlets/pptp-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_nat_pptp.c 2005-07-04 18:44:44 UTC (rev 4093)
@@ -45,6 +45,7 @@
#include <linux/netfilter_ipv4/ip_nat_rule.h>
#include <linux/netfilter_ipv4/ip_nat_helper.h>
#include <linux/netfilter_ipv4/ip_nat_pptp.h>
+#include <linux/netfilter_ipv4/ip_conntrack_core.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
@@ -56,7 +57,7 @@
MODULE_DESCRIPTION("Netfilter NAT helper module for PPTP");
-#if 0
+#if 1
#include "ip_conntrack_pptp_priv.h"
#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, \
__FUNCTION__, ## args)
@@ -64,101 +65,67 @@
#define DEBUGP(format, args...)
#endif
-static void
-pptp_nat_expected(struct sk_buff **pskb,
- unsigned int hooknum,
- struct ip_conntrack *ct,
- struct ip_nat_info *info)
+static void pptp_nat_expected(struct ip_conntrack *ct,
+ struct ip_conntrack_expect *exp)
{
- struct ip_conntrack *master = master_ct(ct);
- struct ip_nat_range range;
+ struct ip_conntrack *master = ct->master;
+ struct ip_conntrack_expect *other_exp;
+ struct ip_conntrack_tuple t;
struct ip_ct_pptp_master *ct_pptp_info;
struct ip_nat_pptp *nat_pptp_info;
- u_int32_t newip, newcid;
- IP_NF_ASSERT(info);
- IP_NF_ASSERT(master);
- IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
-
- DEBUGP("we have a connection!\n");
-
- LOCK_BH(&ip_pptp_lock);
ct_pptp_info = &master->help.ct_pptp_info;
nat_pptp_info = &master->nat.help.nat_pptp_info;
- /* need to alter GRE tuple because conntrack expectfn() used 'wrong'
- * (unmanipulated) values */
- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) {
- DEBUGP("completing tuples with NAT info \n");
- /* we can do this, since we're unconfirmed */
- if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.gre.key ==
- htons(ct_pptp_info->pac_call_id)) {
- /* assume PNS->PAC */
- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key =
- htons(nat_pptp_info->pns_call_id);
- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key =
- htons(nat_pptp_info->pns_call_id);
- newip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
- newcid = htons(nat_pptp_info->pac_call_id);
- } else {
- /* assume PAC->PNS */
- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key =
- htons(nat_pptp_info->pac_call_id);
- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key =
- htons(nat_pptp_info->pac_call_id);
- newip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
- newcid = htons(nat_pptp_info->pns_call_id);
- }
+ /* And here goes the grand finale of corrosion... */
+
+ if (exp->dir == IP_CT_DIR_ORIGINAL) {
+ DEBUGP("we are PNS->PAC\n");
+ /* therefore, build tuple for PAC->PNS */
+ t.src.ip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
+ t.src.u.gre.key = htons(master->help.ct_pptp_info.pac_call_id);
+ t.dst.ip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
+ t.dst.u.gre.key = htons(master->help.ct_pptp_info.pns_call_id);
+ t.dst.protonum = IPPROTO_GRE;
} else {
- if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.gre.key ==
- htons(ct_pptp_info->pac_call_id)) {
- /* assume PNS->PAC */
- newip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
- newcid = htons(ct_pptp_info->pns_call_id);
- }
- else {
- /* assume PAC->PNS */
- newip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
- newcid = htons(ct_pptp_info->pac_call_id);
- }
+ DEBUGP("we are PAC->PNS\n");
+ /* build tuple for PNS->PAC */
+ t.src.ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
+ t.src.u.gre.key =
+ htons(master->nat.help.nat_pptp_info.pns_call_id);
+ t.dst.ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
+ t.dst.u.gre.key =
+ htons(master->nat.help.nat_pptp_info.pac_call_id);
+ t.dst.protonum = IPPROTO_GRE;
}
- range.flags = IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED;
- range.min_ip = range.max_ip = newip;
- range.min = range.max =
- ((union ip_conntrack_manip_proto ) { newcid });
- DEBUGP("change ip to %u.%u.%u.%u\n",
- NIPQUAD(newip));
- DEBUGP("change key to 0x%x\n", ntohs(newcid));
- ip_nat_setup_info(ct, &range, hooknum);
+ DEBUGP("trying to unexpect other dir: ");
+ DUMP_TUPLE(&t);
+ other_exp = __ip_conntrack_exp_find(&t);
+ if (other_exp) {
+ ip_conntrack_unexpect_related(other_exp);
+ DEBUGP("success\n");
+ } else {
+ DEBUGP("not found!\n");
+ }
- UNLOCK_BH(&ip_pptp_lock);
+ ip_nat_follow_master(ct, exp);
}
/* outbound packets == from PNS to PAC */
-static inline unsigned int
+static int
pptp_outbound_pkt(struct sk_buff **pskb,
struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo,
- struct ip_conntrack_expect *exp)
+ struct PptpControlHeader *ctlh,
+ union pptp_ctrl_union *pptpReq)
{
- struct iphdr *iph = (*pskb)->nh.iph;
- struct tcphdr *tcph = (void *) iph + iph->ihl*4;
- struct pptp_pkt_hdr *pptph = (struct pptp_pkt_hdr *)
- ((void *)tcph + tcph->doff*4);
-
- struct PptpControlHeader *ctlh;
- union pptp_ctrl_union *pptpReq;
struct ip_ct_pptp_master *ct_pptp_info = &ct->help.ct_pptp_info;
struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info;
u_int16_t msg, *cid = NULL, new_callid;
- /* FIXME: size checks !!! */
- ctlh = (struct PptpControlHeader *) ((void *) pptph + sizeof(*pptph));
- pptpReq = (void *) ((void *) ctlh + sizeof(*ctlh));
-
new_callid = htons(ct_pptp_info->pns_call_id);
switch (msg = ntohs(ctlh->messageType)) {
@@ -211,115 +178,114 @@
ntohs(*cid), ntohs(new_callid));
/* mangle packet */
- return ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
- (void *)cid - (void *)pptph,
+ if (ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
+ (void *)cid - ((void *)ctlh - sizeof(struct pptp_pkt_hdr)),
sizeof(new_callid),
(char *)&new_callid,
- sizeof(new_callid));
+ sizeof(new_callid)) == 0)
+ return NF_DROP;
+
+ return NF_ACCEPT;
}
+static int
+pptp_exp_gre(struct ip_conntrack_expect *expect_orig,
+ struct ip_conntrack_expect *expect_reply)
+{
+ struct ip_ct_pptp_master *ct_pptp_info =
+ &expect_orig->master->help.ct_pptp_info;
+ struct ip_nat_pptp *nat_pptp_info =
+ &expect_orig->master->nat.help.nat_pptp_info;
+
+ struct ip_conntrack *ct = expect_orig->master;
+
+ struct ip_conntrack_tuple inv_t;
+ struct ip_conntrack_tuple *orig_t, *reply_t;
+
+ /* save original PAC call ID in nat_info */
+ nat_pptp_info->pac_call_id = ct_pptp_info->pac_call_id;
+
+ /* alter expectation */
+ orig_t = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
+ reply_t = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+
+ /* alter expectation for PNS->PAC direction */
+ invert_tuplepr(&inv_t, &expect_orig->tuple);
+ expect_orig->saved_proto.gre.key = htons(nat_pptp_info->pac_call_id);
+ expect_orig->tuple.src.u.gre.key = htons(nat_pptp_info->pns_call_id);
+ expect_orig->tuple.dst.u.gre.key = htons(ct_pptp_info->pac_call_id);
+ inv_t.src.ip = reply_t->src.ip;
+ inv_t.dst.ip = reply_t->dst.ip;
+ inv_t.src.u.gre.key = htons(nat_pptp_info->pac_call_id);
+ inv_t.dst.u.gre.key = htons(ct_pptp_info->pns_call_id);
+
+ if (!ip_conntrack_expect_related(expect_orig)) {
+ DEBUGP("successfully registered expect\n");
+ } else {
+ DEBUGP("can't expect_related(expect_orig)\n");
+ ip_conntrack_expect_free(expect_orig);
+ return 1;
+ }
+
+ /* alter expectation for PAC->PNS direction */
+ invert_tuplepr(&inv_t, &expect_reply->tuple);
+ expect_reply->saved_proto.gre.key = htons(nat_pptp_info->pns_call_id);
+ expect_reply->tuple.src.u.gre.key = htons(nat_pptp_info->pac_call_id);
+ expect_reply->tuple.dst.u.gre.key = htons(ct_pptp_info->pns_call_id);
+ inv_t.src.ip = orig_t->src.ip;
+ inv_t.dst.ip = orig_t->dst.ip;
+ inv_t.src.u.gre.key = htons(nat_pptp_info->pns_call_id);
+ inv_t.dst.u.gre.key = htons(ct_pptp_info->pac_call_id);
+
+ if (!ip_conntrack_expect_related(expect_reply)) {
+ DEBUGP("successfully registered expect\n");
+ } else {
+ DEBUGP("can't expect_related(expect_reply)\n");
+ ip_conntrack_unexpect_related(expect_orig);
+ ip_conntrack_expect_free(expect_reply);
+ return 1;
+ }
+
+ if (ip_ct_gre_keymap_add(ct, &expect_reply->tuple, 0) < 0) {
+ DEBUGP("can't register original keymap\n");
+ ip_conntrack_unexpect_related(expect_orig);
+ ip_conntrack_unexpect_related(expect_reply);
+ return 1;
+ }
+
+ if (ip_ct_gre_keymap_add(ct, &inv_t, 1) < 0) {
+ DEBUGP("can't register reply keymap\n");
+ ip_conntrack_unexpect_related(expect_orig);
+ ip_conntrack_unexpect_related(expect_reply);
+ ip_ct_gre_keymap_destroy(ct);
+ return 1;
+ }
+
+ return 0;
+}
+
/* inbound packets == from PAC to PNS */
-static inline unsigned int
+static int
pptp_inbound_pkt(struct sk_buff **pskb,
struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo,
- struct ip_conntrack_expect *oldexp)
+ struct PptpControlHeader *ctlh,
+ union pptp_ctrl_union *pptpReq)
{
- struct iphdr *iph = (*pskb)->nh.iph;
- struct tcphdr *tcph = (void *) iph + iph->ihl*4;
- struct pptp_pkt_hdr *pptph = (struct pptp_pkt_hdr *)
- ((void *)tcph + tcph->doff*4);
-
- struct PptpControlHeader *ctlh;
- union pptp_ctrl_union *pptpReq;
- struct ip_ct_pptp_master *ct_pptp_info = &ct->help.ct_pptp_info;
struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info;
-
u_int16_t msg, new_cid = 0, new_pcid, *pcid = NULL, *cid = NULL;
- u_int32_t old_dst_ip;
- struct ip_conntrack_tuple t, inv_t;
- struct ip_conntrack_tuple *orig_t, *reply_t;
int ret = NF_ACCEPT, rv;
- /* FIXME: size checks !!! */
- ctlh = (struct PptpControlHeader *) ((void *) pptph + sizeof(*pptph));
- pptpReq = (void *) ((void *) ctlh + sizeof(*ctlh));
-
new_pcid = htons(nat_pptp_info->pns_call_id);
switch (msg = ntohs(ctlh->messageType)) {
case PPTP_OUT_CALL_REPLY:
pcid = &pptpReq->ocack.peersCallID;
cid = &pptpReq->ocack.callID;
- if (!oldexp) {
- DEBUGP("outcall but no expectation\n");
- break;
- }
- old_dst_ip = oldexp->tuple.dst.ip;
- t = oldexp->tuple;
- invert_tuplepr(&inv_t, &t);
-
- /* save original PAC call ID in nat_info */
- nat_pptp_info->pac_call_id = ct_pptp_info->pac_call_id;
-
- /* alter expectation */
- orig_t = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
- reply_t = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
- if (t.src.ip == orig_t->src.ip && t.dst.ip == orig_t->dst.ip) {
- /* expectation for PNS->PAC direction */
- t.src.u.gre.key = htons(nat_pptp_info->pns_call_id);
- t.dst.u.gre.key = htons(ct_pptp_info->pac_call_id);
- inv_t.src.ip = reply_t->src.ip;
- inv_t.dst.ip = reply_t->dst.ip;
- inv_t.src.u.gre.key = htons(nat_pptp_info->pac_call_id);
- inv_t.dst.u.gre.key = htons(ct_pptp_info->pns_call_id);
- } else {
- /* expectation for PAC->PNS direction */
- t.src.u.gre.key = htons(nat_pptp_info->pac_call_id);
- t.dst.u.gre.key = htons(ct_pptp_info->pns_call_id);
- inv_t.src.ip = orig_t->src.ip;
- inv_t.dst.ip = orig_t->dst.ip;
- inv_t.src.u.gre.key = htons(nat_pptp_info->pns_call_id);
- inv_t.dst.u.gre.key = htons(ct_pptp_info->pac_call_id);
- }
-
- if (!ip_conntrack_expect_related(oldexp)) {
- DEBUGP("successfully changed expect\n");
- } else {
- DEBUGP("can't change expect\n");
- ret = NF_DROP;
- break;
- }
- if (ct->proto.gre.keymap_orig)
- ip_ct_gre_keymap_change(ct->proto.gre.keymap_orig,
- &t);
- if (ct->proto.gre.keymap_reply)
- ip_ct_gre_keymap_change(ct->proto.gre.keymap_reply,
- &inv_t);
break;
case PPTP_IN_CALL_CONNECT:
pcid = &pptpReq->iccon.peersCallID;
- if (!oldexp)
- break;
- old_dst_ip = oldexp->tuple.dst.ip;
- t = oldexp->tuple;
-
- /* alter expectation, no need for callID */
- if (t.dst.ip == ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip) {
- /* expectation for PNS->PAC direction */
- t.src.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
- } else {
- /* expectation for PAC->PNS direction */
- t.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
- }
-
- if (!ip_conntrack_expect_related(oldexp)) {
- DEBUGP("successfully changed expect\n");
- } else {
- DEBUGP("can't change expect\n");
- ret = NF_DROP;
- }
break;
case PPTP_IN_CALL_REQUEST:
/* only need to nat in case PAC is behind NAT box */
@@ -355,7 +321,7 @@
ntohs(*pcid), ntohs(new_pcid));
rv = ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
- (void *)pcid - (void *)pptph,
+ (void *)pcid - ((void *)ctlh - sizeof(struct pptp_pkt_hdr)),
sizeof(new_pcid), (char *)&new_pcid,
sizeof(new_pcid));
if (rv != NF_ACCEPT)
@@ -366,7 +332,7 @@
DEBUGP("altering call id from 0x%04x to 0x%04x\n",
ntohs(*cid), ntohs(new_cid));
rv = ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
- (void *)cid - (void *)pptph,
+ (void *)cid - ((void *)ctlh - sizeof(struct pptp_pkt_hdr)),
sizeof(new_cid),
(char *)&new_cid,
sizeof(new_cid));
@@ -383,75 +349,22 @@
}
-static unsigned int ip_nat_pptp(struct sk_buff **pskb,
- enum ip_conntrack_info ctinfo,
- struct ip_conntrack_expect *exp,
- )
-{
- struct iphdr *iph = (*pskb)->nh.iph;
- struct tcphdr *tcph = (void *) iph + iph->ihl*4;
- unsigned int datalen = (*pskb)->len - iph->ihl*4 - tcph->doff*4;
- struct pptp_pkt_hdr *pptph;
-
- int dir;
-#if 0
- DEBUGP("entering\n");
-
- /* Only mangle things once: DST for original direction
- and SRC for reply direction. */
- dir = CTINFO2DIR(ctinfo);
- if (!((HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
- && dir == IP_CT_DIR_ORIGINAL)
- || (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST
- && dir == IP_CT_DIR_REPLY))) {
- DEBUGP("Not touching dir %s at hook %s\n",
- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT"
- : hooknum == NF_IP_LOCAL_IN ? "INPUT" : "???");
- return NF_ACCEPT;
- }
-
- /* if packet is too small, just skip it */
- if (datalen < sizeof(struct pptp_pkt_hdr)+
- sizeof(struct PptpControlHeader)) {
- DEBUGP("pptp packet too short\n");
- return NF_ACCEPT;
- }
-
- pptph = (struct pptp_pkt_hdr *) ((void *)tcph + tcph->doff*4);
-
- /* if it's not a control message, we can't handle it */
- if (ntohs(pptph->packetType) != PPTP_PACKET_CONTROL ||
- ntohl(pptph->magicCookie) != PPTP_MAGIC_COOKIE) {
- DEBUGP("not a pptp control packet\n");
- return NF_ACCEPT;
- }
-#endif
- LOCK_BH(&ip_pptp_lock);
-
- if (dir == IP_CT_DIR_ORIGINAL) {
- /* reuqests sent by client to server (PNS->PAC) */
- pptp_outbound_pkt(pskb, ct, ctinfo, exp);
- } else {
- /* response from the server to the client (PAC->PNS) */
- pptp_inbound_pkt(pskb, ct, ctinfo, exp);
- }
-
- UNLOCK_BH(&ip_pptp_lock);
-
- return NF_ACCEPT;
-}
-
static int __init init(void)
{
DEBUGP("%s: registering NAT helper\n", __FILE__);
- BUG_ON(ip_nat_pptp_hook);
+ BUG_ON(ip_nat_pptp_hook_outbound);
+ ip_nat_pptp_hook_outbound = &pptp_outbound_pkt;
- ip_nat_pptp_hook = ip_nat_pptp;
+ BUG_ON(ip_nat_pptp_hook_inbound);
+ ip_nat_pptp_hook_inbound = &pptp_inbound_pkt;
+ BUG_ON(ip_nat_pptp_hook_exp_gre);
+ ip_nat_pptp_hook_exp_gre = &pptp_exp_gre;
+
+ BUG_ON(ip_nat_pptp_hook_expectfn);
+ ip_nat_pptp_hook_expectfn = &pptp_nat_expected;
+
printk("ip_nat_pptp version %s loaded\n", IP_NAT_PPTP_VERSION);
return 0;
}
@@ -460,7 +373,11 @@
{
DEBUGP("cleanup_module\n" );
- ip_nat_pptp_hook = NULL;
+ ip_nat_pptp_hook_expectfn = NULL;
+ ip_nat_pptp_hook_exp_gre = NULL;
+ ip_nat_pptp_hook_inbound = NULL;
+ ip_nat_pptp_hook_outbound = NULL;
+
/* Make sure noone calls it, meanwhile */
synchronize_net();
More information about the netfilter-cvslog
mailing list