Man page - sock_diag(7)

Packages contains this manual

Available languages:

en fr ru

Manual

sock_diag

NOM
SYNOPSIS
DESCRIPTION
RequĂȘte
Réponse
Sockets de domaine UNIX
Sockets IPv4 et IPv6
Informations sur la mémoire du socket
VERSIONS
STANDARDS
EXEMPLES
VOIR AUSSI
TRADUCTION

NOM

sock_diag – Obtention d’informations à propos des sockets

SYNOPSIS

#include <sys/socket.h>
#include <linux/sock_diag.h>
#include <linux/unix_diag.h>
/* pour sockets de domaine UNIX */
#include <linux/inet_diag.h>
/* pour sockets IPv4 et IPv6 */

diag_socket = socket(AF_NETLINK, socket_type , NETLINK_SOCK_DIAG);

DESCRIPTION

Le sous-systĂšme netlink de sock_diag fournit un mĂ©canisme pour obtenir les informations sur les sockets de diverses familles d’adresses du noyau. Ce sous-systĂšme peut ĂȘtre utilisĂ© pour obtenir des informations Ă  propos de sockets particuliers ou pour obtenir la liste des sockets.

Dans la requĂȘte, l’appelant peut indiquer les informations supplĂ©mentaires qu’il dĂ©sire obtenir Ă  propos du socket, par exemple, les informations sur la mĂ©moire ou les informations spĂ©cifiques Ă  une famille d’adresses.

Lors d’une requĂȘte d’une liste de sockets, l’appelant peut indiquer des filtres Ă  appliquer par le noyau pour sĂ©lectionner un sous-ensemble de sockets. Pour l’instant, il est seulement possible de filtrer les sockets par Ă©tat (connectĂ©, Ă  l’écoute, etc).

Remarquez que sock_diag rapporte seulement les sockets ayant un nom. C’est-Ă -dire soit les sockets liĂ©s explicitement avec bind (2) ou les sockets qui ont Ă©tĂ© automatiquement liĂ©s Ă  une adresse (par exemple, par connect (2)). C’est le mĂȘme ensemble de sockets disponible Ă  l’aide de /proc/net/unix , /proc/net/tcp , /proc/net/udp , etc.

RequĂȘte

La requĂȘte dĂ©bute par un en-tĂȘte struct nlmsghdr dĂ©crit dans netlink (7) avec un champ nlmsg_type rĂ©glĂ© Ă  SOCK_DIAG_BY_FAMILY . Il est suivi par un en-tĂȘte spĂ©cifique Ă  une famille d’adresses qui dĂ©bute par une partie commune partagĂ©e par toutes les familles d’adresses :

struct sock_diag_req {
__u8 sdiag_family;
__u8 sdiag_protocol;
};

Les membres de cette structure sont les suivants :
sdiag_family

Une famille d’adresses. Elle devrait ĂȘtre rĂ©glĂ©e Ă  la constante AF_* appropriĂ©e.

sdiag_protocol

Fonction de sdiag_family . Il devrait ĂȘtre rĂ©glĂ© Ă  la constante IPPROTO_* appropriĂ©e pour AF_INET et AF_INET6 , et à 0 autrement.

Si le champ nlmsg_flags de l’en-tĂȘte struct nlmsghdr a l’indicateur NLM_F_DUMP dĂ©fini, cela signifie qu’une liste de sockets est demandĂ©e. Sinon, il s’agit d’une requĂȘte concernant un socket particulier.

Réponse

La rĂ©ponse dĂ©bute avec un en-tĂȘte struct nlmsghdr et est suivie par un tableau d’objets spĂ©cifique Ă  la famille d’adresses. Le tableau est accessible avec les macros NLMSG_* standards de l’API de netlink (3).

Chaque objet est la liste NLA (attributs netlink) accessible avec les macros RTA_* de l’API de rtnetlink (3).

Sockets de domaine UNIX

Pour les sockets de domaine UNIX, la requĂȘte est dĂ©crite dans la structure suivante :

struct unix_diag_req {
__u8 sdiag_family;
__u8 sdiag_protocol;
__u16 pad;
__u32 udiag_states;
__u32 udiag_ino;
__u32 udiag_show;
__u32 udiag_cookie[2];
};

Les membres de cette structure sont les suivants :
sdiag_family

La famille d’adresses. Elle devrait ĂȘtre AF_UNIX .

sdiag_protocol

pad

Ces champs devraient ĂȘtre rĂ©glĂ©s Ă  0.

udiag_states

C’est un masque de bits dĂ©finissant un filtre d’états des sockets. Seuls les sockets dont les Ă©tats sont dans le masque seront rapportĂ©s. Il est ignorĂ© lors d’une requĂȘte pour un socket particulier. Les valeurs autorisĂ©es sont :

1 << TCP_ESTABLISHED

1 << TCP_LISTEN

udiag_ino

C’est un numĂ©ro d’inƓud lors d’une requĂȘte pour un socket particulier. Il est ignorĂ© lors d’une requĂȘte pour une liste de sockets.

udiag_show

C’est un ensemble d’indicateurs dĂ©finissant quelle sorte d’information rapporter. Chaque sorte d’information est rapportĂ©e sous forme d’attribut netlink comme dĂ©crit ci-dessous :
UDIAG_SHOW_NAME

L’attribut rapportĂ© dans la rĂ©ponse Ă  cette requĂȘte est UNIX_DIAG_NAME . La charge utile associĂ©e Ă  cet attribut est le nom de chemin auquel le socket a Ă©tĂ© liĂ© (une sĂ©quence d’octets de taille maximale UNIX_PATH_MAX ).

UDIAG_SHOW_VFS

L’attribut rapportĂ© dans la rĂ©ponse Ă  cette requĂȘte est UNIX_DIAG_VFS . La charge utile associĂ©e Ă  cet attribut est dĂ©crite dans la structure suivante :

struct unix_diag_vfs {
__u32 udiag_vfs_dev;
__u32 udiag_vfs_ino;
};

Les membres de cette structure sont les suivants :
udiag_vfs_dev

Le numĂ©ro de pĂ©riphĂ©rique de l’inƓud correspondant de socket sur le disque.

udiag_vfs_ino

Le numĂ©ro d’inƓud de l’inƓud correspondant de socket sur le disque.

UDIAG_SHOW_PEER

L’attribut rapportĂ© dans la rĂ©ponse Ă  cette requĂȘte est UNIX_DIAG_PEER . La charge utile associĂ©e Ă  cet attribut est une valeur __u32 qui est le numĂ©ro d’inƓud du pair. Cet attribut est rapportĂ© seulement pour les sockets connectĂ©s.

UDIAG_SHOW_ICONS

L’attribut rapportĂ© dans la rĂ©ponse Ă  cette requĂȘte est UNIX_DIAG_ICONS . La charge utile associĂ©e Ă  cet attribut est un tableau de valeurs __u32 qui sont des numĂ©ros d’inƓuds de sockets qui ont passĂ© l’appel connect (2), mais qui n’ont pas encore Ă©tĂ© traitĂ©s par accept (2). Cet attribut est rapportĂ© seulement pour les sockets Ă  l’écoute.

UDIAG_SHOW_RQLEN

L’attribut rapportĂ© dans la rĂ©ponse Ă  cette requĂȘte est UNIX_DIAG_RQLEN . La charge utile associĂ©e Ă  cet attribut est dĂ©crite dans la structure suivante :

struct unix_diag_rqlen {
__u32 udiag_rqueue;
__u32 udiag_wqueue;
};

Les membres de cette structure sont les suivants :
udiag_rqueue

Pour les sockets Ă  l’écoute : le nombre de connexions en attente. La taille du tableau associĂ© Ă  l’attribut de la rĂ©ponse UNIX_DIAG_ICONS est Ă©gale Ă  cette valeur.

Pour les sockets Ă©tablis : la quantitĂ© de donnĂ©es dans la file d’attente entrante.

udiag_wqueue

Pour les sockets Ă  l’écoute : la taille de l’arriĂ©rĂ© qui est Ă©gale Ă  la valeur passĂ©e comme second argument Ă  listen (2).

Pour les sockets Ă©tablis : la quantitĂ© de mĂ©moire disponible pour l’émission.

UDIAG_SHOW_MEMINFO

L’attribut rapportĂ© dans la rĂ©ponse Ă  cette requĂȘte est UNIX_DIAG_MEMINFO . La charge utile associĂ©e Ă  cet attribut est un tableau de valeurs __u32 dĂ©crites dans la sous-section « Informations sur la mĂ©moire de socket ».

Les attributs suivants sont rapportĂ©s sans requĂȘte particuliĂšre :
UNIX_DIAG_SHUTDOWN

La charge utile associĂ©e Ă  cet attribut est une valeur __u8 reprĂ©sentant les bits de l’état de shutdown (2).

udiag_cookie

C’est un tableau d’identificateurs opaques pouvant ĂȘtre utilisĂ©s avec udiag_ino pour indiquer un socket particulier. Il est ignorĂ© lors de la requĂȘte d’une liste de sockets ainsi que lorsque ses Ă©lĂ©ments sont rĂ©glĂ©s à -1.

La rĂ©ponse Ă  une requĂȘte de sockets de domaine UNIX est dĂ©crite sous forme de tableau de

struct unix_diag_msg {
__u8 udiag_family;
__u8 udiag_type;
__u8 udiag_state;
__u8 pad;
__u32 udiag_ino;
__u32 udiag_cookie[2];
};

suivis par les attributs de netlink.

Les membres de cette structure sont les suivants :
udiag_family

Ce champ a la mĂȘme signification que struct unix_diag_req .

udiag_type

Ce champ est réglé à SOCK_PACKET , SOCK_STREAM ou SOCK_SEQPACKET .

udiag_state

Ce champ est réglé à TCP_LISTEN ou TCP_ESTABLISHED .

pad

Ce champ est réglé à 0.

udiag_ino

Ce champ est le numĂ©ro d’inƓud de socket.

udiag_cookie

Ce champ est un tableau d’identificateurs opaques pouvant ĂȘtre utilisĂ©s dans des requĂȘtes ultĂ©rieures.

Sockets IPv4 et IPv6

Pour les sockets IPv4 et IPv6, la requĂȘte est dĂ©crite dans la structure suivante :

struct inet_diag_req_v2 {
__u8 sdiag_family;
__u8 sdiag_protocol;
__u8 idiag_ext;
__u8 pad;
__u32 idiag_states;
struct inet_diag_sockid id;
};

oĂč struct inet_diag_sockid est dĂ©fini comme suit :

struct inet_diag_sockid {
__be16 idiag_sport;
__be16 idiag_dport;
__be32 idiag_src[4];
__be32 idiag_dst[4];
__u32 idiag_if;
__u32 idiag_cookie[2];
};

Les champs de struct inet_diag_req_v2 sont comme suit :
sdiag_family

Cela devrait ĂȘtre soit AF_INET ou AF_INET6 pour les sockets IPv4 ou IPv6 respectivement.

sdiag_protocol

Cela devrait ĂȘtre rĂ©glĂ© Ă  IPPROTO_TCP , IPPROTO_UDP ou IPPROTO_UDPLITE .

idiag_ext

C’est un ensemble d’indicateurs dĂ©finissant quelle sorte d’informations Ă©tendues Ă  rapporter. Chaque sorte d’informations est rapportĂ©e sous forme d’attribut de netlink comme dĂ©crit ci-dessous :
INET_DIAG_TOS

