我有一个客户端发送带有自定义图层的数据包"预订"用Scapy创建
Client.py
#!/usr/bin/env python
import socket
from scapy.all import *
class Reservation(Packet):
name = "ReservationPacket"
fields_desc=[ ShortField("id", 0),
BitField("type",None, 0),
X3BytesField("update", 0),
ByteField("rssiap", 0)]
pkt = IP(len=16384, src='192.168.240.5', dst='192.168.240.198',
id=RandShort(), ttl=2)/TCP(sport=5005,
dport=5005, flags="S", window=200,
options=[('MSS', 1460), ('WScale', 2)])/Reservation(id=11)/"HELLO"
spkt = bytes(pkt)
spkt += '\x00'*20
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
s.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1)
s.sendto(spkt, ('192.168.240.198', 5005))
s.close()
正确发送和接收数据包。
如何访问数据包的特定字段?如何解释收到的数据?我想使用类似于 spkt.id 的东西来检索该字段的值。有可能吗?
EDIT 我达到了这一点: 我正在通过tcp套接字发送一个pcaket。它具有以下结构:
###[ IP ]###
version = 4
ihl = None
tos = 0x0
len = 16384
id = <RandShort>
flags =
frag = 0
ttl = 2
proto = tcp
chksum = None
src = 192.168.240.5
dst = 192.168.240.1
\options \
###[ TCP ]###
sport = 5005
dport = 5005
seq = 0
ack = 0
dataofs = None
reserved = 0
flags = S
window = 200
chksum = None
urgptr = 0
options = [('MSS', 1460), ('WScale', 2)]
###[ ReservationPacket ]###
id = 9
type = None
update = 0x0
rssiap = 0
###[ Raw ]###
load = 'PROVA'
ReservationPacket 是自定义图层。 收到数据包并使用
data = conn.recv(BUFFER_SIZE)
if not data: break
print "received data:", data
by = str.encode(data)
pkt_hex = by.encode('hex')
hexdump(by)
container = IP(data)
container.show()
我填充容器包,定义为
container = IP()/TCP()/Reservation()
的输出
container.show()
是
###[ IP ]###
version = 4L
ihl = 5L
tos = 0x0
len = 16384
id = 56856
flags =
frag = 0L
ttl = 2
proto = tcp
chksum = 0x3987
src = 192.168.240.5
dst = 192.168.240.1
\options \
###[ TCP ]###
sport = 5005
dport = 5005
seq = 0
ack = 0
dataofs = 7L
reserved = 0L
flags = S
window = 200
chksum = 0xd962
urgptr = 0
options = [('MSS', 1460), ('WScale', 2), ('EOL', None)]
###[ Raw ]###
load = '\x00\t\x00\x00\x00\x00PROVA'
显然,“预留”图层无法识别并解释为RAW。如何构建与传输的数据包相同的数据包?
答案 0 :(得分:2)
您可以使用s=str(packet)
序列化scapy 2和packet=Layer(s)
中的数据包,以强制将字节流反序列化为Layer
。
在你的情况下:
rdata = sock.recv(8192)
layer = Reservation(rdata)
layer.show()
print layer.id
请注意,您还可以使用bind_layers()
绑定您的图层以进行scapys autodissect / payload guess,以使其与sniff()
一起使用或解析tcp / Reservation字节流(具有预留有效负载的tcp数据包)。以下行将TCP.dport = 5005绑定到Reservation。
bind_layers(TCP, Reservation, dport=5005)
更新:您问题的具体答案。
您不必关心IP / TCP层,因为这都是在套接字内处理的。 socket.recv
收到的数据是TCP
的有效负载,因此您所要做的就是强制scapy将收到的data
反序列化为Reservation
。
TCP套接字:
data=[]
while True:
chunk = conn.recv(BUFFER_SIZE)
if not chunk:
break
print "received data:", chunk
data.append(chunk)
layer = Reservation(''.join(data))
layer.show()
print layer.id
此外,您可以指示scapy尝试根据简单的规则自动剖析您的图层,例如TCP.dport==5005
致电bind_layers()
。通过这种方式,它也可以与sniff
一起使用,也可以在收到完整的IP/TCP/Reservation/Raw
字节流时使用。
Raw Socket:
bind_layers(TCP, Reservation, dport=5005) # bind Reservation as nextlayer to TCP.dport=5005
# ...
data, peer = s.recvfrom(BUFFER_SIZE)
print "received data:", peer, repr(data)
layer = IP(data) # dissection automagic based on rules registered with bind_layers
layer.show()
print layer[Reservation].id