Provided by: manpages-fr_4.13-4_all bug

NOM

       packet – Interface de paquets au niveau du périphérique

SYNOPSIS

       #include <sys/socket.h>
       #include <linux/if_packet.h>
       #include <net/ethernet.h> /* Les protocoles L2 */

       packet_socket = socket(AF_PACKET, int type_socket, int protocole);

DESCRIPTION

       Les  sockets  packet sont utilisés pour envoyer ou recevoir des paquets bruts au pilote de
       périphérique (couche 2 OSI). Ils permettent d'implémenter des modules  de  protocole  dans
       l'espace utilisateur au-dessus de la couche physique.

       L'argument  type_socket  est  soit  SOCK_RAW  pour les paquets bruts incluant l'en-tête de
       couche liaison, soit SOCK_DGRAM pour les paquets préparés sans en-tête de couche  liaison.
       Les  informations  d’en-tête de couche liaison sont disponibles dans un format commun, par
       l'intermédiaire  d'une  structure  sockaddr_ll.  protocole  est  un  numéro  de  protocole
       IEEE 802.3   dans   l'ordre   des   octets  du  réseau.  Consultez  le  fichier  d'en-tête
       <linux/if_ether.h> pour avoir une liste des protocoles  autorisés.  Lorsque  le  protocole
       demandé  est  htons(ETH_P_ALL),  alors  tous  les  protocoles sont reçus. Tous les paquets
       entrants du protocole indiqué seront passés au socket packet  avant  d'être  transmis  aux
       protocoles implémentés dans le noyau.

       Pour  pouvoir créer des sockets packet, un processus doit posséder la capacité CAP_NET_RAW
       dans l’espace de noms utilisateur qui régit son espace de noms réseau.

       Les paquets SOCK_RAW sont transmis depuis et vers le pilote de  périphérique  sans  aucune
       modification  des  données  des  paquets.  Lors de la réception d’un paquet, l'adresse est
       toujours examinée et fournie dans une structure standard d’adresse  sockaddr_ll.  Lors  de
       l'émission  d'un  paquet,  le  tampon  fourni par l'utilisateur doit contenir l'en-tête de
       couche physique. Le paquet est alors mis en attente sans  modification  à  l'attention  du
       pilote  de  périphérique correspondant à l'interface définie par l'adresse de destination.
       Certains pilotes  de  périphérique  ajoutent  toujours  d'autres  en-têtes.  SOCK_RAW  est
       similaire mais non compatible avec l'ancien AF_INET/SOCK_PACKET de Linux 2.0.

       SOCK_DGRAM  opère  à  un  niveau  légèrement  plus élevé. L'en-tête de couche physique est
       supprimé avant que le paquet ne soit transmis à l'utilisateur. Les paquets envoyés par  un
       socket  packet  SOCK_DGRAM  reçoivent  un  en-tête de couche physique correct basé sur les
       informations dans l'adresse destination sockaddr_ll avant d'être mis en attente.

       Par défaut, tous les paquets du type de protocole indiqué sont passés  au  socket  packet.
       Pour ne recevoir que les paquets d'une interface donnée, utilisez bind(2) en indiquant une
       adresse dans une struct sockaddr_ll pour attacher le socket à une  interface.  Les  champs
       utilisés  pour  la  liaison  sont  sll_family  (devrait  être  AF_PACKET), sll_protocol et
       sll_ifindex.

       L'opération connect(2) n'est pas prise en charge sur les sockets packet.

       Lorsque l'attribut MSG_TRUNC  est  transmis  à  recvmsg(2),  recv(2)  ou  recvfrom(2),  la
       véritable  longueur  du  paquet sur le réseau est toujours renvoyée, même si elle est plus
       grande que le tampon.

   Types d’adresses
       La structure sockaddr_ll est une adresse de couche physique indépendante du périphérique.

           struct sockaddr_ll {
               unsigned short sll_family;   /* Toujours AF_PACKET */
               unsigned short sll_protocol; /* Protocole couche physique */
               int            sll_ifindex;  /* Numéro d'interface */
               unsigned short sll_hatype;   /* Type de matériel ARP */
               unsigned char  sll_pkttype;  /* Type de paquet */
               unsigned char  sll_halen;    /* Longueur de l'adresse */
               unsigned char  sll_addr[8];  /* Adresse couche physique */
           };

       Les membres de cette structure sont les suivants :

       –  sll_protocol est le type normalisé du protocole Ethernet dans  l’ordre  des  octets  du
          réseau tel que défini dans le fichier d’en-tête <linux/if_ether.h>. C’est par défaut le
          protocole du socket.

       –  sll_ifindex  est  le  numéro  d’interface  (consultez  netdevice(7)).  0 correspond   à
          n’importe  quelle  interface  (autorisée uniquement pour la liaison). sll_hatype est un
          type ARP tel que défini dans le fichier d’en-tête <linux/if_arp.h>.

       –  Le champ sll_pkttype contient le type de paquet. Les types  valables  sont  PACKET_HOST
          pour  un  paquet  destiné  à l'hôte local, PACKET_BROADCAST pour un paquet broadcast de
          couche physique, PACKET_MULTICAST pour un paquet envoyé  à  une  adresse  multicast  de
          couche physique, PACKET_OTHERHOST pour un paquet destiné à un autre hôte capturé par un
          pilote de périphérique en mode promiscuous et PACKET_OUTGOING pour un paquet  provenant
          de  l'hôte  local  rebouclé  sur  un  socket  packet.  Cela  n'a de signification qu'en
          réception.

       –  sll_addr et sll_halen contiennent l'adresse de couche physique (par exemple IEEE 802.3)
          et sa longueur. L'interprétation exacte dépend du périphérique.

       Lorsque  des  paquets  sont envoyés, il suffit d'indiquer sll_family, sll_addr, sll_halen,
       sll_ifindex et sll_protocol. Les autres  champs  devraient  être  à  zéro.  sll_hatype  et
       sll_pkttype sont remplis en réception pour information.

   Options de socket
       Les  options  du  socket  packet sont configurées en appelant setsockopt(2) avec le niveau
       SOL_PACKET.

       PACKET_ADD_MEMBERSHIP
       PACKET_DROP_MEMBERSHIP
              Les options des sockets packet permettent de configurer le multicasting  de  couche
              physique  et  le  mode  promiscuous.  PACKET_ADD_MEMBERSHIP  ajoute  une liaison et
              PACKET_DROP_MEMBERSHIP la  supprime.  Les  deux  options  attendent  une  structure
              packet_mreq en paramètre :

                  struct packet_mreq {
                      int            mr_ifindex;    /* Numéro d'interface */
                      unsigned short mr_type;       /* Action */
                      unsigned short mr_alen;       /* Longueur d'adresse */
                      unsigned char  mr_address[8]; /* Adresse couche physique */
                  };

              mr_ifindex  contient  le  numéro  de  l'interface dont l'état doit être modifié. Le
              champ mr_type indique l'action à effectuer. PACKET_MR_PROMISC valide  la  réception
              de  tous  les  paquets  circulant  sur  le segment de réseau commun (souvent appelé
              « mode promiscuous »), PACKET_MR_MULTICAST attache le socket au groupe multicast de
              couche  physique  indiqué dans mr_address et mr_alen, et PACKET_MR_ALLMULTI demande
              au socket de recevoir tous les paquets multicast arrivant sur l'interface.

              De plus, les ioctls classiques SIOCSIFFLAGS, SIOCADDMULTI et  SIOCDELMULTI  peuvent
              parvenir au même résultat.

       PACKET_AUXDATA (depuis Linux 2.6.21)
              Si  cette  option  est  activée,  le  socket  packet fournit avec chaque paquet une
              structure de métadonnées à l’aide du champ de contrôle de recvmsg(2). La  structure
              peut être lue avec cmsg(3). Elle est définie ci-dessous :

                  struct tpacket_auxdata {
                      __u32 tp_status;
                      __u32 tp_len;      /* Longueur du paquet */
                      __u32 tp_snaplen;  /* Longueur capturée */
                      __u16 tp_mac;
                      __u16 tp_net;
                      __u16 tp_vlan_tci;
                      __u16 tp_vlan_tpid; /* Depuis Linux 3.14 ; précédemment
                                             c’était des octets de remplissage
                                             non utilisés */
                  };

       PACKET_FANOUT (depuis Linux 3.1)
              Pour  s’adapter  au  nombre  de traitements des threads, les sockets packet peuvent
              former un groupe de déploiement. Dans ce mode, tous les paquets correspondants sont
              mis  en  attente  dans  un  seul  socket  du groupe. Un socket rejoint un groupe de
              déploiement en  appelant  setsockopt(2)  avec  le  niveau  SOL_PACKET  et  l’option
              PACKET_FANOUT.  Tous les espaces de noms réseau peuvent avoir jusqu’à 65536 groupes
              indépendants. Un socket sélectionne un groupe en encodant  l’identifiant  dans  les
              16 premiers  bits de la valeur d’entier de cette option. Le premier socket packet à
              rejoindre un groupe le crée implicitement.  Pour  réussir  à  rejoindre  un  groupe
              existant,  les  sockets  packet  suivants  doivent avoir le même protocole, la même
              configuration de périphérique, le même mode de déploiement et les  mêmes  attributs
              (voir  ci-dessous).  Les sockets packet ne peuvent quitter un groupe de déploiement
              qu’en fermant le socket. Le groupe est supprimé quand le dernier socket est fermé.

              Le déploiement gère plusieurs algorithmes pour répartir le trafic entre les sockets
              comme suit :

              –  Le  mode par défaut, PACKET_FANOUT_HASH, envoie les paquets du même flux au même
                 socket pour maintenir l’ordre par flux. Pour chaque paquet, il choisit un socket
                 en  prenant  le  hachage  du flux de paquets modulo le nombre de sockets dans le
                 groupe, où le hachage du flux est un hachage  sur  les  adresses  de  la  couche
                 réseau et les champs facultatifs de port de la couche transport.

              –  Le  mode  répartition  de  charge PACKET_FANOUT_LB met en œuvre un algorithme de
                 tourniquet (round-robin).

              –  PACKET_FANOUT_CPU sélectionne le socket en se basant sur le CPU  sur  lequel  le
                 paquet arrive.

              –  PACKET_FANOUT_ROLLOVER  traite toutes les données sur un seul socket, allant sur
                 le suivant quand le socket devient débordé.

              –  PACKET_FANOUT_RND sélectionne le socket en utilisant un  générateur  de  nombres
                 pseudo-aléatoires.

              –  PACKET_FANOUT_QM   (disponible  depuis  Linux 3.14)  sélectionne  le  socket  en
                 utilisant le queue_mapping enregistré du tampon de socket (SKB) reçu.

              Les modes de déploiement acceptent des options  supplémentaires.  La  fragmentation
              d’IP  force  les  paquets  du  même  flux  à avoir des hachages de flux différents.
              L’attribut  PACKET_FANOUT_FLAG_DEFRAG,  si  défini,  force  la  défragmentation  de
              paquets  avant  l’application  du  déploiement, pour conserver l’ordre même dans ce
              cas. Le mode de déploiement et les  options  sont  communiqués  sur  les  deuxièmes
              16 bits     de     la    valeur    d’entier    de    cette    option.    L’attribut
              PACKET_FANOUT_FLAG_ROLLOVER active le mécanisme de déplacement comme une  stratégie
              de  sauvegarde :  si  l’algorithme  de  déploiement  originel sélectionne un socket
              débordé, le paquet se déplace vers le suivant disponible.

       PACKET_LOSS (avec PACKET_TX_RING)
              Lorsqu'un paquet malformé est trouvé dans le tampon circulaire de transmission,  le
              comportement par défaut est de réinitialiser son tp_status à TP_STATUS_WRONG_FORMAT
              et d'abandonner immédiatement la transmission. Le paquet  malformé  ainsi  que  les
              paquets  suivants  mis en file d'attente voient leur transmission bloquée. L'erreur
              de format doit être corrigée, la valeur tp_status associée doit être  réinitialisée
              à   TP_STATUS_SEND_REQUEST   et   le   processus   de  transmission  redémarré  par
              l'intermédiaire de l'interface send(2). Cependant, si PACKET_LOSS est défini,  tout
              paquet malformé est ignoré, son tp_status est réinitialisé à TP_STATUS_AVAILABLE et
              le processus de transmission continue.

       PACKET_RESERVE (avec PACKET_RX_RING)
              Par défaut, un tampon circulaire de réception des paquets écrit les  paquets  juste
              après  la  structure  de  métadonnées  et  le  remplissage  d'alignement. La valeur
              d’entier de cette option réserve une possibilité de transmission supplémentaire.

       PACKET_RX_RING
              Créer un tampon circulaire projeté en  mémoire  pour  la  réception  asynchrone  de
              paquets.   Le   socket   packet   réserve  une  zone  contiguë  d’espace  d’adresse
              d’application, la dispose dans un tableau d’emplacements de  paquet  et  copie  les
              paquets  (jusqu’à tp_snaplen) dans les emplacements suivants. Tous les paquets sont
              précédés d’une structure de métadonnées similaire à tpacket_auxdata. Les champs  de
              protocole   encodent  la  position  des  données  dès  le  début  de  l’en-tête  de
              métadonnées. tp_net stocke la position de la couche réseau. Si le socket packet est
              de  type  SOCK_DGRAM, alors tp_mac est la même. S’il est de type SOCK_RAW, alors ce
              champ stocke la position de la  trame  de  couche  liaison.  Le  socket  packet  et
              l’application  communiquent  le  début  et  la fin du tampon circulaire à l’aide du
              champ tp_status. Tous  les  emplacements  avec  tp_status  valant  TP_STATUS_KERNEL
              appartiennent  au  socket  packet.  Après  avoir  rempli un emplacement, il modifie
              l’état  de  l’emplacement  pour  qu’il  appartienne  à  l’application.  Lors  d’une
              opération   normale,   la   nouvelle  valeur  de  tp_status  a  au  moins  son  bit
              TP_STATUS_USER activé, pour signaler  qu’un  paquet  reçu  a  été  stocké.  Lorsque
              l’application  a  terminé  de  traiter  un  paquet,  elle transfère la propriété de
              l’emplacement au socket en redéfinissant tp_status à TP_STATUS_KERNEL.

              Les sockets packet mettent en œuvre plusieurs variantes  du  tampon  circulaire  de
              paquets.   Des   précisions   sur   cette  mise  en  place  sont  disponibles  dans
              Documentation/networking/packet_mmap.rst dans l'arborescence des sources  du  noyau
              Linux.

       PACKET_STATISTICS
              Récupérer les statistiques du socket packet sous la forme d'une structure

                  struct tpacket_stats {
                      unsigned int tp_packets;  /* Décompte total des paquets */
                      unsigned int tp_drops;    /* Décompte des paquets jetés */
                  };

              Recevoir  les  statistiques  réinitialise  les  compteurs internes. La structure de
              statistiques est différente lorsque  le  tampon  circulaire  utilisé  est  de  type
              TPACKET_V3.

       PACKET_TIMESTAMP (avec PACKET_RX_RING ; depuis Linux 2.6.36)
              Le  tampon  circulaire de réception des paquets stocke un horodatage dans l’en-tête
              de métadonnées. Par défaut, c’est un horodatage logiciel généré quand le paquet est
              copié  dans  le  tampon  circulaire.  Cette  option  d’entier  sélectionne  le type
              d’horodatage. En plus du fonctionnement par défaut, il gère deux formats  matériels
              décrits  dans  Documentation/networking/timestamping.rst  dans  l'arborescence  des
              sources du noyau Linux.

       PACKET_TX_RING (depuis Linux 2.6.31)
              Créer un tampon circulaire projeté en mémoire  pour  la  transmission  de  paquets.
              Cette  option  est  similaire  à  PACKET_RX_RING  et  accepte  les mêmes arguments.
              L’application écrit des  paquets  dans  des  emplacements  avec  tp_status  égal  à
              TP_STATUS_AVAILABLE  et les programme pour transmission en modifiant tp_status à la
              valeur TP_STATUS_SEND_REQUEST. Quand  les  paquets  sont  prêts  à  être  transmis,
              l’application appelle send(2) ou une de ses variantes. Les champs buf et len de cet
              appel sont ignorés. Si une adresse est passée en utilisant sendto(2) ou sendmsg(2),
              alors  cela  écrase le socket par défaut. En cas de transmission réussie, le socket
              réinitialise  tp_status  à  TP_STATUS_AVAILABLE.  Il  interrompt  immédiatement  la
              transmission en cas d’erreur sauf si PACKET_LOSS est définie.

       PACKET_VERSION (avec PACKET_RX_RING ; depuis Linux 2.6.27)
              Par  défaut,  PACKET_RX_RING  crée un tampon circulaire de réception des paquets de
              variante TPACKET_V1. Pour créer une autre variante, configurer la  variante  voulue
              en définissant l’option d’entier avant de créer le tampon circulaire.

       PACKET_QDISC_BYPASS (depuis Linux 3.14)
              Par défaut, les paquets envoyés par un socket packet passent par la couche qdisc du
              noyau, dédiée au contrôle de trafic, ce qui répond  bien  à  la  majorité  des  cas
              d'utilisation.  Les  équipements  de génération de trafic qui utilisent des sockets
              packet pour inonder par force  brute  le  réseau  — par  exemple  pour  tester  des
              appareils  en  charge  comme  le  fait  pktgen — peuvent contourner cette couche de
              contrôle en définissant cette option à 1. Un effet secondaire est l'absence de mise
              en mémoire tampon des paquets par la couche qdisc, ce qui peut provoquer des pertes
              de paquets lorsque les files de transmission du périphérique réseau  sont  pleines.
              L'utilisation de cette option est à vos risques et périls.

   Ioctls
       SIOCGSTAMP peut servir à obtenir l'horodatage du dernier paquet reçu. Le paramètre est une
       variable struct timeval.

       De plus, les ioctls standards définis dans netdevice(7) et socket(7) sont valables sur les
       sockets packet.

   Traitement des erreurs
       Les  sockets  packet  ne  gèrent  pas  d'autres erreurs que celles se produisant durant la
       transmission des paquets au pilote de périphérique. Elles ne traitent pas  le  concept  de
       file d'erreurs.

