ライブ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)