mirror of https://github.com/secdev/scapy.git
VXLAN: add Generic Packet Encapsulation (GPE) support
Since part of the previously reserved Bytes are now used to annouce the next header, this also updates the vxlan unit tests. Original commit by: Christophe Fontaine <christophe.fontaine@qosmos.com> Signed-off-by: Gabriel Ganne <gabriel.ganne@qosmos.com>
This commit is contained in:
parent
5b5bd11933
commit
d7b900f569
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue