我想构建一个带有Vlan部分的IP数据包.
使用Scapy很容易做到:
from scapy import inet
newpkt = inet.Ether()/inet.Dot1Q()/inet.IP()
有时候我想在包中有inet.Dot1Q(),有时候没有.
应该是inet.Dot1Q()的默认值,所以它只是在运算符’/’中被绕过了?
我试过”和没有 – 他们不工作.
from scapy import inet
myDot1Q = SOME DEFAULT VALUE
newpkt = inet.Ether()/myDot1Q/inet.IP()
#new packet is a valid IP packet here
编辑:我的问题的不同解释
1)我可以创建一个带VLAN标记的数据包
inet.Ether()/inet.Dot1Q/inet.IP()
2)我可以创建一个带有双VLAN标记的数据包
inet.Ether()/inet.Dot1Q/inet.Dot1Q/inet.IP()
3)如何构建可能是未标记数据包,VLAN标记数据包或双VLAN标记数据包的数据包?有这样的东西会很棒:
#No VLAN
myVlan = ???
myDoubleVlan = ???
#VLAN
myVlan = inet.Dot1Q()
myDoubleVlan = ???
#Double VLAN
myVlan = inet.Dot1Q()
myDoubleVlan = inet.Dot1Q()
#In any case the packet structure should remain the same
inet.Ether()/myVlan/myDoubleVlan/inet.IP()
我无法弄清楚默认值是什么???应该是能够正确构建数据包.
解决方法:
首先,我想不出有什么理由不使用这样的简单解决方案:
# example for single Vlan
# myVlan = Dot1Q()
# myDoubleVlan = None
# generate the package
package = Ether()
if myVlan: package /= myVlan
if myDoubleVlan: package /= myDoubleVlan
package /= IP()
但无论如何,如果这种方法出于任何不可接受的原因,还有另一种可能性……
您可以覆盖Packet类并创建自己的类,该类对除法运算符是中性的.您唯一需要的是覆盖__div__方法并添加一些括号以保留正确的优先级.
这是你如何实现它:
from scapy.all import *
class NeutralPacket(Packet):
def __init__(self, _pkt="", _internal=0, **fields):
super(NeutralPacket, self).__init__(_pkt, _internal, **fields)
def __div__(self, other):
return other
#No VLAN
myVlan = NeutralPacket()
myDoubleVlan = NeutralPacket()
#VLAN
myVlan = Dot1Q()
myDoubleVlan = NeutralPacket()
#Double VLAN
myVlan = Dot1Q()
myDoubleVlan = Dot1Q()
# this part doesn't need to change, but you need to have two
# additional parenthesis for proper precedence
Ether()/(myVlan/(myDoubleVlan/IP()))
补充说明:
__div __()方法是除法运算符实现.解释器执行a / b作为.__ div __(b),Packet类有自己的运算符实现.如果你看看它的code,你可以看到它基本上附加了包b的有效载荷来打包a.
我们在这里所做的只是返回另一个包,在这种情况下是b,实际上完全忽略了一个.
请注意,当NeutralPacket是左侧操作符时,这只能在一个方向上起作用,因为否则它正在执行其他一些类’__div __()方法.要处理这个问题,我们必须添加括号,以便优先级使我们的NeutralPacket类始终是左侧操作符.由于Packet的实现不会对整体结果产生影响,因此适用于您的情况.唯一不起作用的是,如果NeutralPacket是最右手边(即最后一个)操作符,那么你就无法强制使用正确的优先级.但是对于VLAN来说这不是问题,因为它上面总是有层……