Logo Central

la frame ethernet

0...7
8...15
16...23
24...31
32...39
40...47
Adresse Mac Destination
Adresse Mac Source
Ether Type
Données ........ [46..1500] + CRC

Préambule (8 octets)

Annonce le début de la trame et permet la synchronisation. Il contient 8 octets dont la valeur est 10101010 (on alterne des 1 et des 0), sauf pour le dernier octet dont les 2 derniers bits sont à 1.

Adresse Destination (6 octets)

Adresse physique de la carte Ethernet destinataire de la trame. On représente une adresse Ethernet comme ses 6 octets en hexadécimal, par exemple : 08:00:07:5C:10:0A. La destination peut être une adresse de (multi-)diffusion. En particulier, l’adresse FF:FF:FF:FF:FF:FF (diffusion ou broadcast) correspond à toutes les stations du réseau physique Ethernet.

Adresse Source (6 octets)

Adresse physique de la carte Ethernet émettrice de la trame.

EtherType (2 octets)

Indique quel protocole est concerné par le message. La carte réalise un démultiplexage en fournissant les données au protocole concerné. Quelques types courants (en hexadécimal) définis par la RFC 1700 :

  • 0x0600 : Xerox Network Systems
  • 0x0800 : IP (Internet Protocol)
  • 0x8100 : 802.1q (encapsulation VLAN)
  • 0x0806 : ARP (Address Resolution Protocol)
  • 0x8035 : RARP (Reverse ARP)
  • 0x8137 et 0x8138 : Novell

Données (46 à 1500 octets)

Les données véhiculées par la trame. Sur la station destinataire de la trame, ces octets seront communiqués à l’entité (protocole) indiquée par le champ EtherType. Notons que la taille minimale des données est de 46 octets. Des octets à 0, dits de “bourrage”, sont utilisés pour compléter des données dont la taille est inférieure à 46 octets.

CRC (Cyclic Redundancy Code)

Champ de contrôle de la redondance cyclique. Permet de s’assurer que la trame a été correctement transmise et que les données peuvent donc être délivrées au protocole destinataire.

Structure de la trame Ethernet en C


typedef struct ethernet {
uint8_t status;         // status
uint8_t nextpage;       // prochaine page
uint16_t length;        // Longueur
uint8_t destnodeid[6];  // Adresse MAC du destinataire
uint8_t sourcenodeid[6]; // Adresse MAC de la source
uint16_t protocal;      // Protocole
uint8_t packet[300];    // paquet
} ethernet;

la frame internet

0...7
8...15
16...23
24...31
Version
Header
Type de service
Longueur totale
Identification
Flags
Position du fragment
Durée de vie
Protocole
Somme de contrôle d'entête
Adresse source
Adresse destination
Options (bourrage)
Données

Champ Version (4 bits)

Indique le numéro de version du protocole IP utilisé (généralement 4).

Champ Header (4 bits)

Indique la longueur de l'en-tête en nombre de mots de 32 bits.

Champ Type de Service

Il est divisé en deux parties :

  • 4 bits de "priorité" |D|T|R|C| : D = délai court, T = haut débit, R = fiabilité élevée, C = coût faible.
  • 4 bits de "service" : 1000 = Telnet, 0100 = FTP data, 0010 = SNMP.

Champ Longueur Totale (16 bits)

Exprimé en octets. Il est utilisé pour distinguer le bourrage dans une trame lorsque la longueur dépasse la taille maximale.

Champ Identification (16 bits)

Permet d'identifier un datagramme en cas de fragmentation. Il est recopié dans chaque segment.

Champ Flags (3 bits)

