Scapy中wrpcap复制自定义Packet丢失invert属性的解决方法咨询
问题描述
我在Scapy中实现了一个自定义Packet协议,该协议可在链路上以反转(inverted)或非反转(non-inverted)形式发送定义字段及app_data。我希望在创建对象时通过一个简单的invert标志属性,指示协议是否反转app_data。由于后续需要基于app_data和其他字段生成security_code,反转操作必须在Packet的post_build方法中执行。
但使用wrpcap()写入带有反转app_data的数据包时遇到问题:wrpcap()会复制传入的对象,但自定义的invert属性未被复制,始终保持默认值False;传入wrpcap()的对象与实际写入的对象ID不同。
代码示例:
pkt = MyProto(invert = True, app_data = b'Hello', ...) wrpcap(file, pkt, append=True) # id(pkt) = 123 # pkt.invert = True ... class MyProto(Packet): invert = False ... def post_build(self, pkt, pay): # id(self) = 789 # self.invert = False
我不想通过添加额外字段的方式解决(该方式需要在__init__和post_build中添加额外逻辑,不够简洁),寻求合适的解决方法。
解决方案
Scapy的Packet类在被wrpcap复制时,默认只会处理协议字段,不会自动复制自定义的实例属性。以下两种方法可以解决这个问题:
方法1:重写__getstate__和__setstate__
通过自定义对象序列化/反序列化逻辑,让自定义属性在复制时被正确保留:
class MyProto(Packet): invert = False # 你的协议字段定义... def __getstate__(self): # 获取默认状态并添加自定义属性 state = super().__getstate__() state['invert'] = self.invert return state def __setstate__(self, state): # 恢复默认状态和自定义属性 super().__setstate__(state) self.invert = state.get('invert', False) def post_build(self, pkt, pay): if self.invert: # 执行app_data反转逻辑(示例:假设app_data在pkt末尾) app_data_len = len(self.app_data) pkt = pkt[:-app_data_len] + self.app_data[::-1] # 生成security_code的逻辑... return pkt + pay
方法2:重写copy方法
直接在对象复制时手动传递自定义属性:
class MyProto(Packet): invert = False # 你的协议字段定义... def copy(self): new_pkt = super().copy() new_pkt.invert = self.invert return new_pkt def post_build(self, pkt, pay): if self.invert: # 执行app_data反转逻辑 app_data_len = len(self.app_data) pkt = pkt[:-app_data_len] + self.app_data[::-1] # 生成security_code的逻辑... return pkt + pay
这两种方法都无需添加额外协议字段,仅需在自定义Packet类中添加少量代码,即可让wrpcap复制对象时正确保留invert属性的值。
内容的提问来源于stack exchange,提问作者CAoT
相关产品推荐
相关产品推荐

