RAW(7)

NOM
raw, SOCK_RAW - Sockets brutes (raw) IPv4 sous Linux

SYNOPSIS
#include <sys/socket.h>
#include <netinet/in.h>
raw_socket = socket(PF_INET, SOCK_RAW, int protocol);

DESCRIPTION
Les sockets brutes (raw) permettent d'implémenter des protocoles IPv4 dans l'espace utilisateur. Une socket raw reçoit ou envoie des datagrammes sans les entêtes de la couche de liaison. La couche IPv4 génère des entêtes IP lorsqu'elle envoie un paquet à moins que l'option IP_HDRINCL soit activée sur la socket. Lorsqu'elle est activée, la socket doit contenir l'entête IP. Pour la réception, l'entête IP est toujours inclus dans le paquet. Seuls les processus avec un UID effectif nul ou une capacité CAP_NET_RAW sont autorisés à ouvrir des sockets raw. Tous les paquets ou les erreurs correspondant au numéro de protocole spécifié pour la socket raw sont transmis à cette socket. Pour voir une liste des protocoles autorisés, consulter les numéros assignés dans la RFC 1700 et getprotobyname(3). Un protocole IPPROTO_RAW implique l'activation de IP_HDRINCL et autorise l'émission suivant n'importe quel protocole IP indiqué dans l'entête. La réception de tous les protocoles IP avec IPPROTO_RAW n'est pas possible avec les sockets raw.
    IP Champs d'entête modifiés en émission par IP_HDRINCL
    Checksum IP | Toujours rempli.
    Adresse source | Rempli si contient des zéros.
    ID Paquet | Rempli si contient des zéros.
    Longueur totale | Toujours rempli.

    Si IP_HDRINCL est spécifié et si l'entête IP à une adresse non nulle, alors l'adresse destination de la socket est utilisée pour router le paquet. Quand MSG_DONTROUTE est spécifié, l'adresse de destination devrait toujours viser une interface locale. Sinon, un examen de la table de routage a quand même lieu, mais les routes avec une passerelle sont ignorées. Si IP_HDRINCL n'est pas spécifié, les options d'entête IP peuvent être fixées sur les sockets raw avec setsockopt(2); voir ip(7) pour plus d'informations. Dans Linux 2.2 tous les champs d'entête et les options peuvent être fixés en utilisant les options IP. Ceci signifie que les sockets raw ne servent en général que pour les nouveaux protocoles ou les protocoles sans interface utilisateur (comme ICMP). Lorsqu'un paquet est reçu, il est passé à toutes les sockets raw qui ont été attachées à son protocole avant d'être transmis aux gestionnaires des autres protocoles (par exemple les modules des protocoles du noyau).

  Format d'adresse
Les sockets raw utilisent la structure d'adresse sockaddr_in standard, définie dans ip(7). Le champ sin_port peut être utilisé pour spécifier un numéro de protocole IP, mais il est ignoré pour l'émission dans Linux 2.2 et devrait toujours
 être mis à zéro (voir paragraphe BOGUES). Pour les paquets entrants sin_port est rempli avec le protocole du paquet. Voir le fichier d'entête <netinet/in.h> pour les protocoles IP valides.

  Options des sockets
Les options des sockets raw peuvent être écrites avec setsockopt(2) et lues avec getsockopt(2) en passant l'attribut de famille IPPROTO_RAW.

ICMP_FILTER
    Active un filtre spécial sur les sockets raw attachées au protocole IPPROTO_ICMP. La valeur a un bit pour chaque type de message ICMP qui doit être rejeté. La valeur par défaut est de ne filtrer aucun messages ICMP.

De plus, toutes les options IPPROTO_IP de ip(7) valides pour les sockets datagrammes sont supportées.

  Gestion d'erreur
Les erreurs provenant du réseau ne sont transmises à l'utilisateur que lorsque la socket est connectée ou si le drapeau IP_RECVERR est actif. Pour les sockets connectées, seules EMSGSIZE et EPROTO sont transmises, pour compatibilité. Avec IP_RECVERR, toutes les erreurs réseau sont sauvegardées dans la file d'erreurs.

ERREURS

EACCES
    L'utilisateur essaye d'envoyer sur une adresse broadcast sans avoir le drapeau broadcast sur la socket.

EFAULT
    Une adresse mémoire invalide a été fournie.

EINVAL
    Argument invalide.

