/*
 * Copyright (c) 2012, 2015, The Linux Foundation. All rights reserved.
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all copies.
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */


#ifdef KVER32
#include <linux/kconfig.h>
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#endif
#include <linux/netfilter_ipv4/ip_tables.h>
#include <net/netfilter/nf_nat.h>
#include <linux/netfilter/nf_nat.h>
#include <linux/netfilter/xt_multiport.h>
#include <linux/netfilter/xt_tcpudp.h>
#include <linux/netfilter/x_tables.h>
#include "nat_helper.h"

#include "lib/nat_helper_hsl.h"
#include "lib/nat_helper_dt.h"


#define nf_nat_ipv4_multi_range_compat  \
                nf_nat_ipv4_multi_range_compat
#define nf_nat_range        nf_nat_ipv4_range
#define ipt_entry_target    xt_entry_target
#define ipt_entry_match     xt_entry_match

#define IPT_MATCH_ITERATE(e, fun, args...) \
({								    \
	unsigned int i;					\
	int ret = 0;					\
	struct xt_entry_match *m;	    \
								    \
	for (i = sizeof(struct ipt_entry);	\
	     i < (e)->target_offset;		\
	     i += m->u.match_size) {	\
		m = (void *)e + i;			\
		ret = fun(m , ##args);		\
		if (ret != 0)					\
			break;					    \
	}							        \
	ret;							\
})

#define IPT_ENTRY_ITERATE(entries, size, fun, args...) \
({								        \
	unsigned int k, j;					\
	int ret = 0;						\
	struct ipt_entry *e;			    \
								        \
	for (k = 0, j = 0; k < (size);		\
	    k += (e)->next_offset, j++) { \
		e = (void *)(entries) + k;	\
		if (j < 0)					\
			continue;				\
								    \
		ret = fun(e , ##args);	    \
		if (ret != 0)				\
			break;					\
	}							    \
	ret;						\
})


#define IPT_BUFFER_INIT_LEN 1000
#define NF_NAT_INIT_ENTRIES_NUM 5

static int
nat_ipt_set_ctl(struct sock *sk, int cmd, void __user * user, unsigned int len);
static int
nat_ipt_get_ctl(struct sock *sk, int cmd, void __user * user, int *len);

int nat_sockopts_init = 0;

/*those initial value will be overwrited by orignal iptables sockopts*/
static struct nf_sockopt_ops orgi_ipt_sockopts;
static struct nf_sockopt_ops tmp_ipt_sockopts =
{
    /*pls check linux/in.h*/
#define IPT_TEMP_BASE_CTL       60
#define IPT_TEMP_SET_MAX        (IPT_TEMP_BASE_CTL+1)
#define IPT_TEMP_GET_MAX        (IPT_TEMP_BASE_CTL+2)
    .pf = PF_INET,
    .set_optmin = IPT_TEMP_BASE_CTL,
    .set_optmax = IPT_TEMP_SET_MAX,
    .set = nat_ipt_set_ctl,
    .get_optmin = IPT_TEMP_BASE_CTL,
    .get_optmax = IPT_TEMP_GET_MAX,
    .get = nat_ipt_get_ctl
};

static struct nf_sockopt_ops *ipt_sockopts = NULL;
static uint32_t snat_seq = 0;
static uint32_t hw_nat_ipt_seq[NAT_HW_NUM] = {0};
static uint32_t hw_nat_pip_idx[NAT_HW_NUM] = {0};
static uint8_t *gbuffer, *sbuffer;
static unsigned int glen, slen;
static struct ipt_replace old_replace;

static void
nat_ipt_del(struct ipt_replace ireplace)
{
    int i, j;
    struct ipt_entry *gentry = NULL;
    struct ipt_entry *sentry = NULL;
    struct xt_entry_target *gtarget = NULL;
    struct xt_entry_target *starget = NULL;
    struct nf_nat_ipv4_multi_range_compat *grange = NULL;
    struct nf_nat_ipv4_multi_range_compat *srange = NULL;
    uint8_t *gptr, *sptr;
	unsigned int oldnum = ireplace.num_counters;
	unsigned int seq = 1;
    gptr = gbuffer;
    sptr = sbuffer;

    HNAT_PRINTK("into nat_ipt_del\n");
    for (i = oldnum; i >= 0; i--)//NF_NAT_INIT_ENTRIES_NUM; i--)
    {
        gentry = (struct ipt_entry *)gptr;
        sentry = (struct ipt_entry *)sptr;
        gtarget = (struct xt_entry_target *)((uint8_t *) gentry + gentry->target_offset);
        starget = (struct xt_entry_target *)((uint8_t *) sentry + sentry->target_offset);
        grange = (struct nf_nat_ipv4_multi_range_compat *)((uint8_t *) gtarget + sizeof (*gtarget));
        srange = (struct nf_nat_ipv4_multi_range_compat *)((uint8_t *) starget + sizeof (*starget));

        HNAT_PRINTK("(%d)isis_nat_del name %s:%s#####(%x:%x %x)###\n",
                    i, gtarget->u.user.name, starget->u.user.name,
                    gentry->ip.src.s_addr, gentry->ip.dst.s_addr,
                    grange->range[0].min.all);

        if (strcmp(gtarget->u.user.name, starget->u.user.name))
        {
            /*if (!strcmp(gtarget->u.user.name, "DNAT")) {
                if (gentry->ip.src.s_addr || !gentry->ip.dst.s_addr
                    || grange->range[0].min.all)
                    return;
                goto delete;
            } else */
            if (!strcmp(gtarget->u.user.name, "SNAT"))
            {
                if (!gentry->ip.src.s_addr || gentry->ip.dst.s_addr
                        || grange->range[0].min.all)
                    return;
                goto delete;
            }
            return;
        } /*else if (!strcmp(gtarget->u.user.name, "DNAT")) {
            if (memcmp(gentry, sentry, gentry->next_offset)) {
                if (gentry->ip.src.s_addr || !gentry->ip.dst.s_addr
                    || grange->range[0].min.all)
                    return;
                goto delete;
            }
        } */else if (!strcmp(gtarget->u.user.name, "SNAT"))
        {
            if (memcmp(gentry, sentry, gentry->next_offset))
            {
                if (!gentry->ip.src.s_addr || gentry->ip.dst.s_addr
                        || grange->range[0].min.all)
                    return;
                goto delete;
            }
        }
        gptr += gentry->next_offset;
        sptr += gentry->next_offset;
        if(!strcmp(gtarget->u.user.name, "SNAT"))
        {
            seq++;
        }
    }
    HNAT_PRINTK("NONE to delete\n");
    return;

delete:
    HNAT_PRINTK("READY to delete one\n");
    for (j = 0; j < NAT_HW_NUM; j++)
    {
        HNAT_PRINTK("ready [%d] (hw)%x:(sw)%x######\n",
                    j, hw_nat_ipt_seq[j], seq);
        if (hw_nat_ipt_seq[j] == seq)
        {
            if(nat_hw_del_by_index(j) != 0)
            {
                return;
            }
            //public_ip_del(hw_nat_pip_idx[j]);
        }
    }

    for(i = 0; i < NAT_HW_NUM; i++)
    {
        if(hw_nat_ipt_seq[i] > seq)
        {
            hw_nat_ipt_seq[i]--;
        }
        else if(hw_nat_ipt_seq[i] == seq)
        {
            hw_nat_ipt_seq[i]=0;
        }
    }

    return;
}

static void
nat_ipt_to_hw_entry(struct ipt_entry *e,
                    nat_entry_t *nat)
{
#define P_ANY  0
#define P_TCP  6
#define P_UDP  17

    struct ipt_entry_target *t = (struct ipt_entry_target *)ipt_get_target(e);

    const struct nf_nat_ipv4_multi_range_compat *mr =
        (struct nf_nat_ipv4_multi_range_compat *)(t->data);
    const struct nf_nat_range *range = &mr->range[0];

    uint32_t sip = ntohl(e->ip.src.s_addr);
    uint32_t pip = ntohl(range->min_ip);
    uint16_t proto = e->ip.proto;

    memset((void *) nat, 0, sizeof (nat_entry_t));

    nat->src_addr = sip;
    nat->trans_addr = pip;

    if (proto == P_TCP)
    {
        nat->flags = FAL_NAT_ENTRY_PROTOCOL_TCP;
    }
    else if (proto == P_UDP)
    {
        nat->flags = FAL_NAT_ENTRY_PROTOCOL_UDP;
    }
    else if (proto == P_ANY)
    {
        nat->flags = FAL_NAT_ENTRY_PROTOCOL_ANY;
    }
}

static int
nat_ipt_hw_add(nat_entry_t *nat)
{
	uint32_t index = 0;
    if(nat_hw_add(nat) != 0)
    {
        return -1;
    }

    hw_nat_ipt_seq[nat->entry_id] = snat_seq;
    HNAT_PRINTK("###nat_ipt_hw_add hw_nat_ipt_seq[%d]:%d###\n",
                nat->entry_id, snat_seq);

    hw_nat_pip_idx[nat->entry_id] = nat->trans_addr;

    if(nat_hw_prv_base_can_update())
    {
        nat_hw_prv_base_set(nat->src_addr);
        nat_hw_prv_base_update_disable();
    }

    if(nat_hw_pub_ip_add(nat->trans_addr, &index)!= 0)
    {
        return -1;
    }

    return 0;
}

static int
nat_ipt_hw_port_range_add(nat_entry_t *nat,
                          uint16_t port_start, uint16_t port_end,
                          struct xt_multiport *xport)
{
    unsigned int i;

    nat->flags |= FAL_NAT_ENTRY_PORT_CHECK;

    if(xport)
    {
        //some discontinuous ports
        for (i = 0; i < xport->count; i++)
        {

            nat->port_num = xport->ports[i];
            nat->port_range = 1;

            if(nat_ipt_hw_add(nat))
            {
                HNAT_PRINTK("isis_nat_add(xport:%d) fail!\n", nat->port_num);
                return -1;
            }

            HNAT_PRINTK("(1)isis_nat_add(xport:%d) success\n", nat->port_num);
        }
    }
    else
    {
        //one port or port range
        uint16_t port_min, port_max;

        for (i = port_start; i <= port_end; i+= NAT_HW_PORT_RANGE_MAX)
        {
            port_min = i;
            if((port_end-port_min)>(NAT_HW_PORT_RANGE_MAX-1))
            {
                port_max = port_min+(NAT_HW_PORT_RANGE_MAX-1);
            }
            else
            {
                port_max = port_end;
            }

            nat->port_num = port_min;
            nat->port_range = (port_max - port_min + 1);

            if(nat_ipt_hw_add(nat))
            {
                HNAT_PRINTK("isis_nat_add(range port:%d~%d) fail!\n",
                            port_min, port_max);
                return -1;
            }

            HNAT_PRINTK("(2)isis_nat_add(range port:%d~%d) success\n", port_min, port_max);
        }
    }

    return 0;
}

static int
nat_ipt_check_none_matches(struct ipt_entry *e)
{
    nat_entry_t nat = {0};

    nat_ipt_to_hw_entry(e, &nat);

    if(nat_ipt_hw_add(&nat) != 0)
    {
        HNAT_PRINTK("(1)isis_nat_add(none port)fail!\n");
        return -1;
    }

    HNAT_PRINTK("(1)isis_nat_add(none port) success\n");

    return 0;
}
static int
nat_ipt_check_matches(struct ipt_entry_match *m,
                      struct ipt_entry *e,
                      unsigned int *j)
{
    int ret = 0;

    nat_entry_t nat = {0};
    uint16_t port_start = 0, port_end = 0;
    struct xt_multiport *xport = NULL;

    if(strcmp(m->u.user.name, "udp") == 0)
    {
        struct xt_udp *udpinfo = (struct xt_udp *)m->data;
        port_start = udpinfo->spts[0];
        port_end = udpinfo->spts[1];

    }
    else if(strcmp(m->u.user.name, "tcp") == 0)
    {
        struct xt_tcp *tcpinfo = (struct xt_tcp *)m->data;
        port_start = tcpinfo->spts[0];
        port_end = tcpinfo->spts[1];

    }
    else if(strcmp(m->u.user.name, "multiport") == 0)
    {
        struct xt_multiport xport_data = {0};
		struct ipt_entry_target *t = ipt_get_target(e);
        xport = &xport_data;

        if(t->u.user.revision == 0)
        {
            xport = (struct xt_multiport *)m->data;

        }
        else if(t->u.user.revision == 1)
        {
            const struct xt_multiport_v1 *xportv1 =
                (struct xt_multiport_v1 *)m->data;
            memcpy(xport->ports, xportv1->ports, sizeof(xportv1->ports));
            xport->count = xportv1->count;
        }

        if(xport->flags != XT_MULTIPORT_SOURCE)
        {
            memset(xport->ports, 0, sizeof(xport->ports));
        }

    }
    else
    {
        (*j)++ ;
        HNAT_PRINTK("###no support matches m->u.user.name:%s\n",
                    m->u.user.name);
        return -1;
    }

    nat_ipt_to_hw_entry(e, &nat);
    ret = nat_ipt_hw_port_range_add(&nat, port_start, port_end, xport);

    (*j)++ ;

    return ret;
}

//check netmask !=32
#define NAT_IPT_RULE_IS_FOR_NAPT(e)  (((e)->ip.smsk.s_addr) != 0xffffffff)
#define NAT_IPT_RULE_IS_NONE_MATCHES(e)  (((e)->target_offset) == \
                                            (sizeof(struct ipt_entry)))

static int
nat_ipt_find_check_entry(struct ipt_entry *e, unsigned int underflow,
                         unsigned int *i)
{
    int ret = 0;
    static uint16_t next_offset = 0;
	struct ipt_entry_target *t = ipt_get_target(e);

    if(*i == 0)
    {
        snat_seq = 0;
        next_offset = e->next_offset;
    }
    else
    {
        next_offset += e->next_offset;
    }

    if (!strcmp(t->u.user.name, "SNAT"))
    {
        ++snat_seq;

        if(NAT_IPT_RULE_IS_FOR_NAPT(e))
        {
            HNAT_PRINTK("this ipt rule only for HW napt offload\n");

        }
        else
        {
            /*for basic nat offload*/
            HNAT_PRINTK("[%d]next_offset:%d underflow:%d\n",
                        *i, next_offset, underflow);

            if(next_offset == underflow)  //new one
            {

                if(NAT_IPT_RULE_IS_NONE_MATCHES(e))
                {
                    /*none matches*/
                    ret = nat_ipt_check_none_matches(e);

                }
                else
                {
                    unsigned int j = 0;
                    /*iterate matches*/
                    ret = IPT_MATCH_ITERATE(e, nat_ipt_check_matches, e, &j);
                }
            }
        }
    }

    (*i)++ ;

    return ret;
}

static void
nat_ipt_data_cleanup(void)
{
    if (gbuffer)
        kfree(gbuffer);

    gbuffer = NULL;

    if (sbuffer)
        kfree(sbuffer);

    sbuffer = NULL;
}

static void
nat_ipt_data_init(void)
{
    /*alloc initial set buffer*/
    sbuffer = kmalloc(IPT_BUFFER_INIT_LEN, GFP_ATOMIC);

    if(sbuffer)
    {
        memset(sbuffer, 0, IPT_BUFFER_INIT_LEN);
        slen = IPT_BUFFER_INIT_LEN;
    }
    else
    {
        HNAT_PRINTK("%s sbuffer memory allocate fail\n", __func__);
    }

    /*alloc initial get buffer*/
    gbuffer = kmalloc(IPT_BUFFER_INIT_LEN, GFP_ATOMIC);

    if(gbuffer)
    {
        memset(gbuffer, 0, IPT_BUFFER_INIT_LEN);
        glen = IPT_BUFFER_INIT_LEN;
    }
    else
    {
        HNAT_PRINTK("%s gbuffer memory allocate fail\n", __func__);
    }


    /*set initial underflow: nf_nat_rule.c*/
    memset(&old_replace, 0, sizeof (old_replace));

    /*record ipt rule(SNAT) sequence for hw nat*/
    memset(hw_nat_ipt_seq, 0, NAT_HW_NUM);

    /*record ipt rule(SNAT) pubip index for hw nat*/
    memset(hw_nat_pip_idx, 0, NAT_HW_NUM);
}

static void
nat_ipt_flush(void)
{
    napt_hw_flush();

    nat_hw_flush();

    nat_ipt_data_cleanup();
    nat_ipt_data_init();

    HNAT_PRINTK("------(nat flush done)------\n");
}

static void
nat_ipt_add(struct ipt_replace ireplace)
{
    unsigned int i = 0;

    IPT_ENTRY_ITERATE(sbuffer,
                      ireplace.size,
                      nat_ipt_find_check_entry,
                      ireplace.underflow[NF_INET_POST_ROUTING],
                      &i);
}

static int
nat_ipt_hook_type_check(struct ipt_replace ireplace)
{
    int ret = -1;

    HNAT_PRINTK("------we only support SNAT-----\n");

    if((old_replace.underflow[NF_INET_POST_ROUTING]-
        old_replace.hook_entry[NF_INET_POST_ROUTING]) !=
        (ireplace.underflow[NF_INET_POST_ROUTING]-
        ireplace.hook_entry[NF_INET_POST_ROUTING]))
    {
        HNAT_PRINTK("------this is POSTROUTING(SNAT):yes!------\n");
        ret = 0;

    }
    else if ((old_replace.underflow[NF_INET_PRE_ROUTING]-
        old_replace.hook_entry[NF_INET_PRE_ROUTING]) !=
        (ireplace.underflow[NF_INET_PRE_ROUTING]-
        ireplace.hook_entry[NF_INET_PRE_ROUTING]))
    {
        HNAT_PRINTK("------this is PREROUTING(DNAT):no!------\n");

    }
    else if((old_replace.underflow[NF_INET_LOCAL_OUT]-
        old_replace.hook_entry[NF_INET_LOCAL_OUT]) !=
        (ireplace.underflow[NF_INET_LOCAL_OUT]-
        ireplace.hook_entry[NF_INET_LOCAL_OUT]))
    {
        HNAT_PRINTK("------this is OUTPUT:no!------\n");

    }
    else
    {
        HNAT_PRINTK("------this is UNKNOW:no!------\n");

    }

    return ret;
}

static void
nat_ipt_rules_cp_from_user(void **buf, unsigned int *buf_len,
                           void __user *user, unsigned int user_len)
{
    if((*buf == 0) || (user == 0))
    {
        return;
    }

    if (*buf_len < user_len)
    {
        if(*buf)
        {
            kfree(*buf);
            *buf = kmalloc(user_len, GFP_ATOMIC);
			if(*buf == NULL)
			{
				HNAT_PRINTK("%s memory allocate fail\n", __func__);
				return;
			}
            *buf_len = user_len;
        }
    }
    HNAT_PRINTK("(2)nat_ipt_rules_cp_from_user *buf:%x user:%x user_len:%d\n",
                (unsigned int)(uintptr_t)*buf, (unsigned int)(uintptr_t)user, user_len);
    copy_from_user(*buf, user, user_len);

    return;
}

static int
nat_ipt_set_ctl(struct sock *sk, int cmd, void __user * user, unsigned int len)
{
    struct ipt_replace ireplace;

	memset(&ireplace, 0, sizeof(ireplace));

    HNAT_PRINTK("NAT set hook\n");

    if (cmd != IPT_SO_SET_REPLACE)
        goto normal;

    copy_from_user(&ireplace, user, sizeof (ireplace));

    if (strcmp(ireplace.name, "nat")
            || (ireplace.num_entries == ireplace.num_counters))
    {
        HNAT_PRINTK("none NAT or no new entry %d", ireplace.num_entries);
        goto normal;
    }


    if (ireplace.num_entries == NF_NAT_INIT_ENTRIES_NUM)
    {
        nat_ipt_flush();
        goto normal;
    }

    if (nat_ipt_hook_type_check(ireplace) != 0)
    {
        goto normal;
    }

    nat_ipt_rules_cp_from_user((void **)&sbuffer, &slen,
                               (user + sizeof (ireplace)),
                               ireplace.size);

    if (ireplace.num_entries > ireplace.num_counters)
    {
        nat_ipt_add(ireplace);
    }
    else
    {
        nat_ipt_del(ireplace);
    }

normal:
    /*save old_replace for next hook type check*/
    old_replace = ireplace;

    return orgi_ipt_sockopts.set(sk, cmd, user, len);
}

static int
nat_ipt_get_ctl(struct sock *sk, int cmd, void __user * user, int *len)
{
    int k = orgi_ipt_sockopts.get(sk, cmd, user, len);

    if (cmd == IPT_SO_GET_ENTRIES)
    {

        struct ipt_get_entries entries;

        copy_from_user(&entries, user, sizeof (entries));

        nat_ipt_rules_cp_from_user((void **)&gbuffer, &glen,
                                   (user + sizeof (struct ipt_get_entries)),
                                   (*len - sizeof (entries)));
    }
    return k;
}


void
nat_ipt_sockopts_replace(void)
{
	int ret = 0;
    /*register an temp sockopts to find ipt_sockopts*/
    if((ret = nf_register_sockopt(&tmp_ipt_sockopts)) < 0) {
		return;
    }
    list_for_each_entry(ipt_sockopts, tmp_ipt_sockopts.list.next, list)
    {
        if (ipt_sockopts->set_optmin == IPT_BASE_CTL)
        {
			nat_sockopts_init = 1;
            break;
        }
    }
    nf_unregister_sockopt(&tmp_ipt_sockopts);
	if(!nat_sockopts_init)
		return;

    /*save orginal ipt_sockopts*/
    orgi_ipt_sockopts = *ipt_sockopts;

    /*replace ipt_sockopts with our opts*/
    ipt_sockopts->set = nat_ipt_set_ctl;
    ipt_sockopts->get = nat_ipt_get_ctl;
}

static void
nat_ipt_sockopts_restore(void)
{
    ipt_sockopts->set = orgi_ipt_sockopts.set;
    ipt_sockopts->get = orgi_ipt_sockopts.get;
}

void
nat_ipt_helper_init(void)
{
    nat_ipt_sockopts_replace();
    nat_ipt_data_init();
}

void
nat_ipt_helper_exit(void)
{
    nat_ipt_sockopts_restore();
    nat_ipt_data_cleanup();
    nat_hw_flush();
}