ERREURS

       EADDRNOTAVAIL
              Adresse de groupe multicast inconnue.

       EFAULT Adresse mémoire incorrecte.

       EINVAL Argument incorrect.

       EMSGSIZE
              Le paquet est plus grand que le MTU de l'interface.

       ENETDOWN
              L'interface n'est pas active.

       ENOBUFS
              Pas assez de mémoire pour le paquet.

       ENODEV Le  nom  du  périphérique  ou  le  numéro  d’interface  indiqué  dans  l'adresse de
              l'interface est inconnu.

       ENOENT Pas de paquet reçu.

       ENOTCONN
              Aucune adresse d'interface n'a été passée.

       ENXIO  Numéro d'interface non valable dans son adresse.

       EPERM  L'utilisateur n'a pas les privilèges nécessaires pour l'opération.

       De plus, d'autres erreurs peuvent être engendrées par le pilote bas niveau.

VERSIONS

       AF_PACKET est une nouveauté de Linux 2.2. Les versions précédentes de Linux  ne  prenaient
       en charge que SOCK_PACKET.

NOTES

       Pour  la  portabilité,  il  est  conseillé  d'utiliser  les  fonctionnalités AF_PACKET par
       l'intermédiaire de l'interface pcap(3), bien que cela ne couvre  qu'un  sous-ensemble  des
       possibilités de AF_PACKET.

       Les  sockets  packet  SOCK_DGRAM  n'essayent  pas  de  créer  ou  de  traiter les en-têtes
       IEEE 802.2 LLC pour une trame IEEE 802.3. Lorsque le protocole ETH_P_802_3 est indiqué  en
       émission, le noyau crée la trame 802.3 et remplit le champ de longueur. L'utilisateur doit
       fournir l'en-tête LLC pour obtenir un  paquet  entièrement  conforme.  Les  paquets  802.3
       entrants  ne  sont  pas multiplexés sur les champs du protocole DSAP/SSAP. À la place, ils
       sont fournis à l'utilisateur sous le protocole ETH_P_802_2 avec un en-tête LLC ajouté.  La
       liaison  ETH_P_802_3  n’est donc pas possible, la liaison ETH_P_802_2 doit être utilisée à
       la place, et vous devez réaliser le multiplexage de protocoles vous-même. Le  comportement
       par  défaut  en  émission  est  l’encapsulation  Ethernet  DIX standard, avec le protocole
       renseigné.

       Les sockets packet ne sont pas soumis aux chaînes de pare-feu en entrée ou sortie.

   Compatibilité
       Avec Linux 2.0, la seule façon d’obtenir un socket paquet était avec l’appel :

           socket(AF_INET, SOCK_PACKET, protocole)

       C’est encore pris  en  charge  mais  obsolète  et  fortement  déconseillé.  La  principale
       différence  entre  les  deux  méthodes  est  que  SOCK_PACKET  utilise  l'ancienne  struct
       sockaddr_pkt pour indiquer l'interface, ce qui ne fournit aucune indépendance vis-à-vis de
       la couche physique.

           struct sockaddr_pkt {
               unsigned short spkt_family;
               unsigned char  spkt_device[14];
               unsigned short spkt_protocol;
           };

       spkt_family  contient  le  type  de  périphérique,  spkt_protocol est le type de protocole
       IEEE 802.3 comme défini dans <sys/if_ether.h> et spkt_device est le  nom  du  périphérique
       sous forme de chaîne terminée par un octet NULL, par exemple eth0.

       Cette structure est obsolète et ne doit pas être employée dans des nouveaux programmes.

