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