IP(7)

NOM
ip - Implémentation Linux du protocole IPv4

SYNOPSIS
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* super ensemble du précédent */

tcp_socket = socket(PF_INET, SOCK_STREAM, 0);
udp_socket = socket(PF_INET, SOCK_DGRAM, 0);
raw_socket = socket(PF_INET, SOCK_RAW, protocol);

DESCRIPTION
Linux implémente le Protocole Internet (IP) version 4, décrit dans les RFC 791 et RFC 1122. ip contient une implémentation du multicasting niveau 2 conforme à la RFC 1112. Elle contient aussi un routeur IP comprenant un filtre de paquets.

L'interface de programmation est compatible avec les sockets BSD. Pour plus de renseignements sur les sockets, voir socket(7).

Une socket IP est créée par la fonction socket(2) invoquée sous la forme socket(PF_INET, type_socket, protocole). les types valides des sockets sont SOCK_STREAM pour ouvrir une socket tcp(7), SOCK_DGRAM pour ouvrir une socket udp(7), ou SOCK_RAW pour ouvrir une socket raw(7) permettant d'accéder directement au protocole IP. Le protocole indiqué est celui inscrit dans les entêtes IP émis ou reçus. Les seules valeurs valides pour le protocole sont 0 et IPPROTO_TCP pour les sockets TCP, et 0 et IPPROTO_UDP pour les sockets UDP. Pour les sockets SOCK_RAW on peut indiquer un protocole IP IANA valide dont la RFC 1700 précise les numéros assignés.

Lorsqu'un processus veut recevoir de nouveaux paquets entrants ou connexions, il doit attacher une socket à une adresse d'interface locale en utilisant bind(2). Une seule socket IP peut être attachée à une paire (adresse, port) locale donnée. Lorsqu'on indique INADDR_ANY lors de l'attachement, la socket sera affectée à toutes les interfaces locales. Si on invoque listen(2) ou connect(2) sur une socket non affectée, elle est automatiquement attachée à un port libre aléatoire, avec l'adresse locale fixée sur INADDR_ANY. L'adresse locale d'une socket TCP qui a été attachée est indisponible pendant quelques instants après sa fermeture, à moins que l'attribut SO_REUSEADDR ait été activé. Il faut être prudent en utilisant ce drapeau, car il rend le protocole TCP moins fiable.

  Format d'adresse
Une adresse de socket IP est définie comme la combinaison d'une adresse IP d'interface et d'un numéro de port 16 bits. Le protocole IP de base ne fournit pas de numéro de port, ils sont implémentés par les protocoles de plus haut-niveau comme udp(7) et tcp(7). Sur les sockets raw, le champ sin_port contient le protocole IP.

struct sockaddr_in {
    sa_family_t    sin_family; /* famille d'adresses : AF_INET     */
    uint16_t       sin_port;   /* port dans l'ordre d'octets réseau */
    struct in_addr sin_addr;   /* adresse Internet                  */
};
/* Adresse Internet */
struct in_addr {
    uint32_t       s_addr;     /* Adresse dans l'ordre d'octets réseau */
};

sin_family est toujours rempli avec AF_INET. C'est indispensable. Sous Linux 2.2, la plupart des fonctions réseau renvoient EINVAL lorsque cette configuration manque. sin_port contient le numéro de port, dans l'ordre des octets du réseau. Les numéros de ports inférieures à 1024 sont dits réservés. Seuls les processus privilégiés (c'est à dire ceux qui ont la capacité CAP_NET_BIND_SERVICE) peuvent appeler bind(2) pour ces ports. Notez que le protocole IPv4 en tant que tel n'a pas de concept de ports, ils sont seulement implémentés par des protocoles de plus haut-niveau comme tcp(7) et udp(7).

sin_addr est l'adresse IP de l'hôte. le membre s_addr de la structure struct in_addr contient l'adresse de l'interface de l'hôte, dans l'ordre des octets du réseau. in_addr devrait être affecté par l'une des valeurs INADDR_* (par exemple, INADDR_ANY) ou configuré avec les fonctions de bibliothèque inet_aton(3), inet_addr(3), inet_makeaddr(3) ou directement par le système de résolution des noms (voir gethostbyname(3)). Les adresses IPv4 sont divisées en adresses unicast, broadcast et multicast. Les adresses unicast décrivent une interface unique d'un hôte, les adresses broadcast correspondent à tous les hôtes d'un réseau, et les adresses multicast représentent tous les hôtes d'un groupe multicast. Les datagrammes vers des adresses broadcast ne peuvent être émis et reçus que si l'attribut de socket SO_BROADCAST est activé. Dans l'implémentation actuelle, les sockets orientées connexion ne sont autorisées que sur des adresses unicast. Remarquez que l'adresse et le port sont toujours stockés dans l'ordre des octets du réseau. Cela signifie qu'il faut invoquer htons(3) sur le numéro attribué à un port. Toutes les fonctions de manipulation d'adresse et port de la bibliothèque standard fonctionne dans l'ordre du réseau. Il existe plusieurs adresses particulières : INADDR_LOOPBACK (127.0.0.1) correspond toujours à l'hôte local via le périphérique loopback ; INADDR_ANY (0.0.0.0) signifie un attachement à n'importe quelle adresse ; INADDR_BROADCAST (255.255.255.255) signifie n'importe quel hôte et à le même effet que INADDR_ANY pour des raisons historiques.

  Options des sockets
IP supporte quelques options des sockets spécifiques aux protocoles, fixées avec setsockopt(2) et consultées avec getsockopt(2). Le niveau d'option de socket pour IP est IPPROTO_IP. Un attribut booléen en faux quand il est nul, et vrai sinon.

IP_OPTIONS
    Fixe ou lit les options IP à envoyer avec chaque paquet sur cette socket. Les arguments sont un pointeur sur un tampon contenant les options et la longueur des options. L'appel setsockopt(2) fixe les options IP associées à une socket. La taille maximale des options pour IPv4 est 40 octets. Voir la RFC 791 pour les options autorisées. Lorsque le paquet de connexion initiale d'une socket SOCK_STREAM contient des options IP, celles-ci seront automatiquement attribué à la socket, avec les options de routage inversées. Les paquets entrants ne peuvent pas modifier les options après que la connexion est établie. Le traitement des options de routage des paquets entrant est désactivé par défaut, et peut être validé en utilisant la requête sysctl accept_source_route. Les autres options, comme l'horodatage sont toujours traitées. Pour les socket datagrammes, les options IP ne peuvent être fixées que par l'utilisateur local. L'appel de getsockopt(2) avec IP_OPTIONS remplit le tampon fourni avec les options d'émission actuelles.

IP_PKTINFO
    Fournit un message IP_PKTINFO de service, qui contient une structure pktinfo fournissant quelques informations à propos du paquet entrant. Ceci ne fonctionne que pour les sockets orientées datagrammes. L'argument est un drapeau indiquant à la socket sur le message IP_PKTINFO doit être passé ou non. Le message lui-même ne peut être écrit ou lu que comme message de contrôle avec un paquet, en utilisant recvmsg(2) ou sendmsg(2).

    struct in_pktinfo {
        unsigned int   ipi_ifindex;  /* Numéro d'interface  */
        struct in_addr ipi_spec_dst; /* Adresse locale      */
        struct in_addr ipi_addr;     /* Adresse destination */
    };

    ipi_ifindex est le numéro unique de l'interface sur laquelle le paquet a été reçu. ipi_spec_dst est l'adresse locale du paquet, et ipi_addr est l'adresse de destination dans l'entête du paquet. Si IP_PKTINFO est passé à sendmsg(2) et si ipi_spec_dest est non nul, alors il sera utilisé comme adresse source pour la recherche dans la table de routage, et pour fixer les options de routage IP. Si ipi_ifindex est non nul, l'adresse locale principale de l'interface indiquée par cet index écrase ipi_spec_dst pour La table de routage.

IP_RECVTOS
    Le message de service IP_TOS est passé avec les paquets entrants. Il contient un octet qui décrit le champ Type-Of-Service/Précédence de l'entête du paquet. Il s'agit d'un drapeau entier booléen.

IP_RECVTTL
    Passer un message de contrôle IP_TTL avec le champ Time-To-Live du paquet reçu comme argument sous forme d'octet. Non supporté pour les sockets SOCK_STREAM.

IP_RECVOPTS
    Passer à l'utilisateur toutes les options IP entrantes dans un message de contrôle IP_OPTIONS. L'entête de routage et les autres options sont déjà remplies pour l'hôte local. Non supporté pour les sockets SOCK_STREAM.

IP_RETOPTS
    Comme IP_RECVOPTS mais renvoie les options non traitées, avec les options d'horodatage et de routage non remplies pour ce saut (hop).

IP_TOS
    Fixe ou consulte le champs Type-Of-Service (TOS) envoyé avec chaque paquet IP sortant de cette socket. Il sert à gérer sur le réseau les priorités entre paquets. TOS est un octet. Quelques attributs TOS standard sont définis : IPTOS_LOWDELAY pour minimiser les délais en trafic interactif, IPTOS_THROUGHPUT pour optimiser le débit, IPTOS_RELIABILITY pour optimiser la fiabilité, IPTOS_MINCOST doit être utilisé pour les données de remplissage, quand la lenteur de transmission importe peu. Une de ces valeurs TOS au maximum peut être indiquée. Les autres bits sont invalides et doivent être effacés. Linux envoie d'abord des datagrammes IPTOS_LOWDELAY par défaut, mais le comportement exact dépend de la politique configurée pour la file d'attente. Quelques niveaux de haute priorité peuvent réclamer des privilèges superutilisateur (la capacité CAP_NET_ADMIN). La priorité peut aussi être indiquée d'une manière indépendante du protocole avec les options (SOL_SOCKET, SO_PRIORITY) de socket (voir socket(7)).

IP_TTL
    Fixer ou consulter le contenu actuel du champ Time-To-Live envoyé avec chaque paquet sortant de cette socket.

IP_HDRINCL
    L'utilisateur doit fournir un entête ip avant les données proprement dites. Uniquement valides pour les sockets SOCK_RAW. Voir raw(7) pour plus de détail. Lorsque cet attribut est activé, les valeurs fixées pour IP_OPTIONS, IP_TTL et IP_TOS sont ignorées.

IP_RECVERR (défini dans <linux/errqueue.h>)
    Active le passage amélioré des messages d'erreur. Lorsque cet attribut est activé sur une socket datagramme, les erreurs seront mémorisées dans une file particulière pour la socket. Quand l'utilisateur détecte un échec d'une opération sur la socket, les erreurs peuvent être examinées en invoquant recvmsg(2) avec l'attribut MSG_ERRQUEUE. La structure sock_extended_err décrivant l'erreur sera passée comme message de service ayant le type IP_RECVERR et le niveau IPPROTO_IP. Ceci permet une gestion d'erreur fiable sur les sockets non connectées. La partie "données reçues" de la file d'erreurs contient le paquet ayant rencontré un problème.

    Le message de contrôle IP_RECVERR contient une structure sock_extended_err :

    #define SO_EE_ORIGIN_NONE    0
    #define SO_EE_ORIGIN_LOCAL   1
    #define SO_EE_ORIGIN_ICMP    2
    #define SO_EE_ORIGIN_ICMP6   3
    struct sock_extended_err {
        uint32_t ee_errno;   /* numéro d'erreur */
        uint8_t  ee_origin;  /* origine de l'erreur */
        uint8_t  ee_type;    /* type */
        uint8_t  ee_code;    /* code */
        uint8_t  ee_pad;
        uint32_t ee_info;    /* autres informations */
        uint32_t ee_data;    /* autres données */
        /* champs supplémentaires éventuels */
    };
    struct sockaddr *SOCK_EE_OFFENDER(struct sock_extended_err *);

    ee_errno contient le numéro de l'erreur mise en file. ee_origin est le code de l'origine de l'erreur. Les autres champs sont spécifiques au protocole. La macro SOCK_EE_OFFENDER renvoie un pointeur sur l'adresse d'un objet réseau d'où l'erreur provient, en prenant en argument un pointeur sur le message de service. Si cette adresse n'est pas disponible, le membre sa_family de la structure sockaddr contient AF_UNSPEC et les autres champs de sockaddr sont indéfinis.

    IP utilise la structure sock_extended_err comme suit : ee_origin contient SO_EE_ORIGIN_ICMP pour les erreurs reçues sous forme de paquet ICMP, ou SO_EE_ORIGIN_LOCAL pour les erreurs locales. Les valeurs inconnues doivent être ignorées. ee_type et ee_code sont remplis avec les champs type et code de l'entête ICMP. ee_info contient le MTU déterminé pour les erreurs EMSGSIZE. Le message contient aussi l'adresse sockaddr_in du n