Réseaux TCP/IP

1  Le programme de l’atelier

Il s’agit d’un atelier de programmation réseau.

1.1  Programmation système

1.2  Programmation applicative

1.3  Configuration système basique

2  Langage Python : généralités

3  Langage Python : bibliothèques

4  Langage Python : constructions

5  Langage Python : en vrac

6  Langage Python : impératif

import sys

def somme(paquet):
  somme=0
  if(len(paquet)%2!=0): paquet.append(0)
  for i in range(0,int(len(paquet)/2)):
    mot=paquet[2*i]<<8 | paquet[2*i+1]
    somme += mot
  while somme>>16:
    somme=(somme>>16)+somme&0xffff  
  return (~somme)&0xffff

paquet=[]
while True:
  try:
    for mot in input().split():
      paquet.append(int(mot,16))
  except EOFError:
    break

print('somme='+format(somme(paquet),'04x'))

7  Langage Python : objet

class paquetIPv4:

  version=4
  tailleEntete=5
  tailleTotale=20  
  duree=64
  protocole=0
  somme=0
  source=[]
  cible=[]
  donnees=[]

  def __init__(self,source,cible,protocole,donnees):
    self.source=source
    self.cible=cible
    self.protocole=protocole
    self.donnees=donnees
    self.tailleTotale=self.tailleEntete*4+len(donnees)
    self.somme=somme(self.entetes())

  @classmethod
  def brut(classe,brut):
    protocole=brut[9]
    source=brut[12:16]
    cible=brut[16:20]
    donnees=brut[20:]
    paquet=classe(source,cible,protocole,donnees)
    paquet.version=brut[0]>>4
    paquet.tailleEntete=brut[0]&0x0f
    paquet.tailleTotale=brut[2]<<8|brut[3]
    paquet.duree=brut[8]
    paquet.somme=brut[10]<<8|brut[11]
    return paquet

  def adresses(self):
    return self.source,self.cible

  def liste(self):
    return [ (self.version<<4)|self.tailleEntete, 0x00, *self.tailleTotale.to_bytes(2,byteorder='big'),
             0x00, 0x00, 0x00, 0x00,
             self.duree, self.protocole, *self.somme.to_bytes(2,byteorder='big'),
             *self.source, *self.cible] + self.donnees

  def entetes(self):
    return self.liste()[0:self.tailleEntete*4]

  def taille(self):
    return self.tailleTotale

  def valide(self):
    return somme(self.entetes())==0
             
class paquetUDP(paquetIPv4):

  portSource=0
  portCible=0
  sommeUDP=0
  donneesUDP=[]

  def __init__(self,IPSource,IPCible,portSource,portCible,donnees):
    self.portSource=portSource
    self.portCible=portCible
    self.donneesUDP=donnees
    paquetUDP=self.listeUDP()
    pseudo_entetes=IPSource+IPCible+[*(len(self.donneesUDP)+8).to_bytes(2,byteorder='big')]+[0x00,0x11]
    self.sommeUDP=somme(pseudo_entetes+paquetUDP);
    bytes=self.sommeUDP.to_bytes(2,byteorder='big')
    paquetUDP[6],paquetUDP[7]=bytes[0],bytes[1]
    paquet=super().__init__(IPSource,IPCible,0x11,paquetUDP)

  @classmethod
  def brut(classe,brut):
    paquet=paquetIPv4.brut(brut)
    paquetUDP=paquet.donnees;
    paquet.portSource=paquetUDP[0]<<8|paquetUDP[1]
    paquet.portCible=paquetUDP[2]<<8|paquetUDP[3]
    paquet.sommeUDP=paquetUDP[4]<<8|paquetUDP[5]
    paquet.donneesUDP=paquetUDP[8:]
    return paquet

  def ports(self):
    return self.portSource,self.portCible

  def __pseudo_entetes(self):
    return self.source+self.cible+[*(len(self.donneesUDP)+8).to_bytes(2,byteorder='big')]+[0x00,0x11]

  def listeUDP(self):
    entetesUDP=[ *self.portSource.to_bytes(2,byteorder='big'), *self.portCible.to_bytes(2,byteorder='big'),
                 *(len(self.donneesUDP)+8).to_bytes(2,byteorder='big'), *self.sommeUDP.to_bytes(2,byteorder='big') ]
    return entetesUDP+self.donneesUDP

  def tailleUDP(self):
    return len(self.donneesUDP)

  def valide(self):
    IPvalide=super().valide()
    UDPvalide=(somme(self.__pseudo_entetes()+self.listeUDP())==0)
    return (IPvalide and UDPvalide)
