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) ; elles
peuvent donc être utilisées 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.65 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> ».