/*
 *  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-2019 OpenVPN Technologies, Inc. <sales@openvpn.net>
 *  Copyright (C) 2010      Fabian Knittel <fabian.knittel@lettink.de>
 *
 *  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 "multi.h"
#include "options.h"
#include "vlan.h"

/*
 * Retrieve the VLAN Identifier (VID) from the IEEE 802.1Q header.
 *
 * @param hdr Pointer to the Ethernet header with IEEE 802.1Q tagging.
 * @return    Returns the VID in host byte order.
 */
static uint16_t
vlanhdr_get_vid(const struct openvpn_8021qhdr *hdr)
{
    return ntohs(hdr->pcp_cfi_vid & OPENVPN_8021Q_MASK_VID);
}

/*
 * Set the VLAN Identifier (VID) in an IEEE 802.1Q header.
 *
 * @param hdr Pointer to the Ethernet header with IEEE 802.1Q tagging.
 * @param vid The VID to set (in host byte order).
 */
static void
vlanhdr_set_vid(struct openvpn_8021qhdr *hdr, const uint16_t vid)
{
    hdr->pcp_cfi_vid = (hdr->pcp_cfi_vid & ~OPENVPN_8021Q_MASK_VID)
                       | (htons(vid) & OPENVPN_8021Q_MASK_VID);
}

/*
 * vlan_decapsulate - remove 802.1q header and return VID
 *
 * For vlan_accept == VLAN_ONLY_UNTAGGED_OR_PRIORITY:
 *   Only untagged frames and frames that are priority-tagged (VID == 0) are
 *   accepted.  (This means that VLAN-tagged frames are dropped.)  For frames
 *   that aren't dropped, the global vlan_pvid is returned as VID.
 *
 * For vlan_accept == VLAN_ONLY_TAGGED:
 *   If a frame is VLAN-tagged the tagging is removed and the embedded VID is
 *   returned.  Any included priority information is lost.
 *   If a frame isn't VLAN-tagged, the frame is dropped.
 *
 * For vlan_accept == VLAN_ALL:
 *   Accepts both VLAN-tagged and untagged (or priority-tagged) frames and
 *   and handles them as described above.
 *
 * @param c   The global context.
 * @param buf The ethernet frame.
 * @return    Returns -1 if the frame is dropped or the VID if it is accepted.
 */
int16_t
vlan_decapsulate(const struct context *c, struct buffer *buf)
{
    const struct openvpn_8021qhdr *vlanhdr;
    struct openvpn_ethhdr *ethhdr;
    uint16_t vid;

    /* assume untagged frame */
    if (BLEN(buf) < sizeof(*ethhdr))
    {
        goto drop;
    }

    ethhdr = (struct openvpn_ethhdr *)BPTR(buf);
    if (ethhdr->proto != htons(OPENVPN_ETH_P_8021Q))
    {
        /* reject untagged frame */
        if (c->options.vlan_accept == VLAN_ONLY_TAGGED)
        {
            msg(D_VLAN_DEBUG,
                "dropping frame without vlan-tag (proto/len 0x%04x)",
                ntohs(ethhdr->proto));
            goto drop;
        }

        /* untagged frame is accepted and associated with the global VID */
        msg(D_VLAN_DEBUG,
            "assuming pvid for frame without vlan-tag, pvid: %u (proto/len 0x%04x)",
            c->options.vlan_pvid, ntohs(ethhdr->proto));

        return c->options.vlan_pvid;
    }

    /* tagged frame */
    if (BLEN(buf) < sizeof(*vlanhdr))
    {
        goto drop;
    }

    vlanhdr = (const struct openvpn_8021qhdr *)BPTR(buf);
    vid = vlanhdr_get_vid(vlanhdr);

    switch (c->options.vlan_accept)
    {
        case VLAN_ONLY_UNTAGGED_OR_PRIORITY:
            /* VLAN-tagged frame: drop packet */
            if (vid != 0)
            {
                msg(D_VLAN_DEBUG, "dropping frame with vlan-tag, vid: %u (proto/len 0x%04x)",
                    vid, ntohs(vlanhdr->proto));
                goto drop;
            }

        /* vid == 0 means prio-tagged packet: don't drop and fall-through */
        case VLAN_ONLY_TAGGED:
        case VLAN_ALL:
            /* tagged frame can be accepted: extract vid and strip encapsulation */

            /* in case of prio-tagged frame (vid == 0), assume the sender
             * knows what he is doing and forward the packet as it is, so to
             * keep the priority information intact.
             */
            if (vid == 0)
            {
                /* return the global VID for priority-tagged frames */
                return c->options.vlan_pvid;
            }

            /* here we have a proper VLAN tagged frame: perform decapsulation
             * and return embedded VID
             */
            msg(D_VLAN_DEBUG,
                "removing vlan-tag from frame: vid: %u, wrapped proto/len: 0x%04x",
                vid, ntohs(vlanhdr->proto));

            /* save inner protocol to be restored later after decapsulation */
            uint16_t proto = vlanhdr->proto;
            /* move the buffer head forward to adjust the headroom to a
             * non-tagged frame
             */
            buf_advance(buf, SIZE_ETH_TO_8021Q_HDR);
            /* move the content of the 802.1q header to the new head, so that
             * src/dst addresses are copied over
             */
            ethhdr = memmove(BPTR(buf), vlanhdr, sizeof(*ethhdr));
            /* restore the inner protocol value */
            ethhdr->proto = proto;

            return vid;
    }

drop:
    buf->len = 0;
    return -1;
}

