/*
 *  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-2018 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"

#if P2MP_SERVER

#include "mroute.h"
#include "proto.h"
#include "error.h"
#include "socket.h"

#include "memdbg.h"

void
mroute_addr_init(struct mroute_addr *addr)
{
    CLEAR(*addr);
}

/*
 * Ethernet multicast addresses.
 */

static inline bool
is_mac_mcast_addr(const uint8_t *mac)
{
    return (bool) (mac[0] & 1);
}

static inline bool
is_mac_mcast_maddr(const struct mroute_addr *addr)
{
    return (addr->type & MR_ADDR_MASK) == MR_ADDR_ETHER
           && is_mac_mcast_addr(addr->eth_addr);
}

/*
 * Don't learn certain addresses.
 */
bool
mroute_learnable_address(const struct mroute_addr *addr, struct gc_arena *gc)
{
    int i;
    bool all_zeros = true;
    bool all_ones = true;

    for (i = 0; i < addr->len; ++i)
    {
        int b = addr->raw_addr[i];
        if (b != 0x00)
        {
            all_zeros = false;
        }
        if (b != 0xFF)
        {
            all_ones = false;
        }
    }

    /* only networkss shorter than 8 bits are allowed to be all 0s. */
    if (all_zeros
        && !((addr->type & MR_WITH_NETBITS) && (addr->netbits < 8)))
    {
        msg(D_MULTI_LOW, "Can't learn %s: network is all 0s, but netbits >= 8",
            mroute_addr_print(addr, gc));
        return false;
    }

    if (all_ones)
    {
        msg(D_MULTI_LOW, "Can't learn %s: network is all 1s",
            mroute_addr_print(addr, gc));
        return false;
    }

    if (is_mac_mcast_maddr(addr))
    {
        msg(D_MULTI_LOW, "Can't learn %s: network is a multicast address",
            mroute_addr_print(addr, gc));
        return false;
    }

    return true;
}

static inline void
mroute_get_in_addr_t(struct mroute_addr *ma, const in_addr_t src, unsigned int mask)
{
    if (ma)
    {
        ma->type = MR_ADDR_IPV4 | mask;
        ma->netbits = 0;
        ma->len = 4;
        ma->v4.addr = src;
    }
}

static inline void
mroute_get_in6_addr(struct mroute_addr *ma, const struct in6_addr src, unsigned int mask)
{
    if (ma)
    {
        ma->type = MR_ADDR_IPV6 | mask;
        ma->netbits = 0;
        ma->len = 16;
        ma->v6.addr = src;
    }
}

static inline bool
mroute_is_mcast(const in_addr_t addr)
{
    return ((addr & htonl(IP_MCAST_SUBNET_MASK)) == htonl(IP_MCAST_NETWORK));
}

/* RFC 4291, 2.7, "binary 11111111 at the start of an address identifies
 *                 the address as being a multicast address"
 */
static inline bool
mroute_is_mcast_ipv6(const struct in6_addr addr)
{
    return (addr.s6_addr[0] == 0xff);
}

#ifdef ENABLE_PF

static unsigned int
mroute_extract_addr_arp(struct mroute_addr *src,
                        struct mroute_addr *dest,
                        const struct buffer *buf)
{
    unsigned int ret = 0;
    if (BLEN(buf) >= (int) sizeof(struct openvpn_arp))
    {
        const struct openvpn_arp *arp = (const struct openvpn_arp *) BPTR(buf);
        if (arp->mac_addr_type == htons(0x0001)
            && arp->proto_addr_type == htons(0x0800)
            && arp->mac_addr_size == 0x06
            && arp->proto_addr_size == 0x04)
        {
            mroute_get_in_addr_t(src, arp->ip_src, MR_ARP);
            mroute_get_in_addr_t(dest, arp->ip_dest, MR_ARP);

            /* multicast packet? */
            if (mroute_is_mcast(arp->ip_dest))
            {
                ret |= MROUTE_EXTRACT_MCAST;
            }

            ret |= MROUTE_EXTRACT_SUCCEEDED;
        }
    }
    return ret;
}

#endif /* ifdef ENABLE_PF */

