- 论坛徽章:
- 0
|
就是下面这个文件了。
/*
This is a module which is used for resending packets with inverted src and dst.
Based on code from: ip_nat_dumb.c,v 1.9 1999/08/20
and various sources.
Copyright (C) 2000 Emmanuel Roger
Changes:
25 Aug 2001 Harald Welte
- decrement and check TTL if not called from FORWARD hook
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.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef CONFIG_NF_NAT_NEEDED
#include
#else
#include
#endif
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Netfilter patch ");
MODULE_DESCRIPTION("iptables MIRROR module");
DEFINE_RWLOCK(ip_mirror_lock);
struct ipt_mirror_info
{
u_int32_t rangesize;
struct ip_nat_range range[1];
};
#if 0
#define DEBUGP printk
#else
#define DEBUGP(format, args...)
#endif
static inline struct rtable *route_mirror(struct sk_buff *skb, int local)
{
struct iphdr *iph = skb->nh.iph;
struct dst_entry *odst;
struct flowi fl = {};
struct rtable *rt;
if (local) {
fl.nl_u.ip4_u.daddr = iph->saddr;
fl.nl_u.ip4_u.saddr = iph->daddr;
fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
if (ip_route_output_key(&rt, &fl) != 0)
return NULL;
} else {
/* non-local src, find valid iif to satisfy
* rp-filter when calling ip_route_input(). */
fl.nl_u.ip4_u.daddr = iph->daddr;
if (ip_route_output_key(&rt, &fl) != 0)
return NULL;
odst = skb->dst;
if (ip_route_input(skb, iph->saddr, iph->daddr,
RT_TOS(iph->tos), rt->u.dst.dev) != 0) {
dst_release(&rt->u.dst);
return NULL;
}
dst_release(&rt->u.dst);
rt = (struct rtable *)skb->dst;
skb->dst = odst;
}
if (rt->u.dst.error) {
dst_release(&rt->u.dst);
rt = NULL;
}
return rt;
}
static inline void ip_rewrite(struct sk_buff *skb)
{
u32 odaddr, osaddr;
odaddr = skb->nh.iph->saddr;
osaddr = skb->nh.iph->daddr;
/* Rewrite IP header */
skb->nh.iph->daddr = odaddr;
skb->nh.iph->saddr = osaddr;
}
static void ip_direct_send(struct sk_buff *skb)
{
struct dst_entry *dst = skb->dst;
struct hh_cache *hh = dst->hh;
if (hh) {
int hh_alen;
read_lock_bh(&ip_mirror_lock);
hh_alen = HH_DATA_ALIGN(hh->hh_len);
memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
read_unlock_bh(&ip_mirror_lock);
skb_push(skb, hh->hh_len);
hh->hh_output(skb);
} else if (dst->neighbour)
dst->neighbour->output(skb);
else {
printk(KERN_DEBUG "khm in MIRROR\n");
kfree_skb(skb);
}
}
static unsigned int ipt_mirror_target(struct sk_buff **pskb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void *targinfo)
{
struct rtable *rt;
struct sk_buff *nskb;
unsigned int hh_len;
printk(KERN_ERR "MIRROR target \n");
/* Make skb writable */
if (!skb_make_writable(pskb, sizeof(struct iphdr)))
return 0;
/* If we are not at FORWARD hook (INPUT/PREROUTING),
* the TTL isn't decreased by the IP stack */
if (hooknum != NF_IP_FORWARD) {
if ((*pskb)->nh.iph->ttl nh.iph);
}
if ((rt = route_mirror(*pskb, hooknum == NF_IP_LOCAL_IN)) == NULL)
return NF_DROP;
hh_len = (rt->u.dst.dev->hard_header_len + 15) & ~15;
/* Copy skb (even if skb is about to be dropped, we can't just
* clone it because there may be other things, such as tcpdump,
* interested in it). We also need to expand headroom in case
* hh_len of incoming interface u.dst);
return NF_DROP;
}
dst_release(nskb->dst);
nskb->dst = &rt->u.dst;
ip_rewrite(nskb);
/* Don't let conntrack code see this packet:
* it will think we are starting a new
* connection! --RR */
ip_direct_send(nskb);
return NF_DROP;
}
static int ipt_mirror_checkentry(const char *tablename,
const void *e_entry,
const struct xt_target *target,
void *targinfo,
unsigned int hook_mask)
{
struct ipt_mirror_info *mr = targinfo;
const struct ipt_entry *e= e_entry;
DEBUGP("ipt_SAME: src=%u.%u.%u.%u dst=%u.%u.%u.%u, "
"new src=%u.%u.%u.%u\n",
NIPQUAD(t->src.ip), NIPQUAD(t->dst.ip),
NIPQUAD(new_ip));
return 1;
}
static struct xt_target ipt_mirror_reg = {
.name = "MIRROR",
.family = AF_INET,
.target = ipt_mirror_target,
.targetsize = IPT_ALIGN(0),
.table = "filter",
.hooks = (1
static int __init init(void)
{
printk(KERN_ERR "Register_MIRROR\n");
return xt_register_target(&ipt_mirror_reg);
}
static void __exit fini(void)
{
printk(KERN_ERR "Exit ipt_MIRROR\n");
xt_unregister_target(&ipt_mirror_reg);
}
module_init(init);
module_exit(fini);
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/2837/showart_317496.html |
|