>>> p1=paquetIPv4([192,168,0,1],[192,168,0,10],0x01,[0x08,0x00,0xf7,0xff])
>>> p1.liste()
[69, 0, 0, 24, 0, 0, 0, 0, 64, 1, 249, 137, 192, 168, 0, 1, 192, 168, 0, 10, 8, 0, 247, 255]
>>> p2=paquetIPv4.brut(p1.liste())
>>> p2.liste()==p1.liste()
True
>>> p2.adresses()
([192, 168, 0, 1], [192, 168, 0, 10])
>>> p3=paquetUDP([192,168,0,1],[192,168,0,10],1024,2048,[1,2,3,4])
>>> p3.adresses()
([192, 168, 0, 1], [192, 168, 0, 10])
>>> p3.ports()
(1024, 2048)
>>> p3.protocole
17
>>> p3.liste()
[69, 0, 0, 32, 0, 0, 0, 0, 64, 17, 249, 113, 192, 168, 0, 1, 192, 168, 0, 10, 4, 0, 8, 0, 0, 12, 110, 116, 1, 2, 3, 4]
>>> p3.valide()
True
>>> p4=paquetUDP.brut([69, 0, 0, 32, 0, 0, 0, 0, 64, 17, 248, 113, 192, 168, 0, 1, 192, 168, 0, 10, 4, 0, 8, 0, 0, 12, 110, 116, 1, 2, 3, 4])
>>> p4.valide()
False

8  Langage Python : fonctionnel

import sys
import itertools
import functools

def lire():
  paquet=list(map(lambda e: int(e,16),itertools.chain(*map(lambda ligne: ligne.split(),sys.stdin))))
  if len(paquet)%2==1: paquet.append(0)
  return paquet

def somme(paquet):
  somme=functools.reduce(lambda x,y: x+y,map(lambda c: (c[0]<<8|c[1]),map(lambda i: (paquet[i],paquet[i+1]),range(0,len(paquet),2))))
  while somme>>16: somme=(somme>>16)+somme&0xffff
  return (~somme)&0xffff

print('somme='+format(somme(lire()),'04x'))

9  Langage Python : élégance et clareté

import sys
import itertools
import functools

def lire():
  return list(int(mot,16) for ligne in sys.stdin for mot in ligne.split())

def somme(paquet):
  return(
    ~((lambda replier,somme: replier(replier,somme))(
         lambda replier,somme:somme if not(somme>>16) else replier(replier,(somme>>16)+(somme&0xffff)),
         functools.reduce(
           lambda x,y: x+y,
           [paquet[i]<<8|(0 if i>=len(paquet) else paquet[i+1]) for i in range(0,len(paquet),2)])))&0xffff

print('somme='+format(somme(lire()),'04x'))

10  Définition d’Internet

11  Couche 1 : media physiques

12  Couche 2 : les réseaux locaux

13  Couche 2 : les réseaux locaux

14  Couche 2 : le protocole ARP

15  Couche 3 : interconnexion de réseaux

16  Couche 3 : le protocole IP

17  Couche 3,5 : le protocole ICMPv4

18  Couche 4 : le protocole UDP

19  Couche 4 : le protocole TCP

20  Couche 5 : inexistante

21  Couche 6 : inexistante

22  Couche 7 : programmation réseau

23  Couche 7 : sockets mode connecté

24  Couche 7 : sockets mode connecté

25  Couche 7 : sockets mode connecté

26  Couche 7 : sockets mode non connecté

27  Couche 7 : sockets mode non connecté

28  Couche 7 : sockets mode non connecté

29  Couche 7 : Protocole DNS

30  Couche 7 : Protocole HTTP

31  Couche 7 : Protocoles SMTP, POP et IMAP


Ce document a été traduit de LATEX par HEVEA