簡體   English   中英

使用python解碼tcp數據包

[英]Decoding tcp packets using python

我正在嘗試解碼通過TCP連接接收的數據。 數據包很小,不超過100個字節。 但是,當它們很多時,我會收到一些連接在一起的數據包。 有沒有辦法防止這種情況。 我正在使用python

我試圖分離數據包,我的來源在下面。 數據包以STX字節開始,以ETX字節結束,STX之后的字節為數據包長度,(數據包長度小於5無效)校驗和是ETX之前的最后一個字節

def decode(data):
  while True:
    start = data.find(STX)
    if start == -1: #no stx in message
        pkt = ''
        data = ''
        break
    #stx found , next byte is the length
    pktlen = ord(data[1])
    #check message ends in ETX (pktken -1) or checksum invalid
    if pktlen < 5 or data[pktlen-1] != ETX or checksum_valid(data[start:pktlen]) == False:
        print "Invalid Pkt"
        data = data[start+1:]
        continue
    else:
        pkt = data[start:pktlen]
        data = data[pktlen:]
        break

return data , pkt

我這樣用

#process reports
try:
    data = sock.recv(256) 
except: continue 
else:
    while data:
        data, pkt = decode(data) 
        if pkt:
           process(pkt)

另外,如果數據流中有多個數據包,則最好將這些數據包作為列表的集合返回,或者僅返回第一個數據包。

我不太熟悉python,只有C,這種方法還可以。 任何建議將不勝感激。 提前致謝

謝謝

我將創建一個類,負責解碼來自流的數據包,如下所示:

class PacketDecoder(object):

    STX = ...
    ETX = ...

    def __init__(self):
        self._stream = ''

    def feed(self, buffer):
        self._stream += buffer

    def decode(self):
        '''
        Yields packets from the current stream.
        '''
        while len(self._stream) > 2:
            end = self._stream.find(self.ETX)
            if end == -1:
                break

            packet_len = ord(self._stream[1])
            packet = self._stream[:end]
            if packet_len >= 5 and check_sum_valid(packet):
                yield packet
            self._stream = self._stream[end+1:]

然后像這樣使用:

decoder = PacketDecoder()
while True:
    data = sock.recv(256) 
    if not data:
        # handle lost connection... 
    decoder.feed(data)
    for packet in decoder.decode():
        process(packet)

TCP在接口級別提供數據流,而不是單個數據包。 如果需要離散數據包,則可以使用UDP(並自行處理丟失或亂序的數據包),或將一些數據分隔符插入行內。 聽起來您已經用STX / ETX作為分隔符了。 但是,請注意,您從TCP堆棧的一個數據塊中獲得了多個消息。

請注意,除非進行其他處理,否則顯示的代碼中的data不一定包含整數的消息。 也就是說,最后一個STX可能沒有匹配的ETX。 沒有STX的情況下,ETX將位於下一個data塊中。

您可能應該從TCP數據流中讀取單個消息,並在出現消息時將其返回。

嘗試scapy ,一個功能強大的交互式數據包處理程序。

數據從哪里來? 與其嘗試手動解碼,不如使用出色的Impacket軟件包:

http://oss.coresecurity.com/projects/impacket.html

不錯,很簡單... :)訣竅在文件對象中。

f=sock.makefile()
while True:
  STX = f.read(1)
  pktlen = f.read(1)
  wholePacket = STX + pktlen + f.read(ord(pktlen)-2)
  doSomethingWithPacket(wholePacket)

就是這樣! (使用TCP時也無需檢查校驗和。)

這是一個更“健壯”的版本(它使用STX和校驗和):

f=sock.makefile()
while True:
  while f.read(1)!=STX:
    continue
  pktlen = f.read(1)
  wholePacket = STX + pktlen + f.read(ord(pktlen)-2)
  if checksum_valid(wholePacket):
    doSomethingWithPacket(wholePacket)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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