Il contient trois bits : |0|DF|MF|.

  • DF (Don't Fragment) : vaut 1 si la trame ne doit pas être fragmentée.
  • MF (More Fragment) : vaut 1 si la trame a été fragmentée et si le fragment n'est pas le dernier.

Champ Position du Fragment (13 bits)

Utilisé pour la reconstruction des fragments lors de la traversée de certains supports. Indique la position relative, en multiples de 8 octets, du fragment dans la trame initiale. Le compteur est décrémenté à chaque seconde tant que tous les fragments n'ont pas été reçus.

Champ Durée de Vie (8 bits)

Indique une durée de vie en secondes de la trame. Elle est détruite lorsque ce champ devient nul. Chaque traversée d'un nœud se traduit par une décrémentation de ce champ.

Champ Protocole (8 bits)

Indique les protocoles utilisés au niveau supérieur :

  • ICMP : 1
  • TCP : 6
  • UDP : 17

Champ Somme de Contrôle d'En-tête (16 bits)

Un CRC recalculé par chaque routeur avant la retransmission. Il permet de détecter les incohérences et erreurs de transmission dans l'en-tête, mais ne prend pas les données en compte.

Champs Adresse Source et Destination (4 octets chacun)

Indiquent les adresses IP source et destination du paquet.

Champ Options

De longueur variable, il peut être nul, avec bourrage pour obtenir un multiple de 32 bits.

Structure de la trame IP en C


	typedef struct ip {
	uint16_t head[9];        // (correspond à la trame Ethernet)
	uint8_t verandihl;       // Version et Header
	uint8_t typeofserver;    // Type de service 
	uint16_t totallength;    // Longueur de la trame totale
	uint16_t frameindex;     // Identification
	uint16_t segment;        // Flags et Position du fragment
	uint8_t ttl;             // Durée de vie
	uint8_t protocal;        // Protocole
	uint16_t crc;            // Somme de contrôle d'entête
	uint8_t sourceip[4];     // Adresse de la source
	uint8_t destip[4];       // Adresse du destinataire
	uint8_t packet[280];     // Paquet
	} ip;
    

Cette structure représente un exemple de trame IP en C, avec des champs pour la version, le service, la longueur totale, l'identification, la durée de vie, le protocole, et les adresses IP source et destination.

la frame ARP

0...7
8...15
16...23
24...31
32...39
40...47
HW type de réseau
Protocole
L. Mac
L.Ip
Opération
Adresse source MAC
Adresse IP Source (Protocolaire)
Adresse Destination MAC
Adresse IP Destination (Protocolaire)

Champ HW (Type de réseau)

Ce champ indique le type de réseau sur lequel la séquence ARP a été activée. Pour Ethernet, le code est généralement (0001)h.

Champ Longueur d'adresse MAC (L. MAC)

Ce champ spécifie le nombre d'octets dans les adresses MAC des paquets ARP. En général, la valeur est (0006)h, indiquant une longueur de 6 octets pour une adresse MAC.

Champ Longueur d'adresse protocolaire (L. IP)

Ce champ indique la longueur des adresses de niveau 3 (adresse IP) en octets. Pour une adresse IP, la valeur est généralement (0004)h, soit 4 octets.

Champ Code d'opération

Le code d'opération précise le type de paquet ARP :

  • (0001)h : ARP_Request (requête ARP)
  • (0002)h : ARP_Response (réponse ARP ou ARP_Reply)

Champs Adresse MAC et Adresse protocolaire (source)

Ces champs contiennent l'adresse MAC et l'adresse protocolaire (IP) de l'émetteur du paquet. Pour un paquet ARP_Request, ces adresses correspondent à celles de l'initiateur de la requête. Pour un ARP_Reply, ces champs sont remplacés par les adresses de la station qui répond à la requête ARP.

Champs Adresse MAC et Adresse protocolaire (destination)

Ces champs contiennent les adresses MAC et IP de la station cible. Dans un paquet ARP_Request, l'adresse MAC destination est inconnue et est donc définie à 0, tandis que l'adresse IP destination est bien renseignée (celle de la station recherchée). Dans un ARP_Reply, la station répondante copie les adresses source du paquet ARP_Request dans les champs destination de la réponse.

Structure du paquet ARP en C

 
typedef struct arp {
uint16_t head[9];        // Correspond à la trame Ethernet
uint16_t harewaretype;   // Type de réseau (Ethernet = 0x0001)
uint16_t protocaltype;   // Protocole (IP = 0x0800)
uint8_t halength;        // Longueur de l'adresse physique (MAC = 6 octets)
uint8_t palength;        // Longueur de l'adresse logique (IP = 4 octets)
uint16_t operation;      // Type d'opération (1: requête ARP, 2: réponse ARP)
uint8_t sourcenodeid[6]; // Adresse MAC source
uint8_t sourceip[4];     // Adresse IP source
uint8_t destnodeid[6];   // Adresse MAC destination (0 si inconnue)
uint8_t destip[4];       // Adresse IP destination
} arp;
        

Cette structure représente un paquet ARP en langage C, avec des champs pour le type de réseau, les adresses MAC et IP source et destination, ainsi que le type d'opération (requête ou réponse ARP).

la frame UDP

0...7
8...15
16...23
24...31
Port Source (16 bits)
Port Destination (16 bits)
Longueur (16 bits)
Somme de controle (16 bits)

Champ Port Source

Ce champ indique le port depuis lequel le paquet a été envoyé. Il correspond à une valeur sur 16 bits qui identifie le port source de l'application émettrice.

Champ Port de Destination

Le champ de port de destination spécifie à quel port le paquet doit être envoyé. Ce port est également représenté sur 16 bits, et il identifie l'application cible sur la machine réceptrice.

Champ Longueur

Le champ Longueur indique la longueur totale du segment UDP, exprimée en octets, y compris l'en-tête et les données. La longueur minimale d'un segment UDP est de 8 octets, correspondant à la taille de l'en-tête UDP sans données.

Champ Somme de contrôle (Checksum)

Le champ Somme de contrôle permet de garantir l'intégrité des données transmises. Si ce champ est non nul, il est utilisé pour vérifier que le paquet a été correctement transmis et n'a pas subi d'altérations. Le checksum est calculé sur l'ensemble de l'en-tête UDP et des données, ainsi que sur un pseudo en-tête.

Calcul du Checksum

Le checksum est calculé en suivant ces étapes :

  • On additionne les valeurs des octets de l'en-tête (en excluant le champ du checksum) et des données, deux par deux, sous la forme de mots de 16 bits.
  • On complète à 1 cette somme sur 16 bits.
  • Si le message contient un nombre impair d'octets, un octet vide (rempli de 0) est ajouté pour terminer le calcul.
  • Les bits occupés par le checksum dans l'en-tête sont initialisés à 0 avant le calcul.

Le checksum est calculé en tenant compte d'un pseudo en-tête de 96 bits, qui inclut :

  • Les adresses IP source et destination (32 bits chacune)
  • Le type de protocole (UDP = 17)
  • La longueur du segment UDP

L'ajout de ce pseudo en-tête permet à l'UDP de se protéger contre les erreurs de routage, en incluant les informations essentielles de l'en-tête IP dans le calcul du checksum.

La Pseudo-en-tête UDP et son rôle

Pseudo en-tête udp

Pseudo-en-tête UDP utilisé pour le calcul du checksum

Note : MBZ (Must Be Zero) correspond à un octet réservé qui doit être entièrement composé de zéros.

La longueur spécifiée dans ce pseudo-en-tête est la longueur totale de l'en-tête UDP réel. Les 12 octets supplémentaires du pseudo-en-tête ne sont pas pris en compte dans ce calcul.

La pseudo-en-tête UDP est une structure temporaire utilisée uniquement pour le calcul du checksum. Bien qu'elle ne soit jamais transmise sur le réseau, elle joue un rôle crucial dans la vérification de l'intégrité du paquet UDP.

Fonctionnement

  • Pseudo-en-tête : Avant de calculer le checksum, une pseudo-en-tête de 96 bits est construite. Cette en-tête inclut :
    • Adresse IP source (32 bits)
    • Adresse IP destination (32 bits)
    • MBZ (Must Be Zero)
    • Type de protocole (UDP = 17)
    • Longueur du segment UDP
  • Checksum : Le checksum est calculé à partir de cette pseudo-en-tête, de l'en-tête UDP proprement dit et des données transmises. Cela garantit que des erreurs liées à la couche IP, notamment les erreurs de routage, peuvent être détectées.
  • Transmission du paquet : Une fois le checksum calculé, la pseudo-en-tête est ignorée. Seuls l'en-tête UDP et les données sont envoyés sur le réseau.

En résumé, la pseudo-en-tête UDP n'est ni avant ni après l'en-tête UDP dans le paquet transmis. Elle est simplement une aide temporaire pour calculer le checksum et garantir l'intégrité du paquet.

Calcul du Checksum UDP

Remarque : En cherchant sur Internet, j'ai constaté que l'explication du calcul du checksum UDP n'était pas toujours très claire. Voici donc une interprétation corrigée, avec quelques précisions supplémentaires.

L'interprétation de la RFC, telle que mentionnée ci-dessus, incite à complémenter à 1 avant d'additionner les valeurs. Cependant, d'après les fonctions que j'ai trouvées, on additionne simplement tous les mots de 16 bits, puis le résultat final est complémenté à 1.

Il existe aussi une astuce lorsque la somme dépasse la taille de 16 bits : si c'est le cas, il faut ajouter la retenue à la somme. Si une nouvelle retenue est générée, il faut également l'ajouter. Voici un exemple pour clarifier ce processus :

Valeur hexadécimale
00 30 D3 20 4A 5D D8 D3 85 93 15 18 08 00 45 00 00 34 58 9E 40 00 80 06 00 00 C0 A8 01 65 C0 A8
01 6B C4 6C 00 50 2A B9 35 95 00 00 00 00 80 02 20 00 84 47 00 00 02 04 05 B4 01 03 03 08 01 01
04 02

On fait donc la somme de 0030 + D320 + 4A5D + D8D3 + 8593 + ... , ce qui donne >6B29F. Comme on travaille sur 16 bits mais que la retenue est conservée, on fait B29F + 6, ce qui donne B2A5.

Si cette somme génère à nouveau une retenue, il faut continuer jusqu'à ce que le résultat tienne sur 16 bits. Ensuite, on effectue le complément à 1 de >B2A5, ce qui donne >4D5A, qui correspond bien au checksum attendu.

Exemple de code C pour le calcul du checksum


unsigned int chksum(unsigned char *check, unsigned int size)
{
uint16_t i;
uint16_t val;
uint32_t sum = 0;
uint16_t *ptr = (uint16_t *)check;

for (i = 0; i < (size) / 2; i++) {
        val = *ptr;
        sum += val;
        ptr++; 
    }

if (size & 0x01) {
        val = *ptr & 0xff;
        sum += val;
    }

sum = (sum & 0xffff) + ((sum >> 16) & 0xffff);
if (sum & 0xffff0000) {
        sum++;
    }

return ((uint16_t)(sum & 0xffff));
}


Question sur le pseudo-en-tête UDP

Remarque :

Dans les exemples de requêtes DHCP, je ne vois pas apparaître la partie MBZ, Type, et Longueur UDP> dans le pseudo-en-tête UDP. Par conséquent, je tiendrai compte d'un pseudo-en-tête tronqué, c'est-à-dire seulement l'adresse IP source et l'adresse IP de destination !

la frame DHCP

octet 1
octet 2
octet 3
octet 4
op (1)
htype (1)
hlen (1)
hops (1)
xid (4)
secs (2)
flags (2)
ciaddr (4)
yiaddr (4)
siaddr (4)
giaddr (4)
chaddr (4)
sname (4)
file (128)
options (variable)

Format des messages DHCP

Voici les différents champs d'un message DHCP et leur signification :

  • op : Vaut 1 pour BOOTREQUEST (requête client), 2 pour BOOTREPLY (réponse serveur).
  • htype : Type de l'adresse hardware (ex : adresse MAC). Voir RFC 1340.
  • hlen : Longueur de l'adresse hardware (en octets). Par exemple, 6 pour une adresse MAC.
  • hops : Utilisé par les relais DHCP.
  • xid : Nombre aléatoire choisi par le client pour identifier sa requête.
  • secs : Temps écoulé (en secondes) depuis le début de la requête client.
  • flags : Indicateurs divers.
  • ciaddr : Adresse IP actuelle du client (si déjà attribuée).
  • yiaddr : Adresse IP à attribuer au client (éventuelle).
  • siaddr : Adresse IP du serveur à utiliser pour la prochaine étape.
  • giaddr : Adresse IP du relais (ex : passerelle), lorsque la connexion directe client/serveur n'est pas possible.
  • chaddr : Adresse hardware du client.
  • sname : Nom optionnel du serveur.
  • file : Nom du fichier à utiliser pour le boot.
  • options : Champs réservé pour les options (voir RFC 2132). Dans les premières versions de BOOTP, ce champ était limité (64 octets), mais il n'y a plus de limitation de taille dans DHCP. Un client doit pouvoir recevoir au moins 576 octets et peut demander au serveur de restreindre la taille des messages.

Passage des options

Le passage de paramètres comme le nom de la machine se fait via des options, documentées dans la RFC 2132. Chaque option est identifiée par un numéro. Par exemple :

  • Option 15 : Permet de donner au client le nom de domaine du réseau.

Il est possible d'envoyer plusieurs options dans un même message DHCP. Dans tous les cas, la zone des options doit se terminer par l'option 255 (fin de message).

Format des options

Le format des options est simple et permet d'ajouter diverses informations importantes pour le client DHCP.

Pseudo en-tête udp

DHCP : Gestion des Options et Structure

Dans le protocole DHCP, les options sont essentielles pour transmettre des informations spécifiques au client ou au serveur. Voici une explication détaillée de leur fonctionnement :

Numéro et longueur des options

Le numéro de chaque option est codé sur 1 octet, ce qui limite le nombre total d'options possibles à 256. Le deuxième octet spécifie la longueur du champ de données associé, sans inclure les deux octets utilisés pour coder le numéro et la longueur de l'option.

Options sans données supplémentaires

Certaines options, comme l'option 255 (fin de message), ne comportent pas de données supplémentaires. Dans ce cas, ni champ de longueur ni champ de données ne sont présents.

Exemple d'options DHCP

Les messages DHCP tels que DHCPACK ou DHCPDISCOVER sont eux-mêmes des options. Par exemple, l'option 53 contient un champ de données de longueur 1, indiquant le type de requête (1 pour DHCPDISCOVER, etc.).

Les quatre premiers octets du champ d'options doivent être initialisés avec les valeurs 99, 130, 83, 99 (en décimal), formant ce qu'on appelle le "magic cookie".

Taille des options

Un client DHCP peut spécifier une taille maximale pour le champ d'options à l'aide de l'option 57. Si le serveur ne peut pas inclure toutes les options dans la réponse à cause de cette limite, il peut utiliser les champs sname et file pour envoyer le reste des options. Le client est averti par l'option 52 dans la zone d'options.

Options utilisées dans mon application


Code  Len   Valeur (hex)           Description
------------------------------------------------------------------
0x35  0x01  0x01                   DHCP Message Type 01 = Discover
0x3d  0x07  0x01, Adresse MAC      Client Identifier
0x0C  0x0f  0x7a, 0x66, ...        Hostname (zfphfr 100_ans..)
0x37  0x0f  0x01, 0x03, ...        Parameter Request List

Options spécifiques

  • Option 55 (0x37) : Liste des paramètres demandés (Parameter Request List).
  • Longueur : 7 octets.
  • Paramètres demandés :
    • Masque de sous-réseau (1)
    • Routeur (3)
    • Serveur de nom de domaine (6)
    • Nom de domaine (15)
    • NetBIOS sur TCP/IP Serveur de noms (44)
    • NetBIOS sur TCP/IP Type de nœud (46)
  • Option 255 : Fin du message.

Structure DHCP dans mon code

Voici la structure de données utilisée pour gérer les messages DHCP dans mon application :


typedef struct dhcp {
    uint16_t    head[9];      // Trame Ethernet
    uint16_t    iphead[10];   // Trame IP
    uint8_t     op;           // Type de message DHCP
    uint8_t     htype;        // Type d'adresse hardware
    uint8_t     hlen;         // Longueur de l'adresse hardware
    uint8_t     hops;         // Relais DHCP
    uint32_t    xid;          // Identifiant aléatoire
    uint16_t    secs;         // Temps écoulé
    uint16_t    flags;        // Divers flags
    uint32_t    ciaddr;       // Adresse IP actuelle du client
    uint32_t    yiaddr;       // Adresse IP à attribuer au client
    uint32_t    siaddr;       // Adresse IP du serveur
    uint32_t    giaddr;       // Adresse IP du relais
    uint8_t     chaddr[16];   // Adresse hardware du client
    uint8_t     sname[64];    // Nom du serveur (optionnel)
    uint8_t     file[128];    // Nom du fichier pour le boot
    uint8_t     options[64];  // Champ d'options (RFC 2132)
} dhcp;

Remarques sur les longueurs

Concernant les longueurs :

  • En-tête IP : La longueur totale spécifiée inclut la taille du datagramme entier, mais pas celle de l'en-tête IP elle-même.
  • En-tête UDP : Le champ de longueur UDP représente la taille totale, moins les en-têtes IP et Ethernet, mais incluant l'en-tête UDP.

La frame TCP

TCP (Transmission Control Protocol), ou en français : Protocole de Contrôle de Transmission, est l'un des principaux protocoles de la couche transport dans le modèle TCP/IP. Ce protocole gère les données au niveau des applications et les prépare pour la couche inférieure, c'est-à-dire le protocole IP.
Lorsqu'il reçoit des données à transmettre, le protocole IP les encapsule dans des datagrammes IP, en fixant le champ protocole à la valeur 6, indiquant que le protocole au-dessus est TCP.

TCP est un protocole orienté connexion, ce qui signifie qu'il permet à deux machines en communication de suivre l'état de la transmission et d'assurer la fiabilité des échanges. Voici les principales caractéristiques de TCP :

  • Remise en ordre : TCP réorganise les datagrammes reçus du protocole IP pour garantir une séquence correcte des données.
  • Contrôle du flux : Il ajuste le flot de données afin d'éviter la congestion du réseau.
  • Segmentation : TCP segmente les données en blocs de taille variable avant de les transmettre à IP.
  • Multiplexage : Il permet à plusieurs flux de données provenant de différentes sources (comme des applications) de circuler simultanément sur une même connexion.
  • Gestion de la connexion : TCP gère l'initialisation et la fin de la connexion de manière "courtoise", garantissant ainsi un bon déroulement des échanges entre les machines.

la frame TCP

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
27
29
30
31
Port source
Port destination
Numéro d'ordre
Numéro d'accusé de réception
Décalage
Réserve
URG
ACK
PSH
RST
SYN
FIN
Fenêtre
Somme de contrôle
Pointeur d'urgence
Options
Remplissage
Données

Signification des différents champs TCP

Voici une description des principaux champs utilisés dans une trame TCP :

  • Port Source (16 bits) : Port relatif à l'application en cours sur la machine source.
  • Port Destination (16 bits) : Port relatif à l'application en cours sur la machine de destination.
  • Numéro d'ordre (32 bits) : Ce numéro représente la position du premier octet de données dans le segment. Si le drapeau SYN est activé (1), il correspond au numéro de séquence initial (ISN).
  • Numéro d'accusé de réception (32 bits) : Ce numéro indique le prochain segment attendu, pas celui du dernier segment reçu.
  • Décalage des données (4 bits) : Il identifie le début des données dans le paquet. Ce champ est crucial lorsque des options TCP sont présentes, car il permet de repérer leur fin. En général, le décalage vaut 05 s'il n'y a pas d'options.
  • Réservé (6 bits) : Ce champ est inutilisé pour le moment, mais il est prévu pour des usages futurs.
  • Drapeaux (flags) (6 bits) : Ils fournissent des informations sur le traitement du paquet :
    • URG : Indique que le paquet contient des données urgentes.
    • ACK : Ce paquet est un accusé de réception.
    • PSH (PUSH) : Demande au destinataire de traiter les données immédiatement.
    • RST : Réinitialise la connexion.
    • SYN : Requête d'établissement de connexion.
    • FIN : Terminaison de la connexion.
  • Fenêtre (16 bits) : Ce champ spécifie le nombre d'octets que le récepteur est prêt à recevoir sans envoi d'accusé de réception.
  • Somme de contrôle (Checksum ou CRC) : La somme de contrôle vérifie l'intégrité de l'en-tête TCP et inclut une pseudo-en-tête de 96 bits avec les adresses IP source et destination, le type de protocole et la longueur du message TCP.

    Pseudo en-tête tcp
  • Pointeur d'urgence (16 bits) : Indique le numéro d'ordre à partir duquel les données deviennent urgentes.
  • Options (Taille variable) : Ce champ permet de transmettre diverses options TCP. Sa taille est variable.
  • Remplissage : L'espace restant après les options est rempli de zéros pour garantir que l'en-tête soit un multiple de 32 bits.

Note : Lors du calcul du checksum, on ajoute la pseudo-en-tête de 12 octets (adresses IP source et destination, type de protocole et longueur du message TCP). Le checksum couvre ainsi l'en-tête TCP et les données, à l'exclusion des 12 octets de la pseudo-en-tête.

Établissement d'une connexion TCP

Pour établir une connexion entre deux machines, un processus de communication est utilisé, basé sur l'émission de données et un accusé de réception. Ce processus repose sur un numéro d'ordre, appelé généralement numéro de séquence, que les deux machines doivent synchroniser pour permettre une communication fiable. Voici les étapes principales :

  1. Les ports TCP des deux machines doivent être ouverts.
  2. Le serveur est en mode ouverture passive, c'est-à-dire qu'il attend une demande de connexion.
  3. Le client effectue une ouverture active, c'est-à-dire qu'il envoie une requête de connexion au serveur.

Pour synchroniser leurs séquences, les deux machines utilisent une procédure appelée three-way handshake (poignée de main en trois temps). Ce processus en trois étapes est également utilisé lors de la clôture de la session.

Les trois étapes du Three-Way Handshake

  1. Étape 1 : Le client envoie un segment avec le drapeau SYN activé (1), ce qui signifie qu'il souhaite synchroniser les séquences. Ce segment contient un numéro d'ordre N, appelé numéro d'ordre initial du client.
  2. Étape 2 : Le serveur reçoit le segment, puis renvoie un accusé de réception avec le drapeau ACK activé (1) et le drapeau SYN toujours à 1 pour signaler la synchronisation. Le numéro d'ordre envoyé par le serveur correspond au numéro d'ordre initial du client, incrémenté de 1.
  3. Étape 3 : Le client renvoie à son tour un accusé de réception avec le drapeau ACK activé et le drapeau SYN désactivé (0), ce qui signifie que la synchronisation est terminée. Le numéro d'ordre du client est incrémenté, et le numéro d'accusé de réception représente le numéro d'ordre initial du serveur, également incrémenté de 1.

Note : Une fois cette séquence de trois échanges terminée, les deux machines sont synchronisées et prêtes à communiquer efficacement.

Ouverture Active et Passive d'une Connexion TCP

Bien que deux systèmes puissent établir une connexion simultanément, dans la majorité des cas, l'un des systèmes ouvre une socket (point d'accès à une connexion TCP) et attend de manière passive les demandes de connexion de l'autre système. Ce processus est appelé ouverture passive, et il est typiquement utilisé du côté serveur de la connexion.