unsigned int
mroute_extract_addr_ip(struct mroute_addr *src, struct mroute_addr *dest,
                       const struct buffer *buf)
{
    unsigned int ret = 0;
    if (BLEN(buf) >= 1)
    {
        switch (OPENVPN_IPH_GET_VER(*BPTR(buf)))
        {
            case 4:
                if (BLEN(buf) >= (int) sizeof(struct openvpn_iphdr))
                {
                    const struct openvpn_iphdr *ip = (const struct openvpn_iphdr *) BPTR(buf);

                    mroute_get_in_addr_t(src, ip->saddr, 0);
                    mroute_get_in_addr_t(dest, ip->daddr, 0);

                    /* multicast packet? */
                    if (mroute_is_mcast(ip->daddr))
                    {
                        ret |= MROUTE_EXTRACT_MCAST;
                    }

                    /* IGMP message? */
                    if (ip->protocol == OPENVPN_IPPROTO_IGMP)
                    {
                        ret |= MROUTE_EXTRACT_IGMP;
                    }

                    ret |= MROUTE_EXTRACT_SUCCEEDED;
                }
                break;

            case 6:
                if (BLEN(buf) >= (int) sizeof(struct openvpn_ipv6hdr))
                {
                    const struct openvpn_ipv6hdr *ipv6 = (const struct openvpn_ipv6hdr *) BPTR(buf);
#if 0                           /* very basic debug */
                    struct gc_arena gc = gc_new();
                    msg( M_INFO, "IPv6 packet! src=%s, dst=%s",
                         print_in6_addr( ipv6->saddr, 0, &gc ),
                         print_in6_addr( ipv6->daddr, 0, &gc ));
                    gc_free(&gc);
#endif

                    mroute_get_in6_addr(src, ipv6->saddr, 0);
                    mroute_get_in6_addr(dest, ipv6->daddr, 0);

                    if (mroute_is_mcast_ipv6(ipv6->daddr))
                    {
                        ret |= MROUTE_EXTRACT_MCAST;
                    }

                    ret |= MROUTE_EXTRACT_SUCCEEDED;
                }
                break;

            default:
                msg(M_WARN, "IP packet with unknown IP version=%d seen",
                    OPENVPN_IPH_GET_VER(*BPTR(buf)));
        }
    }
    return ret;
}

unsigned int
mroute_extract_addr_ether(struct mroute_addr *src,
                          struct mroute_addr *dest,
                          struct mroute_addr *esrc,
                          struct mroute_addr *edest,
                          const struct buffer *buf)
{
    unsigned int ret = 0;
    if (BLEN(buf) >= (int) sizeof(struct openvpn_ethhdr))
    {
        const struct openvpn_ethhdr *eth = (const struct openvpn_ethhdr *) BPTR(buf);
        if (src)
        {
            src->type = MR_ADDR_ETHER;
            src->netbits = 0;
            src->len = 6;
            memcpy(src->eth_addr, eth->source, sizeof(dest->eth_addr));
        }
        if (dest)
        {
            dest->type = MR_ADDR_ETHER;
            dest->netbits = 0;
            dest->len = 6;
            memcpy(dest->eth_addr, eth->dest, sizeof(dest->eth_addr));

            /* ethernet broadcast/multicast packet? */
            if (is_mac_mcast_addr(eth->dest))
            {
                ret |= MROUTE_EXTRACT_BCAST;
            }
        }

        ret |= MROUTE_EXTRACT_SUCCEEDED;

#ifdef ENABLE_PF
        if (esrc || edest)
        {
            struct buffer b = *buf;
            if (buf_advance(&b, sizeof(struct openvpn_ethhdr)))
            {
                switch (ntohs(eth->proto))
                {
                    case OPENVPN_ETH_P_IPV4:
                        ret |= (mroute_extract_addr_ip(esrc, edest, &b) << MROUTE_SEC_SHIFT);
                        break;

                    case OPENVPN_ETH_P_ARP:
                        ret |= (mroute_extract_addr_arp(esrc, edest, &b) << MROUTE_SEC_SHIFT);
                        break;
                }
            }
        }
#endif
    }
    return ret;
}

/*
 * Translate a struct openvpn_sockaddr (osaddr)
 * to a struct mroute_addr (addr).
 */
