Aperçu des réseaux informatiques

1   Les réseaux locaux

1.1   Construire un réseau local

1.1.1   Les types de relais classiques

1.1.2   Démocratisation des commutateurs

1.1.3   Le Spanning Tree

1.1.4   Les réseaux virtuels

1.2   Configuration IP (théorie)

1.2.1   Hypothése de travail

1.2.2   Les protocoles d'Internet

1.2.3   L'adressage IPv4

1.2.4   Exemple d'adresse IPv4

1.2.5   L'adressage IPv6

1.2.6   Exemple d'adresse IPv6

1.2.7   Résolution d'adresse (DHCP)

1.2.8   Paquet DHCP


1.2.9   Autoconfiguration IPv6

1.3   La communication dans les réseaux locaux

1.3.1   Principe de la résolution d'adresse

1.3.2   Résolution d'adresse Ethernet en IPv4

1.3.3   Découverte de voisin en IPv6

1.4   Le routage entre réseaux locaux

1.4.1   Les classes d'adresses IP

1.4.2   Notion de sous-réseaux

1.4.3   Principes du routage IP

Communication entre machines non directement connectées

1.4.4   Exemple de table de routage

Table de routage de soleil.uvsq.fr
réseau cible routeur
193.51.24.0 193.51.24.1
193.51.25.0 193.51.24.2
193.51.38.0 193.51.24.12

1.4.5   Exemple de route par défaut

Table de routage de soleil.uvsq.fr
réseau cible routeur
193.51.24.0 193.51.24.1
193.51.25.0 193.51.24.2
193.51.38.0 193.51.24.12
défaut 193.51.24.30

1.4.6   Principe de la table de routage

1.4.7   Introduction d'une stratégie de routage

1.4.8   Exemple de routage de sous-réseaux

Table de routage de soleil.uvsq.fr
réseau cible masque réseau routeur
193.51.24.0 255.255.255.224 193.51.24.1
193.51.24.64 255.255.255.224 193.51.24.30
193.51.25.0 255.255.255.0 193.51.24.2
193.51.38.0 255.255.255.0 193.51.24.12
0.0.0.0 0.0.0.0 193.51.24.30

1.4.9   Plan du réseau de l'UVSQ

1.5   Configuration IP (station)

1.5.1   Configuration d'interface sous Unix

1.5.2   Résolution des noms DNS

1.5.3   Mise à jour du routage sous Unix

1.5.4   Configuration réseau sous Windows XP

1.5.5   Configuration automatique d'interface

1.6   Configuration IP (cisco)

1.6.1   Exemples de configurations matérielles

1.6.2   Principe de configuration

1.6.3   Configuration basique de l'IOS

1.6.4   Configuration de VLAN

1.6.5   Régles de routage

1.6.6   Table de routage IP

2   Protocoles TCP/IP

2.1   Protocole réseau IPv4

2.1.1   Format des paquets IPv4

2.1.2   Options IPv4

2.1.3   Fragmentation des paquets

2.2   Protocole de contrôle ICMPv4

2.2.1   Format des paquets ICMPv4

2.2.2   Gestion de congestion

2.2.3   Gestion d'erreurs de routage

2.2.4   Utilitaires basés sur ICMP

2.3   Protocole réseau IPv6

2.3.1   Format des paquets IPv6

2.3.2   Format des entêtes IPv6

2.3.3   Les extensions IPv6

2.3.4   Les protocoles IPv6

2.4   Protocole de contrôle ICMPv6

2.4.1   Le format de la trame

2.4.2   Les codes utilisés

2.5   Protocole de transport UDP

2.5.1   Adressage UDP

2.5.2   Les caractéristiques d'UDP

UDP c'est IP offert aux utilisateurs :
(+) simplicité
(+) rapidité
(+) robustesse
(-) non fiable
(-) messages non ordonnés
(-) programmation complexe

2.5.3   Format des datagrammes


2.5.4   Exemple de datagramme


2.6   Protocole de transport TCP

2.6.1   Adressage TCP

2.6.2   Les caractéristiques de TCP

TCP est une couche transport orientée connexion :

2.6.3   Format des datagrammes


