A ciascun tipo di dominio corrisponde un analogo nome simbolico che inizia per
\texttt{AF\_} da \textit{address family}, e che identifica il formato degli
-indirizzi usati in quel dominio; le man pages di linux si riferiscono a questi
+indirizzi usati in quel dominio; le man pages di Linux si riferiscono a questi
anche come \textit{name space}, (nome che però il manuale della glibc riserva
ai domini) e che identifica il formato degli indirizzi usati in quel dominio.
nomi sono equivalenti e corrispondono agli stessi valori.
I domini (e i relativi nomi simbolici), così come i nomi delle famiglie di
-indirizzi sono definiti dall'header \textit{socket.h}. In linux le famiglie di
+indirizzi sono definiti dall'header \textit{socket.h}. In Linux le famiglie di
protocolli disponibili sono riportate in \ntab.
\begin{table}[htb]
PF\_APPLETALK & Appletalk & ddp(7) \\
PF\_PACKET & Low level packet interface & packet(7) \\
\end{tabular}
- \caption{Famiglie di protocolli definiti in linux}
+ \caption{Famiglie di protocolli definiti in Linux}
\label{tab:net_pf_names}
\end{table}
Non tutte le famiglie di protocolli sono accessibili dall'utente generico, ad
esempio in generale tutti i socket di tipo \texttt{SOCK\_RAW} possono essere
-creati solo da processi che hanno i provilegi di root (cioè effective uid
+creati solo da processi che hanno i privilegi di root (cioè effective uid
uguale a zero) o la capability \texttt{CAP\_NET\_RAW}.
La scelta di un dominio non comporta però la scelta dello stile di
comunicazione, questo infatti viene a dipendere dal protocollo che si andrà ad
utilizzare fra quelli disponibili nella famiglia scelta. Le API permettono di
-scegliere lo stile di comunicazione indicando il tipo di socket; linux e le
+scegliere lo stile di comunicazione indicando il tipo di socket; Linux e le
glibc mettono a disposizione i seguenti tipi di socket (che il manuale della
glibc chiama \textit{styles}) definiti come \texttt{int} in \texttt{socket.h}:
\begin{figure}[!htbp]
\footnotesize
- \begin{lstlisting}{}
+ \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
struct sockaddr {
sa_family_t sa_family; /* address family: AF_xxx */
char sa_data[14]; /* address (protocol-specific) */
occorrerà eseguire un casting del relativo puntatore.
I tipi di dati che compongono la struttura sono stabiliti dallo standard
-Posix.1g, riassunti in \ntab\ con i rispettivi file di include in cui sono
+POSIX.1g, riassunti in \ntab\ con i rispettivi file di include in cui sono
definiti; la struttura è invece definita nell'include file
\texttt{sys/socket.h}
\hline
\end{tabular}
\caption{Tipi di dati usati nelle strutture degli indirizzi, secondo quanto
- stabilito dallo standard Posix.1g}
+ stabilito dallo standard POSIX.1g}
\label{tab:sock_data_types}
\end{table}
In alcuni sistemi la struttura è leggermente diversa e prevede un primo membro
aggiuntivo \texttt{uint8\_t sin\_len} (come riportato da R. Stevens nei suoi
libri). Questo campo non verrebbe usato direttamente dal programmatore e non è
-richiesto dallo standard Posix.1g, in linux pertanto non sussiste. Il campo
+richiesto dallo standard POSIX.1g, in Linux pertanto non sussiste. Il campo
\texttt{sa\_family\_t} era storicamente un \texttt{unsigned short}.
Dal punto di vista del programmatore l'unico uso di questa struttura è quello
attraverso internet; la struttura per gli indirizzi per un socket internet
(IPv4) è definita come \texttt{sockaddr\_in} nell'header file
\texttt{netinet/in.h} e secondo le man page ha la forma mostrata in \nfig,
-conforme allo standard Posix.1g.
+conforme allo standard POSIX.1g.
\begin{figure}[!htbp]
\footnotesize
- \begin{lstlisting}{}
+ \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
struct sockaddr_in {
sa_family_t sin_family; /* address family: AF_INET */
u_int16_t sin_port; /* port in network byte order */
Il membro \texttt{sin\_addr} contiene l'indirizzo internet dell'altro capo
della comunicazione, e viene acceduto sia come struttura (un resto di una
-implementazione precedente in cui questa era una union usata per accedere alle
+implementazione precedente in cui questa era una \texttt{union} usata per accedere alle
diverse classi di indirizzi) che come intero.
Infine è da sottolineare che sia gli indirizzi che i numeri di porta devono
\subsection{La struttura degli indirizzi IPv6}
\label{sec:sock_sa_ipv6}
-Essendo IPv6 una estenzione di IPv4 i socket di tipo \texttt{PF\_INET6} sono
+Essendo IPv6 una estensione di IPv4 i socket di tipo \texttt{PF\_INET6} sono
sostanzialmente identici ai precedenti; la parte in cui si trovano
praticamente tutte le differenze è quella della struttura degli indirizzi. La
struttura degli indirizzi è definita ancora in \texttt{netinet/in.h}.
\begin{figure}[!htbp]
\footnotesize
- \begin{lstlisting}{}
+ \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
struct sockaddr_in6 {
u_int16_t sin6_family; /* AF_INET6 */
u_int16_t sin6_port; /* port number */
Il campo \texttt{sin6\_family} deve essere sempre settato ad
\texttt{AF\_INET6}, il campo \texttt{sin6\_port} è analogo a quello di IPv4 e
-segue le stesse regole; il campo \texttt{sin6\_flowinfo} è a dua volta diviso
+segue le stesse regole; il campo \texttt{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 \secref{sec:appA_ipv6}) ed il loro uso è sperimentale.
+(vedi \secref{sec:IP_ipv6head}) ed il loro uso è sperimentale.
Il campo \texttt{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6,
infine il campo \texttt{sin6\_scope\_id} è un campo introdotto con il kernel
\begin{figure}[!htbp]
\footnotesize
- \begin{lstlisting}{}
+ \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
#define UNIX_PATH_MAX 108
struct sockaddr_un {
sa_family_t sun_family; /* AF_UNIX */
\subsection{La \textit{endianess}}
\label{sec:sock_endianess}
-La rappresentazione di un numbero binario in un computer può essere fatta in
+La rappresentazione di un numero binario in un computer può essere fatta in
due modi, chiamati rispettivamente \textit{big endian} e \textit{little
endian} a seconda di come i singoli bit vengono aggregati per formare le
variabili intere (in diretta corrispondenza a come sono poi in realtà cablati
per lo stesso motivo \textit{big endian}.
La \textit{endianess} di un computer dipende essenzialmente dalla architettura
-hardware usata; intel e digital usano il little endian, motorola, ibm, sun
+hardware usata; Intel e Digital usano il little endian, Motorola, IBM, Sun
(sostanzialmente tutti gli altri) usano il big endian. Il formato della rete è
-anch'esso big endian. Esistono poi anche dei processori che possono scegliere
-il tipo di formato all'avvio e alcuni, come il PowerPC o l'intel i860, possono
-pure passare da un tipo all'altro con una specifica istruzione; in ogni caso
-in linux l'ordinamanento è definito dall'archiettura e anche se questi
-cambiamenti sono possibili anche dopo che il sistema è avviato, non vengono
-mai eseguiti.
+anch'esso big endian, quello del bus PCI è little endian, quello del bus VME è
+big endian.
+
+Esistono poi anche dei processori che possono scegliere il tipo di formato
+all'avvio e alcuni, come il PowerPC o l'Intel i860, possono pure passare da un
+tipo di ordinamento all'altro con una specifica istruzione; in ogni caso in
+Linux l'ordinamento è definito dall'architettura e anche se questi cambiamenti
+sono possibili anche dopo che il sistema è avviato, non vengono mai eseguiti.
\subsection{Le funzioni per il riordinamento}
\label{sec:sock_func_ord}
di architettura all'altra i dati vengono interpretati in maniera diversa, e ad
esempio nel caso dell'intero a 16 bit ci si ritroverà con i due bytes in cui è
suddiviso scambiati di posto, e ne sarà quindi invertito l'ordine di lettura
-per cui, per riavere il valore originale dovrenno essere rovesciati.
+per cui, per riavere il valore originale dovranno essere rovesciati.
Per questo motivo si usano le seguenti funzioni di conversione che servono a
tener conto automaticamente della possibile differenza fra l'ordinamento usato
quello della rete.
\end{prototype}
\begin{prototype}{netinet/in.h}
-{unsigned sort int htons(unsigned short int hostshort)}
+{unsigned short int htons(unsigned short int hostshort)}
Converte l'intero a 16 bit \texttt{hostshort} dal formato della macchina a
quello della rete.
\end{prototype}
Un secondo insieme di funzioni di manipolazione serve per passare dal formato
binario usato nelle strutture degli indirizzi alla rappresentazione dei numeri
-IP che si usa normalente.
+IP che si usa normalmente.
Le prime tre funzioni di manipolazione riguardano la conversione degli
indirizzi IPv4 da una stringa in cui il numero di IP è espresso secondo la
Le tre funzioni precedenti sono limitate solo ad indirizzi IPv4, per questo
motivo è preferibile usare le due nuove funzioni \texttt{inet\_pton} e
-\texttt{inet\_ntop} che possono convertire anche gli indirizzi IPv6 (secondo
-lo schema in \nfig). Anche in questo caso le lettere $n$ e $p$ sono degli
-mnemonici per ricordare il tipo di conversione effettuata e stanno per
-\textit{presentation} e \textit{numeric}.
-
-\begin{figure}[htb]
- \centering
-
- \caption{Schema della rappresentazioni utilizzate dalle funzioni di
- conversione \texttt{inet\_pton} e \texttt{inet\_ntop} }
- \label{fig:sock_inet_conv_func}
-
-\end{figure}
-
-Entrambe le funzioni accettano l'argomento \texttt{family} che indica il tipo
-di indirizzo e può essere \texttt{AF\_INET} o \texttt{AF\_INET6}. Se la
-famiglia indicata non è valida entrambe le funzioni ritornano un valore
-negativo e settano la variabile \texttt{errno} al valore
-\texttt{EAFNOSUPPORT}. I prototipi delle suddette funzioni sono i seguenti:
-\begin{prototype}{int inet\_pton(int family, const char *src, void *dest)}
- Converte la stringa puntata da \texttt{src} nell'indirizzo binario da
- memorizzare all'indirizzo puntato da \texttt{dest}, restituendo 0 in caso di
- successo e 1 in caso di fallimento.
+\texttt{inet\_ntop} che possono convertire anche gli indirizzi IPv6. Anche in
+questo caso le lettere $n$ e $p$ sono degli mnemonici per ricordare il tipo di
+conversione effettuata e stanno per \textit{presentation} e \textit{numeric}.
+
+% \begin{figure}[htb]
+% \centering
+
+% \caption{Schema della rappresentazioni utilizzate dalle funzioni di
+% conversione \texttt{inet\_pton} e \texttt{inet\_ntop} }
+% \label{fig:sock_inet_conv_func}
+
+% \end{figure}
+
+Entrambe le funzioni accettano l'argomento \texttt{af} che indica il tipo di
+indirizzo e può essere \texttt{AF\_INET} o \texttt{AF\_INET6}. Se la famiglia
+indicata non è valida entrambe le funzioni settano la variabile \texttt{errno}
+al valore \texttt{EAFNOSUPPORT}. I prototipi delle suddette funzioni sono i
+seguenti:
+\begin{prototype}{sys/socket.h}
+ {int inet\_pton(int af, const char *src, void *addr\_ptr)} Converte la
+ stringa puntata da \texttt{src} nell'indirizzo IP da memorizzare
+ all'indirizzo puntato da \texttt{addr\_ptr}, la funzione restituisce un
+ valore positivo in caso di successo, e zero se la stringa non rappresenta un
+ indirizzo valido, e negativo se \var{af} specifica una famiglia di indirizzi
+ non valida.
\end{prototype}
-\begin{prototype}{char *inet\_ntop(int family, const void *src, char *dest,
- size\_t len)}
- Converte la struttura dell'indirizzo puntata da \texttt{src} in una stringa
- che viene copiata nel buffer puntato dall'indirizzo \texttt{dest}; questo
- deve essere preallocato dall'utente e la lunghezza deve essere almeno
+
+\begin{prototype}{sys/socket.h}
+ {char *inet\_ntop(int af, const void *addr\_ptr, char *dest, size\_t len)}
+ Converte la struttura dell'indirizzo puntata da \texttt{addr\_ptr} in una
+ stringa che viene copiata nel buffer puntato dall'indirizzo \texttt{dest};
+ questo deve essere preallocato dall'utente e la lunghezza deve essere almeno
\texttt{INET\_ADDRSTRLEN} in caso di indirizzi IPv4 e
\texttt{INET6\_ADDRSTRLEN} per indirizzi IPv6; la lunghezza del buffer deve
comunque venire specificata attraverso il parametro \texttt{len}.
-
+
La funzione restituisce un puntatore non nullo a \texttt{dest} in caso di
successo e un puntatore nullo in caso di fallimento, in quest'ultimo caso
viene settata la variabile \texttt{errno} con il valore \texttt{ENOSPC} in
caso le dimensioni dell'indirizzo eccedano la lunghezza specificata da
- \texttt{len}.
+ \texttt{len} o \macro{ENOAFSUPPORT} in caso \var{af} non sia una famiglia di
+ indirizzi valida.
\end{prototype}
+Gli indirizzi vengono cnovertiti da/alle rispettive strutture di indirizzo
+(\var{struct in\_addr} per IPv4, e \var{struct in6\_addr} per IPv6), che
+devono essere precedentemente allocate e passate attraverso il puntatore
+\var{addr\_ptr}; il parametro \var{dest} di \func{inet\_ntop} non può essere
+nullo e deve essere allocato precedentemente.
+
+Il formato usato per gli indirizzi in formato di presentazione è la notazione
+\textit{dotted decimal} per IPv4 e quella descritta in
+\secref{sec:IP_ipv6_notation} per IPv6.
\section{Il comportamento delle funzioni di I/O}
\label{sec:sock_io_behav}