bool
mroute_extract_openvpn_sockaddr(struct mroute_addr *addr,
                                const struct openvpn_sockaddr *osaddr,
                                bool use_port)
{
    switch (osaddr->addr.sa.sa_family)
    {
        case AF_INET:
        {
            if (use_port)
            {
                addr->type = MR_ADDR_IPV4 | MR_WITH_PORT;
                addr->netbits = 0;
                addr->len = 6;
                addr->v4.addr = osaddr->addr.in4.sin_addr.s_addr;
                addr->v4.port = osaddr->addr.in4.sin_port;
            }
            else
            {
                addr->type = MR_ADDR_IPV4;
                addr->netbits = 0;
                addr->len = 4;
                addr->v4.addr = osaddr->addr.in4.sin_addr.s_addr;
            }
            return true;
        }

        case AF_INET6:
            if (use_port)
            {
                addr->type = MR_ADDR_IPV6 | MR_WITH_PORT;
                addr->netbits = 0;
                addr->len = 18;
                addr->v6.addr = osaddr->addr.in6.sin6_addr;
                addr->v6.port = osaddr->addr.in6.sin6_port;
            }
            else
            {
                addr->type = MR_ADDR_IPV6;
                addr->netbits = 0;
                addr->len = 16;
                addr->v6.addr = osaddr->addr.in6.sin6_addr;
            }
            return true;
    }
    return false;
}

/*
 * Zero off the host bits in an address, leaving
 * only the network bits, using the netbits member of
 * struct mroute_addr as the controlling parameter.
 *
 * TODO: this is called for route-lookup for every yet-unhashed
 * destination address, so for lots of active net-iroutes, this
 * might benefit from some "zeroize 32 bit at a time" improvements
 */
void
mroute_addr_mask_host_bits(struct mroute_addr *ma)
{
    if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV4)
    {
        in_addr_t addr = ntohl(ma->v4.addr);
        addr &= netbits_to_netmask(ma->netbits);
        ma->v4.addr = htonl(addr);
    }
    else if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV6)
    {
        int byte = sizeof(ma->v6.addr) - 1;     /* rightmost byte in address */
        int bits_to_clear = 128 - ma->netbits;

        while (byte >= 0 && bits_to_clear > 0)
        {
            if (bits_to_clear >= 8)
            {
                ma->v6.addr.s6_addr[byte--] = 0;
                bits_to_clear -= 8;
            }
            else
            {
                ma->v6.addr.s6_addr[byte--] &= (IPV4_NETMASK_HOST << bits_to_clear);
                bits_to_clear = 0;
            }
        }
        ASSERT( bits_to_clear == 0 );
    }
    else
    {
        ASSERT(0);
    }
}

/*
 * The mroute_addr hash function takes into account the
 * address type, number of bits in the network address,
 * and the actual address.
 */
uint32_t
mroute_addr_hash_function(const void *key, uint32_t iv)
{
    return hash_func(mroute_addr_hash_ptr((const struct mroute_addr *) key),
                     mroute_addr_hash_len((const struct mroute_addr *) key),
                     iv);
}

bool
mroute_addr_compare_function(const void *key1, const void *key2)
{
    return mroute_addr_equal((const struct mroute_addr *) key1,
                             (const struct mroute_addr *) key2);
}

const char *
mroute_addr_print(const struct mroute_addr *ma,
                  struct gc_arena *gc)
{
    return mroute_addr_print_ex(ma, MAPF_IA_EMPTY_IF_UNDEF, gc);
}

