/*
 *  OpenVPN -- An application to securely tunnel IP networks
 *             over a single TCP/UDP port, with support for SSL/TLS-based
 *             session authentication and key exchange,
 *             packet encryption, packet authentication, and
 *             packet compression.
 *
 *  Copyright (C) 2002-2021 OpenVPN Inc <sales@openvpn.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2
 *  as published by the Free Software Foundation.
 *
 *  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.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#elif defined(_MSC_VER)
#include "config-msvc.h"
#endif

#include "syshead.h"

#include "clinat.h"
#include "proto.h"
#include "socket.h"
#include "memdbg.h"

static bool
add_entry(struct client_nat_option_list *dest,
          const struct client_nat_entry *e)
{
    if (dest->n >= MAX_CLIENT_NAT)
    {
        msg(M_WARN, "WARNING: client-nat table overflow (max %d entries)", MAX_CLIENT_NAT);
        return false;
    }
    else
    {
        dest->entries[dest->n++] = *e;
        return true;
    }
}

void
print_client_nat_list(const struct client_nat_option_list *list, int msglevel)
{
    struct gc_arena gc = gc_new();
    int i;

    msg(msglevel, "*** CNAT list");
    if (list)
    {
        for (i = 0; i < list->n; ++i)
        {
            const struct client_nat_entry *e = &list->entries[i];
            msg(msglevel, "  CNAT[%d] t=%d %s/%s/%s",
                i,
                e->type,
                print_in_addr_t(e->network, IA_NET_ORDER, &gc),
                print_in_addr_t(e->netmask, IA_NET_ORDER, &gc),
                print_in_addr_t(e->foreign_network, IA_NET_ORDER, &gc));
        }
    }
    gc_free(&gc);
}

struct client_nat_option_list *
new_client_nat_list(struct gc_arena *gc)
{
    struct client_nat_option_list *ret;
    ALLOC_OBJ_CLEAR_GC(ret, struct client_nat_option_list, gc);
    return ret;
}

struct client_nat_option_list *
clone_client_nat_option_list(const struct client_nat_option_list *src, struct gc_arena *gc)
{
    struct client_nat_option_list *ret;
    ALLOC_OBJ_GC(ret, struct client_nat_option_list, gc);
    *ret = *src;
    return ret;
}

void
copy_client_nat_option_list(struct client_nat_option_list *dest,
                            const struct client_nat_option_list *src)
{
    int i;
    for (i = 0; i < src->n; ++i)
    {
        if (!add_entry(dest, &src->entries[i]))
        {
            break;
        }
    }
}

void
add_client_nat_to_option_list(struct client_nat_option_list *dest,
                              const char *type,
                              const char *network,
                              const char *netmask,
                              const char *foreign_network,
                              int msglevel)
{
    struct client_nat_entry e;
    bool ok;

    if (!strcmp(type, "snat"))
    {
        e.type = CN_SNAT;
    }
    else if (!strcmp(type, "dnat"))
    {
        e.type = CN_DNAT;
    }
    else
    {
        msg(msglevel, "client-nat: type must be 'snat' or 'dnat'");
        return;
    }

    e.network = getaddr(0, network, 0, &ok, NULL);
    if (!ok)
    {
        msg(msglevel, "client-nat: bad network: %s", network);
        return;
    }
    e.netmask = getaddr(0, netmask, 0, &ok, NULL);
    if (!ok)
    {
        msg(msglevel, "client-nat: bad netmask: %s", netmask);
        return;
    }
    e.foreign_network = getaddr(0, foreign_network, 0, &ok, NULL);
    if (!ok)
    {
        msg(msglevel, "client-nat: bad foreign network: %s", foreign_network);
        return;
    }

    add_entry(dest, &e);
}

#if 0
static void
print_checksum(struct openvpn_iphdr *iph, const char *prefix)
{
    uint16_t *sptr;
    unsigned int sum = 0;
    int i = 0;
    for (sptr = (uint16_t *)iph; (uint8_t *)sptr < (uint8_t *)iph + sizeof(struct openvpn_iphdr); sptr++)
    {
        i += 1;
        sum += *sptr;
    }
    msg(M_INFO, "** CKSUM[%d] %s %08x", i, prefix, sum);
}
#endif

static void
print_pkt(struct openvpn_iphdr *iph, const char *prefix, const int direction, const int msglevel)
{
    struct gc_arena gc = gc_new();

    char *dirstr = "???";
    if (direction == CN_OUTGOING)
    {
        dirstr = "OUT";
    }
    else if (direction == CN_INCOMING)
    {
        dirstr = "IN";
    }

    msg(msglevel, "** CNAT %s %s %s -> %s",
        dirstr,
        prefix,
        print_in_addr_t(iph->saddr, IA_NET_ORDER, &gc),
        print_in_addr_t(iph->daddr, IA_NET_ORDER, &gc));

    gc_free(&gc);
}

void
client_nat_transform(const struct client_nat_option_list *list,
                     struct buffer *ipbuf,
                     const int direction)
{
    struct ip_tcp_udp_hdr *h = (struct ip_tcp_udp_hdr *) BPTR(ipbuf);
    int i;
    uint32_t addr, *addr_ptr;
    const uint32_t *from, *to;
    int accumulate = 0;
    unsigned int amask;
    unsigned int alog = 0;

    if (check_debug_level(D_CLIENT_NAT))
    {
        print_pkt(&h->ip, "BEFORE", direction, D_CLIENT_NAT);
    }

    for (i = 0; i < list->n; ++i)
    {
        const struct client_nat_entry *e = &list->entries[i]; /* current NAT rule */
        if (e->type ^ direction)
        {
            addr = *(addr_ptr = &h->ip.daddr);
            amask = 2;
        }
        else
        {
            addr = *(addr_ptr = &h->ip.saddr);
            amask = 1;
        }
        if (direction)
        {
            from = &e->foreign_network;
            to = &e->network;
        }
        else
        {
            from = &e->network;
            to = &e->foreign_network;
        }

        if (((addr & e->netmask) == *from) && !(amask & alog))
        {
            /* pre-adjust IP checksum */
            ADD_CHECKSUM_32(accumulate, addr);

            /* do NAT transform */
            addr = (addr & ~e->netmask) | *to;

            /* post-adjust IP checksum */
            SUB_CHECKSUM_32(accumulate, addr);

            /* write the modified address to packet */
            *addr_ptr = addr;

            /* mark as modified */
            alog |= amask;
        }
    }
    if (alog)
    {
        if (check_debug_level(D_CLIENT_NAT))
        {
            print_pkt(&h->ip, "AFTER", direction, D_CLIENT_NAT);
        }

        ADJUST_CHECKSUM(accumulate, h->ip.check);

        if (h->ip.protocol == OPENVPN_IPPROTO_TCP)
        {
            if (BLEN(ipbuf) >= sizeof(struct openvpn_iphdr) + sizeof(struct openvpn_tcphdr))
            {
                ADJUST_CHECKSUM(accumulate, h->u.tcp.check);
            }
        }
        else if (h->ip.protocol == OPENVPN_IPPROTO_UDP)
        {
            if (BLEN(ipbuf) >= sizeof(struct openvpn_iphdr) + sizeof(struct openvpn_udphdr))
            {
                ADJUST_CHECKSUM(accumulate, h->u.udp.check);
            }
        }
    }
}
