iph = ip_hdr(*pskb);
csum_replace4(&iph->check, iph->daddr, new_addr);
rawnat4_update_l4(*pskb, iph->daddr, new_addr);
iph->daddr = new_addr;
return NF_ACCEPT;
}
//定义数据结构
struct addr_map {
struct list_head list;
__be32 addr[2];
int type; //0:源地址转换;1:目标地址转换
};
//全局的map list
static LIST_HEAD(map_list);
static unsigned int ipv4_static_nat_pre(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
__be32 new_daddr = 0x0;
struct addr_map *map;
const struct iphdr *iph = ip_hdr(skb);
if (list_empty(&map_list)) {
return NF_ACCEPT;
}
//查找是否需要做目标地址转换
list_for_each_entry(map, &map_list, list) {
if (map->addr[((map->type-1)&0x00000001)] == iph->daddr) {
new_daddr = map->addr[map->type&0x00000001];
break;
}
}
if (new_daddr == 0) {
return NF_ACCEPT;
}
return rawdnat(&skb, new_daddr);
}
static unsigned int ipv4_static_nat_post(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
__be32 new_saddr = 0x0;
struct addr_map *map;
const struct iphdr *iph = ip_hdr(skb);
if (list_empty(&map_list)) {
return NF_ACCEPT;
}
//查找是否做源地址转换
list_for_each_entry(map, &map_list, list) {
if (map->addr[map->type&0x00000001] == iph->saddr) {
new_saddr = map->addr[((map->type-1)&0x00000001)];
break;
}
}
if (new_saddr == 0) {
return NF_ACCEPT;
}
return rawsnat(&skb, new_saddr);
}
static struct nf_hook_ops ipv4_static_nat[] __read_mostly = {
{
.hook = ipv4_static_nat_pre,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_NAT_SRC+1,
},
{
.hook = ipv4_static_nat_post,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_RAW+1,
},
};
//以下是定义用户接口
//如果需要添加一条source转换。则:
<strong>//echo +172.16.4.34-128.129.4.34 >/proc/STATIC_Nat/source</strong>
struct proc_dir_entry *nat_entry = NULL;
static ssize_t write_snat(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
struct addr_map *am = NULL;
char addr_temp[20] = {0};
__be32 addr1 = 0, addr2 = 0;
int ret = count;
int i = 1;
for (; i < 48; i++) {
if (buf[i] == '-') {
memcpy(addr_temp, buf+1, i-1);
break;
}
}
addr1 = in_aton(addr_temp);
addr2 = in_aton(buf + i + 1);
if (buf[0] == '+') {
am = kzalloc(sizeof(struct addr_map), GFP_KERNEL);
INIT_LIST_HEAD(&am->list);
am->addr[0] = addr1;
am->addr[1] = addr2;
am->type = 0;
list_add(&am->list, &map_list);
} else if(buf[0] == '-') {
//Remove TODO
}
return ret;
}
static ssize_t write_dnat(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
//TODO
return 0;
}
static ssize_t read_snat(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
//TODO
return 0;
}
static ssize_t read_dnat(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
//TODO
return 0;
}