[netfilter-cvslog] r3253 - trunk/patch-o-matic-ng/pptp-conntrack-nat/linux-2.6/net/ipv4/netfilter

/C=DE/ST=Berlin/L=Berlin/O=Netfilter /C=DE/ST=Berlin/L=Berlin/O=Netfilter
Fri Oct 22 16:59:06 CEST 2004


Author: /C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=laforge/emailAddress=laforge at netfilter.org
Date: 2004-10-22 16:59:05 +0200 (Fri, 22 Oct 2004)
New Revision: 3253

Modified:
   trunk/patch-o-matic-ng/pptp-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_conntrack_pptp.c
   trunk/patch-o-matic-ng/pptp-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_conntrack_proto_gre.c
   trunk/patch-o-matic-ng/pptp-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_nat_pptp.c
   trunk/patch-o-matic-ng/pptp-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_nat_proto_gre.c
Log:
first attempt to get it working with non-linear skb's in 2.6.x


Modified: trunk/patch-o-matic-ng/pptp-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_conntrack_pptp.c
===================================================================
--- trunk/patch-o-matic-ng/pptp-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_conntrack_pptp.c	2004-10-22 11:09:26 UTC (rev 3252)
+++ trunk/patch-o-matic-ng/pptp-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_conntrack_pptp.c	2004-10-22 14:59:05 UTC (rev 3253)
@@ -1,5 +1,5 @@
 /*
- * ip_conntrack_pptp.c	- Version 1.9
+ * ip_conntrack_pptp.c	- Version 2.0
  *
  * Connection tracking support for PPTP (Point to Point Tunneling Protocol).
  * PPTP is a a protocol for creating virtual private networks.
@@ -32,6 +32,9 @@
  * 	2002-02-10 - Version 1.6
  * 	  - move to C99 style initializers
  * 	  - remove second expectation if first arrives
+ * 	2004-10-22 - Version 2.0
+ * 	  - merge Mandrake's 2.6.x port with recent 2.6.x API changes
+ * 	  - fix lots of linear skb assumptions from Mandrake's port
  *
  */
 
@@ -47,7 +50,7 @@
 #include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
 #include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
 
-#define IP_CT_PPTP_VERSION "1.9"
+#define IP_CT_PPTP_VERSION "2.0"
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge at gnumonks.org>");
@@ -156,7 +159,8 @@
 			exp->sibling);
 		exp->sibling->proto.gre.timeout = 0;
 		exp->sibling->proto.gre.stream_timeout = 0;
-		ip_ct_refresh(exp->sibling, 0);
+		/* refresh_acct will not modify counters if skb == NULL */
+		ip_ct_refresh_acct(exp->sibling, 0, NULL, 0);
 	}
 
 	return 0;
@@ -243,55 +247,76 @@
 }
 
 static inline int 
