packet(7) Miscellaneous Information Manual packet(7) NOM packet - Interface de paquets au niveau du peripherique SYNOPSIS #include #include #include /* Les protocoles L2 */ packet_socket = socket(AF_PACKET, int type_socket, int protocole); DESCRIPTION Les sockets packet sont utilises pour envoyer ou recevoir des paquets bruts au pilote de peripherique (couche 2 OSI). Ils permettent d'implementer des modules de protocole dans l'espace utilisateur au-dessus de la couche physique. The socket_type is either SOCK_RAW for raw packets including the link-level header or SOCK_DGRAM for cooked packets with the link-level header removed. The link-level header information is available in a common format in a sockaddr_ll structure. protocol is the IEEE 802.3 protocol number in network byte order. See the include file for a list of allowed protocols. When protocol is set to htons(ETH_P_ALL), then all protocols are received. All incoming packets of that protocol type will be passed to the packet socket before they are passed to the protocols implemented in the kernel. If protocol is set to zero, no packets are received. bind(2) can optionally be called with a nonzero sll_protocol to start receiving packets for the protocols specified. Pour pouvoir creer des sockets packet, un processus doit posseder la capacite CAP_NET_RAW dans l'espace de noms utilisateur qui regit son espace de noms reseau. Les paquets SOCK_RAW sont transmis depuis et vers le pilote de peripherique sans aucune modification des donnees des paquets. Lors de la reception d'un paquet, l'adresse est toujours examinee et fournie dans une structure standard d'adresse sockaddr_ll. Lors de l'emission d'un paquet, le tampon fourni par l'utilisateur doit contenir l'en-tete de couche physique. Le paquet est alors mis en attente sans modification a l'attention du pilote de peripherique correspondant a l'interface definie par l'adresse de destination. Certains pilotes de peripherique ajoutent toujours d'autres en-tetes. SOCK_RAW est similaire mais non compatible avec l'ancien AF_INET/SOCK_PACKET de Linux 2.0. SOCK_DGRAM opere a un niveau legerement plus eleve. L'en-tete de couche physique est supprime avant que le paquet ne soit transmis a l'utilisateur. Les paquets envoyes par un socket packet SOCK_DGRAM recoivent un en-tete de couche physique correct base sur les informations dans l'adresse destination sockaddr_ll avant d'etre mis en attente. Par defaut, tous les paquets du type de protocole indique sont passes au socket packet. Pour ne recevoir que les paquets d'une interface donnee, utilisez bind(2) en indiquant une adresse dans une struct sockaddr_ll pour attacher le socket a une interface. Les champs utilises pour la liaison sont sll_family (devrait etre AF_PACKET), sll_protocol et sll_ifindex. L'operation connect(2) n'est pas prise en charge sur les sockets packet. Lorsque l'attribut MSG_TRUNC est transmis a recvmsg(2), recv(2) ou recvfrom(2), la veritable longueur du paquet sur le reseau est toujours renvoyee, meme si elle est plus grande que le tampon. Types d'adresses La structure sockaddr_ll est une adresse de couche physique independante du peripherique. struct sockaddr_ll { unsigned short sll_family; /* Toujours AF_PACKET */ unsigned short sll_protocol; /* Protocole couche physique */ int sll_ifindex; /* Numero d'interface */ unsigned short sll_hatype; /* Type de materiel 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 is the standard ethernet protocol type in network byte order as defined in the include file. It defaults to the socket's protocol. sll_ifindex is the interface index of the interface (see netdevice(7)); 0 matches any interface (only permitted for binding). sll_hatype is an ARP type as defined in the include file. sll_pkttype contains the packet type. Valid types are PACKET_HOST for a packet addressed to the local host, PACKET_BROADCAST for a physical-layer broadcast packet, PACKET_MULTICAST for a packet sent to a physical-layer multicast address, PACKET_OTHERHOST for a packet to some other host that has been caught by a device driver in promiscuous mode, and PACKET_OUTGOING for a packet originating from the local host that is looped back to a packet socket. These types make sense only for receiving. sll_addr sll_halen contain the physical-layer (e.g., IEEE 802.3) address and its length. The exact interpretation depends on the device. Lorsque des paquets sont envoyes, il suffit d'indiquer sll_family, sll_addr, sll_halen, sll_ifindex et sll_protocol. Les autres champs devraient etre a zero. sll_hatype et sll_pkttype sont remplis en reception pour information. Options de socket Les options du socket packet sont configurees 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 parametre : struct packet_mreq { int mr_ifindex; /* Numero 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 numero de l'interface dont l'etat doit etre modifie. Le champ mr_type indique l'action a effectuer. PACKET_MR_PROMISC valide la reception de tous les paquets circulant sur le segment de reseau commun (souvent appele << mode promiscuous >>), PACKET_MR_MULTICAST attache le socket au groupe multicast de couche physique indique 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 meme resultat. PACKET_AUXDATA (depuis Linux 2.6.21) Si cette option est activee, le socket packet fournit avec chaque paquet une structure de metadonnees a l'aide du champ de controle de recvmsg(2). La structure peut etre lue avec cmsg(3). Elle est definie ci-dessous : struct tpacket_auxdata { __u32 tp_status; __u32 tp_len; /* Longueur du paquet */ __u32 tp_snaplen; /* Longueur capturee */ __u16 tp_mac; __u16 tp_net; __u16 tp_vlan_tci; __u16 tp_vlan_tpid; /* Depuis Linux 3.14 ; precedemment c'etait des octets de remplissage non utilises */ }; PACKET_FANOUT (depuis Linux 3.1) Pour s'adapter au nombre de traitements des threads, les sockets packet peuvent former un groupe de deploiement. Dans ce mode, tous les paquets correspondants sont mis en attente dans un seul socket du groupe. Un socket rejoint un groupe de deploiement en appelant setsockopt(2) avec le niveau SOL_PACKET et l'option PACKET_FANOUT. Tous les espaces de noms reseau peuvent avoir jusqu'a 65536 groupes independants. Un socket selectionne un groupe en encodant l'identifiant dans les 16 premiers bits de la valeur d'entier de cette option. Le premier socket packet a rejoindre un groupe le cree implicitement. Pour reussir a rejoindre un groupe existant, les sockets packet suivants doivent avoir le meme protocole, la meme configuration de peripherique, le meme mode de deploiement et les memes attributs (voir ci-dessous). Les sockets packet ne peuvent quitter un groupe de deploiement qu'en fermant le socket. Le groupe est supprime quand le dernier socket est ferme. Le deploiement gere plusieurs algorithmes pour repartir le trafic entre les sockets comme suit : - Le mode par defaut, PACKET_FANOUT_HASH, envoie les paquets du meme flux au meme 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, ou le hachage du flux est un hachage sur les adresses de la couche reseau et les champs facultatifs de port de la couche transport. - Le mode repartition de charge PACKET_FANOUT_LB met en oeuvre un algorithme de tourniquet (round-robin). - PACKET_FANOUT_CPU selectionne le socket en se basant sur le CPU sur lequel le paquet arrive. - PACKET_FANOUT_ROLLOVER traite toutes les donnees sur un seul socket, allant sur le suivant quand le socket devient deborde. - PACKET_FANOUT_RND selectionne le socket en utilisant un generateur de nombres pseudo-aleatoires. - PACKET_FANOUT_QM (disponible depuis Linux 3.14) selectionne le socket en utilisant le queue_mapping enregistre du tampon de socket (SKB) recu. Les modes de deploiement acceptent des options supplementaires. La fragmentation d'IP force les paquets du meme flux a avoir des hachages de flux differents. L'attribut PACKET_FANOUT_FLAG_DEFRAG, si defini, force la defragmentation de paquets avant l'application du deploiement, pour conserver l'ordre meme dans ce cas. Le mode de deploiement et les options sont communiques sur les deuxiemes 16 bits de la valeur d'entier de cette option. L'attribut PACKET_FANOUT_FLAG_ROLLOVER active le mecanisme de deplacement comme une strategie de sauvegarde : si l'algorithme de deploiement originel selectionne un socket deborde, le paquet se deplace vers le suivant disponible. PACKET_LOSS (avec PACKET_TX_RING) Lorsqu'un paquet malforme est trouve dans le tampon circulaire de transmission, le comportement par defaut est de reinitialiser son tp_status a TP_STATUS_WRONG_FORMAT et d'abandonner immediatement la transmission. Le paquet malforme ainsi que les paquets suivants mis en file d'attente voient leur transmission bloquee. L'erreur de format doit etre corrigee, la valeur tp_status associee doit etre reinitialisee a TP_STATUS_SEND_REQUEST et le processus de transmission redemarre par l'intermediaire de l'interface send(2). Cependant, si PACKET_LOSS est defini, tout paquet malforme est ignore, son tp_status est reinitialise a TP_STATUS_AVAILABLE et le processus de transmission continue. PACKET_RESERVE (avec PACKET_RX_RING) Par defaut, un tampon circulaire de reception des paquets ecrit les paquets juste apres la structure de metadonnees et le remplissage d'alignement. La valeur d'entier de cette option reserve une possibilite de transmission supplementaire. PACKET_RX_RING Creer un tampon circulaire projete en memoire pour la reception asynchrone de paquets. Le socket packet reserve une zone contigue d'espace d'adresse d'application, la dispose dans un tableau d'emplacements de paquet et copie les paquets (jusqu'a tp_snaplen) dans les emplacements suivants. Tous les paquets sont precedes d'une structure de metadonnees similaire a tpacket_auxdata. Les champs de protocole encodent la position des donnees des le debut de l'en-tete de metadonnees. tp_net stocke la position de la couche reseau. Si le socket packet est de type SOCK_DGRAM, alors tp_mac est la meme. 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 debut et la fin du tampon circulaire a l'aide du champ tp_status. Tous les emplacements avec tp_status valant TP_STATUS_KERNEL appartiennent au socket packet. Apres avoir rempli un emplacement, il modifie l'etat de l'emplacement pour qu'il appartienne a l'application. Lors d'une operation normale, la nouvelle valeur de tp_status a au moins son bit TP_STATUS_USER active, pour signaler qu'un paquet recu a ete stocke. Lorsque l'application a termine de traiter un paquet, elle transfere la propriete de l'emplacement au socket en redefinissant tp_status a TP_STATUS_KERNEL. Les sockets packet mettent en oeuvre plusieurs variantes du tampon circulaire de paquets. Des precisions sur cette mise en place sont disponibles dans Documentation/networking/packet_mmap.rst dans l'arborescence des sources du noyau Linux. PACKET_STATISTICS Recuperer les statistiques du socket packet sous la forme d'une structure struct tpacket_stats { unsigned int tp_packets; /* Decompte total des paquets */ unsigned int tp_drops; /* Decompte des paquets jetes */ }; Recevoir les statistiques reinitialise les compteurs internes. La structure de statistiques est differente lorsque le tampon circulaire utilise est de type TPACKET_V3. PACKET_TIMESTAMP (avec PACKET_RX_RING ; depuis Linux 2.6.36) Le tampon circulaire de reception des paquets stocke un horodatage dans l'en-tete de metadonnees. Par defaut, c'est un horodatage logiciel genere quand le paquet est copie dans le tampon circulaire. Cette option d'entier selectionne le type d'horodatage. En plus du fonctionnement par defaut, il gere deux formats materiels decrits dans Documentation/networking/timestamping.rst dans l'arborescence des sources du noyau Linux. PACKET_TX_RING (depuis Linux 2.6.31) Creer un tampon circulaire projete en memoire pour la transmission de paquets. Cette option est similaire a PACKET_RX_RING et accepte les memes arguments. L'application ecrit des paquets dans des emplacements avec tp_status egal a TP_STATUS_AVAILABLE et les programme pour transmission en modifiant tp_status a la valeur TP_STATUS_SEND_REQUEST. Quand les paquets sont prets a etre transmis, l'application appelle send(2) ou une de ses variantes. Les champs buf et len de cet appel sont ignores. Si une adresse est passee en utilisant sendto(2) ou sendmsg(2), alors cela ecrase le socket par defaut. En cas de transmission reussie, le socket reinitialise tp_status a TP_STATUS_AVAILABLE. Il interrompt immediatement la transmission en cas d'erreur sauf si PACKET_LOSS est definie. PACKET_VERSION (avec PACKET_RX_RING ; depuis Linux 2.6.27) Par defaut, PACKET_RX_RING cree un tampon circulaire de reception des paquets de variante TPACKET_V1. Pour creer une autre variante, configurer la variante voulue en definissant l'option d'entier avant de creer le tampon circulaire. PACKET_QDISC_BYPASS (depuis Linux 3.14) By default, packets sent through packet sockets pass through the kernel's qdisc (traffic control) layer, which is fine for the vast majority of use cases. For traffic generator appliances using packet sockets that intend to brute-force flood the network--for example, to test devices under load in a similar fashion to pktgen--this layer can be bypassed by setting this integer option to 1. A side effect is that packet buffering in the qdisc layer is avoided, which will lead to increased drops when network device transmit queues are busy; therefore, use at your own risk. Ioctls SIOCGSTAMP peut servir a obtenir l'horodatage du dernier paquet recu. Le parametre est une variable struct timeval. De plus, les ioctls standards definis dans netdevice(7) et socket(7) sont valables sur les sockets packet. Traitement des erreurs Les sockets packet ne gerent pas d'autres erreurs que celles se produisant durant la transmission des paquets au pilote de peripherique. Elles ne traitent pas le concept de file d'erreurs. ERREURS EADDRNOTAVAIL Adresse de groupe multicast inconnue. EFAULT Adresse memoire 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 memoire pour le paquet. ENODEV Le nom du peripherique ou le numero d'interface indique dans l'adresse de l'interface est inconnu. ENOENT Pas de paquet recu. ENOTCONN Aucune adresse d'interface n'a ete passee. ENXIO Numero d'interface non valable dans son adresse. EPERM L'utilisateur n'a pas les privileges necessaires pour l'operation. De plus, d'autres erreurs peuvent etre engendrees par le pilote bas niveau. VERSIONS AF_PACKET est une nouveaute de Linux 2.2. Les versions precedentes de Linux ne prenaient en charge que SOCK_PACKET. NOTES Pour la portabilite, il est conseille d'utiliser les fonctionnalites AF_PACKET par l'intermediaire de l'interface pcap(3), bien que cela ne couvre qu'un sous-ensemble des possibilites de AF_PACKET. Les sockets packet SOCK_DGRAM n'essayent pas de creer ou de traiter les en-tetes IEEE 802.2 LLC pour une trame IEEE 802.3. Lorsque le protocole ETH_P_802_3 est indique en emission, le noyau cree la trame 802.3 et remplit le champ de longueur. L'utilisateur doit fournir l'en-tete LLC pour obtenir un paquet entierement conforme. Les paquets 802.3 entrants ne sont pas multiplexes sur les champs du protocole DSAP/SSAP. A la place, ils sont fournis a l'utilisateur sous le protocole ETH_P_802_2 avec un en-tete LLC ajoute. La liaison ETH_P_802_3 n'est donc pas possible, la liaison ETH_P_802_2 doit etre utilisee a la place, et vous devez realiser le multiplexage de protocoles vous-meme. Le comportement par defaut en emission est l'encapsulation Ethernet DIX standard, avec le protocole renseigne. Les sockets packet ne sont pas soumis aux chaines de pare-feu en entree ou sortie. Compatibilite Avec Linux 2.0, la seule facon d'obtenir un socket paquet etait avec l'appel : socket(AF_INET, SOCK_PACKET, protocol) C'est encore pris en charge mais obsolete et fortement deconseille. La principale difference entre les deux methodes est que SOCK_PACKET utilise l'ancienne struct sockaddr_pkt pour indiquer l'interface, ce qui ne fournit aucune independance vis-a-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 peripherique, spkt_protocol est le type de protocole IEEE 802.3 comme defini dans et spkt_device est le nom du peripherique sous forme de chaine terminee par un octet NULL, par exemple eth0. Cette structure est obsolete et ne doit pas etre employee dans des nouveaux programmes. BOGUES LLC header handling La gestion des en-tetes LLC IEEE 802.2/802.3 devrait etre consideree comme un bogue. MSG_TRUNC issues L'extension MSG_TRUNC de recvmsg(2) est une bidouille horrible et devrait etre remplacee par un message de controle. Il n'y a actuellement aucun moyen d'obtenir l'adresse de destination originelle des paquets a l'aide de SOCK_DGRAM. spkt_device device name truncation The spkt_device field of sockaddr_pkt has a size of 14 bytes, which is less than the constant IFNAMSIZ defined in which is 16 bytes and describes the system limit for a network interface name. This means the names of network devices longer than 14 bytes will be truncated to fit into spkt_device. All these lengths include the terminating null byte ('\0')). Issues from this with old code typically show up with very long interface names used by the Predictable Network Interface Names feature enabled by default in many modern Linux distributions. The preferred solution is to rewrite code to avoid SOCK_PACKET. Possible user solutions are to disable Predictable Network Interface Names or to rename the interface to a name of at most 13 bytes, for example using the ip(8) tool. Documentation issues Les filtres des sockets ne sont pas documentes. VOIR AUSSI socket(2), pcap(3), capabilities(7), ip(7), raw(7), socket(7), ip(8), RFC 894 pour l'encapsulation IP Ethernet standard. RFC 1700 pour l'encapsulation IP IEEE 802.3. Le fichier d'en-tete pour les protocoles de couche physique. L'arbre des sources du noyau Linux. /Documentation/networking/filter.rst decrit 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. TRADUCTION La traduction francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot et Jean-Paul Guillonneau Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.06 31 octobre 2023 packet(7)