De l'autre côté, le client effectue une ouverture active, qui se déroule en trois étapes :

  1. Le client envoie un segment SYN au serveur.
  2. Le serveur répond par un segment SYN/ACK.
  3. Le client confirme avec un segment ACK.

Synchronisation des Numéros de Séquence

Lors de cet échange initial, les numéros de séquence des deux systèmes sont synchronisés comme suit :

  1. Le client envoie son numéro d'ordre initial (par exemple, x) dans le champ Numéro d'ordre, et il active le drapeau SYN dans le champ FLAGS.
  2. Le serveur utilise son propre numéro d'ordre initial (par exemple, y), il active les drapeaux SYN/ACK dans le champ FLAGS et place le numéro d'ordre du client augmenté de 1 (x+1) dans le champ Numéro d'accusé de réception.
  3. Le client confirme en envoyant un segment ACK avec un Numéro d'ordre de x+1 et un Numéro d'accusé de réception correspondant au numéro de séquence du serveur augmenté de 1 (y+1).

Note : Cet échange permet de synchroniser les numéros de séquence des deux parties, garantissant une communication ordonnée et fiable entre le client et le serveur.

Le client envoie un segment SYN au serveur.

00 30 d3 20 4a 5d d8 d3 85 93 15 18 08 00 45 00
00 34 58 9e 40 00 80 06 00 00 c0 a8 01 65 c0 a8
01 6b c4 6c 00 50 2a b9 35 95 00 00 00 00 80 02
20 00 84 47 00 00 02 04 05 b4 01 03 03 08 01 01
04 02

