diff --git a/scapy/layers/vxlan.py b/scapy/layers/vxlan.py index 6b620d56c..c3027de29 100644 --- a/scapy/layers/vxlan.py +++ b/scapy/layers/vxlan.py @@ -1,24 +1,35 @@ +#! /usr/bin/env python # RFC 7348 - Virtual eXtensible Local Area Network (VXLAN): # A Framework for Overlaying Virtualized Layer 2 Networks over Layer 3 Networks # http://tools.ietf.org/html/rfc7348 +# https://www.ietf.org/id/draft-ietf-nvo3-vxlan-gpe-02.txt # # VXLAN Group Policy Option: # http://tools.ietf.org/html/draft-smith-vxlan-group-policy-00 from scapy.packet import Packet, bind_layers from scapy.layers.l2 import Ether -from scapy.layers.inet import UDP +from scapy.layers.inet import IP, UDP +from scapy.layers.inet6 import IPv6 from scapy.fields import FlagsField, XByteField, ThreeBytesField, \ - ConditionalField, ShortField + ConditionalField, ShortField, ByteEnumField, X3BytesField -_VXLAN_FLAGS = ["R", "R", "R", "I", "R", "R", "R", "G"] _GP_FLAGS = ["R", "R", "R", "A", "R", "R", "D", "R"] + class VXLAN(Packet): name = "VXLAN" fields_desc = [ - FlagsField("flags", 0x8, 8, _VXLAN_FLAGS), + FlagsField("flags", 0x8, 8, + ['OAM', 'R', 'NextProtocol', 'Instance', + 'V1', 'V2', 'R', 'G']), + ByteEnumField('NextProtocol', 0, + {0: 'NotDefined', + 1: 'IPv4', + 2: 'IPv6', + 3: 'Ethernet', + 4: 'NSH'}), ConditionalField( ThreeBytesField("reserved1", 0x000000), lambda pkt: not pkt.flags & 0x80, @@ -31,7 +42,7 @@ class VXLAN(Packet): ShortField("gpid", 0), lambda pkt: pkt.flags & 0x80, ), - ThreeBytesField("vni", 0), + X3BytesField("vni", 0), XByteField("reserved2", 0x00), ] @@ -47,5 +58,9 @@ class VXLAN(Packet): return self.sprintf("VXLAN (vni=%VXLAN.vni%)") bind_layers(UDP, VXLAN, dport=4789) # RFC standard port +bind_layers(UDP, VXLAN, dport=6633) # New IANA assigned port when used with NSH bind_layers(UDP, VXLAN, dport=8472) # Linux implementation port -bind_layers(VXLAN, Ether) +bind_layers(VXLAN, Ether, {'flags': 0x8}, NextProtocol=0) +bind_layers(VXLAN, IP, {'flags': 0xC, 'NextProtocol': 1}, NextProtocol=1) +bind_layers(VXLAN, IPv6, {'flags': 0xC, 'NextProtocol': 2}, NextProtocol=2) +bind_layers(VXLAN, Ether, {'flags': 0xC, 'NextProtocol': 3}, NextProtocol=3) diff --git a/test/regression.uts b/test/regression.uts index b0d5a4385..e5458164e 100644 --- a/test/regression.uts +++ b/test/regression.uts @@ -6123,10 +6123,10 @@ assert(p.data[0].ifname.startswith("lo")) + VXLAN layer = Build a VXLAN packet with VNI of 42 -str(UDP(sport=1024, dport=4789, len=None, chksum=None)/VXLAN(flags=0x08, vni=42)) == "\x04\x00\x12\xb5\x00\x10\x00\x00\x08\x00\x00\x00\x00\x00\x2a\x00" +str(UDP(sport=1024, dport=4789, len=None, chksum=None)/VXLAN(flags=0x08, vni=42)) == '\x04\x00\x12\xb5\x00\x11\x00\x00\x08\x00\x00\x00\x00\x00\x00\x2a\x00' = Verify VXLAN Ethernet Binding -str(VXLAN(vni=23)/Ether(dst="11:11:11:11:11:11", src="11:11:11:11:11:11", type=0x800)) == "\x08\x00\x00\x00\x00\x00\x17\x00\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x08\x00" +str(VXLAN(vni=23)/Ether(dst="11:11:11:11:11:11", src="11:11:11:11:11:11", type=0x800)) == '\x0c\x03\x00\x00\x00\x00\x00\x17\x00\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x08\x00' = Verify UDP dport overloading p = Ether(dst="11:11:11:11:11:11", src="22:22:22:22:22:22")