#include <sys/types.h>
#include <sys/socket.h>
int getsockopt(int s, int level, int optname, void *optval,
socklen_t *optlen);
int setsockopt(int s, int level, int optname, const void *optval,
socklen_t optlen);
Przejdźmy teraz do omówienia poszczególnych opcji, które mamy do dyspozycji. Zaczniemy od poziomu SOL_SOCKET (wszystkie opcje znajdują się w asm/socket.h):
struct linger {
int l_onoff; /* opcja SO_LINGER wł/wył */
int l_linger; /* limit czasowy na wysłanie danych */
};
struct ip_mreqn
{
struct in_addr imr_multiaddr; /* adres multicast */
struct in_addr imr_address; /* adres interfejsu */
int imr_ifindex; /* numer interfejsu */
};
Adres multicast można określić mianem one-to-many, czyli
pakiety skierowane pod adresy typu multicast docierają
do pewnej grupy hostów skonfigurowanych tak aby obsługiwać
dany adres multicast. Linux pozwala na wysyłanie
multicastów tylko na gniazdach SOCK_DGRAM i SOCK_RAW.
Znaczenie poszczególnych pól struktury ip_mreqn powinno być jasne. Tylko jedna uwaga: nie nalezy mylić opisywanych obecnie adresów multicast w warstwie IP z adresami multicast warstwy wizycznej. Tymi ostatnimi zajmiemy sie później.
SOL_TCP (domena PF_INET, typ SOCK_STREAM) dysponuje tylko trzema opcjami (linux/socket.h):
struct packet_mreq
{
int mr_ifindex; /* numer interfejsu */
unsigned short mr_type; /* typ operacji */
unsigned short mr_alen; /* długość adresu */
unsigned char mr_address[8]; /* adres fizyczny */
};
Wszystkie pola oprócz mr_type powinny być zrozumiałe
bez dodatkowych wyjaśnień. Otóż jako typ operacji
możemy użyć:
Kilka słów na temat SOL_RAW. Dla gniazd z domeny PF_INET zestaw dostępnych opcji jest taki sam, jak na poziomie SOL_IP. Istnieje natomiast jedna ciekawa opcja dla gniazd [PF_INET, SOCK_RAW, IPPROTO_ICMP] (jądra 2.2.x):
ICMP_FILTER - Parametrem jest maska bitowa (unsigned long int) określająca typy komunikatów ICMP, które NIE mają być dostarczane do gniazda. Na przykład ustawienie tego parametru na 257 odfiltruje wszystkie komunikaty typu ICMP_ECHO i ICMP_ECHO_REPLY (bity numer 0 i 8 maski ustawione na 1).
Przydałyby się jeszcze konkretne przykłady użycia setsockopt()/getsockopt().
/* Te kilka linijek kodu umożliwi wysyłanie/odbieranie pakietów broadcast */
int b = 1;
s = socket(PF_INET, SOCK_DGRAM, 0);
setsockopt(s, SOL_SOCKET, SO_BROADCAST, &b, sizeof(int));
/* Teraz sprawdzimy, czy włączone jest wysyłanie pakietów keep-alive */
int keepalive, len = sizeof(int);
s = socket(PF_INET, SOCK_STREAM, 0);
getsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &keepalive, &len);
if (keepalive) printf ("Keep-alive włączone.\n");