-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 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
-cosiddetta notazione \textit{dotted-decimal}, (cioè nella forma
-\texttt{192.160.0.1}) al formato binario (direttamente in \textit{network
- order}) e viceversa; in questo caso si usa la lettera \func{a} come
-mnemonico per indicare la stringa. Dette funzioni sono:
-\begin{prototype}{arpa/inet.h}
- {int inet\_aton(const char *src, struct in\_addr *dest)}
- Converte la stringa puntata da \var{src} nell'indirizzo binario da
- memorizzare all'indirizzo puntato da \var{dest}, restituendo 0 in caso di
- successo e 1 in caso di fallimento (è espressa in questa forma in modo da
- poterla usare direttamente con il puntatore usato per passare la struttura
- degli indirizzi). Se usata con \var{dest} inizializzato a \macro{NULL}
- effettua la validazione dell'indirizzo.
-\end{prototype}
-\begin{prototype}{arpa/inet.h}{in\_addr\_t inet\_addr(const char *strptr)}
- Restituisce l'indirizzo a 32 bit in network order a partire dalla stringa
- passata come parametro, in caso di errore restituisce il valore
- \macro{INADDR\_NONE} che tipicamente sono trentadue bit a uno; questo
- comporta che la stringa \texttt{255.255.255.255}, che pure è un indirizzo
- valido, non può essere usata con questa funzione; per questo motivo essa è
- generalmente deprecata in favore della precedente.
-\end{prototype}
-\begin{prototype}{arpa/inet.h}{char *inet\_ntoa(struct in\_addr addrptr)}
- Converte il valore a 32 bit dell'indirizzo (espresso in \textit{network
- order}) restituendo il puntatore alla stringa che contiene l'espressione
- in formato dotted decimal. Si deve tenere presente che la stringa risiede in
- memoria statica, per cui questa funzione non è rientrante.
-\end{prototype}
-
-
-\subsection{Le funzioni \func{inet\_pton} e \func{inet\_ntop}}
-\label{sec:sock_conv_func_gen}
-
-Le tre funzioni precedenti sono limitate solo ad indirizzi IPv4, per questo
-motivo è preferibile usare le due nuove funzioni \func{inet\_pton} e
-\func{inet\_ntop} che possono convertire anche gli indirizzi IPv6. Anche in
-questo caso le lettere \func{n} e \func{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 \var{src} nell'indirizzo IP da memorizzare
- all'indirizzo puntato da \var{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}{sys/socket.h}
- {char *inet\_ntop(int af, const void *addr\_ptr, char *dest, size\_t len)}
- Converte la struttura dell'indirizzo puntata da \var{addr\_ptr} in una
- stringa che viene copiata nel buffer puntato dall'indirizzo \var{dest};
- questo deve essere preallocato dall'utente e la lunghezza deve essere almeno
- \macro{INET\_ADDRSTRLEN} in caso di indirizzi IPv4 e
- \macro{INET6\_ADDRSTRLEN} per indirizzi IPv6; la lunghezza del buffer deve
- comunque venire specificata attraverso il parametro \var{len}.
-
- La funzione restituisce un puntatore non nullo a \var{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 \macro{ENOSPC} in
- caso le dimensioni dell'indirizzo eccedano la lunghezza specificata da
- \var{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{Un esempio di applicazione}
-\label{sec:sock_appplication}
-
-Per evitare di rendere questa introduzione ai socket puramente teorica
-iniziamo con il mostrare un esempio di un client TCP elementare. Prima di
-passare agli esempi del client e del server, esamimeremo una caratteristica
-delle funzioni di I/O sui socket che ci tornerà utile anche in seguito.
-
-
-\subsection{Il comportamento delle funzioni di I/O}
-\label{sec:sock_io_behav}
-
-Una cosa di cui non sempre si è consapevoli quando si ha a che fare con i
-socket è che le funzioni di input/output non sempre hanno lo stesso
-comportamento che avrebbero con i normali files (in particolare questo accade
-per i socket di tipo stream).
-
-Infatti con i socket può accadere che funzioni come \func{read} o
-\func{write} possano restituire in input o scrivere in output un numero di
-bytes minore di quello richiesto. Questo è un comportamento normale e non un
-errore, e succede perché si eccede in lettura o scrittura il limite di buffer
-del kernel.
-
-In questo caso tutto quello che il programma chiamante deve fare è di ripetere
-la lettura (o scrittura) per la quantità di bytes rimanenti (lo stesso può
-avvenire scrivendo più di 4096 bytes in una pipe, dato che quello è il limite
-di solito adottato per il buffer di trasmissione del kernel).
-
-\begin{figure}[htb]
- \centering
- \footnotesize
- \begin{lstlisting}{}
-#include <unistd.h>
-
-ssize_t SockRead(int fd, void *buf, size_t count)
-{
- size_t nleft;
- ssize_t nread;
-
- nleft = count;
- while (nleft > 0) { /* repeat until no left */
- if ( (nread = read(fd, buf, nleft)) < 0) {
- if (errno == EINTR) { /* if interrupted by system call */
- continue; /* repeat the loop */
- } else {
- return(nread); /* otherwise exit */
- }
- } else if (nread == 0) { /* EOF */
- break; /* break loop here */
- }
- nleft -= nread; /* set left to read */
- buf +=nread; /* set pointer */
- }
- return (count - nleft);
-}
- \end{lstlisting}
- \caption{Funzione \func{SockRead}, legge \var{count} bytes da un socket }
- \label{fig:sock_SockRead_code}
-\end{figure}
-
-Per questo motivo seguendo l'esempio di W. R. Stevens si sono definite due
-funzioni \func{SockRead} e \func{SockWrite} che eseguono la lettura da un
-socket tenendo conto di questa caratteristica, ed in grado di ritornare dopo
-avere letto o scritto esattamente il numero di bytes specificato; il sorgente
-è riportato in \curfig\ e \nfig\ ed è disponibile fra i sorgenti allegati alla
-guida nei files \file{SockRead.c} e \file{SockWrite.c}.
-
-\begin{figure}[htb]
- \centering
- \footnotesize
- \begin{lstlisting}{}
-#include <unistd.h>
-
-ssize_t SockWrite(int fd, const void *buf, size_t count)
-{
- size_t nleft;
- ssize_t nwritten;
-
- nleft = count;
- while (nleft > 0) { /* repeat until no left */
- if ( (nwritten = write(fd, buf, nleft)) < 0) {
- if (errno == EINTR) { /* if interrupted by system call */
- continue; /* repeat the loop */
- } else {
- return(nwritten); /* otherwise exit with error */
- }
- }
- nleft -= nwritten; /* set left to write */
- buf +=nwritten; /* set pointer */
- }
- return (count);
-}
- \end{lstlisting}
- \caption{Funzione \func{SockWrite}, scrive \var{count} bytes su un socket }
- \label{fig:sock_SockWrite_code}
-\end{figure}
+Un secondo insieme di funzioni di manipolazione è quello che serve per passare
+dalla rappresentazione simbolica degli indirizzi IP al formato binario
+previsto dalla struttura degli indirizzi di
+fig.~\ref{fig:sock_sa_ipv4_struct}, e viceversa. La notazione più comune è la
+cosiddetta notazione \itindex{dotted-decimal} \textit{dotted-decimal}, che
+prevede che gli indirizzi IPv4 siano indicati con l'espressione del valore
+numerico decimale di ciascuno dei 4 byte che li costituiscono separati da un
+punto (ad esempio \texttt{192.168.0.1}).
+
+In realtà le funzioni che illustreremo supportano una notazione che più
+propriamente dovrebbe esser chiamata \textit{numbers-and-dot} in quanto il
+valore può essere indicato con numeri espressi sia in decimale, che in ottale
+(se indicati apponendo uno zero) che in esadecimale (se indicati apponendo
+\texttt{0x}). Inoltre per la parte meno significativa dell'espressione, quella
+che riguarda l'indirizzo locale, si può usare, eliminando altrettanti punti,
+valori a 16 o a 24 bit, e togliendo tutti i punti, si può usare anche
+direttamente un valore numerico a 32 bit.\footnote{la funzionalità si trova
+ anche in gran parte dei programmi che usano indirizzi di rete, e deriva
+ direttamente da queste funzioni.}
+
+Tradizionalmente la conversione di un indirizzo \textit{dotted-decimal} al
+valore numerico veniva eseguita dalla funzione \funcd{inet\_addr} (prevista
+fin dalle origini in BSD e inclusa in POSIX.1-2001) il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{arpa/inet.h}
+\fdecl{in\_addr\_t inet\_addr(const char *strptr)}
+\fdesc{Converte la stringa dell'indirizzo \textit{dotted decimal} in nel
+ numero IP in network order.}
+}