EMSGSIZE
    Paquet trop grand. Soit la recherche du MTU des chemins est active (voir l'attribut IP_MTU_DISCOVER de socket), soit la taille du paquet dépasse le maximum autorisé par IPv4 (64 Ko).

EOPNOTSUPP
    Un attribut invalide a été transmis à un appel sur la socket (comme MSG_OOB).

EPERM
    L'utilisateur n'a pas la permission d'ouvrir des sockets raw. Seuls les processus avec un UID effectif nul ou la capacité CAP_NET_RAW peuvent le faire.

EPROTO
    Une erreur ICMP est arrivée, indiquant un problème de paramétrage.

VERSIONS
IP_RECVERR et ICMP_FILTER sont nouveaux dans Linux 2.2. Ce sont des extensions Linux et ne doivent pas être employés dans des programmes portables. Linux 2.0 assurait une compatibilité bogue-à-bogue avec le code des sockets raw de BSD lorsque l'option de socket SO_BSDCOMPAT était utilisé. Depuis Linux 2.2, cette option n'a plus d'effet.

NOTES
Par défaut, les sockets effectuent la recherche MTU (Maximum Transmission Unit) des chemins. Cela signifie que le noyau conservera la trace du MTU d'une adresse IP cible spécifique et renverra EMSGSIZE lorsque l'écriture d'un paquet raw excèdera cette valeur. Si cela se produit, l'application doit diminuer la taille du paquet. La recherche MTU des chemins peut être désactivée en utilisant l'option de socket IP_MTU_DISCOVER ou la requête sysctl ip_no_pmtu_disc, voir ip(7) pour plus de détails. Lorsqu'elle est désactivée, les sockets raw fragmenteront les paquets sortants dont la longueur totale dépasse le MTU de l'interface. Toutefois, il n'est pas conseillé de la désactiver pour des raisons de performances et de fiabilité. Une socket raw peut être attachée à une adresse locale spécifique en utilisant l'appel bind(2). Si elle n'est pas attachée, tous les paquets du protocole IP spécifié sont reçus. De plus, une socket raw peut être attachée à un périphérique réseau particulier avec SO_BINDTODEVICE ; voir socket(7). Une socket IPPROTO_RAW ne fonctionne qu'en émission. Si vous désirez vraiment recevoir tous les paquets IP, utilisez une socket packet(7) avec le protocole ETH_P_IP. Notez que les sockets packet ne réassemblent pas les fragments IP contrairement aux sockets raw. Si vous voulez recevoir tous les paquets ICMP pour une socket datagramme, il est souvent préférable d'utiliser IP_RECVERR sur cette socket particulière, voir ip(7). Les sockets raw peuvent capturer tous les protocoles sous Linux, même les protocoles comme ICMP ou TCP qui ont un module dans le noyau. Dans ce cas, le paquet est passé simultanément au module du noyau et à la socket raw. Ce comportement n'est pas portable, de nombreuses autres implémentations des sockets BSD ont des limitations ici. Linux ne modifie jamais les entêtes fournis par l'utilisateur (sauf pour remplir les champs ne contenant que des zéros comme cela est décrit pour IP_HDRINCL). Ceci diffère de nombreuses autres implémentations des sockets raw. Les sockets raw sont en général peu portables et devrait être évitées dans les programmes destinés à être adaptés sur d'autres systèmes. L'émission sur les sockets raw devrait employer le protocole dans sin_port ; ceci a été perdu dans Linux 2.2. Un remède est d'utiliser IP_HDRINCL.

BOGUES
Les extensions de Proxy transparent ne sont pas décrites. Lorsque l'option IP_HDRINCL est active, les datagrammes ne seront pas fragmentés et sont limités au MTU de l'interface. Utiliser en émission le protocole IP indiqué dans sin_port a été supprimé dans Linux 2.2. On utilise toujours le protocole auquel la socket a été attachée avec bind(2) ou celui de l'appel socket(2) initial.

VOIR AUSSI
recvmsg(2), sendmsg(2), capabilities(7), ip(7), socket(7).

RFC 1191 pour la recherche du MTU par chemin. RFC 791 et le fichier d'entête <linux/ip.h> pour le protocole IP.

TRADUCTION

Ce document est une traduction réalisée par Christophe Blaess <http://www.blaess.fr/christophe/> le 7 juin 2001 et révisée le 17 juillet 2008.

L'équipe de traduction a fait le maximum pour réaliser une adaptation française de qualité. La version anglaise la plus à jour de ce document est toujours consultable via la commande : « LANG=C man 7 raw ». N'hésitez pas à signaler à l'auteur ou au traducteur, selon le cas, toute erreur dans cette page de manuel.