diff --git a/scapy/contrib/mpls.py b/scapy/contrib/mpls.py index 8daddf24e..435b915c5 100644 --- a/scapy/contrib/mpls.py +++ b/scapy/contrib/mpls.py @@ -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) diff --git a/test/regression.uts b/test/regression.uts index 02a6482ee..1c4fc4c64 100644 --- a/test/regression.uts +++ b/test/regression.uts @@ -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