1/* Copyright (c) 2015, bugyo
2 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * 1. Redistributions of source code must retain the above copyright notice,
7 *    this list of conditions and the following disclaimer.
8 * 2. Redistributions in binary form must reproduce the above copyright notice,
9 *    this list of conditions and the following disclaimer in the documentation
10 *    and/or other materials provided with the distribution.
11 *
12 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
13 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
16 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 */
23
24/* \summary: Generic Protocol Extension for VXLAN (VXLAN GPE) printer */
25
26/* specification: draft-ietf-nvo3-vxlan-gpe-01 */
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <netdissect-stdinc.h>
33
34#include "netdissect.h"
35#include "extract.h"
36
37static const char tstr[] = " [|VXLAN-GPE]";
38static const struct tok vxlan_gpe_flags [] = {
39    { 0x08, "I" },
40    { 0x04, "P" },
41    { 0x01, "O" },
42    { 0, NULL }
43};
44
45#define VXLAN_GPE_HDR_LEN 8
46
47/*
48 * VXLAN GPE header, draft-ietf-nvo3-vxlan-gpe-01
49 *                   Generic Protocol Extension for VXLAN
50 *
51 *     0                   1                   2                   3
52 *     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
53 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54 *    |R|R|Ver|I|P|R|O|       Reserved                |Next Protocol  |
55 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56 *    |                VXLAN Network Identifier (VNI) |   Reserved    |
57 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58 */
59
60void
61vxlan_gpe_print(netdissect_options *ndo, const u_char *bp, u_int len)
62{
63    uint8_t flags;
64    uint8_t next_protocol;
65    uint32_t vni;
66
67    if (len < VXLAN_GPE_HDR_LEN)
68        goto trunc;
69
70    ND_TCHECK2(*bp, VXLAN_GPE_HDR_LEN);
71
72    flags = *bp;
73    bp += 3;
74
75    next_protocol = *bp;
76    bp += 1;
77
78    vni = EXTRACT_24BITS(bp);
79    bp += 4;
80
81    ND_PRINT((ndo, "VXLAN-GPE, "));
82    ND_PRINT((ndo, "flags [%s], ",
83              bittok2str_nosep(vxlan_gpe_flags, "none", flags)));
84    ND_PRINT((ndo, "vni %u", vni));
85    ND_PRINT((ndo, ndo->ndo_vflag ? "\n    " : ": "));
86
87    switch (next_protocol) {
88    case 0x1:
89        ip_print(ndo, bp, len - 8);
90        break;
91    case 0x2:
92        ip6_print(ndo, bp, len - 8);
93        break;
94    case 0x3:
95        ether_print(ndo, bp, len - 8, ndo->ndo_snapend - bp, NULL, NULL);
96        break;
97    case 0x4:
98        nsh_print(ndo, bp, len - 8);
99        break;
100    case 0x5:
101        mpls_print(ndo, bp, len - 8);
102        break;
103    default:
104        ND_PRINT((ndo, "ERROR: unknown-next-protocol"));
105        return;
106    }
107
108	return;
109
110trunc:
111	ND_PRINT((ndo, "%s", tstr));
112}
113
114