Author: Christian.Queinnec@lip6.fr

## Réseau Internet

Internet est un réseau de réseaux (Inter Networking). L'interconnexion est hiérarchisée en domaines, sous-domaines, etc. jusqu'aux interfaces. Une interface est l'équipement matériel d'une machine permettant sa connexion (typiquement : une carte ethernet). Certaines machines peuvent posséder plusieurs interfaces. Chaque interface possède une adresse IP unique qui respecte, en général, la hiérarchie d'interconnexion. L'acheminement, ou routage des messages peut ainsi être lui-même hiérarchisé : de domaine à domaine ; puis de domaine à sous domaines, etc. jusqu'à l'interface ultime. Outre l'adresse de leur(s) interface(s), les machines ont la plupart du temps un nom, de même que les domaines, sous-domaines, etc.
Certaines machines ont dans ce méta réseau un rôle particulier :

les passerelles
  opèrent le passage d'un réseau à un autre ;
les routeurs
  connaissent, en partie, la topologie d'Internet et opèrent l'acheminement des données ;
les serveurs de noms
  connaissent la correspondance entre noms de machines et adresses réseau.

L'intérêt d'Internet (i.e. : du protocole IP) est que le réseau de réseaux devient une seule entité. C'est pourquoi on peut parler du réseau Internet. Deux machines quelconques connectées sur Internet peuvent communiquer. Différents types de machines et de systèmes cohabitent sur Internet. Elles parlent toutes les protocoles IP et, majoritairement, ses surcouches UDP et TCP.
Les différents protocoles et services du réseau Internet sont décrits dans les RFC (Request For Comments), autrement dit <<appels à commentaires>>, que l'on trouve sur le site miroir de Jussieu :

### Lien

ftp://ftp.lip6.fr/pub/rfc

#### Protocoles et services Internet

L'unité de transfert du protocole IP est le datagramme ou paquet IP. C'est un protocole non fiable : il n'assure ni le bon ordre, ni le bon port, ni la non duplication des datagrammes transmis. Il traite juste le routage correct des paquets et la signalisation d'erreurs lorsqu'un datagramme n'a pu arriver à destination. Un datagramme contient un en-tête et des données. Dans l'en-tête apparaissent les adresses du destinataire et de l'expéditeur du datagramme. Les adresses sont codées sur 32 bits dans la version courante du protocole : IPv4. Ces 32 bits sont scindés en 4 champs comportant une valeur comprise entre 0 et 255. On note ces adresses sous forme de quatre entiers séparés par un point comme par exemple : `132.227.60.30`.
Le protocole IP connaît à l'heure actuelle une réforme importante rendue nécessaire par l'épuisement de l'espace d'adressage et la complexité croissante des problèmes de routage dûs à l'expansion d'Internet. La nouvelle version du protocole IP est IPv6 dont on peut trouver une présentation dans [Ciz98].
Au dessus d'IP, deux protocoles permettent des transmissions de plus haut niveau : UDP (User Datagram Protocol) et TCP (Transfert Control Protocol). Ces deux protocoles qui utilisent IP pour la communication entre machines permettent en plus la communication entre des applications (ou programmes) tournant sur ces machines. Ils s'occupent de la transmission correcte de l'information indépendamment du contenu. L'identification des applications sur une machine est faite en utilisant un numéro de port.
UDP est un protocole sans connexion et non fiable, il est aux applications ce qu'IP est aux interfaces. TCP est un protocole orienté connexion et fiable : il gère l'acquittement, la retransmission et l'ordonnancement des paquets. De plus, il est capable d'optimiser la transmission par une technique de fenêtrage.
Les services standard (applications) d'Internet utilisent le plus souvent le modèle client-serveur. Le serveur gère les requêtes des clients à qui il offre un service spécifique. Il y a une asymétrie entre le client et le serveur. Ces services implantent des protocoles de plus haut niveau tenant compte cette fois du contenu de l'information transmise. Parmi les services standard, on peut citer :

- FTP (File Transfert Protocol)
- TELNET (Terminal Transfert Protocol)
- SMTP (Simple Mail Transfert Protocol)
- HTTP (Hyper Text Transfert Protocol)

D'autres services utilisent ce modèle client-serveur :

- NFS (Network File System)
- X-Windows
- les services Unix : rlogin, rwho ...

