2013-11-04 35 views
1

我有一個應用程序,其中讀取的內容爲live SIP實時分組和解碼信息。 當數據包是小UDP/TCP是能夠得到的信息,但是當數據包較大,到達不同的部分: 下面是Wireshark的摘錄:Python中的分段TCP消息

3 Reassembled TCP Segments (3331 bytes): #1(1448), #3(1448), #5(435) 
Frame: 1, payload: 0-1447 (1448 bytes) 
Frame: 3, payload: 1448-2895 (1448 bytes) 
Frame: 5, payload: 2896-3330 (435 bytes) 
Segment count: 3 
Reassembled TCP length: 3331 

我的應用程序認爲有一個新的每個分段的SIP分組並且無法解碼信息。 我該怎麼做?我需要讀取數據包,如果碎片將所有sip消息彙總並將信息傳遞給我的控制模塊。這是我當前的代碼:

s = socket.socket(socket.AF_PACKET , socket.SOCK_RAW , socket.ntohs(0x0003)) 

while (True): 
packet = s.recvfrom(65565) 
     #packet string from tuple 
     packet = packet[0] 
     #parse ethernet header 
     eth_length = 14 

     eth_header = packet[:eth_length] 
     eth = unpack('!6s6sH' , eth_header) 
     eth_protocol = socket.ntohs(eth[2]) 


if eth_protocol == 8 : 
      #Parse IP header 
      #take first 20 characters for the ip header 
      ip_header = packet[eth_length:20+eth_length] 

      #now unpack them :) 
      iph = unpack('!BBHHHBBH4s4s' , ip_header) 

      version_ihl = iph[0] 
      version = version_ihl >> 4 
      ihl = version_ihl & 0xF 

      iph_length = ihl * 4 

      ttl = iph[5] 
      protocol = iph[6] 
      s_addr = socket.inet_ntoa(iph[8]); 
      d_addr = socket.inet_ntoa(iph[9]); 


      #TCP protocol 

      if protocol == 6 : 
       t = iph_length + eth_length 
       tcp_header = packet[t:t+20] 

       #now unpack them :) 
       tcph = unpack('!HHLLBBHHH' , tcp_header) 

       source_port = tcph[0] 
       dest_port = tcph[1] 
       sequence = tcph[2] 
       acknowledgement = tcph[3] 
       doff_reserved = tcph[4] 
       tcph_length = doff_reserved >> 4 

       if dest_port == sipLocatorConfig.SIP_PORT: 
        print    
        logging.info("------------------------------------------------------SIP Packet detected------------------------------------------------------") 
        h_size = eth_length + iph_length + tcph_length * 4 
        data_size = len(packet) - h_size 
        #get data from the packet 
        data = packet[h_size:] 

        ipInfo = {} 
        ipInfo['protocol'] = protocol 
        ipInfo['s_addr'] = str(s_addr) 
        ipInfo['source_port'] = source_port 
        ipInfo['d_addr'] = str(d_addr) 
        ipInfo['dest_port'] = dest_port 
        processSipPacket(data,ipInfo) 
+0

TCP只能傳輸一個字節的消息。任何更多需要在該流服務之上的協議。 –

回答

1

我相信這是我寫的bufsock爲: http://stromberg.dnsalias.org/~strombrg/bufsock.html

它可以讓你說「給我,直到下一個空的所有數據」或「給我接下來的64個字節「和類似的東西。它智能處理碎片和聚合數據包。

與許多此類工具不同,它不要求您在生產者和消費者都擁有bufsock - 您可以在一端使用它而不使用其他端口。它有點像在Python中用於套接字的stdio。

它適用於CPython 2.x,CPython 3.x,Pypy,Pypy3(目前仍是測試版)和Jython。