La charge utile associée à cet attribut est une valeur __u8 qui est le TOS du socket.

INET_DIAG_TCLASS

La charge utile associĂ©e Ă  cet attribut est une valeur __u8 qui est la TClass du socket — sockets IPv6 uniquement. Pour les sockets LISTEN et CLOSE, cela est suivi par l’attribut INET_DIAG_SKV6ONLY avec la valeur associĂ©e __u8 de charge utile signifiant si le socket est seulement IPv6 ou non.

INET_DIAG_MEMINFO

La charge utile associée à cet attribut est décrite dans la structure suivante :

struct inet_diag_meminfo {
__u32 idiag_rmem;
__u32 idiag_wmem;
__u32 idiag_fmem;
__u32 idiag_tmem;
};

Les membres de cette structure sont les suivants :

idiag_rmem

La quantité de données dans la file de réception.

idiag_wmem

La quantité de données mises dans la file par TCP mais non encore envoyées.

idiag_fmem

La quantité de mémoire prévue pour une utilisation future (TCP uniquement).

idiag_tmem

La quantitĂ© de donnĂ©es dans la file d’émission.

INET_DIAG_SKMEMINFO

La charge utile associée à cet attribut est un tableau de valeurs __u32 décrites ci-dessous dans la sous-section « Informations sur la mémoire de socket ».

INET_DIAG_INFO

La charge utile associĂ©e Ă  cet attribut est spĂ©cifique Ă  la famille d’adresses. Pour les sockets TCP, c’est un objet de type struct tcp_info .

INET_DIAG_CONG

La charge utile associĂ©e avec cet attribut est une chaĂźne dĂ©crivant l’algorithme de contrĂŽle de congestion utilisĂ©. Uniquement pour les sockets TCP.

pad

Cela devrait ĂȘtre rĂ©glĂ© à 0.

idiag_states

C’est un masque de bits dĂ©finissant un filtre d’états des sockets. Seuls les sockets dont les Ă©tats sont dans le masque seront rapportĂ©s. Il est ignorĂ© lors d’une requĂȘte pour un socket particulier.

id

C’est un objet d’ID de socket utilisĂ© dans les requĂȘtes de vidage, dans les requĂȘtes Ă  propos de sockets particuliers et qui est rapportĂ© dans chaque rĂ©ponse. Au contraire des sockets de domaine UNIX, les sockets IPv4 et IPv6 sont identifiĂ©s en utilisant des adresses et des ports. Toutes les valeurs sont dans l’ordre d’octets du rĂ©seau.

Les champs de struct inet_diag_sockid sont comme suit :
idiag_sport

Le port de la source.

idiag_dport

Le port de la destination.

idiag_src

L’adresse de la source.

idiag_dst

L’adresse de la destination.

idiag_if

Le numĂ©ro d’interface auquel le socket est liĂ©.

idiag_cookie

C’est un tableau d’identificateurs opaques pouvant ĂȘtre utilisĂ©s dans d’autres champs de cette structure pour indiquer un socket particulier. Il est ignorĂ© lors d’une requĂȘte pour une liste de sockets, de mĂȘme que lorsque tous ses Ă©lĂ©ments sont rĂ©glĂ©s à -1.

La rĂ©ponse Ă  une requĂȘte de sockets IPv4 ou IPv6 est dĂ©crite sous forme d’un tableau de

struct inet_diag_msg {
__u8 idiag_family;
__u8 idiag_state;
__u8 idiag_timer;
__u8 idiag_retrans;
struct inet_diag_sockid id;
__u32 idiag_expires;
__u32 idiag_rqueue;
__u32 idiag_wqueue;
__u32 idiag_uid;
__u32 idiag_inode;
};

suivis par les attributs de netlink.

Les membres de cette structure sont les suivants :
idiag_family

c’est le mĂȘme champ que dans struct inet_diag_req_v2 .

