NOM
raw, SOCK_RAW - Sockets brutes (raw) IPv4 sous Linux.
SYNOPSIS
#include <sys/socket.h>
#include <netinet/in.h>
raw_socket = socket(AF_INET, SOCK_RAW, int protocol);
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 en-têtes de la couche de liaison.
La couche IPv4 génère des en-tê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’en-tête IP. Pour la réception,
l’en-tê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
RFC1700 et getprotobyname(3).
Un protocole IPPROTO_RAW implique l’activation de IP_HDRINCL et
autorise l’émission suivant n’importe quel protocole IP indiquée dans
l’en-tête. La réception de tous les protocoles IP avec IPPROTO_RAW
n’est pas possible avec les sockets raw.
+--------------------------------------------------------+
|IP Champs d’en-tê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’en-tê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’en-tê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’en-tê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 pourrait être utilisé pour
spécifier un numéro de protocole IP, mais il est ignoré pour l’émission
dans Linux 2.2 et devrait être toujours mis à zéro (voir paragraphe
BOGUES). Pour les paquets entrants sin_port est rempli avec le
protocole du paquet. Voir le fichier d’en-tête <netinet/in.h> pour les
protocoles IP valides.
Options de 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 prises en charge.
Traitement des erreurs
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’attribut SO_BSDCOMPAT était utilisé. Ceci
a été supprimé dans 2.2.
NOTES
Par défaut, les sockets brutes utilisent la détection du MTU (« Maximum
Transmission Unit ») pour le chemin. Cela signifie que le noyau garde
en mémoire le MTU vers une adresse IP cible spécifique, et renvoie
EMSGSIZE lorsqu’un paquet brut dépasse cette taille. Dans ce cas,
l’application doit diminuer la taille du paquet. La détection du MTU
par chemin peut aussi être désactivée en utilisant l’option de socket
IP_MTU_DISCOVER ou le fichier /proc/sys/net/ipv4/ip_no_pmtu_disc, voir
ip(7) pour plus de détails. Lorsque cette option est désactivée, les
sockets brutes fragmenteront les paquets sortants qui dépassent le MTU
de l’interface. Ceci est cependant découragé, pour des raisons de
performance 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 IP 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 en-tê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 portables.
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 du chemin.
RFC 791 et le fichier d’en-tête <linux/ip.h> pour le protocole IP.
COLOPHON
Cette page fait partie de la publication 3.23 du projet man-pages
Linux. Une description du projet et des instructions pour signaler des
anomalies peuvent être trouvées à l’adresse
http://www.kernel.org/doc/man-pages/.
TRADUCTION
Cette page de manuel a été traduite et mise à jour par Christophe
Blaess <http://www.blaess.fr/christophe/> entre 1996 et 2003, puis par
Alain Portal <aportal AT univ-montp2 DOT fr> jusqu’en 2006, et mise à
disposition sur http://manpagesfr.free.fr/.
Les mises à jour et corrections de la version présente dans Debian sont
directement gérées par Julien Cristau <jcristau@debian.org> et l’équipe
francophone de traduction de Debian.
Veuillez signaler toute erreur de traduction en écrivant à
<debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
paquet manpages-fr.
Vous pouvez toujours avoir accès à la version anglaise de ce document
en utilisant la commande « man -L C <section> <page_de_man> ».