/*
 * vlan_encapsulate - add 802.1q header and set the context related VID
 *
 * Assumes vlan_accept == VLAN_ONLY_TAGGED
 *
 * @param c   The current context.
 * @param buf The ethernet frame to encapsulate.
 */
void
vlan_encapsulate(const struct context *c, struct buffer *buf)
{
    const struct openvpn_ethhdr *ethhdr;
    struct openvpn_8021qhdr *vlanhdr;

    if (BLEN(buf) < sizeof(*ethhdr))
    {
        goto drop;
    }

    ethhdr = (const struct openvpn_ethhdr *)BPTR(buf);
    if (ethhdr->proto == htons(OPENVPN_ETH_P_8021Q))
    {
        /* Priority-tagged frame. (VLAN-tagged frames have been dropped before
         * getting to this point)
         */

        /* Frame too small for header type? */
        if (BLEN(buf) < sizeof(*vlanhdr))
        {
            goto drop;
        }

        vlanhdr = (struct openvpn_8021qhdr *)BPTR(buf);

        /* sanity check: ensure this packet is really just prio-tagged */
        uint16_t vid = vlanhdr_get_vid(vlanhdr);
        if (vid != 0)
        {
            goto drop;
        }
    }
    else
    {
        /* Untagged frame. */

        /* Not enough head room for VLAN tag? */
        if (buf_reverse_capacity(buf) < SIZE_ETH_TO_8021Q_HDR)
        {
            goto drop;
        }

        vlanhdr = (struct openvpn_8021qhdr *)buf_prepend(buf,
                                                         SIZE_ETH_TO_8021Q_HDR);

        /* Initialise VLAN/802.1q header.
         * Move the Eth header so to keep dst/src addresses the same and then
         * assign the other fields.
         *
         * Also, save the inner protocol first, so that it can be restored later
         * after the memmove()
         */
        uint16_t proto = ethhdr->proto;
        memmove(vlanhdr, ethhdr, sizeof(*ethhdr));
        vlanhdr->tpid = htons(OPENVPN_ETH_P_8021Q);
        vlanhdr->pcp_cfi_vid = 0;
        vlanhdr->proto = proto;
    }

    /* set the VID corresponding to the current context (client) */
    vlanhdr_set_vid(vlanhdr, c->options.vlan_pvid);

    msg(D_VLAN_DEBUG, "tagging frame: vid %u (wrapping proto/len: %04x)",
        c->options.vlan_pvid, vlanhdr->proto);
    return;

drop:
    /* Drop the frame. */
    buf->len = 0;
}

/*
 * vlan_is_tagged - check if a packet is VLAN-tagged
 *
 * Checks whether ethernet frame is VLAN-tagged.
 *
 * @param buf The ethernet frame.
 * @return    Returns true if the frame is VLAN-tagged, false otherwise.
 */
bool
vlan_is_tagged(const struct buffer *buf)
{
    const struct openvpn_8021qhdr *vlanhdr;
    uint16_t vid;

    if (BLEN(buf) < sizeof(struct openvpn_8021qhdr))
    {
        /* frame too small to be VLAN-tagged */
        return false;
    }

    vlanhdr = (const struct openvpn_8021qhdr *)BPTR(buf);

    if (ntohs(vlanhdr->tpid) != OPENVPN_ETH_P_8021Q)
    {
        /* non tagged frame */
        return false;
    }

    vid = vlanhdr_get_vid(vlanhdr);
    if (vid == 0)
    {
        /* no vid: piority tagged only */
        return false;
    }

    return true;
}

void
vlan_process_outgoing_tun(struct multi_context *m, struct multi_instance *mi)
{
    if (!m->top.options.vlan_tagging)
    {
        return;
    }

    if (m->top.options.vlan_accept == VLAN_ONLY_UNTAGGED_OR_PRIORITY)
    {
        /* Packets forwarded to the TAP devices aren't VLAN-tagged. Only packets
         * matching the PVID configured globally are allowed to be received
         */
        if (m->top.options.vlan_pvid != mi->context.options.vlan_pvid)
        {
            /* Packet is coming from the wrong VID, drop it.  */
            mi->context.c2.to_tun.len = 0;
        }
    }
    else if (m->top.options.vlan_accept == VLAN_ALL)
    {
        /* Packets either need to be VLAN-tagged or not, depending on the
         * packet's originating VID and the port's native VID (PVID).  */

        if (m->top.options.vlan_pvid != mi->context.options.vlan_pvid)
        {
            /* Packets need to be VLAN-tagged, because the packet's VID does not
             * match the port's PVID.  */
            vlan_encapsulate(&mi->context, &mi->context.c2.to_tun);
        }
    }
    else if (m->top.options.vlan_accept == VLAN_ONLY_TAGGED)
    {
        /* All packets on the port (the tap device) need to be VLAN-tagged.  */
        vlan_encapsulate(&mi->context, &mi->context.c2.to_tun);
    }
}
