Provided by: manpages-fr_1.67.0-1_all bug

NOM

       packet, PF_PACKET - Interface par paquet au niveau périphérique.

SYNOPSIS

       #include <sys/socket.h>
       #include <netpacket/packet.h>
       #include <net/ethernet.h>     /* protocoles L2 */

       packet_socket = socket(PF_PACKET, int socket_type, int protocol);

DESCRIPTION

       Les sockets packets sont utilisées pour envoyer ou recevoir des paquets
       de données bruts au pilote  de  périphérique  (Niveau  OSI  2).   Elles
       permettent   d’implémenter   des   modules   protocoles  dans  l’espace
       utilisateur au dessus du niveau physique.

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

       Seuls les processus avec un UID effectif nul ou la capacité CAP_NET_RAW
       peuvent ouvrir des sockets packet.

       Les paquets des sockets 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,  l’adresse est toujours examinée et fournie dans une
       structure standard sockaddr_ll  Lors  de  l’émission  d’un  paquet,  le
       buffer  fourni  par  l’utilisateur  doit  contenir  l’en-tête du niveau
       physique.  Le  paquet  est  alors  mis  en  file  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
       ajoute  toujours  d’autres  en-têtes.   SOCK_RAW est identique mais non
       compatible avec l’ancien SOCK_PACKET de Linux 2.0.

       SOCK_DGRAM opère à un niveau légèrement plus élevé. L’en-tête du niveau
       physique   est  supprimé  avant  que  le  paquet  ne  soit  transmis  à
       l’utilisateur. Les paquets envoyés par  une  socket  packet  SOCK_DGRAM
       reçoivent  un  en-tête  de  niveau  physique  correct,  en fonction des
       informations dans l’adresse destination sockaddr_ll avant d’être mis en
       file.

       Par défaut, tous les paquets du type de protocole indiqué sont passés à
       la 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 la socket à une interface. Seuls  les  champs
       d’adresse sll_protocol et sll_ifindex sont utilisés pour l’attachement.

       L’opération connect(3) n’est pas supportée sur les sockets packet.

       Lorsque  l’attribut  MSG_TRUNC  est  transmis  à  recvmsg(2),  recv(2),
       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 buffer.

TYPES DADRESSE
       La structure sockaddr_ll est une adresse du niveau  physique  dépendant
       du périphérique.

              struct sockaddr_ll {
                  unsigned short  sll_family;   /* Toujours AF_PACKET        */
                  unsigned short  sll_protocol; /* Protocole niveau physique */
                  int             sll_ifindex;  /* Numéro d’interface        */
                  unsigned short  sll_hatype;   /* Type d’en-tête            */
                  unsigned char   sll_pkttype;  /* Type de paquet            */
                  unsigned char   sll_halen;    /* Longueur de l’adresse     */
                  unsigned char   sll_addr[8];  /* Adresse niveau physique   */
              };

       sll_protocol  est  le type de protocole standard ethernet, dans l’ordre
       des  octets  du  réseau,  comme  défini  dans  le   fichier   d’en-tête
       linux/if_ether.h.   Par  défaut  il  s’agit  du protocole de la socket.
       sll_ifindex  est  le  numéro  de  l’interface  (voir  netdevice(2));  0
       correspond  à  n’importe  quelle  interface  (autorisé  uniquement pour
       l’attachement).  sll_hatype est un  type  ARP,  comme  défini  dans  le
       fichier  d’en-tête  linux/if_arp.h.   Le  champ sll_pkttype contient le
       type de paquet. Les types  valides  sont  PACKET_HOST  pour  un  paquet
       destiné  à  l’hôte  local, PACKET_BROADCAST pour un paquet broadcast du
       niveau physique, PACKET_MULTICAST pour un paquet envoyé à  une  adresse
       multicast du niveau 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 une socket packet.  Ceci n’a de signification  qu’en
       réception.   sll_addr  et  sll_halen  contiennent  l’adresse  de niveau
       physique (par exemple IEEE  802.3)  et  sa  longueur.  L’interprétation
       exacte dépend du périphérique.

       Lorsqu’on   envoie   des  paquets,  il  suffit  d’indiquer  sll_family,
       sll_addr, sll_halen, sll_ifindex.  Les autres champs devraient  être  à
       zéro.   sll_hatype  et  sll_pkttype  sont  remplis  en  réception  pour
       information.  Pour l’attachement,  seuls  sll_protocol  et  sll_ifindex
       sont utilisés.

OPTIONS DES SOCKETS

       Les   options   des   sockets   packets  permettent  de  configurer  le
       multicasting du niveau physique et le mode promiscuous. Cela fonctionne
       en  appelant  setsockopt(2)  sur  une  socket packet avec SOL_PACKET et
       l’option  PACKET_ADD_MEMBERSHIP  pour   ajouter   un   attachement   ou
       PACKET_DROP_MEMBERSHIP pour en supprimer un.  Toutes les deux attendent
       une structure packet_mreq en argument :

              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 niveau physique */
              };

       mr_ifindex contient le numéro de l’interface dont le statut  doit  être
       modifié.    Le   paramètre   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 la socket au  groupe  multicast  de  niveau
       physique  indiqué  dans  mr_address  et  mr_alen, et PACKET_MR_ALLMULTI
       demande à la socket de recevoir tous les paquets multicast arrivant sur
       l’interface.

       De plus, les ioctls classiques SIOCSIFFLAGS, SIOCADDMULTI, SIOCDELMULTI
       peuvent donner les mêmes résultats.

IOCTLS

       SIOCGSTAMP peut servir à obtenir l’horodatage du dernier  paquet  reçu.
       L’argument est une structure struct timeval.

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

GESTION DERREUR
       Les sockets  packets  ne  gère  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.

COMPATIBILITÉ

       Sous Linux 2.0, la seule manière  d’obtenir  une  socket  packet  était
       l’appel   socket(PF_INET,  SOCK_PACKET,  protocol).   Ceci  est  encore
       supporté mais 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 du niveau 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 caractère nul, par exemple eth0.

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

NOTES

       Pour  la  portabilité,  il est conseillé d’utiliser les fonctionnalités
       PF_PACKET par l’intermédiaire de l’interface pcap(3); bien que cela  ne
       couvre qu’un sous-ensembles des possibilités de PF_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.
       A  la  place,  ils  sont  fournis  à  l’utilisateur  sous  le protocole
       ETH_P_802_2 sans en-tête LLC ajouté. Il  n’est  donc  pas  possible  de
       faire  d’attachement  ETH_P_802_3;  L’attachement ETH_P_802_2 doit être
       réalisé à la place, et le multiplexage de protocole doit  être  réalisé
       manuellement.    Le   comportement   par   défaut   en   émission   est
       l’encapsulation Ethernet DIX standard, avec le protocole renseigné.

       Les sockets packets ne sont pas soumises aux  chaînes  de  firewall  en
       entrée ou sortie.

ERREURS

       ENETDOWN
              L’interface n’est pas en marche.

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

       ENODEV Le  nom  du  prériphérique  ou  l’index  interface spécifié dans
              l’adresse de l’interface est inconnu.

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

       ENOBUFS
              Pas assez de mémoire pour le paquet.

       EFAULT Adresse mémoire invalide.

       EINVAL Argument invalide.

       ENXIO  Numéro d’interface illégal.

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

       EADDRNOTAVAIL
              Adresse de groupe multicast inconnue.

       ENOENT Pas  de  paquet  reçu.   De  plus, d’autres erreurs peuvent être
              engendrées par le pilote bas-niveau.

VERSIONS

       PF_PACKET est une nouveauté de Linux 2.2. Les versions Linux précédente
       ne supportaient que SOCK_PACKET.

BOGUES

       La  GlibC  2.1 ne définit pas la constante symbolique SOL_PACKET.  Pour
       contourner ce problème, il est conseillé d’écrire :
              #ifndef SOL_PACKET
              #define SOL_PACKET 263
              #endif
       Ceci est corrigé dans les dernières versions  de  la  GlibC  et  ne  se
       produit pas sur les LibC5.

       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 recmsg est une bidouille horrible  et  devrait
       être remplacée par un message de commande.  Il n’y a actuellement aucun
       moyen d’obtenir l’adresse de  destination  originale  des  paquets  via
       SOCK_DGRAM.

NOTE HISTORIQUE

       Le fichier d’inclusion <netpacket/packet.h> existe depuis glibc2.1. Les
       systèmes plus anciens ont besoin de

       #include <asm/types.h>
       #include <linux/if_packet.h>
       #include <linux/if_ether.h> /* Les protocoles L2 */

VOIR AUSSI

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

       RFC 894 pour l’encapsulation standard Ethernet.

       RFC 1700 pour l’encapsulation IP IEEE 802.3.

       Le fichier d’en-tête linux/if_ether.h pour  les  protocoles  du  niveau
       physique.

TRADUCTION

       Christophe Blaess, 2001-2003.