簡體   English   中英

在Python的TCP套接字中提取接收到的數據

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM