/*
- * ip_conntrack_proto_gre.c - Version 1.2
+ * ip_conntrack_proto_gre.c - Version 2.0
*
* Connection tracking 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/)
*
#define GRE_STREAM_TIMEOUT (180*HZ)
#if 0
-#define DEBUGP(format, args...) printk(KERN_DEBUG __FILE__ ":" __FUNCTION__ \
- ": " format, ## args)
-#define DUMP_TUPLE_GRE(x) printk("%u.%u.%u.%u:0x%x -> %u.%u.%u.%u:0x%x:%u:0x%x\n", \
+#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, __FUNCTION__, ## args)
+#define DUMP_TUPLE_GRE(x) printk("%u.%u.%u.%u:0x%x -> %u.%u.%u.%u:0x%x\n", \
NIPQUAD((x)->src.ip), ntohl((x)->src.u.gre.key), \
- NIPQUAD((x)->dst.ip), ntohl((x)->dst.u.gre.key), \
- (x)->dst.u.gre.version, \
- ntohs((x)->dst.u.gre.protocol))
+ NIPQUAD((x)->dst.ip), ntohl((x)->dst.u.gre.key))
#else
#define DEBUGP(x, args...)
#define DUMP_TUPLE_GRE(x)
static int gre_invert_tuple(struct ip_conntrack_tuple *tuple,
const struct ip_conntrack_tuple *orig)
{
- tuple->dst.u.gre.protocol = orig->dst.u.gre.protocol;
- tuple->dst.u.gre.version = orig->dst.u.gre.version;
-
tuple->dst.u.gre.key = orig->src.u.gre.key;
tuple->src.u.gre.key = orig->dst.u.gre.key;
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)
- 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 */
+ grehdr = skb_header_pointer(skb, dataoff, sizeof(_grehdr), &_grehdr);
+ /* PPTP header is variable length, only need up to the call_id field */
+ pgrehdr = skb_header_pointer(skb, dataoff, 8, &_pgrehdr);
- tuple->dst.u.gre.version = grehdr.version;
- tuple->dst.u.gre.protocol = grehdr.protocol;
+ if (!grehdr || !pgrehdr)
+ return 0;
- 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:
printk(KERN_WARNING "unknown GRE version %hu\n",
- tuple->dst.u.gre.version);
+ grehdr->version);
return 0;
}
srckey = gre_keymap_lookup(tuple);
+ tuple->src.u.gre.key = srckey;
#if 0
DEBUGP("found src key %x for tuple ", ntohl(srckey));
DUMP_TUPLE_GRE(tuple);
#endif
- tuple->src.u.gre.key = srckey;
return 1;
}
/* print gre part of tuple */
-static unsigned int gre_print_tuple(char *buffer,
+static int gre_print_tuple(struct seq_file *s,
const struct ip_conntrack_tuple *tuple)
{
- return sprintf(buffer, "version=%d protocol=0x%04x srckey=0x%x dstkey=0x%x ",
- tuple->dst.u.gre.version,
- ntohs(tuple->dst.u.gre.protocol),
+ return 0;
+/*
+ return seq_printf(s, "srckey=0x%x dstkey=0x%x ",
ntohl(tuple->src.u.gre.key),
ntohl(tuple->dst.u.gre.key));
+*/
}
/* print private data for conntrack */
-static unsigned int gre_print_conntrack(char *buffer,
+static int gre_print_conntrack(struct seq_file *s,
const struct ip_conntrack *ct)
{
- return sprintf(buffer, "timeout=%u, stream_timeout=%u ",
+ return 0;
+/*
+ return seq_printf(s, "timeout=%u, stream_timeout=%u ",
(ct->proto.gre.timeout / HZ),
(ct->proto.gre.stream_timeout / HZ));
+*/
}
/* Returns verdict for packet, and may modify conntrack */
static int gre_packet(struct ip_conntrack *ct,
- const struct sk_buff *skb,
+ struct sk_buff *skb,
enum ip_conntrack_info conntrackinfo)
{
/* 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);
+ ip_ct_refresh(ct,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);
+ ip_ct_refresh(ct,ct->proto.gre.timeout);
return NF_ACCEPT;
}
}
/* protocol helper struct */
-static struct ip_conntrack_protocol gre = { { NULL, NULL }, IPPROTO_GRE,
- "gre",
- gre_pkt_to_tuple,
- gre_invert_tuple,
- gre_print_tuple,
- gre_print_conntrack,
- gre_packet,
- gre_new,
- gre_destroy,
- NULL,
- THIS_MODULE };
+static struct ip_conntrack_protocol gre = {
+ .proto = IPPROTO_GRE,
+ .name = "gre",
+ .pkt_to_tuple = gre_pkt_to_tuple,
+ .invert_tuple = gre_invert_tuple,
+ .print_tuple = gre_print_tuple,
+ .print_conntrack = gre_print_conntrack,
+ .packet = gre_packet,
+ .new = gre_new,
+ .destroy = gre_destroy,
+ .exp_matches_pkt = NULL,
+ .me = THIS_MODULE
+};
/* ip_conntrack_proto_gre initialization */
static int __init init(void)
{
int retcode;
- return 0;
if ((retcode = ip_conntrack_protocol_register(&gre))) {
printk(KERN_ERR "Unable to register conntrack protocol "
"helper for gre: %d\n", retcode);
{
struct list_head *pos, *n;
- return 0;
/* delete all keymap entries */
WRITE_LOCK(&ip_ct_gre_lock);
list_for_each_safe(pos, n, &gre_keymap_list) {