124 lines
3.6 KiB
Python
124 lines
3.6 KiB
Python
|
# scapy.contrib.description = ForCES Inter-FE LFB type (IFE)
|
||
|
# scapy.contrib.status = loads
|
||
|
|
||
|
"""
|
||
|
IFE - ForCES Inter-FE LFB type
|
||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
:author: Alexander Aring, aring@mojatatu.com
|
||
|
:license: GPLv2
|
||
|
|
||
|
This module is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU General Public License
|
||
|
as published by the Free Software Foundation; either version 2
|
||
|
of the License, or (at your option) any later version.
|
||
|
|
||
|
This module is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
:description:
|
||
|
|
||
|
This module provides Scapy layers for the IFE protocol.
|
||
|
|
||
|
normative references:
|
||
|
- RFC 8013
|
||
|
Forwarding and Control Element Separation (ForCES)
|
||
|
Inter-FE Logical Functional Block (LFB)
|
||
|
https://tools.ietf.org/html/rfc8013
|
||
|
"""
|
||
|
|
||
|
import functools
|
||
|
|
||
|
from scapy.data import ETHER_TYPES
|
||
|
from scapy.packet import Packet, bind_layers
|
||
|
from scapy.fields import FieldLenField, PacketListField, IntField, \
|
||
|
MultipleTypeField, ShortField, ShortEnumField, StrField, PadField
|
||
|
from scapy.layers.l2 import Ether
|
||
|
|
||
|
ETH_P_IFE = 0xed3e
|
||
|
ETHER_TYPES['IFE'] = ETH_P_IFE
|
||
|
|
||
|
# The value to set for the skb mark.
|
||
|
IFE_META_SKBMARK = 0x0001
|
||
|
IFE_META_HASHID = 0x0002
|
||
|
# Value to set for priority in the skb structure.
|
||
|
IFE_META_PRIO = 0x0003
|
||
|
IFE_META_QMAP = 0x0004
|
||
|
# Value to set for the traffic control index in the skb structure.
|
||
|
IFE_META_TCINDEX = 0x0005
|
||
|
|
||
|
IFE_META_TYPES = {
|
||
|
IFE_META_SKBMARK: "SKBMark",
|
||
|
IFE_META_HASHID: "HashID",
|
||
|
IFE_META_PRIO: "Prio",
|
||
|
IFE_META_QMAP: "QMap",
|
||
|
IFE_META_TCINDEX: "TCIndex"
|
||
|
}
|
||
|
|
||
|
IFE_TYPES_SHORT = [IFE_META_TCINDEX]
|
||
|
IFE_TYPES_INT = [
|
||
|
IFE_META_SKBMARK,
|
||
|
IFE_META_PRIO,
|
||
|
]
|
||
|
|
||
|
|
||
|
class IFETlv(Packet):
|
||
|
"""
|
||
|
Parent Class interhit by all ForCES TLV strucutures
|
||
|
"""
|
||
|
name = "IFETlv"
|
||
|
|
||
|
fields_desc = [
|
||
|
ShortEnumField("type", 0, IFE_META_TYPES),
|
||
|
FieldLenField("length", None, length_of="value",
|
||
|
adjust=lambda pkt, x: x + 4),
|
||
|
MultipleTypeField(
|
||
|
[
|
||
|
(PadField(ShortField("value", 0), 4, padwith=b'\x00'),
|
||
|
lambda pkt: pkt.type in IFE_TYPES_SHORT),
|
||
|
(PadField(IntField("value", 0), 4, padwith=b'\x00'),
|
||
|
lambda pkt: pkt.type in IFE_TYPES_INT),
|
||
|
],
|
||
|
PadField(IntField("value", 0), 4, padwith=b'\x00')
|
||
|
),
|
||
|
]
|
||
|
|
||
|
def extract_padding(self, s):
|
||
|
return "", s
|
||
|
|
||
|
|
||
|
class IFETlvStr(IFETlv):
|
||
|
"""
|
||
|
A IFE TLV with variable payload
|
||
|
"""
|
||
|
fields_desc = [
|
||
|
ShortEnumField("type", 0, IFE_META_TYPES),
|
||
|
FieldLenField("length", None, length_of="value",
|
||
|
adjust=lambda pkt, x: x + 4),
|
||
|
StrField("value", "")
|
||
|
]
|
||
|
|
||
|
|
||
|
class IFE(Packet):
|
||
|
"""
|
||
|
Main IFE Packet Class
|
||
|
"""
|
||
|
name = "IFE"
|
||
|
|
||
|
fields_desc = [
|
||
|
FieldLenField("mdlen", None, length_of="tlvs",
|
||
|
adjust=lambda pkt, x: x + 2),
|
||
|
PacketListField("tlvs", None, IFETlv),
|
||
|
]
|
||
|
|
||
|
|
||
|
IFESKBMark = functools.partial(IFETlv, type=IFE_META_SKBMARK)
|
||
|
IFEHashID = functools.partial(IFETlv, type=IFE_META_HASHID)
|
||
|
IFEPrio = functools.partial(IFETlv, type=IFE_META_PRIO)
|
||
|
IFEQMap = functools.partial(IFETlv, type=IFE_META_QMAP)
|
||
|
IFETCIndex = functools.partial(IFETlv, type=IFE_META_TCINDEX)
|
||
|
|
||
|
bind_layers(Ether, IFE, type=ETH_P_IFE)
|