/*
 * Copyright (c) 2014 VMware, Inc. All Rights Reserved.
 *
 * Jesse Gross <jesse@nicira.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that: (1) source code
 * distributions retain the above copyright notice and this paragraph
 * in its entirety, and (2) distributions including binary code include
 * the above copyright notice and this paragraph in its entirety in
 * the documentation or other materials provided with the distribution.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE.
 */

#define NETDISSECT_REWORKED
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <tcpdump-stdinc.h>

#include "interface.h"
#include "extract.h"
#include "ethertype.h"

/*
 * Geneve header, draft-gross-geneve-02
 *
 *    0                   1                   2                   3
 *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    |Ver|  Opt Len  |O|C|    Rsvd.  |          Protocol Type        |
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    |        Virtual Network Identifier (VNI)       |    Reserved   |
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    |                    Variable Length Options                    |
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *
 * Options:
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    |          Option Class         |      Type     |R|R|R| Length  |
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    |                      Variable Option Data                     |
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 */

#define VER_SHIFT 6
#define HDR_OPTS_LEN_MASK 0x3F

#define FLAG_OAM      (1 << 7)
#define FLAG_CRITICAL (1 << 6)
#define FLAG_R1       (1 << 5)
#define FLAG_R2       (1 << 4)
#define FLAG_R3       (1 << 3)
#define FLAG_R4       (1 << 2)
#define FLAG_R5       (1 << 1)
#define FLAG_R6       (1 << 0)

#define OPT_TYPE_CRITICAL (1 << 7)
#define OPT_LEN_MASK 0x1F

static const struct tok geneve_flag_values[] = {
        { FLAG_OAM, "O" },
        { FLAG_CRITICAL, "C" },
        { FLAG_R1, "R1" },
        { FLAG_R2, "R2" },
        { FLAG_R3, "R3" },
        { FLAG_R4, "R4" },
        { FLAG_R5, "R5" },
        { FLAG_R6, "R6" },
        { 0, NULL }
};

static const char *
format_opt_class(uint16_t opt_class)
{
    if (opt_class <= 0xff)
        return "Standard";
    else if (opt_class == 0xffff)
        return "Experimental";
    else
        return "Unknown";
}

static void
geneve_opts_print(netdissect_options *ndo, const u_char *bp, u_int len)
{
    const char *sep = "";

    while (len > 0) {
        uint16_t opt_class;
        uint8_t opt_type;
        uint8_t opt_len;

        ND_PRINT((ndo, "%s", sep));
        sep = ", ";

        opt_class = EXTRACT_16BITS(bp);
        opt_type = *(bp + 2);
        opt_len = 4 + ((*(bp + 3) & OPT_LEN_MASK) * 4);

        ND_PRINT((ndo, "class %s (0x%x) type 0x%x%s len %u",
                  format_opt_class(opt_class), opt_class, opt_type,
                  opt_type & OPT_TYPE_CRITICAL ? "(C)" : "", opt_len));

        if (opt_len > len) {
            ND_PRINT((ndo, " [bad length]"));
            return;
        }

        if (ndo->ndo_vflag > 1 && opt_len > 4) {
            uint32_t *print_data = (uint32_t *)(bp + 4);
            int i;

            ND_PRINT((ndo, " data"));

            for (i = 4; i < opt_len; i += 4) {
                ND_PRINT((ndo, " %08x", EXTRACT_32BITS(print_data)));
                print_data++;
            }
        }

        bp += opt_len;
        len -= opt_len;
    }
}

void
geneve_print(netdissect_options *ndo, const u_char *bp, u_int len)
{
    uint8_t ver_opt;
    uint version;
    uint8_t flags;
    uint16_t prot;
    uint32_t vni;
    uint8_t reserved;
    u_int opts_len;

    ND_PRINT((ndo, "Geneve"));

    ND_TCHECK2(*bp, 8);

    ver_opt = *bp;
    bp += 1;
    len -= 1;

    version = ver_opt >> VER_SHIFT;
    if (version != 0) {
        ND_PRINT((ndo, " ERROR: unknown-version %u", version));
        return;
    }

    flags = *bp;
    bp += 1;
    len -= 1;

    prot = EXTRACT_16BITS(bp);
    bp += 2;
    len -= 2;

    vni = EXTRACT_24BITS(bp);
    bp += 3;
    len -= 3;

    reserved = *bp;
    bp += 1;
    len -= 1;

    ND_PRINT((ndo, ", Flags [%s]",
              bittok2str_nosep(geneve_flag_values, "none", flags)));
    ND_PRINT((ndo, ", vni 0x%x", vni));

    if (reserved)
        ND_PRINT((ndo, ", rsvd 0x%x", reserved));

    if (ndo->ndo_eflag)
        ND_PRINT((ndo, ", proto %s (0x%04x)",
                  tok2str(ethertype_values, "unknown", prot), prot));

    opts_len = (ver_opt & HDR_OPTS_LEN_MASK) * 4;

    if (len < opts_len) {
        ND_PRINT((ndo, " truncated-geneve - %u bytes missing",
                  len - opts_len));
        return;
    }

    ND_TCHECK2(*bp, opts_len);

    if (opts_len > 0) {
        ND_PRINT((ndo, ", options ["));

        if (ndo->ndo_vflag)
            geneve_opts_print(ndo, bp, opts_len);
        else
            ND_PRINT((ndo, "%u bytes", opts_len));

        ND_PRINT((ndo, "]"));
    }

    bp += opts_len;
    len -= opts_len;

    if (ndo->ndo_vflag < 1)
        ND_PRINT((ndo, ": "));
    else
        ND_PRINT((ndo, "\n\t"));

    if (ethertype_print(ndo, prot, bp, len, len) == 0) {
        if (prot == ETHERTYPE_TEB)
            ether_print(ndo, bp, len, len, NULL, NULL);
        else
            ND_PRINT((ndo, "geneve-proto-0x%x", prot));
    }

    return;

trunc:
    ND_PRINT((ndo, " [|geneve]"));
}