La communication entre applications s'effectue via des prises de communication. Elles permettent la communication entre des processus ne résidant pas forcément sur une même machine. Différents processus peuvent lire et écrire dans cette voie de communication.

### Module `Unix` et adressage IP

Le module `Unix` fournit le type abstrait inet_addr représentant les adresses Internet ainsi que deux fonctions de conversion entre représentation interne des adresses et chaînes de caractères :

    # Unix.inet_addr_of_string ;;
    - : string -> Unix.inet_addr = <fun>
    # Unix.string_of_inet_addr ;;
    - : Unix.inet_addr -> string = <fun>

Dans les applications, les adresses Internet et les numéros de port de services (ou numéros de services) sont souvent remplacés par des noms. La correspondance entre noms et adresse ou numéro est gérée à partir de bases de données. Le module `Unix` fournit des fonctions de requête sur ces bases et les types de données permettant le stockage des informations obtenues. Nous les décrivons brièvement ci-dessous.

##### Base d'adresses

La base d'adresses (hosts database) contient l'association entre nom(s) de machine et adresse(s) d'interface(s). La structure des entrées de la base d'adresses est représentée par :

    # type host_entry =
       { h_name : string;
         h_aliases : string array;
         h_addrtype : socket_domain;
         h_addr_list : inet_addr array } ;;

Les deux premiers champs contiennent le nom de la machine et ses alias, le troisième, le type d'adresse (voir page ??) et le dernier, la liste des adresses des interfaces de la machine.
On obtient le nom de sa machine par la fonction :

    # Unix.gethostname ;;
    - : unit -> string = <fun>
    # let my_name = Unix.gethostname() ;;
    val my_name : string = "zinc.pps.jussieu.fr"

Les fonctions d'interrogation de la base d'adresses nécessitent en entrée soit le nom, soit l'adresse de la machine.

    # Unix.gethostbyname ;;
    - : string -> Unix.host_entry = <fun>
    # Unix.gethostbyaddr ;;
    - : Unix.inet_addr -> Unix.host_entry = <fun>
    # let my_entrie_byname = Unix.gethostbyname my_name ;;
    val my_entrie_byname : Unix.host_entry =
      {Unix.h_name="zinc.pps.jussieu.fr"; Unix.h_aliases=[|"zinc"; "zn"|];
       Unix.h_addrtype=Unix.PF_INET; Unix.h_addr_list=[|<abstr>|]}
    # let my_addr = my_entrie_byname.Unix.h_addr_list.(0) ;;
    val my_addr : Unix.inet_addr = <abstr>

    # let my_entrie_byaddr = Unix.gethostbyaddr my_addr ;;
    val my_entrie_byaddr : Unix.host_entry =
      {Unix.h_name="zinc.pps.jussieu.fr"; Unix.h_aliases=[|"zinc"; "zn"|];
       Unix.h_addrtype=Unix.PF_INET; Unix.h_addr_list=[|<abstr>|]}

    # let my_full_name = my_entrie_byaddr.Unix.h_name ;;
    val my_full_name : string = "zinc.pps.jussieu.fr"

Ces fonctions déclenchent l'exception `Not_found` en cas d'échec de la requête.

##### Base de services

La base de services contient la correspondance entre noms de service et numéros de port. La plupart des services d'Internet sont standardisés. La structure des entrées de la base de services est :

    # type service_entry =
       { s_name : string;
         s_aliases : string array;
         s_port : int;
         s_proto : string } ;;

Les premiers champs sont le nom du service et ses éventuels alias, le troisième contient le numéro de port du service et le dernier, le nom du protocole utilisé.
Un service est en fait caractérisé par son numéro de port et son protocole. Les fonctions d'interrogation sont :

    # Unix.getservbyname ;;
    - : string -> string -> Unix.service_entry = <fun>
    # Unix.getservbyport ;;
    - : int -> string -> Unix.service_entry = <fun>
    # Unix.getservbyport 80 "tcp" ;;
    - : Unix.service_entry =
    {Unix.s_name="http"; Unix.s_aliases=[||]; Unix.s_port=80; Unix.s_proto="tcp"}
    # Unix.getservbyname "ftp" "tcp" ;;
    - : Unix.service_entry =
    {Unix.s_name="ftp"; Unix.s_aliases=[||]; Unix.s_port=21; Unix.s_proto="tcp"}

Ces fonctions déclenchent l'exception `Not_found` si elles ne trouvent pas le service demandé.