idiag_state

Cela indique l’état comme dans struct inet_diag_req_v2 .

idiag_timer

Pour les sockets TCP, ce champ décrit le type de temporisateur actuellement actif pour le socket. Il est réglé à une des constantes suivantes :

0

aucun temporisateur actif

1

un temporisateur de retransmission

2

un temporisateur d’entretien

3

un temporisateur TIME_WAIT

4

un temporisateur de sonde de fenĂȘtre nulle

Pour les sockets non TCP, ce champ doit ĂȘtre rĂ©glĂ© à 0.

idiag_retrans

Pour les valeurs 1, 2 et 4 d’ idiag_timer , ce champ contient le nombre de retransmissions. Pour les autres valeurs d’ idiag_timer , ce champ est rĂ©glĂ© à 0.

idiag_expires

Pour les sockets TCP ayant un temporisateur actif, ce champ indique son dĂ©lai d’expiration en milliseconde. Pour les autres sockets, ce champ est rĂ©glĂ© à 0.

idiag_rqueue

Pour les sockets Ă  l’écoute : le nombre de connexions en attente.

Pour les autres sockets : la quantitĂ© de donnĂ©es dans la file d’attente entrante.

idiag_wqueue

Pour les sockets Ă  l’écoute : la taille de l’arriĂ©rĂ©.

Pour les autres sockets : la quantitĂ© de mĂ©moire disponible pour l’envoi.

idiag_uid

C’est l’UID du propriĂ©taire du socket.

idiag_inode

Ce champ est le numĂ©ro d’inƓud de socket.

Informations sur la mémoire du socket

La charge utile associée avec les attributs UNIX_DIAG_MEMINFO et INET_DIAG_SKMEMINFO de netlink est un tableau des valeurs __u32 suivantes :
SK_MEMINFO_RMEM_ALLOC

La quantitĂ© de donnĂ©es dans la file d’attente de rĂ©ception.

SK_MEMINFO_RCVBUF

Le tampon de réception de socket comme réglé par SO_RCVBUF .

SK_MEMINFO_WMEM_ALLOC

La quantitĂ© de donnĂ©es dans la file d’émission.

SK_MEMINFO_SNDBUF

Le tampon d’émission de socket comme rĂ©glĂ© par SO_SNDBUF .

SK_MEMINFO_FWD_ALLOC

La quantité de mémoire prévue pour une utilisation future (TCP uniquement).

SK_MEMINFO_WMEM_QUEUED

La quantité de données mises en attente par TCP, mais pas encore envoyées.

SK_MEMINFO_OPTMEM

La quantité de mémoire allouée pour les besoins du service du socket (par exemple, filtre du socket).

SK_MEMINFO_BACKLOG

La quantitĂ© de paquets dans l’arriĂ©rĂ© (pas encore traitĂ©).

VERSIONS

NETLINK_INET_DIAG a été introduit dans Linux 2.6.14 et ne gÚre que les sockets AF_INET et AF_INET6 . Dans Linux 3.3, il a été renommé NETLINK_SOCK_DIAG et étendu pour gérer les sockets AF_UNIX .

UNIX_DIAG_MEMINFO et INET_DIAG_SKMEMINFO ont été introduits dans Linux 3.6.

STANDARDS

Linux.

EXEMPLES

