NOME¶
CMSG_ALIGN, CMSG_SPACE, CMSG_NXTHDR, CMSG_FIRSTHDR - Accesso a dados
acessórios.
SINOPSE¶
#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);
void *CMSG_DATA(struct cmsghdr *cmsg);
struct cmsghdr {
socklen_t cmsg_len; /* total de bytes de dados, incluindo o cabeçalho */
int cmsg_level; /* protocolo original */
int cmsg_type; /* tipo protocolo-específico */
/* followed by
unsigned char cmsg_data[]; */
};
DESCRIÇÃO¶
Estas macros servem para criar e acessar mensagens de controle (também
chamadas dados acessórios) que não são parte do
conteúdo do socket. Esta informação pode incluir a
interface onde o pacote foi recebido, uma miscelânea de
cabeçalhos raramente usados, uma descrição de erro mais
detalhada, um conjunto de descritores de arquivo ou credenciais unix. Por
exemplo, pode se usar mensagens de controle para enviar campos de
cabeçalho adicionais tais como opções IP. Os dados
são enviados com
sendmsg(2) e recebidos com
recvmsg(2).
Veja as manpages para mais informações.
Os dados acessórios consistem numa seqüência de
struct
cmsghdr seguidas de dados adicionais, que devem ser acessadas apenas com
as macros descritas nesta manpage e não diretamente. Veja os tipos de
mensagens de controle nas manpages dos protocolos. O tamanho máximo do
buffer auxiliar do socket pode ser definido com
net.core.optmem_max do
sysctl. Ver
socket(7).
CMSG_FIRSTHDR retorna um ponteiro para o primeiro
cmsghdr do
buffer acessório associado ao
msghdr.
CMSG_NXTHDR retorna o próximo
cmsghdr válido depois
do
cmsghdr. indicado, e retorna
NULL se não houver mais
espaço suficiente no buffer.
CMSG_ALIGN, given a length, returns it including the required alignment.
This is a constant expression.
CMSG_SPACE retorna o número de bytes de um elemento
acessório com um conteúdo do comprimento indicado. Esta
expressão é constante.
CMSG_DATA retorna um ponteiro para os dados de um
cmsghdr.
CMSG_LEN retorna o valor do membro
cmsg_len do struct
cmsghdr considerando qualquer alinhamento necessário. Esta
expressão é constante.
Para criar dados acessórios, inicialize o membro
msg_controllen do
msghdr com o comprimento do buffer de mensagem de controle. Use
CMSG_FIRSTHDR no
msghdr para recuperar a primeira mensagem de
controle e
CMSG_NEXTHDR para as seguintes. Para cada mensagem de
controle, inicialize
cmsg_len (com
CMSG_LEN), e os outros campos
e a porção de dados de
cmsghdr com
CMSG_DATA. No
final, coloque a soma dos comprimentos de todas as mensagens de controle
(dados em
CMSG_SPACE ) no campo
msg_controllen do
msghdr
Para mais informações sobre o
msghdr, veja
recvmsg(2).
Quando o buffer de mensagens de controle não comportar todas as
mensagens, o flag
MSG_CTRUNC do
msg_flags de
msghdr
será ativado.
EXEMPLO¶
Este código procura a opção
IP_TTL num buffer
acessório recebido:
struct msghdr msgh;
struct cmsghdr *cmsg;
int *ttlptr;
int received_ttl;
/* Receber dados acessórios em msgh */
for (cmsg = CMSG_FIRSTHDR(&msgh);
cmsg != NULL;
cmsg = CMSG_NXTHDR(&msgh,cmsg) {
if (cmsg->cmsg_level == SOL_IP
&& cmsg->cmsg_type == IP_TTL) {
ttlptr = (int *) CMSG_DATA(cmsg);
received_ttl = *ttlptr;
break;
}
}
if (cmsg == NULL) {
/* Erro: IP_TTL desabilitado ou buffer muito curto
* ou erro de I/O .
*/
}
O código abaixo transmite um array de descritores de arquivo
através de um socket Unix usando
SCM_RIGHTS:
struct msghdr msg = {0};
struct cmsghdr *cmsg;
int myfds[NUM_FD]; /* Descritores de arquivo a transmitir. */
char buf[CMSG_SPACE(sizeof myfds)]; /* buffer de dados acessórios */
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);
/* Inicializar o conteúdo: */
fdptr = (int *)CMSG_DATA(cmsg);
memcpy(fdptr, myfds, NUM_FD * sizeof(int));
/* Soma dos comprimentos de todas as mensagens de controle no buffer: */
msg.msg_controllen = cmsg->cmsg_len;
OBSERVAÇÕES¶
Os dados acessórios devem ser acessados apenas com as macros definidas
aqui para manter a portabilidade.
CMSG_ALIGN é uma
extensão linux, e deve ser evitada em programas portáveis.
No linux,
CMSG_LEN,
CMSG_DATA, e
CMSG_ALIGN são
constantes (se receberem um argumento constante), e podem ser usados para
declarar o tamanho de variáveis globais. Isto pode, no entanto,
não ser portável.
DE ACORDO COM¶
O modelo de dados acessórios segue o draft POSIX.1003.1g, 4.4BSD-Lite, a
API IPv6 avançada descrita no RFC2292 e a Single Unix specification v2.
CMSG_ALIGN é uma extensão linux.
VER TAMBÉM¶
sendmsg(2),
recvmsg(2)
RFC 2292
TRADUZIDO POR LDP-BR em 21/08/2000.¶
Paulo César Mendes <drpc@ism.com.br> (tradução)
xxxxxxxxxxxxxxxxxxxxxxxxx <xxx@xxxxxx.xxx.xx> (revisão)