1# SPDX-License-Identifier: GPL-2.0-only 2# This file is part of Scapy 3# See https://scapy.net/ for more information 4# Copyright (C) Philippe Biondi <phil@secdev.org> 5 6""" 7Virtual eXtensible Local Area Network (VXLAN) 8- RFC 7348 - 9 10A Framework for Overlaying Virtualized Layer 2 Networks over Layer 3 Networks 11http://tools.ietf.org/html/rfc7348 12https://www.ietf.org/id/draft-ietf-nvo3-vxlan-gpe-02.txt 13 14VXLAN Group Policy Option: 15http://tools.ietf.org/html/draft-smith-vxlan-group-policy-00 16""" 17 18from scapy.packet import Packet, bind_layers, bind_bottom_up, bind_top_down 19from scapy.layers.l2 import Ether 20from scapy.layers.inet import IP, UDP 21from scapy.layers.inet6 import IPv6 22from scapy.fields import FlagsField, XByteField, ThreeBytesField, \ 23 ConditionalField, ShortField, ByteEnumField, X3BytesField 24 25_GP_FLAGS = ["R", "R", "R", "A", "R", "R", "D", "R"] 26 27 28class VXLAN(Packet): 29 name = "VXLAN" 30 31 fields_desc = [ 32 FlagsField("flags", 0x8, 8, 33 ['OAM', 'R', 'NextProtocol', 'Instance', 34 'V1', 'V2', 'R', 'G']), 35 ConditionalField( 36 ShortField("reserved0", 0), 37 lambda pkt: pkt.flags.NextProtocol, 38 ), 39 ConditionalField( 40 ByteEnumField('NextProtocol', 0, 41 {0: 'NotDefined', 42 1: 'IPv4', 43 2: 'IPv6', 44 3: 'Ethernet', 45 4: 'NSH'}), 46 lambda pkt: pkt.flags.NextProtocol, 47 ), 48 ConditionalField( 49 ThreeBytesField("reserved1", 0), 50 lambda pkt: (not pkt.flags.G) and (not pkt.flags.NextProtocol), 51 ), 52 ConditionalField( 53 FlagsField("gpflags", 0, 8, _GP_FLAGS), 54 lambda pkt: pkt.flags.G, 55 ), 56 ConditionalField( 57 ShortField("gpid", 0), 58 lambda pkt: pkt.flags.G, 59 ), 60 X3BytesField("vni", 0), 61 XByteField("reserved2", 0), 62 ] 63 64 # Use default linux implementation port 65 overload_fields = { 66 UDP: {'dport': 8472}, 67 } 68 69 def mysummary(self): 70 if self.flags.G: 71 return self.sprintf("VXLAN (vni=%VXLAN.vni% gpid=%VXLAN.gpid%)") 72 else: 73 return self.sprintf("VXLAN (vni=%VXLAN.vni%)") 74 75 76bind_layers(UDP, VXLAN, dport=4789) # RFC standard vxlan port 77bind_layers(UDP, VXLAN, dport=4790) # RFC standard vxlan-gpe port 78bind_layers(UDP, VXLAN, dport=6633) # New IANA assigned port for use with NSH 79bind_layers(UDP, VXLAN, dport=8472) # Linux implementation port 80bind_layers(UDP, VXLAN, dport=48879) # Cisco ACI 81bind_layers(UDP, VXLAN, sport=4789) 82bind_layers(UDP, VXLAN, sport=4790) 83bind_layers(UDP, VXLAN, sport=6633) 84bind_layers(UDP, VXLAN, sport=8472) 85# By default, set both ports to the RFC standard 86bind_layers(UDP, VXLAN, sport=4789, dport=4789) 87 88# Dissection 89bind_bottom_up(VXLAN, Ether, NextProtocol=0) 90bind_bottom_up(VXLAN, IP, NextProtocol=1) 91bind_bottom_up(VXLAN, IPv6, NextProtocol=2) 92bind_bottom_up(VXLAN, Ether, NextProtocol=3) 93bind_bottom_up(VXLAN, Ether, NextProtocol=None) 94# Build 95bind_top_down(VXLAN, Ether, flags=12, NextProtocol=0) 96bind_top_down(VXLAN, IP, flags=12, NextProtocol=1) 97bind_top_down(VXLAN, IPv6, flags=12, NextProtocol=2) 98bind_top_down(VXLAN, Ether, flags=12, NextProtocol=3) 99