📄 ip_nat_amanda.c
字号:
/* Amanda extension for TCP NAT alteration. * (C) 2002 by Brian J. Murrell <netfilter@interlinx.bc.ca> * 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 <linux/module.h>#include <linux/netfilter_ipv4.h>#include <linux/ip.h>#include <linux/udp.h>#include <linux/kernel.h>#include <net/tcp.h>#include <net/udp.h>#include <linux/netfilter_ipv4/ip_nat.h>#include <linux/netfilter_ipv4/ip_nat_helper.h>#include <linux/netfilter_ipv4/ip_nat_rule.h>#include <linux/netfilter_ipv4/ip_conntrack_helper.h>#include <linux/netfilter_ipv4/ip_conntrack_amanda.h>#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)#endifMODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");MODULE_DESCRIPTION("Amanda network address translation module");MODULE_LICENSE("GPL");/* protects amanda part of conntracks */DECLARE_LOCK_EXTERN(ip_amanda_lock);static unsigned intamanda_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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -