diff --exclude CVS -Nur ./patch-o-matic/extra/amanda-conntrack-nat.patch ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch --- ./patch-o-matic/extra/amanda-conntrack-nat.patch 1969-12-31 19:00:00.000000000 -0500 +++ ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch 2002-08-28 04:16:34.000000000 -0400 @@ -0,0 +1,486 @@ +diff -uNr linux-2.4.18-6mdk-pom-clean/include/linux/netfilter_ipv4/ip_conntrack_amanda.h linux-2.4.18-6mdkuml-48um-pom/include/linux/netfilter_ipv4/ip_conntrack_amanda.h +--- linux-2.4.18-6mdk-pom-clean/include/linux/netfilter_ipv4/ip_conntrack_amanda.h 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.4.18-6mdkuml-48um-pom/include/linux/netfilter_ipv4/ip_conntrack_amanda.h 2002-08-16 04:11:23.000000000 -0400 +@@ -0,0 +1,29 @@ ++#ifndef _IP_CONNTRACK_AMANDA_H ++#define _IP_CONNTRACK_AMANDA_H ++/* AMANDA tracking. */ ++ ++#ifdef __KERNEL__ ++ ++#include ++ ++/* Protects amanda part of conntracks */ ++DECLARE_LOCK_EXTERN(ip_amanda_lock); ++ ++#endif ++ ++struct conn { ++ char* match; ++ int matchlen; ++}; ++ ++#define NUM_MSGS 3 ++ ++ ++struct ip_ct_amanda_expect ++{ ++ u_int16_t port; /* port number of this expectation */ ++ u_int16_t offset; /* offset of the port specification in ctrl packet */ ++ u_int16_t len; /* the length of the port number specification */ ++}; ++ ++#endif /* _IP_CONNTRACK_AMANDA_H */ +diff -uNr linux-2.4.18-6mdk-pom-clean/net/ipv4/netfilter/ip_conntrack_amanda.c linux-2.4.18-6mdkuml-48um-pom/net/ipv4/netfilter/ip_conntrack_amanda.c +--- linux-2.4.18-6mdk-pom-clean/net/ipv4/netfilter/ip_conntrack_amanda.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.4.18-6mdkuml-48um-pom/net/ipv4/netfilter/ip_conntrack_amanda.c 2002-08-16 04:24:25.000000000 -0400 +@@ -0,0 +1,219 @@ ++/* Amanda extension for IP connection tracking, Version 0.1 ++ * (C) 2002 by Brian J. Murrell ++ * based on HW's ip_conntrack_irc.c as well as other modules ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ * ++ * Module load syntax: ++ * insmod ip_conntrack_amanda.o ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++MODULE_AUTHOR("Brian J. Murrell "); ++MODULE_DESCRIPTION("Amanda connection tracking module"); ++MODULE_LICENSE("GPL"); ++ ++DECLARE_LOCK(ip_amanda_lock); ++struct module *ip_conntrack_amanda = THIS_MODULE; ++ ++#define MAXMATCHLEN 6 ++struct conn conns[NUM_MSGS] = { ++ {"DATA ", 5}, ++ {"MESG ", 5}, ++ {"INDEX ", 6}, ++}; ++ ++#if 0 ++#define DEBUGP printk ++#else ++#define DEBUGP(format, args...) ++#endif ++ ++ ++/* FIXME: This should be in userspace. Later. */ ++static int help(const struct iphdr *iph, size_t len, ++ struct ip_conntrack *ct, enum ip_conntrack_info ctinfo) ++{ ++ struct udphdr *udph = (void *)iph + iph->ihl * 4; ++ u_int32_t udplen = len - iph->ihl * 4; ++ u_int32_t datalen = udplen - sizeof(struct udphdr); ++ char *data = (char *)udph + sizeof(struct udphdr); ++ char *datap = data; ++ char *data_limit = (char *) data + datalen; ++ int dir = CTINFO2DIR(ctinfo); ++ struct ip_ct_amanda *info = ++ (struct ip_ct_amanda *)&ct->help.ct_ftp_info; ++ ++ /* Can't track connections formed before we registered */ ++ if (!info) ++ return NF_ACCEPT; ++ ++ /* If packet is coming from Amanda server */ ++ if (dir == IP_CT_DIR_ORIGINAL) ++ return NF_ACCEPT; ++ ++ /* Not whole UDP header? */ ++ if (udplen < sizeof(struct udphdr)) { ++ printk("ip_conntrack_amanda_help: udplen = %u\n", ++ (unsigned)udplen); ++ return NF_ACCEPT; ++ } ++ ++ /* Checksum invalid? Ignore. */ ++ if (csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP, ++ csum_partial((char *)udph, udplen, 0))) { ++ DEBUGP("ip_ct_talk_help: bad csum: %p %u %u.%u.%u.%u " ++ "%u.%u.%u.%u\n", ++ udph, udplen, NIPQUAD(iph->saddr), ++ NIPQUAD(iph->daddr)); ++ return NF_ACCEPT; ++ } ++ ++ /* Search for the CONNECT string */ ++ while (data < data_limit) { ++ if (!memcmp(data, "CONNECT ", 8)) { ++ break; ++ } ++ data++; ++ } ++ if (memcmp(data, "CONNECT ", 8)) ++ return NF_ACCEPT; ++ ++ DEBUGP("ip_conntrack_amanda_help: CONNECT found in connection " ++ "%u.%u.%u.%u:%u %u.%u.%u.%u:%u\n", ++ NIPQUAD(iph->saddr), htons(udph->source), ++ NIPQUAD(iph->daddr), htons(udph->dest)); ++ data += 8; ++ while (*data != 0x0a && data < data_limit) { ++ ++ int i; ++ ++ for (i = 0; i < NUM_MSGS; i++) { ++ if (!memcmp(data, conns[i].match, ++ conns[i].matchlen)) { ++ ++ char *portchr; ++ struct ip_conntrack_expect expect; ++ struct ip_ct_amanda_expect ++ *exp_amanda_info = ++ &expect.help.exp_amanda_info; ++ ++ memset(&expect, 0, sizeof(expect)); ++ ++ data += conns[i].matchlen; ++ /* this is not really tcp, but let's steal an ++ * idea from a tcp stream helper :-) ++ */ ++ // XXX expect.seq = data - datap; ++ exp_amanda_info->offset = data - datap; ++// XXX DEBUGP("expect.seq = %p - %p = %d\n", data, datap, expect.seq); ++DEBUGP("exp_amanda_info->offset = %p - %p = %d\n", data, datap, exp_amanda_info->offset); ++ portchr = data; ++ exp_amanda_info->port = ++ simple_strtoul(data, &data, 10); ++ exp_amanda_info->len = data - portchr; ++ ++ /* eat whitespace */ ++ while (*data == ' ') ++ data++; ++ DEBUGP ("ip_conntrack_amanda_help: " ++ "CONNECT %s request with port " ++ "%u found\n", conns[i].match, ++ exp_amanda_info->port); ++ ++ LOCK_BH(&ip_amanda_lock); ++ ++ expect.tuple = ((struct ip_conntrack_tuple) ++ { { ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip, ++ { 0 } }, ++ { ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip, ++ { htons(exp_amanda_info->port) }, ++ IPPROTO_TCP }}); ++ expect.mask = ((struct ip_conntrack_tuple) ++ { { 0, { 0 } }, ++ { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }}); ++ ++ expect.expectfn = NULL; ++ ++ DEBUGP ("ip_conntrack_amanda_help: " ++ "expect_related: %u.%u.%u.%u:%u - " ++ "%u.%u.%u.%u:%u\n", ++ NIPQUAD(expect.tuple.src.ip), ++ ntohs(expect.tuple.src.u.tcp.port), ++ NIPQUAD(expect.tuple.dst.ip), ++ ntohs(expect.tuple.dst.u.tcp.port)); ++ if (ip_conntrack_expect_related(ct, &expect) == ++ -EEXIST) { ++ ; ++ /* this must be a packet being resent */ ++ /* XXX - how do I get the ++ * ip_conntrack_expect that ++ * already exists so that I can ++ * update the .seq so that the ++ * nat module rewrites the port ++ * numbers? ++ * Perhaps I should use the ++ * exp_amanda_info instead of ++ * .seq. ++ */ ++ } ++ UNLOCK_BH(&ip_amanda_lock); ++ } /* if memcmp(conns) */ ++ } /* for .. NUM_MSGS */ ++ data++; ++ } /* while (*data != 0x0a && data < data_limit) */ ++ ++ return NF_ACCEPT; ++} ++ ++static struct ip_conntrack_helper amanda_helper; ++ ++static void fini(void) ++{ ++ DEBUGP("ip_ct_amanda: unregistering helper for port 10080\n"); ++ ip_conntrack_helper_unregister(&amanda_helper); ++} ++ ++static int __init init(void) ++{ ++ int ret; ++ ++ memset(&amanda_helper, 0, sizeof(struct ip_conntrack_helper)); ++ amanda_helper.tuple.src.u.udp.port = htons(10080); ++ amanda_helper.tuple.dst.protonum = IPPROTO_UDP; ++ amanda_helper.mask.src.u.udp.port = 0xFFFF; ++ amanda_helper.mask.dst.protonum = 0xFFFF; ++ amanda_helper.max_expected = NUM_MSGS; ++ amanda_helper.timeout = 180; ++ amanda_helper.flags = IP_CT_HELPER_F_REUSE_EXPECT; ++ amanda_helper.me = ip_conntrack_amanda; ++ amanda_helper.help = help; ++ amanda_helper.name = "amanda"; ++ ++ DEBUGP("ip_ct_amanda: registering helper for port 10080\n"); ++ ++ ret = ip_conntrack_helper_register(&amanda_helper); ++ ++ if (ret) { ++ printk("ip_ct_amanda: ERROR registering helper\n"); ++ fini(); ++ return -EBUSY; ++ } ++ return 0; ++} ++ ++module_init(init); ++module_exit(fini); +diff -uNr linux-2.4.18-6mdk-pom-clean/net/ipv4/netfilter/ip_nat_amanda.c linux-2.4.18-6mdkuml-48um-pom/net/ipv4/netfilter/ip_nat_amanda.c +--- linux-2.4.18-6mdk-pom-clean/net/ipv4/netfilter/ip_nat_amanda.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.4.18-6mdkuml-48um-pom/net/ipv4/netfilter/ip_nat_amanda.c 2002-08-16 04:24:51.000000000 -0400 +@@ -0,0 +1,226 @@ ++/* Amanda extension for TCP NAT alteration. ++ * (C) 2002 by Brian J. Murrell ++ * based on a copy of HW's ip_nat_irc.c as well as other modules ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ * ++ * Module load syntax: ++ * insmod ip_nat_amanda.o ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++ ++#if 0 ++#define DEBUGP printk ++#define DUMP_OFFSET(x) printk("offset_before=%d, offset_after=%d, correction_pos=%u\n", x->offset_before, x->offset_after, x->correction_pos); ++#else ++#define DEBUGP(format, args...) ++#define DUMP_OFFSET(x) ++#endif ++ ++MODULE_AUTHOR("Brian J. Murrell "); ++MODULE_DESCRIPTION("Amanda network address translation module"); ++MODULE_LICENSE("GPL"); ++ ++/* protects amanda part of conntracks */ ++DECLARE_LOCK_EXTERN(ip_amanda_lock); ++ ++static unsigned int ++amanda_nat_expected(struct sk_buff **pskb, ++ unsigned int hooknum, ++ struct ip_conntrack *ct, ++ struct ip_nat_info *info) ++{ ++ struct ip_nat_multi_range mr; ++ u_int32_t newdstip, newsrcip, newip; ++ u_int16_t port; ++ struct ip_ct_amanda_expect *exp_info; ++ struct ip_conntrack *master = master_ct(ct); ++ ++ IP_NF_ASSERT(info); ++ IP_NF_ASSERT(master); ++ ++ IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum)))); ++ ++ DEBUGP("nat_expected: We have a connection!\n"); ++ exp_info = &ct->master->help.exp_amanda_info; ++ ++ newdstip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip; ++ newsrcip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; ++ DEBUGP("nat_expected: %u.%u.%u.%u->%u.%u.%u.%u\n", ++ NIPQUAD(newsrcip), NIPQUAD(newdstip)); ++ ++ port = exp_info->port; ++ ++ if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) ++ newip = newsrcip; ++ else ++ newip = newdstip; ++ ++ DEBUGP("nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip)); ++ ++ mr.rangesize = 1; ++ /* We don't want to manip the per-protocol, just the IPs. */ ++ mr.range[0].flags = IP_NAT_RANGE_MAP_IPS; ++ mr.range[0].min_ip = mr.range[0].max_ip = newip; ++ ++ if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) { ++ mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED; ++ mr.range[0].min = mr.range[0].max ++ = ((union ip_conntrack_manip_proto) ++ { htons(port) }); ++ } ++ ++ return ip_nat_setup_info(ct, &mr, hooknum); ++} ++ ++static int amanda_data_fixup(struct ip_conntrack *ct, ++ struct sk_buff **pskb, ++ enum ip_conntrack_info ctinfo, ++ struct ip_conntrack_expect *expect) ++{ ++ u_int32_t newip; ++ /* DATA 99999 MESG 99999 INDEX 99999 */ ++ char buffer[6]; ++ struct ip_conntrack_expect *exp = expect; ++ struct ip_ct_amanda_expect *ct_amanda_info = &exp->help.exp_amanda_info; ++ struct ip_conntrack_tuple t = exp->tuple; ++ int port; ++ ++ MUST_BE_LOCKED(&ip_amanda_lock); ++ ++ newip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; ++ DEBUGP ("ip_nat_amanda_help: newip = %u.%u.%u.%u\n", NIPQUAD(newip)); ++ ++ /* Alter conntrack's expectations. */ ++ ++ /* We can read expect here without conntrack lock, since it's ++ only set in ip_conntrack_amanda, with ip_amanda_lock held ++ writable */ ++ ++ t.dst.ip = newip; ++ for (port = ct_amanda_info->port + 10; port != 0; port++) { ++ t.dst.u.tcp.port = htons(port); ++ if (ip_conntrack_change_expect(exp, &t) == 0) ++ break; ++ } ++ ++ if (port == 0) ++ return 0; ++ ++ sprintf(buffer, "%u", port); ++ ++ return ip_nat_mangle_udp_packet(pskb, ct, ctinfo, /* XXX exp->seq */ ct_amanda_info->offset, ++ ct_amanda_info->len, buffer, strlen(buffer)); ++} ++ ++static unsigned int help(struct ip_conntrack *ct, ++ struct ip_conntrack_expect *exp, ++ struct ip_nat_info *info, ++ enum ip_conntrack_info ctinfo, ++ unsigned int hooknum, ++ struct sk_buff **pskb) ++{ ++ int dir; ++ ++ if (!exp) ++ DEBUGP("ip_nat_amanda: no exp!!"); ++ ++ /* Only mangle things once: original direction in POST_ROUTING ++ and reply direction on PRE_ROUTING. */ ++ dir = CTINFO2DIR(ctinfo); ++ if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL) ++ || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) { ++ DEBUGP("ip_nat_amanda_help: 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; ++ } ++ DEBUGP("ip_nat_amanda_help: got beyond not touching: dir %s at hook %s for expect: ", ++ 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" : "???"); ++ DUMP_TUPLE(&exp->tuple); ++ ++ LOCK_BH(&ip_amanda_lock); ++// XXX if (exp->seq != 0) ++ if (exp->help.exp_amanda_info.offset != 0) ++ /* if this packet has a "seq" it needs to have it's content mangled */ ++ if (!amanda_data_fixup(ct, pskb, ctinfo, exp)) { ++ UNLOCK_BH(&ip_amanda_lock); ++ DEBUGP("ip_nat_amanda: NF_DROP\n"); ++ return NF_DROP; ++ } ++ exp->help.exp_amanda_info.offset = 0; ++ UNLOCK_BH(&ip_amanda_lock); ++ ++ DEBUGP("ip_nat_amanda: NF_ACCEPT\n"); ++ return NF_ACCEPT; ++} ++ ++static struct ip_nat_helper ip_nat_amanda_helper; ++ ++/* This function is intentionally _NOT_ defined as __exit, because ++ * it is needed by init() */ ++static void fini(void) ++{ ++ DEBUGP("ip_nat_amanda: unregistering nat helper\n"); ++ ip_nat_helper_unregister(&ip_nat_amanda_helper); ++} ++ ++static int __init init(void) ++{ ++ int ret = 0; ++ struct ip_nat_helper *hlpr; ++ ++ hlpr = &ip_nat_amanda_helper; ++ memset(hlpr, 0, sizeof(struct ip_nat_helper)); ++ ++ hlpr->tuple.dst.protonum = IPPROTO_UDP; ++ hlpr->tuple.src.u.udp.port = htons(10080); ++ hlpr->mask.src.u.udp.port = 0xFFFF; ++ hlpr->mask.dst.protonum = 0xFFFF; ++ hlpr->help = help; ++ hlpr->flags = 0; ++ hlpr->me = THIS_MODULE; ++ hlpr->expect = amanda_nat_expected; ++ ++ hlpr->name = "amanda"; ++ ++ DEBUGP ++ ("ip_nat_amanda: Trying to register nat helper\n"); ++ ret = ip_nat_helper_register(hlpr); ++ ++ if (ret) { ++ printk ++ ("ip_nat_amanda: error registering nat helper\n"); ++ fini(); ++ return 1; ++ } ++ return ret; ++} ++ ++ ++module_init(init); ++module_exit(fini); diff --exclude CVS -Nur ./patch-o-matic/extra/amanda-conntrack-nat.patch~ ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch~ --- ./patch-o-matic/extra/amanda-conntrack-nat.patch~ 1969-12-31 19:00:00.000000000 -0500 +++ ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch~ 2002-08-28 04:15:43.000000000 -0400 @@ -0,0 +1,486 @@ +diff -uNr linux-2.4.18-6mdk-pom-clean/include/linux/netfilter_ipv4/ip_conntrack_amanda.h linux-2.4.18-6mdkuml-48um-pom/include/linux/netfilter_ipv4/ip_conntrack_amanda.h +--- linux-2.4.18-6mdk-pom-clean/include/linux/netfilter_ipv4/ip_conntrack_amanda.h 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.4.18-6mdkuml-48um-pom/include/linux/netfilter_ipv4/ip_conntrack_amanda.h 2002-08-16 04:11:23.000000000 -0400 +@@ -0,0 +1,28 @@ ++#ifndef _IP_CONNTRACK_AMANDA_H ++#define _IP_CONNTRACK_AMANDA_H ++/* AMANDA tracking. */ ++ ++#ifdef __KERNEL__ ++ ++#include ++ ++/* Protects amanda part of conntracks */ ++DECLARE_LOCK_EXTERN(ip_amanda_lock); ++ ++#endif ++ ++struct conn { ++ char* match; ++ int matchlen; ++}; ++ ++#define NUM_MSGS 3 ++ ++ ++struct ip_ct_amanda_expect ++{ ++ u_int16_t port; /* port number of this expectation */ ++ u_int16_t offset; /* offset of the port specification in ctrl packet */ ++ u_int16_t len; /* the length of the port number specification */ ++}; ++ ++#endif /* _IP_CONNTRACK_AMANDA_H */ +diff -uNr linux-2.4.18-6mdk-pom-clean/net/ipv4/netfilter/ip_conntrack_amanda.c linux-2.4.18-6mdkuml-48um-pom/net/ipv4/netfilter/ip_conntrack_amanda.c +--- linux-2.4.18-6mdk-pom-clean/net/ipv4/netfilter/ip_conntrack_amanda.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.4.18-6mdkuml-48um-pom/net/ipv4/netfilter/ip_conntrack_amanda.c 2002-08-16 04:24:25.000000000 -0400 +@@ -0,0 +1,219 @@ ++/* Amanda extension for IP connection tracking, Version 0.1 ++ * (C) 2002 by Brian J. Murrell ++ * based on HW's ip_conntrack_irc.c as well as other modules ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ * ++ * Module load syntax: ++ * insmod ip_conntrack_amanda.o ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++MODULE_AUTHOR("Brian J. Murrell "); ++MODULE_DESCRIPTION("Amanda connection tracking module"); ++MODULE_LICENSE("GPL"); ++ ++DECLARE_LOCK(ip_amanda_lock); ++struct module *ip_conntrack_amanda = THIS_MODULE; ++ ++#define MAXMATCHLEN 6 ++struct conn conns[NUM_MSGS] = { ++ {"DATA ", 5}, ++ {"MESG ", 5}, ++ {"INDEX ", 6}, ++}; ++ ++#if 0 ++#define DEBUGP printk ++#else ++#define DEBUGP(format, args...) ++#endif ++ ++ ++/* FIXME: This should be in userspace. Later. */ ++static int help(const struct iphdr *iph, size_t len, ++ struct ip_conntrack *ct, enum ip_conntrack_info ctinfo) ++{ ++ struct udphdr *udph = (void *)iph + iph->ihl * 4; ++ u_int32_t udplen = len - iph->ihl * 4; ++ u_int32_t datalen = udplen - sizeof(struct udphdr); ++ char *data = (char *)udph + sizeof(struct udphdr); ++ char *datap = data; ++ char *data_limit = (char *) data + datalen; ++ int dir = CTINFO2DIR(ctinfo); ++ struct ip_ct_amanda *info = ++ (struct ip_ct_amanda *)&ct->help.ct_ftp_info; ++ ++ /* Can't track connections formed before we registered */ ++ if (!info) ++ return NF_ACCEPT; ++ ++ /* If packet is coming from Amanda server */ ++ if (dir == IP_CT_DIR_ORIGINAL) ++ return NF_ACCEPT; ++ ++ /* Not whole UDP header? */ ++ if (udplen < sizeof(struct udphdr)) { ++ printk("ip_conntrack_amanda_help: udplen = %u\n", ++ (unsigned)udplen); ++ return NF_ACCEPT; ++ } ++ ++ /* Checksum invalid? Ignore. */ ++ if (csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP, ++ csum_partial((char *)udph, udplen, 0))) { ++ DEBUGP("ip_ct_talk_help: bad csum: %p %u %u.%u.%u.%u " ++ "%u.%u.%u.%u\n", ++ udph, udplen, NIPQUAD(iph->saddr), ++ NIPQUAD(iph->daddr)); ++ return NF_ACCEPT; ++ } ++ ++ /* Search for the CONNECT string */ ++ while (data < data_limit) { ++ if (!memcmp(data, "CONNECT ", 8)) { ++ break; ++ } ++ data++; ++ } ++ if (memcmp(data, "CONNECT ", 8)) ++ return NF_ACCEPT; ++ ++ DEBUGP("ip_conntrack_amanda_help: CONNECT found in connection " ++ "%u.%u.%u.%u:%u %u.%u.%u.%u:%u\n", ++ NIPQUAD(iph->saddr), htons(udph->source), ++ NIPQUAD(iph->daddr), htons(udph->dest)); ++ data += 8; ++ while (*data != 0x0a && data < data_limit) { ++ ++ int i; ++ ++ for (i = 0; i < NUM_MSGS; i++) { ++ if (!memcmp(data, conns[i].match, ++ conns[i].matchlen)) { ++ ++ char *portchr; ++ struct ip_conntrack_expect expect; ++ struct ip_ct_amanda_expect ++ *exp_amanda_info = ++ &expect.help.exp_amanda_info; ++ ++ memset(&expect, 0, sizeof(expect)); ++ ++ data += conns[i].matchlen; ++ /* this is not really tcp, but let's steal an ++ * idea from a tcp stream helper :-) ++ */ ++ // XXX expect.seq = data - datap; ++ exp_amanda_info->offset = data - datap; ++// XXX DEBUGP("expect.seq = %p - %p = %d\n", data, datap, expect.seq); ++DEBUGP("exp_amanda_info->offset = %p - %p = %d\n", data, datap, exp_amanda_info->offset); ++ portchr = data; ++ exp_amanda_info->port = ++ simple_strtoul(data, &data, 10); ++ exp_amanda_info->len = data - portchr; ++ ++ /* eat whitespace */ ++ while (*data == ' ') ++ data++; ++ DEBUGP ("ip_conntrack_amanda_help: " ++ "CONNECT %s request with port " ++ "%u found\n", conns[i].match, ++ exp_amanda_info->port); ++ ++ LOCK_BH(&ip_amanda_lock); ++ ++ expect.tuple = ((struct ip_conntrack_tuple) ++ { { ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip, ++ { 0 } }, ++ { ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip, ++ { htons(exp_amanda_info->port) }, ++ IPPROTO_TCP }}); ++ expect.mask = ((struct ip_conntrack_tuple) ++ { { 0, { 0 } }, ++ { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }}); ++ ++ expect.expectfn = NULL; ++ ++ DEBUGP ("ip_conntrack_amanda_help: " ++ "expect_related: %u.%u.%u.%u:%u - " ++ "%u.%u.%u.%u:%u\n", ++ NIPQUAD(expect.tuple.src.ip), ++ ntohs(expect.tuple.src.u.tcp.port), ++ NIPQUAD(expect.tuple.dst.ip), ++ ntohs(expect.tuple.dst.u.tcp.port)); ++ if (ip_conntrack_expect_related(ct, &expect) == ++ -EEXIST) { ++ ; ++ /* this must be a packet being resent */ ++ /* XXX - how do I get the ++ * ip_conntrack_expect that ++ * already exists so that I can ++ * update the .seq so that the ++ * nat module rewrites the port ++ * numbers? ++ * Perhaps I should use the ++ * exp_amanda_info instead of ++ * .seq. ++ */ ++ } ++ UNLOCK_BH(&ip_amanda_lock); ++ } /* if memcmp(conns) */ ++ } /* for .. NUM_MSGS */ ++ data++; ++ } /* while (*data != 0x0a && data < data_limit) */ ++ ++ return NF_ACCEPT; ++} ++ ++static struct ip_conntrack_helper amanda_helper; ++ ++static void fini(void) ++{ ++ DEBUGP("ip_ct_amanda: unregistering helper for port 10080\n"); ++ ip_conntrack_helper_unregister(&amanda_helper); ++} ++ ++static int __init init(void) ++{ ++ int ret; ++ ++ memset(&amanda_helper, 0, sizeof(struct ip_conntrack_helper)); ++ amanda_helper.tuple.src.u.udp.port = htons(10080); ++ amanda_helper.tuple.dst.protonum = IPPROTO_UDP; ++ amanda_helper.mask.src.u.udp.port = 0xFFFF; ++ amanda_helper.mask.dst.protonum = 0xFFFF; ++ amanda_helper.max_expected = NUM_MSGS; ++ amanda_helper.timeout = 180; ++ amanda_helper.flags = IP_CT_HELPER_F_REUSE_EXPECT; ++ amanda_helper.me = ip_conntrack_amanda; ++ amanda_helper.help = help; ++ amanda_helper.name = "amanda"; ++ ++ DEBUGP("ip_ct_amanda: registering helper for port 10080\n"); ++ ++ ret = ip_conntrack_helper_register(&amanda_helper); ++ ++ if (ret) { ++ printk("ip_ct_amanda: ERROR registering helper\n"); ++ fini(); ++ return -EBUSY; ++ } ++ return 0; ++} ++ ++module_init(init); ++module_exit(fini); +diff -uNr linux-2.4.18-6mdk-pom-clean/net/ipv4/netfilter/ip_nat_amanda.c linux-2.4.18-6mdkuml-48um-pom/net/ipv4/netfilter/ip_nat_amanda.c +--- linux-2.4.18-6mdk-pom-clean/net/ipv4/netfilter/ip_nat_amanda.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.4.18-6mdkuml-48um-pom/net/ipv4/netfilter/ip_nat_amanda.c 2002-08-16 04:24:51.000000000 -0400 +@@ -0,0 +1,226 @@ ++/* Amanda extension for TCP NAT alteration. ++ * (C) 2002 by Brian J. Murrell ++ * based on a copy of HW's ip_nat_irc.c as well as other modules ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ * ++ * Module load syntax: ++ * insmod ip_nat_amanda.o ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++ ++#if 0 ++#define DEBUGP printk ++#define DUMP_OFFSET(x) printk("offset_before=%d, offset_after=%d, correction_pos=%u\n", x->offset_before, x->offset_after, x->correction_pos); ++#else ++#define DEBUGP(format, args...) ++#define DUMP_OFFSET(x) ++#endif ++ ++MODULE_AUTHOR("Brian J. Murrell "); ++MODULE_DESCRIPTION("Amanda network address translation module"); ++MODULE_LICENSE("GPL"); ++ ++/* protects amanda part of conntracks */ ++DECLARE_LOCK_EXTERN(ip_amanda_lock); ++ ++static unsigned int ++amanda_nat_expected(struct sk_buff **pskb, ++ unsigned int hooknum, ++ struct ip_conntrack *ct, ++ struct ip_nat_info *info) ++{ ++ struct ip_nat_multi_range mr; ++ u_int32_t newdstip, newsrcip, newip; ++ u_int16_t port; ++ struct ip_ct_amanda_expect *exp_info; ++ struct ip_conntrack *master = master_ct(ct); ++ ++ IP_NF_ASSERT(info); ++ IP_NF_ASSERT(master); ++ ++ IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum)))); ++ ++ DEBUGP("nat_expected: We have a connection!\n"); ++ exp_info = &ct->master->help.exp_amanda_info; ++ ++ newdstip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip; ++ newsrcip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; ++ DEBUGP("nat_expected: %u.%u.%u.%u->%u.%u.%u.%u\n", ++ NIPQUAD(newsrcip), NIPQUAD(newdstip)); ++ ++ port = exp_info->port; ++ ++ if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) ++ newip = newsrcip; ++ else ++ newip = newdstip; ++ ++ DEBUGP("nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip)); ++ ++ mr.rangesize = 1; ++ /* We don't want to manip the per-protocol, just the IPs. */ ++ mr.range[0].flags = IP_NAT_RANGE_MAP_IPS; ++ mr.range[0].min_ip = mr.range[0].max_ip = newip; ++ ++ if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) { ++ mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED; ++ mr.range[0].min = mr.range[0].max ++ = ((union ip_conntrack_manip_proto) ++ { htons(port) }); ++ } ++ ++ return ip_nat_setup_info(ct, &mr, hooknum); ++} ++ ++static int amanda_data_fixup(struct ip_conntrack *ct, ++ struct sk_buff **pskb, ++ enum ip_conntrack_info ctinfo, ++ struct ip_conntrack_expect *expect) ++{ ++ u_int32_t newip; ++ /* DATA 99999 MESG 99999 INDEX 99999 */ ++ char buffer[6]; ++ struct ip_conntrack_expect *exp = expect; ++ struct ip_ct_amanda_expect *ct_amanda_info = &exp->help.exp_amanda_info; ++ struct ip_conntrack_tuple t = exp->tuple; ++ int port; ++ ++ MUST_BE_LOCKED(&ip_amanda_lock); ++ ++ newip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; ++ DEBUGP ("ip_nat_amanda_help: newip = %u.%u.%u.%u\n", NIPQUAD(newip)); ++ ++ /* Alter conntrack's expectations. */ ++ ++ /* We can read expect here without conntrack lock, since it's ++ only set in ip_conntrack_amanda, with ip_amanda_lock held ++ writable */ ++ ++ t.dst.ip = newip; ++ for (port = ct_amanda_info->port + 10; port != 0; port++) { ++ t.dst.u.tcp.port = htons(port); ++ if (ip_conntrack_change_expect(exp, &t) == 0) ++ break; ++ } ++ ++ if (port == 0) ++ return 0; ++ ++ sprintf(buffer, "%u", port); ++ ++ return ip_nat_mangle_udp_packet(pskb, ct, ctinfo, /* XXX exp->seq */ ct_amanda_info->offset, ++ ct_amanda_info->len, buffer, strlen(buffer)); ++} ++ ++static unsigned int help(struct ip_conntrack *ct, ++ struct ip_conntrack_expect *exp, ++ struct ip_nat_info *info, ++ enum ip_conntrack_info ctinfo, ++ unsigned int hooknum, ++ struct sk_buff **pskb) ++{ ++ int dir; ++ ++ if (!exp) ++ DEBUGP("ip_nat_amanda: no exp!!"); ++ ++ /* Only mangle things once: original direction in POST_ROUTING ++ and reply direction on PRE_ROUTING. */ ++ dir = CTINFO2DIR(ctinfo); ++ if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL) ++ || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) { ++ DEBUGP("ip_nat_amanda_help: 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; ++ } ++ DEBUGP("ip_nat_amanda_help: got beyond not touching: dir %s at hook %s for expect: ", ++ 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" : "???"); ++ DUMP_TUPLE(&exp->tuple); ++ ++ LOCK_BH(&ip_amanda_lock); ++// XXX if (exp->seq != 0) ++ if (exp->help.exp_amanda_info.offset != 0) ++ /* if this packet has a "seq" it needs to have it's content mangled */ ++ if (!amanda_data_fixup(ct, pskb, ctinfo, exp)) { ++ UNLOCK_BH(&ip_amanda_lock); ++ DEBUGP("ip_nat_amanda: NF_DROP\n"); ++ return NF_DROP; ++ } ++ exp->help.exp_amanda_info.offset = 0; ++ UNLOCK_BH(&ip_amanda_lock); ++ ++ DEBUGP("ip_nat_amanda: NF_ACCEPT\n"); ++ return NF_ACCEPT; ++} ++ ++static struct ip_nat_helper ip_nat_amanda_helper; ++ ++/* This function is intentionally _NOT_ defined as __exit, because ++ * it is needed by init() */ ++static void fini(void) ++{ ++ DEBUGP("ip_nat_amanda: unregistering nat helper\n"); ++ ip_nat_helper_unregister(&ip_nat_amanda_helper); ++} ++ ++static int __init init(void) ++{ ++ int ret = 0; ++ struct ip_nat_helper *hlpr; ++ ++ hlpr = &ip_nat_amanda_helper; ++ memset(hlpr, 0, sizeof(struct ip_nat_helper)); ++ ++ hlpr->tuple.dst.protonum = IPPROTO_UDP; ++ hlpr->tuple.src.u.udp.port = htons(10080); ++ hlpr->mask.src.u.udp.port = 0xFFFF; ++ hlpr->mask.dst.protonum = 0xFFFF; ++ hlpr->help = help; ++ hlpr->flags = 0; ++ hlpr->me = THIS_MODULE; ++ hlpr->expect = amanda_nat_expected; ++ ++ hlpr->name = "amanda"; ++ ++ DEBUGP ++ ("ip_nat_amanda: Trying to register nat helper\n"); ++ ret = ip_nat_helper_register(hlpr); ++ ++ if (ret) { ++ printk ++ ("ip_nat_amanda: error registering nat helper\n"); ++ fini(); ++ return 1; ++ } ++ return ret; ++} ++ ++ ++module_init(init); ++module_exit(fini); diff --exclude CVS -Nur ./patch-o-matic/extra/amanda-conntrack-nat.patch.config.in ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch.config.in --- ./patch-o-matic/extra/amanda-conntrack-nat.patch.config.in 1969-12-31 19:00:00.000000000 -0500 +++ ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch.config.in 2002-08-16 14:00:31.000000000 -0400 @@ -0,0 +1,2 @@ + dep_tristate ' FTP protocol support' CONFIG_IP_NF_FTP $CONFIG_IP_NF_CONNTRACK + dep_tristate ' Amanda protocol support' CONFIG_IP_NF_AMANDA $CONFIG_IP_NF_CONNTRACK diff --exclude CVS -Nur ./patch-o-matic/extra/amanda-conntrack-nat.patch.config.in-2 ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch.config.in-2 --- ./patch-o-matic/extra/amanda-conntrack-nat.patch.config.in-2 1969-12-31 19:00:00.000000000 -0500 +++ ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch.config.in-2 2002-08-16 14:03:01.000000000 -0400 @@ -0,0 +1,8 @@ + dep_tristate ' REDIRECT target support' CONFIG_IP_NF_TARGET_REDIRECT $CONFIG_IP_NF_NAT + if [ "$CONFIG_IP_NF_AMANDA" = "m" ]; then + define_tristate CONFIG_IP_NF_NAT_AMANDA m + else + if [ "$CONFIG_IP_NF_AMANDA" = "y" ]; then + define_tristate CONFIG_IP_NF_NAT_AMANDA $CONFIG_IP_NF_NAT + fi + fi diff --exclude CVS -Nur ./patch-o-matic/extra/amanda-conntrack-nat.patch.configure.help ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch.configure.help --- ./patch-o-matic/extra/amanda-conntrack-nat.patch.configure.help 1969-12-31 19:00:00.000000000 -0500 +++ ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch.configure.help 2002-08-16 13:53:48.000000000 -0400 @@ -0,0 +1,13 @@ +CONFIG_IP_NF_IRC +Amanda protocol support +CONFIG_IP_NF_AMANDA + If you are running the Amanda backup package (http://www.amanda.org/) + on this machine or machines that will be MASQUERADED through this + machine, then you may want to enable this feature. This allows the + connection tracking and natting code to allow the sub-channels that + Amanda requires for communication of the backup data, messages and + index. + + If you want to compile it as a module, say M here and read + Documentation/modules.txt. If unsure, say `N'. + diff --exclude CVS -Nur ./patch-o-matic/extra/amanda-conntrack-nat.patch.help ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch.help --- ./patch-o-matic/extra/amanda-conntrack-nat.patch.help 1969-12-31 19:00:00.000000000 -0500 +++ ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch.help 2002-08-16 13:56:26.000000000 -0400 @@ -0,0 +1,5 @@ +Author: Brian J. Murrell +Status: Works for me + +This adds CONFIG_IP_NF_AMANDA: +Connection tracking and NATting for the Amanda backup protocol. diff --exclude CVS -Nur ./patch-o-matic/extra/amanda-conntrack-nat.patch.ip_conntrack.h ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch.ip_conntrack.h --- ./patch-o-matic/extra/amanda-conntrack-nat.patch.ip_conntrack.h 1969-12-31 19:00:00.000000000 -0500 +++ ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch.ip_conntrack.h 2002-08-16 14:05:08.000000000 -0400 @@ -0,0 +1,3 @@ +/* Add protocol helper include file here */ +#include + diff --exclude CVS -Nur ./patch-o-matic/extra/amanda-conntrack-nat.patch.ip_conntrack.h-2 ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch.ip_conntrack.h-2 --- ./patch-o-matic/extra/amanda-conntrack-nat.patch.ip_conntrack.h-2 1969-12-31 19:00:00.000000000 -0500 +++ ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch.ip_conntrack.h-2 2002-08-21 05:57:34.000000000 -0400 @@ -0,0 +1,2 @@ + /* insert conntrack helper private data (expect) here */ + struct ip_ct_amanda_expect exp_amanda_info; diff --exclude CVS -Nur ./patch-o-matic/extra/amanda-conntrack-nat.patch.ip_conntrack.h-2~ ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch.ip_conntrack.h-2~ --- ./patch-o-matic/extra/amanda-conntrack-nat.patch.ip_conntrack.h-2~ 1969-12-31 19:00:00.000000000 -0500 +++ ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch.ip_conntrack.h-2~ 2002-08-16 15:02:23.000000000 -0400 @@ -0,0 +1,2 @@ + /* insert conntrack helper private data (expect) here */ + struct ip_ct_amanda_expect exp_amanda_info; diff --exclude CVS -Nur ./patch-o-matic/extra/amanda-conntrack-nat.patch.makefile ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch.makefile --- ./patch-o-matic/extra/amanda-conntrack-nat.patch.makefile 1969-12-31 19:00:00.000000000 -0500 +++ ../netfilter/patch-o-matic/extra/amanda-conntrack-nat.patch.makefile 2002-08-16 14:09:25.000000000 -0400 @@ -0,0 +1,9 @@ +obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o + +# Amanda protocol support +obj-$(CONFIG_IP_NF_AMANDA) += ip_conntrack_amanda.o +obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.o +ifdef CONFIG_IP_NF_NAT_AMANDA + export-objs += ip_conntrack_amanda.o +endif +