1/* Amanda extension for TCP NAT alteration. 2 * (C) 2002 by Brian J. Murrell <netfilter@interlinx.bc.ca> 3 * based on a copy of HW's ip_nat_irc.c as well as other modules 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 8 * 2 of the License, or (at your option) any later version. 9 */ 10 11#include <linux/kernel.h> 12#include <linux/module.h> 13#include <linux/skbuff.h> 14#include <linux/udp.h> 15 16#include <net/netfilter/nf_nat_helper.h> 17#include <net/netfilter/nf_nat_rule.h> 18#include <net/netfilter/nf_conntrack_helper.h> 19#include <net/netfilter/nf_conntrack_expect.h> 20#include <linux/netfilter/nf_conntrack_amanda.h> 21 22MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>"); 23MODULE_DESCRIPTION("Amanda NAT helper"); 24MODULE_LICENSE("GPL"); 25MODULE_ALIAS("ip_nat_amanda"); 26 27static unsigned int help(struct sk_buff *skb, 28 enum ip_conntrack_info ctinfo, 29 unsigned int matchoff, 30 unsigned int matchlen, 31 struct nf_conntrack_expect *exp) 32{ 33 char buffer[sizeof("65535")]; 34 u_int16_t port; 35 unsigned int ret; 36 37 /* Connection comes from client. */ 38 exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port; 39 exp->dir = IP_CT_DIR_ORIGINAL; 40 41 /* When you see the packet, we need to NAT it the same as the 42 * this one (ie. same IP: it will be TCP and master is UDP). */ 43 exp->expectfn = nf_nat_follow_master; 44 45 /* Try to get same port: if not, try to change it. */ 46 for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) { 47 exp->tuple.dst.u.tcp.port = htons(port); 48 if (nf_ct_expect_related(exp) == 0) 49 break; 50 } 51 52 if (port == 0) 53 return NF_DROP; 54 55 sprintf(buffer, "%u", port); 56 ret = nf_nat_mangle_udp_packet(skb, exp->master, ctinfo, 57 matchoff, matchlen, 58 buffer, strlen(buffer)); 59 if (ret != NF_ACCEPT) 60 nf_ct_unexpect_related(exp); 61 return ret; 62} 63 64static void __exit nf_nat_amanda_fini(void) 65{ 66 rcu_assign_pointer(nf_nat_amanda_hook, NULL); 67 synchronize_rcu(); 68} 69 70static int __init nf_nat_amanda_init(void) 71{ 72 BUG_ON(nf_nat_amanda_hook != NULL); 73 rcu_assign_pointer(nf_nat_amanda_hook, help); 74 return 0; 75} 76 77module_init(nf_nat_amanda_init); 78module_exit(nf_nat_amanda_fini); 79