L’exemple suivant affiche le numĂ©ro d’inƓud, le numĂ©ro d’inƓud du pair et le nom de tous les sockets de domaine UNIX dans l’espace de noms en cours.

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/sock_diag.h>
#include <linux/unix_diag.h>
static int
send_query(int fd)
{
struct sockaddr_nl nladdr = {
.nl_family = AF_NETLINK
};
struct
{
struct nlmsghdr nlh;
struct unix_diag_req udr;
} req = {
.nlh = {
.nlmsg_len = sizeof(req),
.nlmsg_type = SOCK_DIAG_BY_FAMILY,
.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP
},
.udr = {
.sdiag_family = AF_UNIX,
.udiag_states = -1,
.udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER
}
};
struct iovec iov = {
.iov_base = &req,
.iov_len = sizeof(req)
};
struct msghdr msg = {
.msg_name = &nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1
};
for (;;) {
if (sendmsg(fd, &msg, 0) < 0) {
if (errno == EINTR)
continue;
perror("sendmsg");
return -1;
}
return 0;
}
}
static int
print_diag(const struct unix_diag_msg *diag, unsigned int len)
{
if (len < NLMSG_LENGTH(sizeof(*diag))) {
fputs("short response\n", stderr);
return -1;
}
if (diag->udiag_family != AF_UNIX) {
fprintf(stderr, "unexpected family %u\n", diag->udiag_family);
return -1;
}
unsigned int rta_len = len - NLMSG_LENGTH(sizeof(*diag));
unsigned int peer = 0;
size_t path_len = 0;
char path[sizeof(((struct sockaddr_un *) 0)->sun_path) + 1];
for (struct rtattr *attr = (struct rtattr *) (diag + 1);
RTA_OK(attr, rta_len); attr = RTA_NEXT(attr, rta_len)) {
switch (attr->rta_type) {
case UNIX_DIAG_NAME:
if (!path_len) {
path_len = RTA_PAYLOAD(attr);
if (path_len > sizeof(path) - 1)
path_len = sizeof(path) - 1;
memcpy(path, RTA_DATA(attr), path_len);
path[path_len] = '\0';
}
break;
case UNIX_DIAG_PEER:
if (RTA_PAYLOAD(attr) >= sizeof(peer))
peer = *(unsigned int *) RTA_DATA(attr);
break;
}
}
printf("inode=%u", diag->udiag_ino);
if (peer)
printf(", peer=%u", peer);
if (path_len)
printf(", name=%s%s", *path ? "" : "@",
*path ? path : path + 1);
putchar('\n');
return 0;
}
static int
receive_responses(int fd)
{
long buf[8192 / sizeof(long)];
struct sockaddr_nl nladdr;
struct iovec iov = {
.iov_base = buf,
.iov_len = sizeof(buf)
};
int flags = 0;
for (;;) {
struct msghdr msg = {
.msg_name = &nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1
};
ssize_t ret = recvmsg(fd, &msg, flags);
if (ret < 0) {
if (errno == EINTR)
continue;
perror("recvmsg");
return -1;
}
if (ret == 0)
return 0;
if (nladdr.nl_family != AF_NETLINK) {
fputs("!AF_NETLINK\n", stderr);
return -1;
}
const struct nlmsghdr *h = (struct nlmsghdr *) buf;
if (!NLMSG_OK(h, ret)) {
fputs("!NLMSG_OK\n", stderr);
return -1;
}
for (; NLMSG_OK(h, ret); h = NLMSG_NEXT(h, ret)) {
if (h->nlmsg_type == NLMSG_DONE)
return 0;
if (h->nlmsg_type == NLMSG_ERROR) {
const struct nlmsgerr *err = NLMSG_DATA(h);
if (h->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) {
fputs("NLMSG_ERROR\n", stderr);
} else {
errno = -err->error;
perror("NLMSG_ERROR");
}
return -1;
}
if (h->nlmsg_type != SOCK_DIAG_BY_FAMILY) {
fprintf(stderr, "unexpected nlmsg_type %u\n",
(unsigned) h->nlmsg_type);
return -1;
}
if (print_diag(NLMSG_DATA(h), h->nlmsg_len))
return -1;
}
}
}
int
main(void)
{
int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG);
if (fd < 0) {
perror("socket");
return 1;
}
int ret = send_query(fd) || receive_responses(fd);
close(fd);
return ret;
}

VOIR AUSSI

netlink (3), rtnetlink (3), netlink (7), tcp (7)

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 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 .