NOM¶
CMSG_ALIGN, CMSG_SPACE, CMSG_NXTHDR, CMSG_FIRSTHDR - Accéder aux
informations de service
SYNOPSIS¶
#include <sys/socket.h>
struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *msgh);
struct cmsghdr *CMSG_NXTHDR(struct msghdr *msgh, struct
cmsghdr *cmsg);
size_t CMSG_ALIGN(size_t length);
size_t CMSG_SPACE(size_t length);
size_t CMSG_LEN(size_t length);
unsigned char *CMSG_DATA(struct cmsghdr *cmsg);
struct cmsghdr {
socklen_t cmsg_len; /* Nombre d'octets de données, incluant l'en-tête */
int cmsg_level; /* Protocole d'origine */
int cmsg_type; /* Type spécifique au protocole */
/* suivi par unsigned char cmsg_data[]; */
};
DESCRIPTION¶
Ces macros sont utilisées pour créer et accéder aux messages de
contrôle (aussi appelé informations de service) qui ne font pas
partie du trafic normal des sockets. Ces informations de contrôle peuvent
inclure l'interface sur laquelle le paquet a été reçu, des
champs d'en-tête rarement employés, des descriptions d'erreur
approfondies, un ensemble de descripteurs de fichiers ou des identificateurs
UNIX. Par exemple, les messages de contrôle peuvent être
utilisés pour envoyer des champs d'en-tête supplémentaires tels
que des options IP. Les données de service sont émises avec
sendmsg(2) et reçues avec
recvmsg(2). Reportez-vous à
leur page de manuel respective pour plus d'informations.
Une information de service est une séquence de structures
cmsghdr
avec des données ajoutées. Cette séquence ne doit être
manipulée qu'au moyen des macros décrites dans cette page de manuel,
et jamais directement. Consultez les pages relatives aux protocoles des types
de message de commande disponibles. La taille maximale d'un tampon de service
par socket peut être définie à l'aide de
/proc/sys/net/core/optmem_max. Consultez
socket(7).
CMSG_FIRSTHDR() renvoie un pointeur sur la première
cmsghdr
du tampon de données de service associé au
msghdr passé.
CMSG_NXTHDR() renvoie le prochain
cmsghdr valable suivant
après le
cmsghdr transmis. Elle renvoie NULL s'il n'y a plus assez
de place dans le tampon.
CMSG_ALIGN(), avec comme argument une longueur, renvoie l'alignement
nécessaire. C'est une expression constante.
CMSG_SPACE() renvoie le nombre d'octets d'un élément de service
avec la charge utile de la longueur passée en paramètre. C'est une
expression constante.
CMSG_DATA() renvoie un pointeur sur une partie des données d'un
cmsghdr.
CMSG_LEN() renvoie la valeur à stocker dans le membre
cmsg_len de la structure
cmsghdr, en tenant compte des
alignements. Elle prend en paramètre la longueur des données. C'est
une expression constante.
Pour créer des données de service, il faut tout d'abord initialiser le
membre
msg_controllen de la structure
msghdr avec la longueur du
message de contrôle. Utilisez
CMSG_FIRSTHDR() sur la structure
msghdr pour obtenir le premier message de contrôle, puis
CMSG_NXTHDR() pour obtenir les suivants. Dans chaque message de
contrôle, initialisez
cmsg_len (avec
CMSG_LEN()), les
autres champs d'en-tête de
cmsghdr, et la partie de données
avec
CMSG_DATA(). Enfin, il faut définir le membre
msg_controllen de la structure
msghdr avec la somme de tous les
messages de contrôle dans le tampon renvoyé par
CMSG_SPACE().Pour plus d'informations sur
msghdr, consultez
recvmsg(2).
Lorsque le tampon de message de contrôle est trop petit pour stocker tous
les messages, le drapeau
MSG_CTRUNC du membre
msg_flags de
msghdr est activé.
Le modèle des données de service est conforme à POSIX.1g draft,
BSD 4.4-Lite, « IPv6 advanced API » décrite dans
la RFC 2292 et SUSv2.
CMSG_ALIGN() est une extension Linux.
NOTES¶
Pour des questions de portabilité, les données de service ne doivent
être manipulées qu'avec les macros décrites ici.
CMSG_ALIGN() est une extension Linux et ne doit pas être
utilisée dans un programme portable.
Sous Linux,
CMSG_LEN(),
CMSG_DATA(), et
CMSG_ALIGN() sont
des expressions constantes (si leur argument est une constante) ; on peut
donc les utiliser pour déclarer la taille de variables globales. Cela
peut néanmoins ne pas être portable.
EXEMPLE¶
Ce code recherche l'option
IP_TTL dans un tampon de service
reçu :
struct msghdr msgh;
struct cmsghdr *cmsg;
int *ttlptr;
int received_ttl;
/* Receive auxiliary data in msgh */
for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
cmsg = CMSG_NXTHDR(&msgh,cmsg)) {
if (cmsg->cmsg_level == IPPROTO_IP
&& cmsg->cmsg_type == IP_TTL) {
ttlptr = (int *) CMSG_DATA(cmsg);
received_ttl = *ttlptr;
break;
}
}
if (cmsg == NULL) {
/*
* Error: IP_TTL not enabled or small buffer
* or I/O error.
*/
}
Ce code, ci-dessous, passe une table de descripteurs de fichier au travers d'une
socket de domaine UNIX avec
SCM_RIGHTS :
struct msghdr msg = {0};
struct cmsghdr *cmsg;
int myfds[NUM_FD]; /* Contains the file descriptors to pass. */
char buf[CMSG_SPACE(sizeof myfds)]; /* ancillary data buffer */
int *fdptr;
msg.msg_control = buf;
msg.msg_controllen = sizeof buf;
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int) * NUM_FD);
/* Initialize the payload: */
fdptr = (int *) CMSG_DATA(cmsg);
memcpy(fdptr, myfds, NUM_FD * sizeof(int));
/* Sum of the length of all control messages in the buffer: */
msg.msg_controllen = cmsg->cmsg_len;
VOIR AUSSI¶
recvmsg(2),
sendmsg(2)
RFC 2292
COLOPHON¶
Cette page fait partie de la publication 3.44 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¶
Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a
<
http://po4a.alioth.debian.org/> par l'équipe de traduction
francophone au sein du projet perkamon
<
http://perkamon.alioth.debian.org/>.
Christophe Blaess <
http://www.blaess.fr/christophe/> (1996-2003), Alain
Portal <
http://manpagesfr.free.fr/> (2003-2006). Florentin Duneau et
l'équipe francophone de traduction de Debian (2006-2009).
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> ».