En-tête Ethernet (14 octets)

00 30 d3 20 4a 5d : Adresse MAC de destination
d8 d3 85 93 15 18 : Adresse MAC source
08 00 : Type de protocole (Ethernet type) : 0x0800, ce qui signifie que c'est une trame IP (Internet Protocol).

En-tête IP (20 octets suivants)

45 : Version du protocole (4) et longueur de l'en-tête IP (5 x 4 = 20 octets)
00 : Type de service (ToS)
00 34 : Longueur totale du paquet IP (52 octets)
58 9e : Identifiant de fragment
40 00 : Flags et décalage de fragment
80 : TTL (Time to Live) = 128
06 : Protocole = 6 (TCP)
c0 a8 01 65 : Adresse IP source (192.168.1.101)
c0 a8 01 6b : Adresse IP destination (192.168.1.107)
c4 6c : Port source.
00 50 : Port destination
2a b9 35 95 : Numéro d'ordre
00 00 00 00 : Numéro d'accusé de réception
80 02 : Décalage + Flags

Note : On remarque que le numéro d'accusé de réception est à zéro et que le drapeau SYN est activé (8002).

Réponse du serveur S A

00 30 d3 20 4a 5d d8 d3 85 93 15 18 08 00 45 00
00 34 58 9e 40 00 80 06 00 00 c0 a8 01 65 c0 a8
01 65 00 50 c4 6c 00 60 0d 00 2a b9 35 96 80 12
83 2c 35 4f 00 00 02 04 05 b4 01 03 03 00 01 01
04 02
En-tête Ethernet (14 octets)
En-tête IP (20 octets suivants)
00 50 : Port source.
c4 6c : Port destination
00 60 0d 00 : Numéro d'ordre
2a b9 35 96 : Numéro d'accusé de réception
80 12 : Décalage + Flags

