在 Python 的 tcp 套接字中提取接收到的数据
Extract received data in a tcp socket in Python
我有一个客户端发送一个带有自定义层的数据包 "Reservation" 使用 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 的东西来检索该字段的值。有可能吗?
编辑
我已经达到了这一点:
我正在通过 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'
显然,Reservation 层未被识别和解释为 RAW。如何构建与传输的数据包相同的数据包?
您可以使用 s=str(packet)
在 scapy 2 中序列化数据包,并使用 packet=Layer(s)
强制将字节流反序列化为 Layer
.
你的情况:
rdata = sock.recv(8192)
layer = Reservation(rdata)
layer.show()
print layer.id
请注意,您还可以为 scapys autodissect/payload 猜测绑定层 bind_layers()
以使其与 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
字节流时。
原始套接字:
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
我有一个客户端发送一个带有自定义层的数据包 "Reservation" 使用 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 的东西来检索该字段的值。有可能吗?
编辑 我已经达到了这一点: 我正在通过 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'
显然,Reservation 层未被识别和解释为 RAW。如何构建与传输的数据包相同的数据包?
您可以使用 s=str(packet)
在 scapy 2 中序列化数据包,并使用 packet=Layer(s)
强制将字节流反序列化为 Layer
.
你的情况:
rdata = sock.recv(8192)
layer = Reservation(rdata)
layer.show()
print layer.id
请注意,您还可以为 scapys autodissect/payload 猜测绑定层 bind_layers()
以使其与 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
字节流时。
原始套接字:
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