2.6.4   Options TCP

2.6.5   Fiabilité

2.6.6   Adaptabilité

2.6.7   Quelques types d'attaques

2.6.8   Exemple de datagramme

3   Programmation réseau

3.1   Généralité sur les sockets

3.1.1   Présentation

3.1.2   Caractéristiques des sockets

3.1.3   Les familles de sockets

3.1.4   Les modes de connexion

3.1.5   Les adressages

3.1.6   Les adressages

3.2   Primitives communes

3.2.1   Création d'une socket

3.2.2   Contrôle d'une socket

3.3   Primitives pour le mode connecté

3.3.1   Schéma de principe


3.3.2   Primitives pour le serveur

3.3.3   Primitive pour le client

3.3.4   Exemple de serveur

3.3.5   Exemple de client

3.4   Primitives pour le mode non connecté

3.4.1   Schéma de principe


3.4.2   Primitives de communication

3.4.3   Exemple de serveur

int main(int argc,char *argv[])
{
int s;     /* Descripteur de la SOCKET */
struct sockaddr_in6 adresseServeur; /* Structure adresse du serveur */
socklen_t taille=sizeof addresseServeur;
int statut;

/* Lecture des arguments de la commande */
analyseArguments(argc,argv);

/* Creation de la SOCKET d'ecoute du serveur */
s=socket(PF_INET6,SOCK_DGRAM,0);
if(s<0) {perror("socket"); exit(-1);}

/* Preparation de la structure adresse du serveur */
adresseServeur.sin6_family=AF_INET6;
adresseServeur.sin6_addr=in6addr_any;
adresseServeur.sin6_port=htons(SERVEUR_PORT);
adresseServeur.sin6_flowinfo=0;
adresseServeur.sin6_scope_id=0;

/* Installation du serveur a la bonne adresse */
statut=bind(s,(struct sockaddr *)&adresseServeur,taille);
if(statut<0) {perror("bind"); exit(-1);}   

/* Attente de la connexion d'un client puis dialogue avec ce client */
while(1){
    struct sockaddr_in6 adresseClient; /* Structure adresse du client */
    socklen_t taille=sizeof adresseClient; /* Taille de cette adresse */
    char tampon1[MAX_TAMPON];
    char tampon2[MAX_TAMPON];
    int nboctets;

    nboctets=recvfrom(s,tampon1,MAX_TAMPON-1,0,
                      (struct sockaddr *)&adresseClient,
                      &taille);
    tampon1[nboctets]='\0';
    sprintf(tampon2,"%s%s",PREFIXE,tampon1);
    sendto(s,tampon2,strlen(tampon2),0,
           (struct sockaddr *)&adresseClient,taille);
    }
}

3.4.4   Exemple de client

int main(int argc,char *argv[])
{
int s;    /* Descripteur de SOCKET */
struct sockaddr_in6 adresse; /* Adresse de la SOCKET du serveur */
int statut;   /* Stocke le statut des commandes */

/* Analyse des arguments */
analyseArguments(argc,argv);

/* Creation de la SOCKET du client */
s=socket(PF_INET6,SOCK_DGRAM,0);
if(s<0){perror("socket"); exit(-1);}

/* Preparation de la structure adresse du serveur */
adresse.sin6_family=AF_INET6;
if(nomVersAdresse(machine,(void *)&adresse)<0){
  fprintf(stderr,"Impossible de trouver l'adresse IP du serveur !\n");
  exit(-1);
  }
adresse.sin6_port=htons(port);
adresse.sin6_flowinfo=0;
adresse.sin6_scope_id=0;

/* Dialogue avec le serveur */
{ char tampon[MAX_TAMPON];
  int taille;

  fgets(tampon,MAX_TAMPON,stdin);
  sendto(s,tampon,strlen(tampon),0,(struct sockaddr *)&adresse,sizeof adresse);
  taille=recvfrom(s,tampon,MAX_TAMPON,0,NULL,NULL);
  fputs(tampon,stdout);
  }

/* Fermeture de la SOCKET de dialogue */
close(s);
exit(0);
}

3.5   Fonctions de bibliothèque

3.5.1   Obtention des adresses IP (classique)

