add support for encapsulating Ethernet frame in MPLS (#1047)

* add support for encapsulating Ethernet frame in MPLS with optional
control word per rfc 4448

* add import of ShortField in mpls.py to fix a ut failure

* add MPLS tests in test/regression.uts

* revert indentation fixes in mpls.py to perserve clean histry
This commit is contained in:
haozheng10 2018-02-24 00:42:18 -08:00 committed by Guillaume Valadon
parent 229fd23870
commit 344797043d
2 changed files with 69 additions and 2 deletions

View File

@ -16,12 +16,22 @@
# scapy.contrib.status = loads
from scapy.packet import Packet, bind_layers, Padding
from scapy.fields import BitField,ByteField
from scapy.fields import BitField,ByteField,ShortField
from scapy.layers.inet import IP
from scapy.layers.inet6 import IPv6
from scapy.layers.l2 import Ether, GRE
from scapy.compat import orb
class EoMCW(Packet):
name = "EoMCW"
fields_desc = [ BitField("zero", 0, 4),
BitField("reserved", 0, 12),
ShortField("seq", 0) ]
def guess_payload_class(self, payload):
if len(payload) >= 1:
return Ether
return Padding
class MPLS(Packet):
name = "MPLS"
fields_desc = [ BitField("label", 3, 20),
@ -38,8 +48,15 @@ class MPLS(Packet):
return IP
elif ip_version == 6:
return IPv6
else:
if orb(payload[0]) == 0 and orb(payload[1]) == 0:
return EoMCW
else:
return Ether
return Padding
bind_layers(Ether, MPLS, type=0x8847)
bind_layers(GRE, MPLS, proto=0x8847)
bind_layers(MPLS, MPLS, s=0)
bind_layers(MPLS, EoMCW)
bind_layers(EoMCW, Ether, zero=0, reserved=0)

View File

@ -9492,7 +9492,7 @@ assert(pkt.ByteCount == 1)
+ MPLS tests
= MPLS - build/dissection
from scapy.contrib.mpls import MPLS
from scapy.contrib.mpls import EoMCW, MPLS
p1 = MPLS()/IP()/UDP()
assert(p1[MPLS].s == 1)
p2 = MPLS()/MPLS()/IP()/UDP()
@ -9504,6 +9504,56 @@ p2[MPLS]
p2[MPLS:1]
p2[IP]
= MPLS encapsulated Ethernet with CW - build/dissection
p = Ether(dst="11:11:11:11:11:11", src="22:22:22:22:22:22")
p /= MPLS(label=1)/EoMCW(seq=1234)
p /= Ether(dst="33:33:33:33:33:33", src="44:44:44:44:44:44")/IP()
p = Ether(raw(p))
assert(p[EoMCW].zero == 0)
assert(p[EoMCW].reserved == 0)
assert(p[EoMCW].seq == 1234)
= MPLS encapsulated Ethernet without CW - build/dissection
p = Ether(dst="11:11:11:11:11:11", src="22:22:22:22:22:22")
p /= MPLS(label=2)/MPLS(label=1)
p /= Ether(dst="33:33:33:33:33:33", src="44:44:44:44:44:44")/IP()
p = Ether(raw(p))
assert(p[Ether:2].type == 0x0800)
try:
p[EoMCW]
except IndexError:
ret = True
else:
ret = False
assert(ret)
assert(p[Ether:2].type == 0x0800)
= MPLS encapsulated IP - build/dissection
p = Ether(dst="11:11:11:11:11:11", src="22:22:22:22:22:22")
p /= MPLS(label=1)/IP()
p = Ether(raw(p))
try:
p[EoMCW]
except IndexError:
ret = True
else:
ret = False
assert(ret)
try:
p[Ether:2]
except IndexError:
ret = True
else:
ret = False
assert(ret)
p[IP]
+ Restore normal routes & Ifaces