Note : La réponse du serveur implique naturellement un échange entre les deux ports. Le numéro de séquence du client devient le numéro d'accusé de réception du serveur, auquel on ajoute 1. Le serveur attribue ensuite son propre numéro de séquence. Il est important de noter que les indicateurs SYN et ACK sont actifs dans cette phase.

Le client confirme par un segment ACK.

00 30 d3 20 4a 5d d8 d3 85 93 15 18 08 00 45 00
00 34 58 9e 40 00 80 06 00 00 c0 a8 01 65 c0 a8
01 6b c4 6c 00 50 2a b9 35 96 00 60 0d 01 50 10
01 00 84 3b 00 00
En-tête Ethernet (14 octets)
En-tête IP (20 octets suivants)
c4 6c : Port source.
00 50 : Port destination
2a b9 35 96 : Numéro d'ordre
00 60 0d 00 : Numéro d'accusé de réception
50 10 : Décalage + Flags

Note : Comme dans le premier cas, les deux ports sont à nouveau inversés. Le numéro d'accusé de réception du serveur devient le numéro de séquence du client, et le numéro d'accusé de réception du client devient le numéro de séquence du serveur + 1. Concernant les indicateurs, seul le flag ACK reste actif.

La liaison entre le client et le serveur est alors établie (socket). Les quatre premiers bits du champ "Décalage + Flags" permettent d'indiquer si le champ des options est utilisé. Dans le dernier exemple, la valeur 5 indique qu'il n'est pas utilisé. Une valeur supérieure à 5 indique la présence d'options. Dans l'exemple précédent, le nombre 8 est placé dans le champ Décalage (Offset), ce qui implique la présence de 12 octets d'options.

