ciao spider-net,
ho letto ,tutto ok, ma come ho detto il problema è il calcolo del checksum.
Adesso ti faccio vedere realmente la problematica alla quale mi riferisco con un semplice esempio pratico in python.
il codice seguente è un client UDP che invia un semplice pacchetto al mio router, creando il socket come da standard:
Codice: Seleziona tutto
import socket
UDP_IP = "192.168.1.254"
UDP_PORT = 8888
MESSAGE = "Hello, World!"
print "UDP target IP:", UDP_IP
print "UDP target port:", UDP_PORT
print "message:", MESSAGE
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))
il checksuk generato è 0x6f93 = 28563, come si vede nel dump esadecimale (terza righa, quinta coppia):
Codice: Seleziona tutto
00 21 96 6c d3 14 08 62 66 51 18 3d 08 00 45 00
00 29 b4 4f 40 00 40 11 01 a6 c0 a8 01 80 c0 a8
01 fe a7 7d 22 b8 00 15 6f 93 48 65 6c 6c 6f 2c
20 57 6f 72 6c 64 21
il mio router mi risponde con un pacchetto ICMP che comunica l'irraggiungibilità della porta.
tutto ok, il paccheto UDP viene accettato e la risposta lo conferma.
ho creato i pacchetti pseudoheader, UDP e DATA unguali a quelli generati dal socket precedente,
questo è il dump esadecimale del l'intero pacchetto UDP:
Codice: Seleziona tutto
a7 7d 22 b8 00 15 6f 93 48 65 6c 6c 6f 2c
20 57 6f 72 6c 64 21
ma calcolandone il valore del checksum, con 3 differenti funzioni, il risultato non è lo stesso
myChecksum: 0x4E85 = 20101
myChecksum1: 0x4E85 = 20101
myChecksum2: 0x854E = 34126
Codice: Seleziona tutto
src = "192.168.1.128"
dst = "192.168.1.254"
srcport = 42877
dstport = 8888
UDP_CODE = socket.getprotobyname('udp')
proto = UDP_CODE
def checksum(source_string):
sum = 0
count_to = (len(source_string) / 2) * 2
count = 0
while count < count_to:
this_val = ord(source_string[count + 1])*256+ord(source_string[count])
sum = sum + this_val
sum = sum & 0xffffffff # Necessary?
count = count + 2
if count_to < len(source_string):
sum = sum + ord(source_string[len(source_string) - 1])
sum = sum & 0xffffffff # Necessary?
sum = (sum >> 16) + (sum & 0xffff)
sum = sum + (sum >> 16)
answer = ~sum
answer = answer & 0xffff
answer = answer >> 8 | (answer << 8 & 0xff00)
return answer
def checksum1(pkt):
pkt=str(pkt)
s=0
if len(pkt) % 2 == 1:
pkt += "\0"
for i in range(len(pkt)/2):
s = s + (struct.unpack("!H",pkt[2*i:2*i+2])[0])
s = (s >> 16) + (s & 0xffff)
s += s >> 16
return ~s & 0xffff
def checksum2(data):
s = 0
n = len(data) % 2
for i in range(0, len(data)-n, 2):
s+= ord(data[i]) + (ord(data[i+1]) << 8)
if n:
s+= ord(data[i+1])
while (s >> 16):
s = (s & 0xFFFF) + (s >> 16)
s = ~s & 0xFFFF
return s
data = "Hello, World!!!"
udpHeader = struct.pack("!4H", srcport, dstport, 0, 0)
length = len(udpHeader)+len(data);
# pseudo header fields
source_address = socket.inet_aton( src )
dest_address = socket.inet_aton(dst)
placeholder = 0
protocol = socket.IPPROTO_UDP
udp_length = length
psh = struct.pack('!4s4sBBH' , source_address , dest_address , placeholder , protocol , udp_length)
psh = psh + udpHeader + data
myChecksum = checksum( psh)
print ("myChecksum: "+ str(myChecksum))
myChecksum1 = checksum1( psh)
print ("myChecksum1: "+ str(myChecksum1))
myChecksum2 = checksum2( psh)
print ("myChecksum2: "+ str(myChecksum2))
è questo quello che dico, tutto tira fuori un risultato, ma a volte non è quello giusto!
Sai dirmi dove le 3 funzioni errano????
GRAZIEEEEEEE
