/*
- * ip_nat_proto_gre.c - Version 1.2
+ * ip_nat_proto_gre.c - Version 2.0
*
* NAT protocol helper module for GRE.
*
*
* Documentation about PPTP can be found in RFC 2637
*
- * (C) 2000-2003 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2000-2004 by Harald Welte <laforge@gnumonks.org>
*
* Development of this code funded by Astaro AG (http://www.astaro.com/)
*
MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE");
#if 0
-#define DEBUGP(format, args...) printk(KERN_DEBUG __FILE__ ":" __FUNCTION__ \
- ": " format, ## args)
+#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, \
+ __FUNCTION__, ## args)
#else
#define DEBUGP(x, args...)
#endif
keyptr = &tuple->dst.u.gre.key;
if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
-
- switch (tuple->dst.u.gre.version) {
- case 0:
- DEBUGP("NATing GRE version 0 (ct=%p)\n",
- conntrack);
- min = 1;
- range_size = 0xffffffff;
- break;
- case GRE_VERSION_PPTP:
- DEBUGP("%p: NATing GRE PPTP\n",
- conntrack);
- min = 1;
- range_size = 0xffff;
- break;
- default:
- printk(KERN_WARNING "nat_gre: unknown GRE version\n");
- return 0;
- break;
- }
-
+ DEBUGP("%p: NATing GRE PPTP\n", conntrack);
+ min = 1;
+ range_size = 0xffff;
} else {
min = ntohl(range->min.gre.key);
range_size = ntohl(range->max.gre.key) - min + 1;
}
/* manipulate a GRE packet according to maniptype */
-static void
-gre_manip_pkt(struct iphdr *iph, size_t len,
+static int
+gre_manip_pkt(struct sk_buff **pskb,
+ unsigned int iphdroff,
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;
+ struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
+ unsigned int hdroff = iphdroff + iph->ihl*4;
+
+ /* pgreh includes two optional 32bit fields which are not required
+ * to be there. That's where the magic '8' comes from */
+ if (!skb_ip_make_writable(pskb, hdroff + sizeof(*pgreh)-8))
+ return 0;
+
+ greh = (void *)(*pskb)->data + hdroff;
+ pgreh = (struct gre_hdr_pptp *) greh;
/* we only have destination manip of a packet, since 'source key'
* is not present in the packet itself */
break;
default:
DEBUGP("can't nat unknown GRE version\n");
+ return 0;
break;
}
}
+ return 1;
}
/* print out a nat tuple */
{
unsigned int len = 0;
- if (mask->dst.u.gre.version)
- len += sprintf(buffer + len, "version=%d ",
- ntohs(match->dst.u.gre.version));
-
- if (mask->dst.u.gre.protocol)
- len += sprintf(buffer + len, "protocol=0x%x ",
- ntohs(match->dst.u.gre.protocol));
-
if (mask->src.u.gre.key)
len += sprintf(buffer + len, "srckey=0x%x ",
ntohl(match->src.u.gre.key));
}
/* nat helper struct */
-static struct ip_nat_protocol gre =
- { { NULL, NULL }, "GRE", IPPROTO_GRE,
- gre_manip_pkt,
- gre_in_range,
- gre_unique_tuple,
- gre_print,
- gre_print_range
- };
+static struct ip_nat_protocol gre = {
+ .name = "GRE",
+ .protonum = IPPROTO_GRE,
+ .manip_pkt = gre_manip_pkt,
+ .in_range = gre_in_range,
+ .unique_tuple = gre_unique_tuple,
+ .print = gre_print,
+ .print_range = gre_print_range
+};
static int __init init(void)
{
- return 0;
- 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)
{
- return 0;
- ip_nat_protocol_unregister(&gre);
+ ip_nat_protocol_unregister(&gre);
}
module_init(init);