我已经实现了这段代码来从 pc 与我的设备进行通信。它得到几个数据包,然后在 while 循环中挂在 recvfrom() 上?
import socket, sys, random
from struct import *
import struct
import select
import codecs
import base64
import time
import pdb
def checksum(msg):
s = 0
for i in range(0, len(msg), 2):
w = (ord(msg[i]) <<8) + (ord(msg[i+1]) )
s = s + w
s = (s>>16) + (s & 0xffff);
s = ~s & 0xffff
return s
def create_socket(source_ip,dest_ip):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
except socket.error , msg:
print 'Socket could not be created. Error: ',str(msg[0]),' Message: ',msg[1]
sys.exit()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
return s
def create_ip_header(source_ip, dest_ip):
packet = ''
headerlen = 5
version = 4
tos = 0
tot_len = 20 + 20
id = random.randrange(18000,65535,1)
flags = 2
frag_off = 0
ttl = 255
protocol = socket.IPPROTO_TCP
check = 10
saddr = socket.inet_aton ( source_ip )
daddr = socket.inet_aton ( dest_ip )
hl_version = (version << 4) + headerlen
flags = (flags << 13) + frag_off
ip_header = pack('!BBHHHBBH4s4s', hl_version, tos, tot_len, id, flags, ttl, protocol, check, saddr, daddr)
return ip_header
def create_tcp_syn_header(source_ip, source, dest_ip, dest_port, syn_flag, ack_num, ack_flag, seq_num, psh_flag, user_data):
seq = seq_num
ack_seq = ack_num
doff = 5
# tcp flags
fin = 0
syn = syn_flag
rst = 0
psh = psh_flag
ack = ack_flag
urg = 0
window = socket.htons(19253500)
check = 0
urg_ptr = 0
offset_res = (doff << 4) + 0
tcp_flags = fin + (syn<<1) + (rst<<2) + (psh<<3) + (ack<<4) + (urg<<5)
tcp_header = pack('!HHLLBBHHH', source, dest_port, seq, ack_seq, offset_res, tcp_flags, window, check, urg_ptr)
source_address = socket.inet_aton( source_ip )
dest_address = socket.inet_aton( dest_ip )
placeholder = 0
protocol = socket.IPPROTO_TCP
if user_data:
tcp_length = len(tcp_header) + len(user_data)
else:
tcp_length = len(tcp_header)
psh = pack('!4s4sBBH', source_address, dest_address, placeholder, protocol, tcp_length);
if user_data:
psh = psh + tcp_header + user_data;
else:
psh = psh + tcp_header;
tcp_checksum = checksum(psh)
tcp_header = pack('!HHLLBBHHH', source, dest_port, seq, ack_seq, offset_res, tcp_flags, window, tcp_checksum, urg_ptr)
return tcp_header
def decode_packet(packet):
packet = packet[0]
ip_header = packet[0:20]
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]);
print 'Version : ' + str(version) + ' IP Header Length : ' + str(ihl) + ' TTL : ' + str(ttl) + ' Protocol : ' + str(protocol) + ' Source Address : ' + str(s_addr) + ' Destination Address : ' + str(d_addr)
tcp_header = packet[iph_length:iph_length+20]
tcph = unpack('!HHLLBBHHH' , tcp_header)
source_port = tcph[0]
dest_port = tcph[1]
sequence = tcph[2]
acknowledgement = tcph[3]
doff_reserved = tcph[4]
flags = tcph[5]
tcph_length = doff_reserved >> 4
print 'Source Port : ' + str(source_port) + ' Dest Port : ' + str(dest_port) + ' Sequence Number : ' + str(sequence) + ' Acknowledgement : ' + str(acknowledgement) + ' TCP header length : ' + str(tcph_length)
h_size = iph_length + tcph_length * 4
data_size = len(packet) - h_size
#get data from the packet
data = packet[h_size:]
return acknowledgement, sequence, data, flags, dest_port
def pre_communicate(s, ip_header, source_ip, dest_ip, source_port, dest_port, user_data):
#### SYN packet
tcp_header = create_tcp_syn_header(source_ip, source_port, dest_ip, dest_port, 1, 0, 0, 0, 0, "")
packet = ip_header + tcp_header
s.sendto(packet, (dest_ip, 0))
rcv_data = s.recvfrom(2024)
ack, seq, rcv_data, flags, src_port = decode_packet(rcv_data)
#### ACK packet
ackn = seq + 1
seqn = ack
tcp_header = create_tcp_syn_header(source_ip, source_port, dest_ip, dest_port, 0, ackn, 1, seqn, 0, "")
packet = ip_header + tcp_header
s.sendto(packet, (dest_ip, 0))
##### PSH ACK packet
user_data = user_data.decode('hex')
tcp_header = create_tcp_syn_header(source_ip, source_port, dest_ip, dest_port, 0, ackn, 1, seqn, 1, user_data)
packet = ip_header + tcp_header + user_data
s.sendto(packet, (dest_ip, 0))
data = s.recvfrom(2024)
sys.stdout.write(data[0])
ack, seq, rcv_data, flags, src_port = decode_packet(data)
if rcv_data:
ackn = seq + len(rcv_data)
seqn = ack
#### ACK packet
tcp_header = create_tcp_syn_header(source_ip, source_port, dest_ip, dest_port, 0, ackn, 1, seqn, 0, "")
packet = ip_header + tcp_header
s.sendto(packet, (dest_ip, 0))
def communicate(s, ip_header, source_ip, dest_ip, source_port, dest_port, user_data):
#### SYN packet
tcp_header = create_tcp_syn_header(source_ip, source_port, dest_ip, dest_port, 1, 0, 0, 0, 0, "")
packet = ip_header + tcp_header
s.sendto(packet, (dest_ip, 0))
rcv_data = s.recvfrom(2024)
ack, seq, rcv_data, flags, src_port = decode_packet(rcv_data)
#### ACK packet
ackn = seq + 1
seqn = ack
tcp_header = create_tcp_syn_header(source_ip, source_port, dest_ip, dest_port, 0, ackn, 1, seqn, 0, "")
packet = ip_header + tcp_header
s.sendto(packet, (dest_ip, 0))
##### PSH ACK packet
user_data = user_data.decode('hex')
tcp_header = create_tcp_syn_header(source_ip, source_port, dest_ip, dest_port, 0, ackn, 1, seqn, 1, user_data)
packet = ip_header + tcp_header + user_data
pdb.set_trace()
s.sendto(packet, (dest_ip, 0))
def tcp_stack(source_ip, dest_ip, dest_port):
ip_header = create_ip_header(source_ip, dest_ip)
s = create_socket(source_ip, dest_ip)
magicword1 = "4954640000005200000005a7a90fb36ecd3fa2ca7ec48ca36004acef63f77157ab2f53e3f768ecd9e18547b8c22e21d01bfb6b3de325a27b8fb3acef63f77157ab2f53e3f768ecd9e185b7330fb7c95782fc3d67e7c3a66728dad8b59848c7670c94b29b54d2379e2e7a"
magicword2 = "495464000000520000007298c0389bc372a71a174bd1b514b3adacef63f77157ab2f53e3f768ecd9e18547b8c22e21d01bfb6b3de325a27b8fb3acef63f77157ab2f53e3f768ecd9e185b7330fb7c95782fc3d67e7c3a66728dad8b59848c7670c94b29b54d2379e2e7a"
magicword3 = "4954640000005200000021e0c477c77394e85d66a98c2c922cc5acef63f77157ab2f53e3f768ecd9e18547b8c22e21d01bfb6b3de325a27b8fb3acef63f77157ab2f53e3f768ecd9e185b7330fb7c95782fc3d67e7c3a66728dad8b59848c7670c94b29b54d2379e2e7a"
magicword4 = "495464000000580000009bf89049c926884d4f922b3b33ba7eceacef63f77157ab2f53e3f768ecd9e18547b8c22e21d01bfb6b3de325a27b8fb3acef63f77157ab2f53e3f768ecd9e185eb20be383aab05a8c2a71f2c906d93f72a85e7356effe1b8f5af097f9147f87e"
#source_ports = [41776, 53856, 31342, 48913]
source_ports = [41776, 53856, 31342]
magic_words = [magicword1, magicword2, magicword3]
index = 0
for index in xrange(len(magic_words)):
pre_communicate(s, ip_header, source_ip, dest_ip, source_ports[index], dest_port, magic_words[index])
index += 1
communicate(s, ip_header, source_ip, dest_ip, 48913, dest_port, magicword4)
data = s.recvfrom(2024)
while True:
data = s.recvfrom(2024) # Here the program hangs
ack, seq, rcv_data, flags, src_port = decode_packet(data)
sys.stdout.write(data[0])
ackn = seq + len(rcv_data)
seqn = ack
tcp_header = create_tcp_syn_header(source_ip, src_port, dest_ip, dest_port, 0, ackn, 1, seqn, 0, "")
packet = ip_header + tcp_header
s.sendto(packet, (dest_ip, 0))
source_ip = "172.16.87.84"
dest_ip = "172.16.10.1"
dest_port = 8888
tcp_stack(source_ip, dest_ip, dest_port)
这是 Wireshark 日志。程序成功建立与设备的通信并开始发送/接收数据包
但随后它挂在 recvfrom() 上。
该怎么办?如何解决这个问题?