BOGUES

       La gestion des en-têtes LLC IEEE 802.2/802.3 devrait être considérée comme un bogue.

       Les filtres des sockets ne sont pas documentés.

       L'extension  MSG_TRUNC  de recvmsg(2) est une bidouille horrible et devrait être remplacée
       par un message de contrôle. Il n'y a  actuellement  aucun  moyen  d'obtenir  l'adresse  de
       destination originelle des paquets à l’aide de SOCK_DGRAM.

VOIR AUSSI

       socket(2), pcap(3), capabilities(7), ip(7), raw(7), socket(7)

       RFC 894  pour  l'encapsulation  IP  Ethernet  standard.  RFC 1700  pour l'encapsulation IP
       IEEE 802.3.

       Le fichier d'en-tête <linux/if_ether.h> pour les protocoles de couche physique.

       L'arbre des sources du noyau Linux.  /Documentation/networking/filter.rst  décrit  comment
       appliquer     des     filtres     Berkeley     de     paquets    aux    sockets    packet.
       /tools/testing/selftests/net/psock_tpacket.c contient  un  exemple  de  code  source  pour
       toutes les versions de PACKET_RX_RING et PACKET_TX_RING.

COLOPHON

       Cette  page  fait partie de la publication 5.10 du projet man-pages Linux. Une description
       du projet et des instructions pour signaler des anomalies et la dernière version de  cette
       page peuvent être trouvées à l'adresse https://www.kernel.org/doc/man-pages/.

TRADUCTION

       La  traduction  française  de  cette  page  de  manuel  a  été créée par Christophe Blaess
       <https://www.blaess.fr/christophe/>, Stéphan  Rafin  <stephan.rafin@laposte.net>,  Thierry
       Vignaud  <tvignaud@mandriva.com>,  François Micaux, Alain Portal <aportal@univ-montp2.fr>,
       Jean-Philippe   Guérard   <fevrier@tigreraye.org>,   Jean-Luc   Coulon   (f5ibh)    <jean-
       luc.coulon@wanadoo.fr>,    Julien    Cristau    <jcristau@debian.org>,    Thomas   Huriaux
       <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin
       Duneau  <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis
       Barbier <barbier@debian.org>, David Prévot <david@tilapin.org>  et  Jean-Paul  Guillonneau
       <guillonneau.jeanpaul@free.fr>

       Cette  traduction  est  une  documentation libre ; veuillez vous reporter à la GNU General
       Public  License  version 3  ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩   concernant   les
       conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

       Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un
       message à debian-l10n-french@lists.debian.org ⟨⟩.