Fenêtre (WINDOW)

01 00 :

Le flux TCP est contrôlé de part et d'autre pour les octets compris dans une zone bien délimitée et nommée "fenêtre". La taille de celle-ci est définie par un entier non signé de 16 bits, limitant théoriquement sa taille à 65 535 octets (ce n'est pas tout à fait exact, voir plus loin l'option wscale). Chaque partie annonce ainsi la taille de son buffer de réception. Par construction, l'émetteur n'envoie pas plus de données que le récepteur ne peut en accepter.

CHECKSUM

84 3b :

Le CHECKSUM est un calcul qui porte sur la totalité du segment, en-tête et données.

Adresse d'urgence

00 00 :

Le champ options

Après l’adresse d’urgence, il peut y avoir une série d’options :

02 04 05 b4  01 03 03 00  01 01 04 02

Dans l'exemple ci-dessus, il y a plusieurs options :

  • L'option 02 (Maximum Segment Size) a une longueur totale de 4 octets, avec une valeur de 0x05b4 (1460 en décimal), qui définit la taille maximale des segments.
  • L'option 01 correspond à un octet No-Operation (NOP), utilisé comme bourrage pour garantir un alignement correct.
  • L'option 03 (Window Scale) a une longueur de 3 octets, avec une valeur de 0, ce qui signifie qu'il n'y a pas d'échelle appliquée à la fenêtre.
  • Encore un octet 01 NOP est ajouté pour le bourrage.
  • L'option 04 (Selective Acknowledgment Permitted) a une longueur de 2 octets, permettant l'accusé de réception sélectif.

La liste complète des options se trouve dans la RFC xxxx.