NAZWA¶
CMSG_ALIGN, CMSG_SPACE, CMSG_NXTHDR, CMSG_FIRSTHDR - dostęp do danych
pomocniczych
SKŁADNIA¶
#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; /* liczba bajtów danych, włączając nagłówek */
int cmsg_level; /* protokół źródłowy */
int cmsg_type; /* typ zależny od protokołu */
/* następuje po nim unsigned char cmsg_data[]; */
};
OPIS¶
Makrodefinicje te służą do tworzenia i dostępu do
komunikatów sterujących (zwanych również danymi
pomocniczymi), które nie są częścią
gniazda. Te informacje sterujące mogą zawierać:
interfejs, przez który pakiet został odebrany,
różne rzadko używane pola nagłówka,
rozszerzony opis błędu, zestaw deskryptorów plików
lub uwierzytelnień uniksowych. Na przykład, komunikaty
sterujące mogą służyć do ustawiania
dodatkowych pól nagłówka, takich jak opcje IP, dla
wysyłanych pakietów. Dane pomocnicze są wysyłane
poprzez wywołanie
sendmsg(2), a odbierane poprzez
wywołanie
recvmsg(2). Więcej informacji znajduje
się na stronach podręcznika tych poleceń.
Dane pomocnicze są ciągiem struktur
struct cmsghdr z
dodanymi danymi. Dostęp do tego ciągu powinien się
odbywać wyłącznie przez opisane na tej stronie
podręcznika makrodefinicje, nigdy zaś bezpośrednio.
Dostępne rodzaje komunikatów sterujących opisano na
stronach podręcznika poszczególnych protokołów.
Maksymalny rozmiar bufora danych pomocniczych dla gniazda można
ustawić, używając
/proc/sys/net/core/optmem_max;
patrz
socket(7).
CMSG_FIRSTHDR() zwraca wskaźnik do pierwszego
cmsghdr w
buforze danych pomocniczych związanym z przekazanym
msghdr.
CMSG_NXTHDR() zwraca następny poprawny
cmsghdr po
przekazanym
cmsghdr. Zwraca NULL, gdy brak dostatecznej ilości
miejsca w buforze.
CMSG_ALIGN() zwraca żądaną
długość, włączając niezbędne
wyrównanie. Jest to wyrażenie stałe.
CMSG_SPACE() zwraca liczbę bajtów elementu pomocniczego
włączając długość, jaką
zajmują przekazane dane. Jest to wyrażenie stałe.
CMSG_DATA() zwraca wskaźnik do części
cmsghdr
zawierającej dane.
CMSG_LEN() zwraca wartość, która ma być
przechowywana w elemencie
cmsg_len struktury
cmsghdr,
biorąc pod uwagę wszelkie niezbędne wyrównania.
Jako argument pobiera długość danych. Jest to
wyrażenie stałe.
Aby utworzyć dane pomocnicze, należy najpierw zainicjować
element
msg_controllen struktury
msghdr
długością bufora komunikatów sterujących.
Należy użyć
CMSG_FIRSTHDR() dla
msghdr, aby
otrzymać pierwszy komunikat sterujący, oraz
CMSG_NXTHDR(), aby otrzymać wszystkie następne. Dla
każdego komunikatu sterującego należy zainicjować
cmsg_len (za pomocą
CMSG_LEN()), inne pola
nagłówka
cmsghdr oraz część
zawierającą dane za pomocą
CMSG_DATA().
Ostatecznie pole
msg_controllen struktury
msghdr powinno
zawierać sumę
CMSG_SPACE() długości
wszystkich komunikatów sterujących w buforze. Więcej
informacji dotyczących
msghdr znajduje się w
recvmsg(2).
Gdy bufor komunikatów sterujących jest za krótki, aby
przechować wszystkie komunikaty, ustawiany jest znacznik
MSG_CTRUNC elementu
msg_flags struktury
msghdr.
ZGODNE Z¶
Ten model danych pomocniczych jest zgodny ze szkicem POSIX.1g, z 4.4BSD-Lite, z
zaawansowanym API dla IPv6 opisanym w RFC 2292 oraz z SUSv2.
CMSG_ALIGN() jest rozszerzeniem Linuksa.
UWAGI¶
Dla przenośności, dostęp do danych pomocniczych powinien
się odbywać jedynie za pomocą opisanych tu
makrodefinicji.
CMSG_ALIGN() jest rozszerzeniem Linuksa i nie powinno
być używane w przenośnych programach.
W Linuksie,
CMSG_LEN(),
CMSG_DATA() i
CMSG_ALIGN()
są wyrażeniami stałymi (zakładając,
że ich argument jest stały) - można to wykorzystać
do zadeklarowania rozmiaru zmiennych globalnych. Jednakże, może
się to okazać nieprzenośnym.
PRZYKŁAD¶
Następujący kod poszukuje opcji
IP_TTL w otrzymanym buforze
pomocniczym:
struct msghdr msgh;
struct cmsghdr *cmsg;
int *ttlptr;
int received_ttl;
/* Otrzymywanie danych z zewnątrz do 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) {
/*
* Błąd: IP_TTL not jest włączone, za mały bufor lub
* błąd I/O.
*/
}
Poniższy kod przekazuje tablicę deskryptorów plików
przez gniazdo domeny UNIX
SCM_RIGHTS:
struct msghdr msg = {0};
struct cmsghdr *cmsg;
int myfds[NUM_FD]; /* Zawiera przekazywane deskryptory plików. */
char buf[CMSG_SPACE(sizeof myfds)]; /* bufor danych pomocniczych */
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);
/* Inicjacja: */
fdptr = (int *) CMSG_DATA(cmsg);
memcpy(fdptr, myfds, NUM_FD * sizeof(int));
/* Suma długości wszystkich komunikatów sterujących w buforze: */
msg.msg_controllen = cmsg->cmsg_len;
ZOBACZ TAKŻE¶
recvmsg(2),
sendmsg(2)
RFC 2292
O STRONIE¶
Angielska wersja tej strony pochodzi z wydania 3.71 projektu Linux
man-pages. Opis projektu, informacje dotyczące zgłaszania
błędów, oraz najnowszą wersję
oryginału można znaleźć pod adresem
http://www.kernel.org/doc/man-pages/.
TŁUMACZENIE¶
Autorami polskiego tłumaczenia niniejszej strony podręcznika man
są: Andrzej Krzysztofowicz (PTM) <ankry@mif.pg.gda.pl>, Robert
Luberda <robert@debian.org> i Michał Kułach
<michal.kulach@gmail.com>.
Polskie tłumaczenie jest częścią projektu
manpages-pl; uwagi, pomoc, zgłaszanie błędów na
stronie
http://sourceforge.net/projects/manpages-pl/. Jest zgodne z
wersją
3.71 oryginału.