const char *
mroute_addr_print_ex(const struct mroute_addr *ma,
                     const unsigned int flags,
                     struct gc_arena *gc)
{
    struct buffer out = alloc_buf_gc(64, gc);
    if (ma)
    {
        struct mroute_addr maddr = *ma;

        switch (maddr.type & MR_ADDR_MASK)
        {
            case MR_ADDR_ETHER:
                buf_printf(&out, "%s", format_hex_ex(ma->eth_addr,
                                                     sizeof(ma->eth_addr), 0, 1, ":", gc));
                break;

            case MR_ADDR_IPV4:
            {
                if ((flags & MAPF_SHOW_ARP) && (maddr.type & MR_ARP))
                {
                    buf_printf(&out, "ARP/");
                }
                buf_printf(&out, "%s", print_in_addr_t(ntohl(maddr.v4.addr),
                                                       (flags & MAPF_IA_EMPTY_IF_UNDEF) ? IA_EMPTY_IF_UNDEF : 0, gc));
                if (maddr.type & MR_WITH_NETBITS)
                {
                    if (flags & MAPF_SUBNET)
                    {
                        const in_addr_t netmask = netbits_to_netmask(maddr.netbits);
                        buf_printf(&out, "/%s", print_in_addr_t(netmask, 0, gc));
                    }
                    else
                    {
                        buf_printf(&out, "/%d", maddr.netbits);
                    }
                }
                if (maddr.type & MR_WITH_PORT)
                {
                    buf_printf(&out, ":%d", ntohs(maddr.v4.port));
                }
            }
            break;

            case MR_ADDR_IPV6:
            {
                if (IN6_IS_ADDR_V4MAPPED( &maddr.v6.addr ) )
                {
                    buf_printf(&out, "%s", print_in_addr_t(maddr.v4mappedv6.addr,
                                                           IA_NET_ORDER, gc));
                    /* we only print port numbers for v4mapped v6 as of
                     * today, because "v6addr:port" is too ambiguous
                     */
                    if (maddr.type & MR_WITH_PORT)
                    {
                        buf_printf(&out, ":%d", ntohs(maddr.v6.port));
                    }
                }
                else
                {
                    buf_printf(&out, "%s", print_in6_addr(maddr.v6.addr, 0, gc));
                }
                if (maddr.type & MR_WITH_NETBITS)
                {
                    buf_printf(&out, "/%d", maddr.netbits);
                }
            }
            break;

            default:
                buf_printf(&out, "UNKNOWN");
                break;
        }
        return BSTR(&out);
    }
    else
    {
        return "[NULL]";
    }
}

/*
 * mroute_helper's main job is keeping track of
 * currently used CIDR netlengths, so we don't
 * have to cycle through all 33.
 */

struct mroute_helper *
mroute_helper_init(int ageable_ttl_secs)
{
    struct mroute_helper *mh;
    ALLOC_OBJ_CLEAR(mh, struct mroute_helper);
    mh->ageable_ttl_secs = ageable_ttl_secs;
    return mh;
}

static void
mroute_helper_regenerate(struct mroute_helper *mh)
{
    int i, j = 0;
    for (i = MR_HELPER_NET_LEN - 1; i >= 0; --i)
    {
        if (mh->net_len_refcount[i] > 0)
        {
            mh->net_len[j++] = (uint8_t) i;
        }
    }
    mh->n_net_len = j;

#ifdef ENABLE_DEBUG
    if (check_debug_level(D_MULTI_DEBUG))
    {
        struct gc_arena gc = gc_new();
        struct buffer out = alloc_buf_gc(256, &gc);
        buf_printf(&out, "MROUTE CIDR netlen:");
        for (i = 0; i < mh->n_net_len; ++i)
        {
            buf_printf(&out, " /%d", mh->net_len[i]);
        }
        dmsg(D_MULTI_DEBUG, "%s", BSTR(&out));
        gc_free(&gc);
    }
#endif
}

void
mroute_helper_add_iroute46(struct mroute_helper *mh, int netbits)
{
    if (netbits >= 0)
    {
        ASSERT(netbits < MR_HELPER_NET_LEN);
        ++mh->cache_generation;
        ++mh->net_len_refcount[netbits];
        if (mh->net_len_refcount[netbits] == 1)
        {
            mroute_helper_regenerate(mh);
        }
    }
}

void
mroute_helper_del_iroute46(struct mroute_helper *mh, int netbits)
{
    if (netbits >= 0)
    {
        ASSERT(netbits < MR_HELPER_NET_LEN);
        ++mh->cache_generation;
        --mh->net_len_refcount[netbits];
        ASSERT(mh->net_len_refcount[netbits] >= 0);
        if (!mh->net_len_refcount[netbits])
        {
            mroute_helper_regenerate(mh);
        }
    }
}

void
mroute_helper_free(struct mroute_helper *mh)
{
    free(mh);
}

#else  /* if P2MP_SERVER */
static void
dummy(void)
{
}
#endif /* P2MP_SERVER */
