darkneurone
39Messages postés
11 mars 2007Date d'inscription
24 mars 2008 à 21:18
Merci :)
J'ai trouvé les RFC très instructives ^^ Ce qui me motive, c'est la curiosité de savoir comment ces protocoles fonctionnent ^^ je suis trop curieux peut-être mais c'est pas grave ! J'aimerai bien savoir comment ils sont assemblés/désassemblés, interprétés... etc ^^ j'ai lu pas mal de sujet sur ça, mais ça reste de la théorie ^^ j'aimerai bien faire quelque chose de concret là dessus !
J'ai trouvé ce script sur internet... mais je ne comprends pas tout, est ce que quelqu'un pourrait m'expliquer les points ci-dessous svp ?
-----------------------------------------------------------------------------------------------
"""UDP packets."""
# Copyright 1997, Corporation for National Research Initiatives
# written by Jeremy Hylton, jeremy@cnri.reston.va.us
import inet
import struct
import string
class Packet:
def __init__(self, packet=None, cksum=1):
if packet:
self.__disassemble(packet, cksum)
else:
self.sport = 0
self.dport = 0
self.ulen = 8
self.sum = 0
self.data = ''
def __repr__(self):
begin = "<UDP %d->%d len=%d " % (self.sport, self.dport, self.ulen)
if self.ulen == 8:
rep = begin + "\'\'>"
elif self.ulen < 18:
rep = begin + "%s>" % repr(self.data)
else:
rep = begin + "%s>" % repr(self.data[:10] + '...')
return rep
def assemble(self, cksum=1):
self.ulen = 8 + len(self.data)
begin = struct.pack('hhh', self.sport, self.dport, self.ulen)
packet = begin + '\000\000' + self.data
if cksum:
self.sum = inet.cksum(packet)
packet = begin + struct.pack('h', self.sum) + self.data
self.__packet = inet.udph2net(packet)
return self.__packet
def __disassemble(self, raw_packet, cksum=1):
packet = inet.net2updh(raw_packet)
if cksum and packet[6:8] != '\000\000':
our_cksum = inet.cksum(packet)
if our_cksum != 0:
raise ValueError, packet
elts = map(lambda x:x & 0xffff, struct.unpack('hhhh', packet[:8]))
[self.sport, self.dport, self.ulen, self.sum] = elts
self.data = packet[8:]
-------------------------------------------------------------------------------------
voilà le code ^^
les points que je ne comprends pas :
- L'intérêt de la fonction __repr__
PS : j'ai compris qu'en fonction de la longueur de quelque chose... (ulen = u length / u = ?)... quoiqu'il en soit... si ulen = 8, ça retourne : <UDP *chiffre*->*chiffre* len=*chiffre* '' *à partir du 10eme char, on met la suite*>
Je comprends bien les fonctions... mais l'intérêt... pas compris ^^
- pareil pour la fonction assemble :S
PS : j'ai compris que ça calcul la longueur du truc encore... ^^ on format begin en structure, en insérant certaines données... alors pourquoi mettre 'hhh' déjà ^^ on concatène begin avec le string ''\000\000' et data... pourquoi mettre '\000\000 lol ^^
Ce que je pense : c'est qu'on construit le paquet selon le datagramme UDP, parce qu'on insère d'abord ce qu'on a mit dans begin... (seulement je ne sais pas à quoi ça sert ^^) et on ajoute '\000\000... lol et à la fin on rajoute e "data". Donc peut-être que c'est ça... enfin comme vous pouvez le constater, j'ai beaucoup de mal ^^ surtout quand je ne sais pas à quoi correspond tout ça !
Ensuite, on calcul la taille du paquet... on ajoute encore des données... mais je ne sais pas encore à quoi ça sert ^^ à quoi correspond cet ajout...
Sinon, on peut remarquer qu'il fait appel à la fonction udph2net du module inet... et avant à cksum... voilà les deux fonctions (elles se trouvent dans inet.py) :
def cksum(s):
if len(s) & 1:
s = s + '\0'
words = array.array('h', s)
sum = 0
for word in words:
sum = sum + (word & 0xffff)
hi = sum >> 16
lo = sum & 0xffff
sum = hi + lo
sum = sum + (sum >> 16)
return (~sum) & 0xffff
def gets(s):
return struct.unpack('h', s)[0] & 0xffff
def mks(h):
return struct.pack('h', h)
def udph2net(s):
sp = htons(gets(s[0:2]))
dp = htons(gets(s[2:4]))
len = htons(gets(s[4:6]))
return mks(sp) + mks(dp) + mks(len) + s[6:]
############################################
Voilà à quoi sert la fonction htons :
Convert 16-bit positive integers from host to network byte order. On machines where the host byte order is the same as network byte order, this is a no-op; otherwise, it performs a 2-byte swap operation.
Ces fonctions ont été.... la cerise sur le gâteau ! ^^ Je ne vois pas l'intérêt de faire len(s) & 1. Pourquoi mettre & 1 ? ça renvois toujours "vrai" non ?
Voilà, félicitation si vous avez lu mon post en entier !! et un grand merci à tout ceux qui pourront m'aider. Faut dire que pour l'instant... ça reste très flou pour moi tout ça !
PS : voilà le datagramme d'un paquet UDP
<-----------------32bits----------------------->
+-----------------------+-----------------------+
| Port Source | Port Destination |
+-----------------------+-----------------------+
| Longueur UDP | Somme de ctrl (message)
+-----------------------+-----------------------+
... Données
+-----------------------------------------------+