[英]Extract received data in a tcp socket in Python
我有一個客戶端發送帶有Scapy創建的自定義層“ Reservation”的數據包
客戶端
#!/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'
顯然,保留層未被識別並解釋為RAW。 如何構建與發送的數據包相同的數據包?
您可以使用s=str(packet)
序列化scapy 2中的數據包,並使用packet=Layer(s)
強制將字節流反序列化為Layer
。
在您的情況下:
rdata = sock.recv(8192)
layer = Reservation(rdata)
layer.show()
print layer.id
請注意,您還可以使用bind_layers()
將圖層綁定到scapys自動分解/有效負載猜測,以使其與sniff()
或tcp / Reservation字節流(帶有保留有效載荷的tcp數據包bind_layers()
一起使用。 下一行將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嘗試基於簡單規則(例如,調用bind_layers()
TCP.dport==5005
自動剖析圖層。 這樣,它也可以與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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.