+In alcuni sistemi la struttura è leggermente diversa e prevede un primo membro
+aggiuntivo \code{uint8\_t sin\_len} (come riportato da R. Stevens in
+\cite{UNP1}). Questo campo non verrebbe usato direttamente dal programmatore e
+non è richiesto dallo standard POSIX.1g, in Linux pertanto non esiste. Il
+campo \type{sa\_family\_t} era storicamente un \ctyp{unsigned short}.
+
+Dal punto di vista del programmatore l'unico uso di questa struttura è quello
+di fare da riferimento per il casting, per il kernel le cose sono un po'
+diverse, in quanto esso usa il puntatore per recuperare il campo
+\var{sa\_family}, comune a tutte le famiglie, con cui determinare il tipo di
+indirizzo; per questo motivo, anche se l'uso di un puntatore \ctyp{void *}
+sarebbe più immediato per l'utente (che non dovrebbe più eseguire il casting),
+è stato mantenuto l'uso di questa struttura.
+
+
+\subsection{La struttura degli indirizzi IPv4}
+\label{sec:sock_sa_ipv4}
+
+I socket di tipo \const{PF\_INET} vengono usati per la comunicazione
+attraverso internet; la struttura per gli indirizzi per un socket internet (se
+si usa IPv4) è definita come \struct{sockaddr\_in} nell'header file
+\headfile{netinet/in.h} ed ha la forma mostrata in
+fig.~\ref{fig:sock_sa_ipv4_struct}, conforme allo standard POSIX.1g.
+
+\begin{figure}[!htb]
+ \footnotesize\centering
+ \begin{minipage}[c]{\textwidth}
+ \includestruct{listati/sockaddr_in.h}
+ \end{minipage}
+ \caption{La struttura \structd{sockaddr\_in} degli indirizzi dei socket
+ internet (IPv4) e la struttura \structd{in\_addr} degli indirizzi IPv4.}
+ \label{fig:sock_sa_ipv4_struct}
+\end{figure}
+
+L'indirizzo di un socket internet (secondo IPv4) comprende l'indirizzo
+internet di un'interfaccia più un \textsl{numero di porta} (affronteremo in
+dettaglio il significato di questi numeri in sez.~\ref{sec:TCP_port_num}). Il
+protocollo IP non prevede numeri di porta, che sono utilizzati solo dai
+protocolli di livello superiore come TCP e UDP. Questa struttura però viene
+usata anche per i socket RAW che accedono direttamente al livello di IP, nel
+qual caso il numero della porta viene impostato al numero di protocollo.
+
+Il membro \var{sin\_family} deve essere sempre impostato a \const{AF\_INET},
+altrimenti si avrà un errore di \errcode{EINVAL}; il membro \var{sin\_port}
+specifica il \textsl{numero di porta}. I numeri di porta sotto il 1024 sono
+chiamati \textsl{riservati} in quanto utilizzati da servizi standard e
+soltanto processi con i privilegi di amministratore (con \ids{UID} effettivo
+uguale a zero) o con la \itindex{capabilities} \textit{capability}
+\const{CAP\_NET\_BIND\_SERVICE} possono usare la funzione \func{bind} (che
+vedremo in sez.~\ref{sec:TCP_func_bind}) su queste porte.
+
+Il membro \var{sin\_addr} contiene un indirizzo internet, e viene acceduto sia
+come struttura (un resto di una implementazione precedente in cui questa era
+una \direct{union} usata per accedere alle diverse classi di indirizzi) che
+direttamente come intero. In \headfile{netinet/in.h} vengono definite anche
+alcune costanti che identificano alcuni indirizzi speciali, riportati in
+tab.~\ref{tab:TCP_ipv4_addr}, che rincontreremo più avanti.
+
+Infine occorre sottolineare che sia gli indirizzi che i numeri di porta devono
+essere specificati in quello che viene chiamato \textit{network order}, cioè
+con i bit ordinati in formato \textit{big endian} (vedi
+sez.~\ref{sec:sock_endianness}), questo comporta la necessità di usare apposite
+funzioni di conversione per mantenere la portabilità del codice (vedi
+sez.~\ref{sec:sock_addr_func} per i dettagli del problema e le relative
+soluzioni).
+
+
+\subsection{La struttura degli indirizzi IPv6}
+\label{sec:sock_sa_ipv6}
+
+Essendo IPv6 un'estensione di IPv4, i socket di tipo \const{PF\_INET6} sono
+sostanzialmente identici ai precedenti; la parte in cui si trovano
+praticamente tutte le differenze fra i due socket è quella della struttura
+degli indirizzi; la sua definizione, presa da \headfile{netinet/in.h}, è
+riportata in fig.~\ref{fig:sock_sa_ipv6_struct}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\textwidth}
+ \includestruct{listati/sockaddr_in6.h}
+ \end{minipage}
+ \caption{La struttura \structd{sockaddr\_in6} degli indirizzi dei socket
+ IPv6 e la struttura \structd{in6\_addr} degli indirizzi IPv6.}
+ \label{fig:sock_sa_ipv6_struct}
+\end{figure}
+
+Il campo \var{sin6\_family} deve essere sempre impostato ad \const{AF\_INET6},
+il campo \var{sin6\_port} è analogo a quello di IPv4 e segue le stesse regole;
+il campo \var{sin6\_flowinfo} è a sua volta diviso in tre parti di cui i 24
+bit inferiori indicano l'etichetta di flusso, i successivi 4 bit la priorità e
+gli ultimi 4 sono riservati. Questi valori fanno riferimento ad alcuni campi
+specifici dell'header dei pacchetti IPv6 (vedi sez.~\ref{sec:IP_ipv6head}) ed
+il loro uso è sperimentale.
+
+Il campo \var{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6,
+espresso da un vettore di 16 byte. Infine il campo \var{sin6\_scope\_id} è un
+campo introdotto in Linux con il kernel 2.4, per gestire alcune operazioni
+riguardanti il \itindex{multicast} \textit{multicasting}. Si noti infine che
+\struct{sockaddr\_in6} ha una dimensione maggiore della struttura
+\struct{sockaddr} generica di fig.~\ref{fig:sock_sa_gen_struct}, quindi
+occorre stare attenti a non avere fatto assunzioni riguardo alla possibilità
+di contenere i dati nelle dimensioni di quest'ultima.
+
+
+\subsection{La struttura degli indirizzi locali}
+\label{sec:sock_sa_local}
+
+I socket di tipo \const{PF\_UNIX} o \const{PF\_LOCAL} vengono usati per una
+comunicazione fra processi che stanno sulla stessa macchina (per questo
+vengono chiamati \textit{local domain} o anche \textit{Unix domain}); essi
+hanno la caratteristica ulteriore di poter essere creati anche in maniera
+anonima attraverso la funzione \func{socketpair} (che abbiamo trattato in
+sez.~\ref{sec:ipc_socketpair}). Quando però si vuole fare riferimento
+esplicito ad uno di questi socket si deve usare una struttura degli indirizzi
+di tipo \struct{sockaddr\_un}, la cui definizione si è riportata in
+fig.~\ref{fig:sock_sa_local_struct}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\textwidth}
+ \includestruct{listati/sockaddr_un.h}
+ \end{minipage}
+ \caption{La struttura \structd{sockaddr\_un} degli indirizzi dei socket
+ locali (detti anche \textit{unix domain}) definita in
+ \headfile{sys/un.h}.}
+ \label{fig:sock_sa_local_struct}
+\end{figure}
+
+In questo caso il campo \var{sun\_family} deve essere \const{AF\_UNIX}, mentre
+il campo \var{sun\_path} deve specificare un indirizzo. Questo ha due forme;
+può essere un file (di tipo socket) nel filesystem o una stringa univoca
+(mantenuta in uno spazio di nomi astratto). Nel primo caso l'indirizzo viene
+specificato come una stringa (terminata da uno zero) corrispondente al
+\textit{pathname} del file; nel secondo invece \var{sun\_path} inizia con uno
+zero e vengono usati come nome i restanti byte come stringa, senza
+terminazione.
+
+
+\subsection{La struttura degli indirizzi AppleTalk}
+\label{sec:sock_sa_appletalk}
+
+I socket di tipo \const{PF\_APPLETALK} sono usati dalla libreria
+\file{netatalk} per implementare la comunicazione secondo il protocollo
+AppleTalk, uno dei primi protocolli di rete usato nel mondo dei personal
+computer, usato dalla Apple per connettere fra loro computer e stampanti. Il
+kernel supporta solo due strati del protocollo, DDP e AARP, e di norma è
+opportuno usare le funzioni della libreria \texttt{netatalk}, tratteremo qui
+questo argomento principalmente per mostrare l'uso di un protocollo
+alternativo.
+
+I socket AppleTalk permettono di usare il protocollo DDP, che è un protocollo
+a pacchetto, di tipo \const{SOCK\_DGRAM}; l'argomento \param{protocol} di
+\func{socket} deve essere nullo. È altresì possibile usare i socket raw
+specificando un tipo \const{SOCK\_RAW}, nel qual caso l'unico valore valido
+per \param{protocol} è \const{ATPROTO\_DDP}.
+
+Gli indirizzi AppleTalk devono essere specificati tramite una struttura
+\struct{sockaddr\_atalk}, la cui definizione è riportata in
+fig.~\ref{fig:sock_sa_atalk_struct}; la struttura viene dichiarata includendo
+il file \headfile{netatalk/at.h}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\textwidth}
+ \includestruct{listati/sockaddr_atalk.h}
+ \end{minipage}
+ \caption{La struttura \structd{sockaddr\_atalk} degli indirizzi dei socket
+ AppleTalk, e la struttura \structd{at\_addr} degli indirizzi AppleTalk.}
+ \label{fig:sock_sa_atalk_struct}
+\end{figure}
+
+Il campo \var{sat\_family} deve essere sempre \const{AF\_APPLETALK}, mentre il
+campo \var{sat\_port} specifica la porta che identifica i vari servizi. Valori
+inferiori a 129 sono usati per le \textsl{porte riservate}, e possono essere
+usati solo da processi con i privilegi di amministratore o con la
+\itindex{capabilities} \textit{capability} \const{CAP\_NET\_BIND\_SERVICE}.
+L'indirizzo remoto è specificato nella struttura \var{sat\_addr}, e deve
+essere in \textit{network order} (vedi sez.~\ref{sec:sock_endianness}); esso è
+composto da un parte di rete data dal campo \var{s\_net}, che può assumere il
+valore \const{AT\_ANYNET}, che indica una rete generica e vale anche per
+indicare la rete su cui si è, il singolo nodo è indicato da \var{s\_node}, e
+può prendere il valore generico \const{AT\_ANYNODE} che indica anche il nodo
+corrente, ed il valore \const{ATADDR\_BCAST} che indica tutti i nodi della
+rete.
+
+
+\subsection{La struttura degli indirizzi dei \textit{packet socket}}
+\label{sec:sock_sa_packet}
+
+I \textit{packet socket}, identificati dal dominio \const{PF\_PACKET}, sono
+un'interfaccia specifica di Linux per inviare e ricevere pacchetti
+direttamente su un'interfaccia di rete, senza passare per le funzioni di
+gestione dei protocolli di livello superiore. In questo modo è possibile
+implementare dei protocolli in user space, agendo direttamente sul livello
+fisico. In genere comunque si preferisce usare la libreria
+\file{pcap},\footnote{la libreria è mantenuta insieme al comando
+ \cmd{tcpdump}, informazioni e documentazione si possono trovare sul sito del
+ progetto \url{http://www.tcpdump.org/}.} che assicura la portabilità su
+altre piattaforme, anche se con funzionalità ridotte.
+
+Questi socket possono essere di tipo \const{SOCK\_RAW} o \const{SOCK\_DGRAM}.
+Con socket di tipo \const{SOCK\_RAW} si può operare sul livello di
+collegamento, ed i pacchetti vengono passati direttamente dal socket al driver
+del dispositivo e viceversa. In questo modo, in fase di trasmissione, il
+contenuto completo dei pacchetti, comprese le varie intestazioni, deve essere
+fornito dall'utente. In fase di ricezione invece tutto il contenuto del
+pacchetto viene passato inalterato sul socket, anche se il kernel analizza
+comunque il pacchetto, riempiendo gli opportuni campi della struttura
+\struct{sockaddr\_ll} ad esso associata.
+
+Si usano invece socket di tipo \const{SOCK\_DGRAM} quando si vuole operare a
+livello di rete. In questo caso in fase di ricezione l'intestazione del
+protocollo di collegamento viene rimossa prima di passare il resto del
+pacchetto all'utente, mentre in fase di trasmissione viene creata una
+opportuna intestazione per il protocollo a livello di collegamento
+utilizzato, usando le informazioni necessarie che devono essere specificate
+sempre con una struttura \struct{sockaddr\_ll}.
+
+Nella creazione di un \textit{packet socket} il valore dell'argomento
+\param{protocol} di \func{socket} serve a specificare, in \textit{network
+ order}, il numero identificativo del protocollo di collegamento si vuole
+utilizzare. I valori possibili sono definiti secondo lo standard IEEE 802.3, e
+quelli disponibili in Linux sono accessibili attraverso opportune costanti
+simboliche definite nel file \file{linux/if\_ether.h}. Se si usa il valore
+speciale \const{ETH\_P\_ALL} passeranno sul \textit{packet socket} tutti i
+pacchetti, qualunque sia il loro protocollo di collegamento. Ovviamente l'uso
+di questi socket è una operazione privilegiata e può essere effettuati solo da
+un processo con i privilegi di amministratore (\ids{UID} effettivo nullo) o con
+la \itindex{capabilities} \textit{capability} \const{CAP\_NET\_RAW}.
+
+Una volta aperto un \textit{packet socket}, tutti i pacchetti del protocollo
+specificato passeranno attraverso di esso, qualunque sia l'interfaccia da cui
+provengono; se si vuole limitare il passaggio ad una interfaccia specifica
+occorre usare la funzione \func{bind} per agganciare il socket a quest'ultima.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\textwidth}
+ \includestruct{listati/sockaddr_ll.h}
+ \end{minipage}
+ \caption{La struttura \structd{sockaddr\_ll} degli indirizzi dei
+ \textit{packet socket}.}
+ \label{fig:sock_sa_packet_struct}
+\end{figure}
+
+Nel caso dei \textit{packet socket} la struttura degli indirizzi è di tipo
+\struct{sockaddr\_ll}, e la sua definizione è riportata in
+fig.~\ref{fig:sock_sa_packet_struct}; essa però viene ad assumere un ruolo
+leggermente diverso rispetto a quanto visto finora per gli altri tipi di
+socket. Infatti se il socket è di tipo \const{SOCK\_RAW} si deve comunque
+scrivere tutto direttamente nel pacchetto, quindi la struttura non serve più a
+specificare gli indirizzi. Essa mantiene questo ruolo solo per i socket di
+tipo \const{SOCK\_DGRAM}, per i quali permette di specificare i dati necessari
+al protocollo di collegamento, mentre viene sempre utilizzata in lettura (per
+entrambi i tipi di socket), per la ricezione dei i dati relativi a ciascun
+pacchetto.
+
+Al solito il campo \var{sll\_family} deve essere sempre impostato al valore
+\const{AF\_PACKET}. Il campo \var{sll\_protocol} indica il protocollo scelto,
+e deve essere indicato in \textit{network order}, facendo uso delle costanti
+simboliche definite in \file{linux/if\_ether.h}. Il campo \var{sll\_ifindex} è
+l'indice dell'interfaccia, che, in caso di presenza di più interfacce dello
+stesso tipo (se ad esempio si hanno più schede ethernet), permette di
+selezionare quella con cui si vuole operare (un valore nullo indica qualunque
+interfaccia). Questi sono i due soli campi che devono essere specificati
+quando si vuole selezionare una interfaccia specifica, usando questa struttura
+con la funzione \func{bind}.
+
+I campi \var{sll\_halen} e \var{sll\_addr} indicano rispettivamente
+l'indirizzo associato all'interfaccia sul protocollo di collegamento e la
+relativa lunghezza; ovviamente questi valori cambiano a seconda del tipo di
+collegamento che si usa, ad esempio, nel caso di ethernet, questi saranno il
+MAC address della scheda e la relativa lunghezza. Essi vengono usati, insieme
+ai campi \var{sll\_family} e \var{sll\_ifindex} quando si inviano dei
+pacchetti, in questo caso tutti gli altri campi devono essere nulli.
+
+Il campo \var{sll\_hatype} indica il tipo ARP, come definito in
+\file{linux/if\_arp.h}, mentre il campo \var{sll\_pkttype} indica il tipo di
+pacchetto; entrambi vengono impostati alla ricezione di un pacchetto ed han
+senso solo in questo caso. In particolare \var{sll\_pkttype} può assumere i
+seguenti valori: \const{PACKET\_HOST} per un pacchetto indirizzato alla
+macchina ricevente, \const{PACKET\_BROADCAST} per un pacchetto di
+\itindex{broadcast} \textit{broadcast}, \const{PACKET\_MULTICAST} per un
+pacchetto inviato ad un indirizzo fisico di \itindex{multicast}
+\textit{multicast}, \const{PACKET\_OTHERHOST} per un pacchetto inviato ad
+un'altra stazione (e ricevuto su un'interfaccia in \index{modo~promiscuo} modo
+promiscuo), \const{PACKET\_OUTGOING} per un pacchetto originato dalla propria
+macchina che torna indietro sul socket.
+
+
+Si tenga presente infine che in fase di ricezione, anche se si richiede il
+troncamento del pacchetto, le funzioni \func{recv}, \func{recvfrom} e
+\func{recvmsg} (vedi sez.~\ref{sec:net_sendmsg}) restituiranno comunque la
+lunghezza effettiva del pacchetto così come arrivato sulla linea.
+
+%% \subsection{La struttura degli indirizzi DECnet}
+%% \label{sec:sock_sa_decnet}
+
+%% I socket di tipo \const{PF\_DECnet} usano il protocollo DECnet, usato dai VAX
+%% Digital sotto VMS quando ancora il TCP/IP non era diventato lo standard di
+%% fatto. Il protocollo è un protocollo chiuso, ed il suo uso attuale è limitato
+%% alla comunicazione con macchine che stanno comunque scomparendo. Lo si riporta
+%% solo come esempio
+
+
+% TODO: trattare i socket RDS, vedi documentazione del kernel, file
+% Documentation/networking/rds.txt