3.5.2   Obtention des adresses IP (moderne)

3.5.3   Trouver l'adresse de socket

3.5.4   Numéros de ports

3.5.5   Numéros de protocoles

3.5.6   Exemples de résolution

3.6   Le super-serveur Unix

3.6.1   Définition d'un démon

3.6.2   Le super-serveur d'Unix

3.6.3   Schéma de fonctionnement

3.6.4   Exemples de serveurs

A   Annexes

A.1   Démonstrations

A.1.1   Construire un réseau local

A.1.2   Configuration IP de base

A.1.3   La communication dans les réseaux locaux

A.1.4   Le routage entre réseaux locaux

A.1.5   Protocoles TCP/IP

A.1.6   Programmation réseau

A.2   Programmation en Bourne Shell

A.2.1   Serveur Web en Bourne Shell

#!/bin/sh
#
# Exemple de serveur HTTP en shell
#

#
# Quelques constantes
#

NC=/usr/bin/nc
PORT=8080
TTY_PREFIXE=/dev/tty
PTY_PREFIXE=/dev/pty
TTY_NUMERO=q3
REPERTOIRE=${HOME}/Scripts/Web

#
# Boucle principale
# (ecoute sur le port, traitement de la requete, envoi du fichier)
#

while true ; do
    #
    # On ecoute sur le cote maitre du terminal virtuel
    #
    ${NC} -l -p ${PORT} 4<>${PTY_PREFIXE}${TTY_NUMERO} >&4 2>&4 <&4 &
    PID=$!
    #
    # On lance un sous-shell sur le cote esclave
    #
    (
    stty -echo igncr
    #
    # Lecture de la requete HTTP
    #
    read requete
    #
    # Lecture des entetes (mises a la poubelle)
    #
    while read line ; do 
 if [ -z "${line}" ] ; then break ; fi
    done
    #
    # Analyse de la requete
    #
    set -- ${requete}
    commande=$1 ; file=$2 ; protocole=$3
    #
    # Reponse a la requete
    #
    if [ "${commande}" != "GET" -o ! -f "${REPERTOIRE}/${file}" ] ; then
 echo "${protocole} 400 erreur"
 echo
 echo "Erreur !!"
    else
 echo "${protocole} 200 OK"
 echo "Content-type: text/html"
 echo
 cat "${REPERTOIRE}/${file}"
    fi
    ) 4<>${TTY_PREFIXE}${TTY_NUMERO} >&4 2>&4 <&4
    #
    # On stoppe l'ecoute
    #
    kill ${PID}
    sleep 2
done

A.2.2   Exemple de page Web

<html>
 <head>
  <title>Serveur web de demonstration</title>
 </head>

  Voici deux p't liens :

  <dl>
    <dt>
      <a href="/fichier1">Premier fichier</a>
    <dt>
      <a href="/fichier2">Second fichier</a>
  </dl>
  <p align=right>
    Serveur Script
  </p>
 </body>
</html>

A.3   Sources pour RPC

A.3.1   Makefile pour le serveur et le client RPC

#
# Generation d'un client et d'un serveur RPC de demonstration
# (simple addition et soustraction d'entiers).
#

# Quelques constantes liees au projet

CLIENT_OBJS=calc_client.o calc_clnt.o calc_xdr.o
SERVER_OBJS=calc_server.o calc_svc.o calc_xdr.o

# Message pour la marche a suivre

all:
 @echo -e "\
Tapez d'abord make generate pour obtenir le fichier d'inclusion .h et\n\
les fichiers C. Modifiez les programmes calc_client.c et calc_server.c\n\
puis lancez la compilation par make compile."

# Generation des fichiers C par rpcgen

generate: calc.x
 rpcgen -a -C $^ 

# Copie des fichiers modifies a la main sur leurs modeles

copy:
 cp calc_client_modified.c calc_client.c
 cp calc_server_modified.c calc_server.c

# Compilation des programmes C

compile: client server

client: ${CLIENT_OBJS} calc.h
 gcc -o client ${CLIENT_OBJS}

server: ${SERVER_OBJS} calc.h
 gcc -o server ${SERVER_OBJS}

