1

ライブSIP パケットを読み取り、情報をリアルタイムでデコードするアプリケーションがあります。パケットが小さい場合、UDP/TCP は情報を取得できますが、パケットが大きい場合、別のセグメントに到着します。以下は Wireshark からの抜粋です。

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)
4

1 に答える 1

2

これが私がbufsockを書いたものだと思います: http://stromberg.dnsalias.org/~strombrg/bufsock.html

「次の null まですべてのデータをください」または「次の 64 バイトをください」などと言うことができます。断片化および集約されたパケットをインテリジェントに処理します。

多くのそのようなツールとは異なり、プロデューサーとコンシューマーの両方で bufsock を使用する必要はありません。一方の端で問題なく使用でき、もう一方の端では問題なく使用できます。これは、Python のソケットの stdio に少し似ています。

CPython 2.x、CPython 3.x、Pypy、Pypy3 (現時点ではまだベータ版)、および Jython で動作します。

于 2013-11-04T05:10:16.867 に答える