我试图理解PacketListField和FieldListField之间的区别。有人可以在添加新协议时告诉我如何使用它们。
我也不清楚StrLenField,FieldLenField和PacketLenField。我正在尝试制作BGP更新消息,以便我可以理解它是如何工作的。我看到这是BGPUpdate消息的定义方式。当我尝试制作BGP数据包时,我不知道如何传递Withdrawn Routes字段和nlri字段的值。我也不确定如何传递路径属性的值。
>>> pkt=BGPUpdate()
>>> pkt.show()
###[ BGP Update fields ]###
withdrawn_len= None
withdrawn= []
tp_len= None
\total_path\
nlri= []
>>>
class BGPPathAttribute(Packet):
"the attribute of total path"
name = "BGP Attribute fields"
fields_desc = [
FlagsField("flags", 0x40, 8, ["NA0","NA1","NA2","NA3","Extended-Length","Partial","Transitive","Optional"]), #Extened leght may not work
ByteEnumField("type", 1, {1:"ORIGIN", 2:"AS_PATH", 3:"NEXT_HOP", 4:"MULTI_EXIT_DISC", 5:"LOCAL_PREF", 6:"ATOMIC_AGGREGATE", 7:"AGGREGATOR"}),
ByteField("attr_len", None),
StrLenField("value", "", length_from = lambda p: p.attr_len),
]
def post_build(self, p, pay):
if self.attr_len is None:
l = len(p) - 3 # 3 is regular length with no additional options
p = p[:2] + struct.pack("!B",l) +p[3:]
return p+pay
def extract_padding(self, p):
"""any thing after this packet is extracted is padding"""
return "",p
class BGPUpdate(Packet):
"""Update the routes WithdrawnRoutes = UnfeasiableRoutes"""
name = "BGP Update fields"
fields_desc = [
ShortField("withdrawn_len", None),
FieldListField("withdrawn",[], BGPIPField("","0.0.0.0/0"), length_from=lambda p:p.withdrawn_len),
ShortField("tp_len", None),
PacketListField("total_path", [], BGPPathAttribute, length_from = lambda p: p.tp_len),
FieldListField("nlri",[], BGPIPField("","0.0.0.0/0"), length_from=lambda p:p.underlayer.len - 23 - p.tp_len - p.withdrawn_len), # len should be BGPHeader.len
]
def post_build(self,p,pay):
wl = self.withdrawn_len
subpacklen = lambda p: len ( str( p ))
subfieldlen = lambda p: BGPIPField("", "0.0.0.0/0").i2len(self, p )
if wl is None:
wl = sum ( map ( subfieldlen , self.withdrawn))
p = p[:0]+struct.pack("!H", wl)+p[2:]
if self.tp_len is None:
l = sum ( map ( subpacklen , self.total_path))
p = p[:2+wl]+struct.pack("!H", l)+p[4+wl:]
return p+pay
答案 0 :(得分:3)
他们只对不同类型的物体进行操作。见scapy build dissect
PacketListField
描述了相同类型的 PacketFields 列表,而一个 PacketField 表示放入另一个数据包字段的 Packet 类型对象。它将Packet原型作为第三个参数 cls __init__(self, name, default, cls, count_from=None, length_from=None)
。 PacketListField的构造函数要求设置count_from(对象数)或lengt_from(字节)参数,以便知道要传递给数据包列表的字节数或要解析的对象数(例如,您可以{{1} }作为PacketField或PacketListField的原型)。
例如:
BGPUpdate
创建一个名为" total_path"的字段,默认值为空列表[],并尝试将raw_bytestream的length_from字节解析为BGPPathAttribute(Packet)。
<强> FieldListField 强>
相反, FieldListField 将Field作为原型,并尝试将raw_bytestream剖析为原型字段列表PacketListField("total_path", [], BGPPathAttribute, length_from = lambda p: p.tp_len),
__init__(self, name, default, field, length_from=None, count_from=None):
<强> StrLenField 强>
DataField通常最多支持length_from bytes FieldListField("withdrawn",[], BGPIPField("","0.0.0.0/0"), length_from=lambda p:p.withdrawn_len),
。
<强> FieldLenField 强>
保存同一数据包__init__(self, name, default, fld=None, length_from=None):
__init__(self, name, default, length_of=None, fmt = "H", count_of=None, adjust=lambda pkt,x:x, fld=None):
在剖析上,scapy会将第一个字节放入&#39;输入&#39;,接下来的2个字节(默认fmt =&#34; H&#34;简称为短?整数&#34;长度&#34;,以及长达&#39;字节到&#39;数据&#39;
在构建时,scapy会自动填充&#39;长度&#39;与len(数据)。
<强> PacketLenField 强>
是一个将length_from bytes解析为一个原型包class SomePacket(Packet):
name = "SomePacket"
fields_desc = [ByteEnumField("type", 0x00, {0x00:"SomeType"}),
FieldLenField("length", None, length_of="data"), # hold length of data
StrLenField("data", "", length_from=lambda x:x.length), # holds data
]
__init__(self, name, default, cls, length_from=None):
在剖析上,scapy会将第一个字节放入ByteLengthField&#39;长度&#39;最长的&#39;长度&#39;字节被解剖为&#39; SomePacket&#39;进入&#39;数据&#39;
在构建时,scapy会自动填充&#39;长度&#39;与序列化的SomePacket的大小。