-pptp_inbound_pkt(struct tcphdr *tcph,
-		 struct pptp_pkt_hdr *pptph, 
+pptp_inbound_pkt(struct sk_buff *skb,
 		 size_t datalen,
-		 struct ip_conntrack *ct,
-		 enum ip_conntrack_info ctinfo)
+		 struct ip_conntrack *ct)
 {
-	struct PptpControlHeader *ctlh;
-        union pptp_ctrl_union pptpReq;
-	
+	struct PptpControlHeader _ctlh, *ctlh;
+	unsigned int reqlen;
+	union pptp_ctrl_union _pptpReq, *pptpReq;
 	struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
 	u_int16_t msg, *cid, *pcid;
 	u_int32_t seq;	
 
-	ctlh = (struct PptpControlHeader *) 
-		((char *) pptph + sizeof(struct pptp_pkt_hdr));
-	pptpReq.rawreq = (void *) 
-		((char *) ctlh + sizeof(struct PptpControlHeader));
+	ctlh = skb_header_pointer(skb, 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, reqoff, reqlen, &_pptpReq);
+	if (unlikely(!pptpReq)) {
+		DEBUGP("error during skb_header_pointer\n");
+		return NF_ACCEPT;
+	}
+
 	msg = ntohs(ctlh->messageType);
 	DEBUGP("inbound control message %s\n", strMName[msg]);
 
 	switch (msg) {
 	case PPTP_START_SESSION_REPLY:
+		if (reqlen < sizeof(_pptpReq.srep)) {
+			DEBUGP("%s: short packet\n", strMName[msg]);
+			break;
+		}
+
 		/* server confirms new control session */
 		if (info->sstate < PPTP_SESSION_REQUESTED) {
 			DEBUGP("%s without START_SESS_REQUEST\n",
 				strMName[msg]);
 			break;
 		}
-		if (pptpReq.srep->resultCode == PPTP_START_OK)
+		if (pptpReq->srep.resultCode == PPTP_START_OK)
 			info->sstate = PPTP_SESSION_CONFIRMED;
 		else 
 			info->sstate = PPTP_SESSION_ERROR;
 		break;
 
 	case PPTP_STOP_SESSION_REPLY:
+		if (reqlen < sizeof(_pptpReq.strep)) {
+			DEBUGP("%s: short packet\n", strMName[msg]);
+			break;
+		}
+
 		/* server confirms end of control session */
 		if (info->sstate > PPTP_SESSION_STOPREQ) {
 			DEBUGP("%s without STOP_SESS_REQUEST\n",
 				strMName[msg]);
 			break;
 		}
-		if (pptpReq.strep->resultCode == PPTP_STOP_OK)
+		if (pptpReq->strep.resultCode == PPTP_STOP_OK)
 			info->sstate = PPTP_SESSION_NONE;
 		else
 			info->sstate = PPTP_SESSION_ERROR;
 		break;
 
 	case PPTP_OUT_CALL_REPLY:
+		if (reqlen < sizeof(_pptpReq.ocack)) {
+			DEBUGP("%s: short packet\n", strMName[msg]);
+			break;
+		}
+
 		/* server accepted call, we now expect GRE frames */
 		if (info->sstate != PPTP_SESSION_CONFIRMED) {
 			DEBUGP("%s but no session\n", strMName[msg]);
@@ -302,13 +327,13 @@
 			DEBUGP("%s without OUTCALL_REQ\n", strMName[msg]);
 			break;
 		}
-		if (pptpReq.ocack->resultCode != PPTP_OUTCALL_CONNECT) {
+		if (pptpReq->ocack.resultCode != PPTP_OUTCALL_CONNECT) {
 			info->cstate = PPTP_CALL_NONE;
 			break;
 		}
 
-		cid = &pptpReq.ocack->callID;
-		pcid = &pptpReq.ocack->peersCallID;
+		cid = &pptpReq->ocack.callID;
+		pcid = &pptpReq->ocack.peersCallID;
 
 		info->pac_call_id = ntohs(*cid);
 		
@@ -323,24 +348,37 @@
 		
 		info->cstate = PPTP_CALL_OUT_CONF;
 
-		seq = ntohl(tcph->seq) + ((void *)pcid - (void *)pptph);
+		seq = ntohl(tcph->seq) + sizeof(struct pptp_pkt_hdr)
+				       + sizeof(struct PptpControlHeader)
+				       + ((void *)pcid - (void *)pptpReq);
+			
 		if (exp_gre(ct, seq, *cid, *pcid) != 0)
 			printk("ip_conntrack_pptp: error during exp_gre\n");
 		break;
 
 	case PPTP_IN_CALL_REQUEST:
+		if (reqlen < sizeof(_pptpReq.icack)) {
+			DEBUGP("%s: short packet\n", strMName[msg]);
+			break;
+		}
+
 		/* server tells us about incoming call request */
 		if (info->sstate != PPTP_SESSION_CONFIRMED) {
 			DEBUGP("%s but no session\n", strMName[msg]);
 			break;
 		}
-		pcid = &pptpReq.icack->peersCallID;
+		pcid = &pptpReq->icack.peersCallID;
 		DEBUGP("%s, PCID=%X\n", strMName[msg], ntohs(*pcid));
 		info->cstate = PPTP_CALL_IN_REQ;
-		info->pac_call_id= ntohs(*pcid);
+		info->pac_call_id = ntohs(*pcid);
 		break;
 
 	case PPTP_IN_CALL_CONNECT:
+		if (reqlen < sizeof(_pptpReq.iccon)) {
+			DEBUGP("%s: short packet\n", strMName[msg]);
+			break;
+		}
+
 		/* server tells us about incoming call established */
 		if (info->sstate != PPTP_SESSION_CONFIRMED) {
 			DEBUGP("%s but no session\n", strMName[msg]);
@@ -353,7 +391,7 @@
 			break;
 		}
 
-		pcid = &pptpReq.iccon->peersCallID;
+		pcid = &pptpReq->iccon.peersCallID;
 		cid = &info->pac_call_id;
 
 		if (info->pns_call_id != ntohs(*pcid)) {
@@ -366,15 +404,23 @@
 		info->cstate = PPTP_CALL_IN_CONF;
 
 		/* we expect a GRE connection from PAC to PNS */
-		seq = ntohl(tcph->seq) + ((void *)pcid - (void *)pptph);
+		seq = ntohl(tcph->seq) + sizeof(struct pptp_pkt_hdr)
+				       + sizeof(struct PptpControlHeader)
+				       + ((void *)pcid - (void *)pptpReq);
+			
 		if (exp_gre(ct, seq, *cid, *pcid) != 0)
 			printk("ip_conntrack_pptp: error during exp_gre\n");
 
 		break;
 
 	case PPTP_CALL_DISCONNECT_NOTIFY:
+		if (reqlen < sizeof(_pptpReq.disc)) {
+			DEBUGP("%s: short packet\n", strMName[msg]);
+			break;
+		}
+
 		/* server confirms disconnect */
-		cid = &pptpReq.disc->callID;
+		cid = &pptpReq->disc.callID;
 		DEBUGP("%s, CID=%X\n", strMName[msg], ntohs(*cid));
 		info->cstate = PPTP_CALL_NONE;
 
@@ -400,19 +446,25 @@
 }
 
 static inline int
-pptp_outbound_pkt(struct tcphdr *tcph,
-		  struct pptp_pkt_hdr *pptph,
+pptp_outbound_pkt(struct sk_buff *skb,
 		  size_t datalen,
-		  struct ip_conntrack *ct,
-		  enum ip_conntrack_info ctinfo)
+		  struct ip_conntrack *ct)
 {
-	struct PptpControlHeader *ctlh;
-        union pptp_ctrl_union pptpReq;
+	struct PptpControlHeader _ctlh, *ctlh;
+	unsigned int reqlen;
+	union pptp_ctrl_union _pptpReq, *pptpReq;
 	struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
 	u_int16_t msg, *cid, *pcid;
 
-	ctlh = (struct PptpControlHeader *) ((void *) pptph + sizeof(*pptph));
-	pptpReq.rawreq = (void *) ((void *) ctlh + sizeof(*ctlh));
+	ctlh = skb_header_pointer(skb, 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);
+	if (!pptpReq)
+		return NF_ACCEPT;
 
 	msg = ntohs(ctlh->messageType);
 	DEBUGP("outbound control message %s\n", strMName[msg]);
@@ -432,6 +484,11 @@
 		break;
 
 	case PPTP_OUT_CALL_REQUEST:
+		if (reqlen < sizeof(_pptpReq.ocreq)) {
+			DEBUGP("%s: short packet\n", strMName[msg]);
+			break;
+		}
+
 		/* client initiating connection to server */
 		if (info->sstate != PPTP_SESSION_CONFIRMED) {
 			DEBUGP("%s but no session\n",
@@ -440,11 +497,16 @@
 		}
 		info->cstate = PPTP_CALL_OUT_REQ;
 		/* track PNS call id */
-		cid = &pptpReq.ocreq->callID;
+		cid = &pptpReq->ocreq.callID;
 		DEBUGP("%s, CID=%X\n", strMName[msg], ntohs(*cid));
 		info->pns_call_id = ntohs(*cid);
 		break;
 	case PPTP_IN_CALL_REPLY:
+		if (reqlen < sizeof(_pptpReq.icack)) {
+			DEBUGP("%s: short packet\n", strMName[msg]);
+			break;
+		}
+
 		/* client answers incoming call */
 		if (info->cstate != PPTP_CALL_IN_REQ
 		    && info->cstate != PPTP_CALL_IN_REP) {
@@ -452,11 +514,11 @@
 				strMName[msg]);
 			break;
 		}
-		if (pptpReq.icack->resultCode != PPTP_INCALL_ACCEPT) {
+		if (pptpReq->icack.resultCode != PPTP_INCALL_ACCEPT) {
 			info->cstate = PPTP_CALL_NONE;
 			break;
 		}
-		pcid = &pptpReq.icack->peersCallID;
+		pcid = &pptpReq->icack.peersCallID;
 		if (info->pac_call_id != ntohs(*pcid)) {
 			DEBUGP("%s for unknown call %u\n", 
 				strMName[msg], ntohs(*pcid));
@@ -502,11 +564,11 @@
 		    struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
 
 {
-	struct pptp_pkt_hdr *pptph;
+	struct pptp_pkt_hdr _pptph, *pptph;
 	
-	struct tcphdr *tcph = (void *) skb->nh.iph + skb->nh.iph->ihl * 4;
+	struct tcphdr _tcph, *tcph;
 	u_int32_t tcplen = skb->len - skb->nh.iph->ihl * 4;
-	u_int32_t datalen = tcplen - tcph->doff * 4;
+	u_int32_t datalen;
 	void *datalimit;
 	int dir = CTINFO2DIR(ctinfo);
 	struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
@@ -527,6 +589,13 @@
 		return NF_ACCEPT;
 	}
 
+	tcph = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_tcph),
+				  &_tcph);
+	if (!tcph)
+		return NF_ACCEPT;
+
+ 	datalen = tcplen - tcph->doff * 4;
+
 	/* checksum invalid? */
 	if (tcp_v4_check(tcph, tcplen, skb->nh.iph->saddr, skb->nh.iph->daddr,
 			csum_partial((char *) tcph, tcplen, 0))) {
@@ -544,18 +613,17 @@
 		pptp_timeout_related(ct);
 	}
 
+	pptph = skb_header_pointer(skb, skb->nh.iph->ihl*4 + tcph->doff*4,
+				   sizeof(_pptph), &_pptph);
+	if (!pptph) {
+		DEBUGP("no full PPTP header, can't track\n");
+		return NF_ACCEPT;
+	}
 
-	pptph = (struct pptp_pkt_hdr *) ((void *) tcph + tcph->doff * 4);
 	datalimit = (void *) pptph + datalen;
 
-	/* not a full pptp packet header? */
-	if ((void *) pptph+sizeof(*pptph) >= datalimit) {
-		DEBUGP("no full PPTP header, can't track\n");
-		return NF_ACCEPT;
-	}
-	
 	/* if it's not a control message we can't do anything with it */
-        if (ntohs(pptph->packetType) != PPTP_PACKET_CONTROL ||
+	if (ntohs(pptph->packetType) != PPTP_PACKET_CONTROL ||
 	    ntohl(pptph->magicCookie) != PPTP_MAGIC_COOKIE) {
 		DEBUGP("not a control packet\n");
 		return NF_ACCEPT;
@@ -570,10 +638,10 @@
 	 * established from PNS->PAC.  However, RFC makes no guarantee */
 	if (dir == IP_CT_DIR_ORIGINAL)
 		/* client -> server (PNS -> PAC) */
-		ret = pptp_outbound_pkt(tcph, pptph, datalen, ct, ctinfo);
+		ret = pptp_outbound_pkt(skb, datalen, ct);
 	else
 		/* server -> client (PAC -> PNS) */
-		ret = pptp_inbound_pkt(tcph, pptph, datalen, ct, ctinfo);
+		ret = pptp_inbound_pkt(skb, datalen, ct);
 	DEBUGP("sstate: %d->%d, cstate: %d->%d\n",
 		oldsstate, info->sstate, oldcstate, info->cstate);
 	UNLOCK_BH(&ip_pptp_lock);
@@ -616,7 +684,7 @@
 
 	DEBUGP(__FILE__ ": registering helper\n");
 	if ((retcode = ip_conntrack_helper_register(&pptp))) {
-                printk(KERN_ERR "Unable to register conntrack application "
+		printk(KERN_ERR "Unable to register conntrack application "
 				"helper for pptp: %d\n", retcode);
 		return -EIO;
 	}

Modified: trunk/patch-o-matic-ng/pptp-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_conntrack_proto_gre.c
===================================================================
--- trunk/patch-o-matic-ng/pptp-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_conntrack_proto_gre.c	2004-10-22 11:09:26 UTC (rev 3252)
+++ trunk/patch-o-matic-ng/pptp-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_conntrack_proto_gre.c	2004-10-22 14:59:05 UTC (rev 3253)
@@ -1,5 +1,5 @@
 /*
- * ip_conntrack_proto_gre.c - Version 1.2 
+ * ip_conntrack_proto_gre.c - Version 2.0 
  *
  * Connection tracking protocol helper module for GRE.
  *
@@ -17,7 +17,7 @@
  *
  * Documentation about PPTP can be found in RFC 2637
  *
- * (C) 2000-2003 by Harald Welte <laforge at gnumonks.org>
+ * (C) 2000-2004 by Harald Welte <laforge at gnumonks.org>
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  *
@@ -56,7 +56,7 @@
 
 #if 0
 #define DEBUGP(format, args...) printk(KERN_DEBUG __FILE__ ":" __FUNCTION__ \
-		                       ": " format, ## args)
+				       ": " format, ## args)
 #define DUMP_TUPLE_GRE(x) printk("%u.%u.%u.%u:0x%x -> %u.%u.%u.%u:0x%x:%u:0x%x\n", \
 			NIPQUAD((x)->src.ip), ntohl((x)->src.u.gre.key), \
 			NIPQUAD((x)->dst.ip), ntohl((x)->dst.u.gre.key), \
@@ -75,8 +75,8 @@
 {
 	return ((km->tuple.src.ip == t->src.ip) &&
 		(km->tuple.dst.ip == t->dst.ip) &&
-	        (km->tuple.dst.protonum == t->dst.protonum) &&
-	        (km->tuple.dst.u.all == t->dst.u.all));
+		(km->tuple.dst.protonum == t->dst.protonum) &&
+		(km->tuple.dst.u.all == t->dst.u.all));
 }
 
 /* look up the source key for a given tuple */
@@ -181,41 +181,35 @@
 static int gre_pkt_to_tuple(const struct sk_buff *skb,
 			   unsigned int dataoff,
 			   struct ip_conntrack_tuple *tuple)
-     /*(const void *datah, size_t datalen,
-       struct ip_conntrack_tuple *tuple) */
 {
-  /*	struct gre_hdr *grehdr = (struct gre_hdr *) datah;
-	struct gre_hdr_pptp *pgrehdr = (struct gre_hdr_pptp *) datah;
-	u_int32_t srckey;*/
-	struct gre_hdr grehdr;
-	struct gre_hdr_pptp pgrehdr;
+	struct gre_hdr _grehdr, *grehdr;
+	struct gre_hdr_pptp _pgrehdr, *pgrehdr;
 	u_int32_t srckey;
 
-	if (skb_copy_bits(skb, dataoff, &grehdr, sizeof(struct gre_hdr)) != 0)
+	grehdr = skb_header_pointer(skb, dataoff, &_grehdr, sizeof(_grehdr));
+	pgrehdr = skb_header_pointer(skb, dataoff, &_pgrehdr, sizeof(_pgrehdr));
+
+	if (!grehdr || !pgrehdr)
 		return 0;
-	if (skb_copy_bits(skb, dataoff, &pgrehdr, sizeof(struct gre_hdr_pptp)) != 0)
-		return 0;
 
-	/* core guarantees 8 protocol bytes, no need for size check */
+	tuple->dst.u.gre.version = grehdr->version; 
+	tuple->dst.u.gre.protocol = grehdr->protocol;
 
-	tuple->dst.u.gre.version = grehdr.version; 
-	tuple->dst.u.gre.protocol = grehdr.protocol;
-
-	switch (grehdr.version) {
+	switch (grehdr->version) {
 		case GRE_VERSION_1701:
-			if (!grehdr.key) {
+			if (!grehdr->key) {
 				DEBUGP("Can't track GRE without key\n");
 				return 0;
 			}
-			tuple->dst.u.gre.key = *(gre_key(&grehdr));
+			tuple->dst.u.gre.key = *(gre_key(grehdr));
 			break;
 
 		case GRE_VERSION_PPTP:
-			if (ntohs(grehdr.protocol) != GRE_PROTOCOL_PPTP) {
+			if (ntohs(grehdr->protocol) != GRE_PROTOCOL_PPTP) {
 				DEBUGP("GRE_VERSION_PPTP but unknown proto\n");
 				return 0;
 			}
-			tuple->dst.u.gre.key = htonl(ntohs(pgrehdr.call_id));
+			tuple->dst.u.gre.key = htonl(ntohs(pgrehdr->call_id));
 			break;
 
 		default:
@@ -263,11 +257,13 @@
 	/* If we've seen traffic both ways, this is a GRE connection.
 	 * Extend timeout. */
 	if (ct->status & IPS_SEEN_REPLY) {
-		ip_ct_refresh(ct, ct->proto.gre.stream_timeout);
+		ip_ct_refresh_acct(ct, conntrackinfo, skb,
+				   ct->proto.gre.stream_timeout);
 		/* Also, more likely to be important, and not a probe. */
 		set_bit(IPS_ASSURED_BIT, &ct->status);
 	} else
-		ip_ct_refresh(ct, ct->proto.gre.timeout);
+		ip_ct_refresh_acct(ct, conntrackinfo, skb,
+				   ct->proto.gre.timeout);
 	
 	return NF_ACCEPT;
 }
@@ -322,8 +318,8 @@
 	int retcode;
 
 	if ((retcode = ip_conntrack_protocol_register(&gre))) {
-                printk(KERN_ERR "Unable to register conntrack protocol "
-			        "helper for gre: %d\n",	retcode);
+		printk(KERN_ERR "Unable to register conntrack protocol "
+		       "helper for gre: %d\n", retcode);
 		return -EIO;
 	}
 

Modified: trunk/patch-o-matic-ng/pptp-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_nat_pptp.c
===================================================================
--- trunk/patch-o-matic-ng/pptp-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_nat_pptp.c	2004-10-22 11:09:26 UTC (rev 3252)
+++ trunk/patch-o-matic-ng/pptp-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_nat_pptp.c	2004-10-22 14:59:05 UTC (rev 3253)
@@ -1,5 +1,5 @@
 /*
- * ip_nat_pptp.c	- Version 1.5
+ * ip_nat_pptp.c	- Version 2.0
  *
  * NAT support for PPTP (Point to Point Tunneling Protocol).
  * PPTP is a a protocol for creating virtual private networks.
@@ -9,7 +9,7 @@
  * GRE is defined in RFC 1701 and RFC 1702.  Documentation of
  * PPTP can be found in RFC 2637
  *
- * (C) 2000-2003 by Harald Welte <laforge at gnumonks.org>
+ * (C) 2000-2004 by Harald Welte <laforge at gnumonks.org>
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  *
@@ -28,7 +28,9 @@
  *       - print version number at module loadtime
  *     2003-09-22 - Version 1.5
  *       - use SNATed tcp sourceport as callid, since we get called before
- *         TCP header is mangled (Philip Craig <philipc at snapgear.com>)
+ *	   TCP header is mangled (Philip Craig <philipc at snapgear.com>)
+ *     2004-10-22 - Version 2.0
+ *       - kernel 2.6.x version
  * 
  */
 
@@ -45,7 +47,7 @@
 #include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
 #include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
 
-#define IP_NAT_PPTP_VERSION "1.5"
+#define IP_NAT_PPTP_VERSION "2.0"
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge at gnumonks.org>");

Modified: trunk/patch-o-matic-ng/pptp-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_nat_proto_gre.c
===================================================================
--- trunk/patch-o-matic-ng/pptp-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_nat_proto_gre.c	2004-10-22 11:09:26 UTC (rev 3252)
+++ trunk/patch-o-matic-ng/pptp-conntrack-nat/linux-2.6/net/ipv4/netfilter/ip_nat_proto_gre.c	2004-10-22 14:59:05 UTC (rev 3253)
@@ -1,5 +1,5 @@
 /*
- * ip_nat_proto_gre.c - Version 1.2
+ * ip_nat_proto_gre.c - Version 2.0
  *
  * NAT protocol helper module for GRE.
  *
@@ -17,7 +17,7 @@
  *
  * Documentation about PPTP can be found in RFC 2637
  *
- * (C) 2000-2003 by Harald Welte <laforge at gnumonks.org>
+ * (C) 2000-2004 by Harald Welte <laforge at gnumonks.org>
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  *
@@ -116,13 +116,20 @@
 
 /* manipulate a GRE packet according to maniptype */
 static void 
-gre_manip_pkt(struct iphdr *iph, size_t len, 
+gre_manip_pkt(struct sk_buff **pskb,
+	      unsigned int hdroff,
 	      const struct ip_conntrack_manip *manip,
 	      enum ip_nat_manip_type maniptype)
 {
-	struct gre_hdr *greh = (struct gre_hdr *)((u_int32_t *)iph+iph->ihl);
-	struct gre_hdr_pptp *pgreh = (struct gre_hdr_pptp *) greh;
+	struct gre_hdr *greh;
+	struct gre_hdr_pptp *pgreh;
 
+	if (!skb_ip_make_writable(pskb, hdroff + sizeof(hdr)))
+		return 0;
+
+	greh = (void *)(*pskb)->data + hdroff;
+	pgreh = greh;
+
 	/* we only have destination manip of a packet, since 'source key' 
 	 * is not present in the packet itself */
 	if (maniptype == IP_NAT_MANIP_DST) {
@@ -210,15 +217,15 @@
 				  
 static int __init init(void)
 {
-        if (ip_nat_protocol_register(&gre))
-                return -EIO;
+	if (ip_nat_protocol_register(&gre))
+		return -EIO;
 
-        return 0;
+	return 0;
 }
 
 static void __exit fini(void)
 {
-        ip_nat_protocol_unregister(&gre);
+	ip_nat_protocol_unregister(&gre);
 }
 
 module_init(init);




More information about the netfilter-cvslog mailing list