# Regle de nettoyage

clean: 
 rm -f client server *.o calc.h calc_svc.c calc_clnt.c calc_xdr.c
 rm -f calc_client.c calc_server.c

A.3.2   Définition des RPC

/********************************************************************/
/** Fichier de definition de RPC d'addition et de soustraction     **/
/********************************************************************/

/** Quelques constantes **/

#define PROGRAM_NUMBER 19992000
#define VERSION_NUMBER 1

/** Structures des parametres des procedures **/

struct operandes {
 int x;
 int y;
};

/** Definition des RPC **/

program CALC_PROG {
   version CALC_VERSION {
     int ADD(operandes) = 1;
     int SUB(operandes) = 2;
   } = VERSION_NUMBER;
} = PROGRAM_NUMBER;

A.3.3   Fichier C du serveur

/*
 * This is sample code generated by rpcgen.
 * These are only templates and you can use them
 * as a guideline for developing your own functions.
 */

#include "calc.h"

int * 
add_1_svc(operandes *argp, struct svc_req *rqstp)
{

 static int  result;

/* AJOUT DE CODE : implantation de l'addition */
 result=argp->x+argp->y;
/* FIN D'AJOUT DE CODE */

 return(&result);
}

int * 
sub_1_svc(operandes *argp, struct svc_req *rqstp)
{

 static int  result;

/* AJOUT DE CODE : implantation de la soustraction */
 result=argp->x-argp->y;
/* FIN D'AJOUT DE CODE */

 return(&result);
}

A.3.4   Fichier C du client

/*
 * This is sample code generated by rpcgen.
 * These are only templates and you can use them
 * as a guideline for developing your own functions.
 */

#include "calc.h"


void
/** MODIFICATION DE CODE : ajout des operandes en parametre **/
calc_prog_1( char* host, int x, int y )
/** FIN DE MODIFICATION DE CODE **/
{
 CLIENT *clnt;
 int  *result_1;
 operandes  add_1_arg;
 int  *result_2;
 operandes  sub_1_arg;
 clnt = clnt_create(host, CALC_PROG, CALC_VERSION, "udp");
 if (clnt == NULL) {
  clnt_pcreateerror(host);
  exit(1);
 }
/** AJOUT DE CODE : initialisation du parametre de la RPC **/
 add_1_arg.x = x ; add_1_arg.y = y ; 
/** FIN D'AJOUT DE CODE **/
 result_1 = add_1(&add_1_arg, clnt);
 if (result_1 == NULL) {
  clnt_perror(clnt, "call failed:");
 }
/** AJOUT DE CODE : affichage du resultat de la RPC **/
 printf("%d + %d = %d\n",add_1_arg.x,add_1_arg.y,*result_1);
/** FIN D'AJOUT DE CODE **/
/** AJOUT DE CODE : initialisation du parametre de la RPC **/
 sub_1_arg.x = x ; sub_1_arg.y = y ; 
/** FIN D'AJOUT DE CODE **/
 result_2 = sub_1(&sub_1_arg, clnt);
 if (result_2 == NULL) {
  clnt_perror(clnt, "call failed:");
 }
/** AJOUT DE CODE : affichage du resultat de la RPC **/
 printf("%d - %d = %d\n",sub_1_arg.x,sub_1_arg.y,*result_2);
/** FIN D'AJOUT DE CODE **/
 clnt_destroy( clnt );
}


main( int argc, char* argv[] )
{
 char *host;
/** AJOUT DE CODE : variables pour les operandes **/
 int x,y;
/** FIN D'AJOUT DE CODE **/

/** MODIFICATION DE CODE : nouvelle syntaxe **/
 if(argc < 4) {
  printf("usage: %s server_host op1 op2\n", argv[0]);
/** FIN DE MODIFICATION DE CODE **/
  exit(1);
 }
 host = argv[1];
/** MODIFICATION DE CODE : recuperation et utilisation des operandes **/
 x = atoi(argv[2]);
 y = atoi(argv[3]);
 calc_prog_1( host, x, y );
/** FIN DE MODIFICATION DE CODE **/
}

This document was translated from LATEX by HEVEA.