[Python] Construire un paquet UDP/TCP
Fermé
darkneurone
Messages postés
39
Date d'inscription
dimanche 11 mars 2007
Statut
Membre
Dernière intervention
12 juin 2008
-
23 mars 2008 à 21:16
EminoMeneko Messages postés 2435 Date d'inscription jeudi 24 janvier 2008 Statut Membre Dernière intervention 23 mai 2018 - 25 mars 2008 à 22:53
EminoMeneko Messages postés 2435 Date d'inscription jeudi 24 janvier 2008 Statut Membre Dernière intervention 23 mai 2018 - 25 mars 2008 à 22:53
Bonsoir à tous !!!
La question est dans le titre ^^ Ca fait pas mal de temps que je cherche sur google des moyens de construire entièrement un paquet UDP (aussi TCP). J'ai déjà trouvé les datagrammes sur internet mais il n'y aucun tutorial pour les fabriquer... surtout en python ! est-ce que quelqu'un connait un site où il y aurait un cours qui explique clairement comment procéder ? une librairie ?
Merci pour votre aide.
Bonne soirée à tous !
La question est dans le titre ^^ Ca fait pas mal de temps que je cherche sur google des moyens de construire entièrement un paquet UDP (aussi TCP). J'ai déjà trouvé les datagrammes sur internet mais il n'y aucun tutorial pour les fabriquer... surtout en python ! est-ce que quelqu'un connait un site où il y aurait un cours qui explique clairement comment procéder ? une librairie ?
Merci pour votre aide.
Bonne soirée à tous !
A voir également:
- [Python] Construire un paquet UDP/TCP
- Udp vs tcp - Guide
- Tcp optimizer - Télécharger - Optimisation
- Citizen code python avis - Accueil - Outils
- Construire un organigramme - Guide
8 réponses
EminoMeneko
Messages postés
2435
Date d'inscription
jeudi 24 janvier 2008
Statut
Membre
Dernière intervention
23 mai 2018
318
23 mars 2008 à 21:23
23 mars 2008 à 21:23
https://www.google.fr/search?q=python+socket&meta=lr%3Dlang_fr&gws_rd=ssl
Pour faire de la communication TCP UDP on utilise dans la plupart des langages de programmation ce qu'on appel des sockets...
Pour faire de la communication TCP UDP on utilise dans la plupart des langages de programmation ce qu'on appel des sockets...
darkneurone
Messages postés
39
Date d'inscription
dimanche 11 mars 2007
Statut
Membre
Dernière intervention
12 juin 2008
12
23 mars 2008 à 21:49
23 mars 2008 à 21:49
merci pour ta réponse mais je sais déjà utiliser les sockets ^^ je veux vraiment construire un packet pas à pas.
EminoMeneko
Messages postés
2435
Date d'inscription
jeudi 24 janvier 2008
Statut
Membre
Dernière intervention
23 mai 2018
318
24 mars 2008 à 16:41
24 mars 2008 à 16:41
Bon ben bonne chance ! :)
Qu'est-ce qui motive une telle décision ?
Bonne lecture des RFC correspondantes...
Qu'est-ce qui motive une telle décision ?
Bonne lecture des RFC correspondantes...
darkneurone
Messages postés
39
Date d'inscription
dimanche 11 mars 2007
Statut
Membre
Dernière intervention
12 juin 2008
12
24 mars 2008 à 21:18
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
+-----------------------------------------------+
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
+-----------------------------------------------+
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
EminoMeneko
Messages postés
2435
Date d'inscription
jeudi 24 janvier 2008
Statut
Membre
Dernière intervention
23 mai 2018
318
25 mars 2008 à 16:34
25 mars 2008 à 16:34
Amuse toi bien moi j'ai de la fumée qui sors des oreilles ! ^^
sport et dport ça doit être source port et destination port si ça peut t'aider...
je connais pas le python mais il semble que la fonction assemble créer le paquet et disassemble le déballe.
Tu sais comment ça marche je pense.
Bonne chance.
sport et dport ça doit être source port et destination port si ça peut t'aider...
je connais pas le python mais il semble que la fonction assemble créer le paquet et disassemble le déballe.
Tu sais comment ça marche je pense.
Bonne chance.
darkneurone
Messages postés
39
Date d'inscription
dimanche 11 mars 2007
Statut
Membre
Dernière intervention
12 juin 2008
12
25 mars 2008 à 17:52
25 mars 2008 à 17:52
Merci pour tes encouragements !
Effectivement, ça doit être source port et destination port mais je vois pas ces deux variables sont initialisées à 0 ^^ C'est assez bizarre ! Mais bon, je persévère ! je tente de comprendre petit à petit ce code mais c'est assez compliqué !
Effectivement, ça doit être source port et destination port mais je vois pas ces deux variables sont initialisées à 0 ^^ C'est assez bizarre ! Mais bon, je persévère ! je tente de comprendre petit à petit ce code mais c'est assez compliqué !
EminoMeneko
Messages postés
2435
Date d'inscription
jeudi 24 janvier 2008
Statut
Membre
Dernière intervention
23 mai 2018
318
25 mars 2008 à 19:28
25 mars 2008 à 19:28
Utilise les balises de code quand tu en envoi sur le forum ça aide...
Bon j'ai essayé de commenter et mais comme je connais pas la syntaxe Python t'y fie pas de trop mais inspire toi en au pire...
Au fait tu as le droit de formater un minimum son code source avec la fonctionnalité qui va bien.
Comme ça....
Retrouve ce code coloré et indenté (je sais pas où se limite un if etc en Python) plus bas.
http://pastebin.com/m10e3546d lien valable un mois...
Bonne chance.
Je voulais apprendre le Python mais pas trop le temps...
Bon j'ai essayé de commenter et mais comme je connais pas la syntaxe Python t'y fie pas de trop mais inspire toi en au pire...
Au fait tu as le droit de formater un minimum son code source avec la fonctionnalité qui va bien.
Comme ça....
"""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: # Fonction d'initialisation de l'objet def __init__(self, packet=None, cksum=1): if packet: # Si on a un pasuet on le désassemble ? self.__disassemble(packet, cksum) else: # Sinon on initialise des valeurs self.sport = 0 self.dport = 0 self.ulen = 8 self.sum = 0 self.data = '' def __repr__(self): # On affiche les ports source et destination puis la longueur du paquet. begin = "<UDP %d->%d len=%d " % (self.sport, self.dport, self.ulen) # Si la longueur du paquet courant vaut 8 on concatène avec "''>" if self.ulen == 8: rep = begin + "\'\'>" # Si inférieur à 18 on ajoure une chaine mais je sais pas quoi elif self.ulen < 18: rep = begin + "%s>" % repr(self.data) else: # sinon je sais pas trop... xD rep = begin + "%s>" % repr(self.data[:10] + '...') return rep def assemble(self, cksum=1): # checksum initialisé à 1 par défaut. # On ajoute 8 à la taille de la donnée "surement on a un entête de 8 caractères/octets/bits" self.ulen = 8 + len(self.data) # On inscrit les données du paquet dans l'entête... begin = struct.pack('hhh', self.sport, self.dport, self.ulen) packet = begin + '\000\000' + self.data # MAJ du code ce contrôle if cksum: self.sum = inet.cksum(packet) # Ajout de la donnée dans le paquet packet = begin + struct.pack('h', self.sum) + self.data self.__packet = inet.udph2net(packet) return self.__packet def __disassemble(self, raw_packet, cksum=1): # convertion d'une IP vers un nom DNS je crois packet = inet.net2updh(raw_packet) # Comprend pas cette syntaxe... if cksum and packet[6:8] != '\000\000': our_cksum = inet.cksum(packet) # Levée d'une exception si les CRC ne correspondent pas. if our_cksum != 0: raise ValueError, packet # Je comprends plus elts = map(lambda x:x & 0xffff, struct.unpack('hhhh', packet[:8])) [self.sport, self.dport, self.ulen, self.sum] = elts self.data = packet[8:]
Retrouve ce code coloré et indenté (je sais pas où se limite un if etc en Python) plus bas.
http://pastebin.com/m10e3546d lien valable un mois...
Bonne chance.
Je voulais apprendre le Python mais pas trop le temps...
darkneurone
Messages postés
39
Date d'inscription
dimanche 11 mars 2007
Statut
Membre
Dernière intervention
12 juin 2008
12
25 mars 2008 à 21:14
25 mars 2008 à 21:14
Merci pour tes commentaires et pour le code ! :)
Ca éclaircit quelques points... Mais il y a toujours des trucs qui me semblent bizarre ou incompréhensible comme l'ajout de 'hhh' dans le header ^^ Dans un autre script, pour un paquet ICMP, j'ai vu que l'auteur ajoutait 'bbHHh' !
En ce qui concerne les instructions conditionnelles sur la taille du paquet, je crois qu'elle peut varier en fonction de l'ip... ipv6 ou ipv4 ^^ Mais je ne suis sûr de rien ^^
Mais ce qui reste flou, c'est vraiment le pourquoi de la chose ^^ pourquoi est ce qu'il ajoute telle valeur ? etc... c'est vraiment pas simple !
Merci en tout cas pour ton aide ^^ j'espère que tes oreilles n'ont pas trop fumées ! :o)
Ca éclaircit quelques points... Mais il y a toujours des trucs qui me semblent bizarre ou incompréhensible comme l'ajout de 'hhh' dans le header ^^ Dans un autre script, pour un paquet ICMP, j'ai vu que l'auteur ajoutait 'bbHHh' !
En ce qui concerne les instructions conditionnelles sur la taille du paquet, je crois qu'elle peut varier en fonction de l'ip... ipv6 ou ipv4 ^^ Mais je ne suis sûr de rien ^^
Mais ce qui reste flou, c'est vraiment le pourquoi de la chose ^^ pourquoi est ce qu'il ajoute telle valeur ? etc... c'est vraiment pas simple !
Merci en tout cas pour ton aide ^^ j'espère que tes oreilles n'ont pas trop fumées ! :o)
EminoMeneko
Messages postés
2435
Date d'inscription
jeudi 24 janvier 2008
Statut
Membre
Dernière intervention
23 mai 2018
318
25 mars 2008 à 22:53
25 mars 2008 à 22:53
D'après ce que tu dit il semblerait que ces hhh ne soient pas un hasard. Reste à savoir à quoi cela correspond.
Maintenant j'ai pas vu IPv6 des masses, mais il me semble que (logiquement ça colle aussi) les adresses IPv6 sont plus lourdes en taille donc oui la taille change.
Pour le reste je sais pas. :)
Maintenant j'ai pas vu IPv6 des masses, mais il me semble que (logiquement ça colle aussi) les adresses IPv6 sont plus lourdes en taille donc oui la taille change.
Pour le reste je sais pas. :)