-motivo è preferibile usare le due nuove funzioni \texttt{inet\_pton} e
-\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}{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} 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}
-
-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 \texttt{read} o
-\texttt{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 \texttt{SockRead}, legge $n$ 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 \texttt{SockRead} e \texttt{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 \texttt{SockRead.c} e \texttt{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 \texttt{SockWrite}, scrive $n$ bytes su un socket }
- \label{fig:sock_SockWrite_code}
-\end{figure}
-
-Come si può notare le funzioni ripetono la lettura/scrittura in un loop fino
-all'esaurimento del numero di bytes richiesti, in caso di errore viene
-controllato se questo è \texttt{EINTR} (cioè un'interruzione della system call
-dovuta ad un segnale), nel qual caso l'accesso viene ripetuto, altrimenti
-l'errore viene ritornato interrompendo il loop.
-
-Nel caso della lettura se il numero di bytes letti è zero significa che è
-arrivati alla fine del file e pertanto si ritorna senza aver concluso la
-lettura di tutti i bytes richiesti.
-
+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 \texttt{n} e \texttt{p} sono degli mnemonici per
+ricordare il tipo di conversione effettuata e stanno per \textit{presentation}
+e \textit{numeric}.
+
+Entrambe le funzioni accettano l'argomento \param{af} che indica il tipo di
+indirizzo, e che può essere soltanto \const{AF\_INET} o \const{AF\_INET6}. La
+prima funzione, \funcd{inet\_pton}, serve a convertire una stringa in un
+indirizzo; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/socket.h}
+\fdecl{int inet\_pton(int af, const char *src, void *addr\_ptr)}
+\fdesc{Converte l'indirizzo espresso tramite una stringa nel valore numerico.}
+}
+
+{La funzione ritorna $1$ in caso di successo, $0$ se \param{src} non contiene
+ una rappresentazione valida per la famiglia di indirizzi indicati
+ da \param{af} e $-1$ se \param{af} specifica una famiglia di indirizzi non
+ valida, e solo in quest'ultimo caso \var{errno} assumerà il valore
+ \errcode{EAFNOSUPPORT}.
+}
+\end{funcproto}
+
+La funzione converte la stringa indicata tramite \param{src} nel valore
+numerico dell'indirizzo IP del tipo specificato da \param{af} che viene
+memorizzato all'indirizzo puntato da \param{addr\_ptr}. La funzione supporta
+per IPv4 la sola notazione \textit{dotted-decimal}, e non quella più completa
+\textit{number-and-dot} che abbiamo visto per \func{inet\_aton}. Per IPv6 la
+notazione prevede la suddivisione dei 128 bit dell'indirizzo in 16 parti di 16
+bit espresse con valori esadecimali separati dal carattere ``\texttt{:}'' ed
+una serie di valori nulli possono essere sostituiti (una sola volta, sempre a
+partire dalla sinistra) con la notazione ``\texttt{::}'', un esempio di
+indirizzo in questa forma potrebbe essere \texttt{2001:db8::8:ba98:2078:e3e3},
+per una descrizione più completa si veda sez.~\ref{sec:IP_ipv6_notation}.
+
+La seconda funzione di conversione è \funcd{inet\_ntop} che converte un
+indirizzo in una stringa; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/socket.h}
+\fdecl{char *inet\_ntop(int af, const void *addr\_ptr, char *dest, size\_t len)}
+\fdesc{Converte l'indirizzo dalla relativa struttura in una stringa simbolica.}
+}
+
+{La funzione ritorna un puntatore non nullo alla stringa convertita in caso di
+ successo e \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno
+ dei valori:
+ \begin{errlist}
+ \item[\errcode{ENOSPC}] le dimensioni della stringa con la conversione
+ dell'indirizzo eccedono la lunghezza specificata da \param{len}.
+ \item[\errcode{ENOAFSUPPORT}] la famiglia di indirizzi \param{af} non è
+ una valida.
+ \end{errlist}
+}
+\end{funcproto}
+
+
+La funzione converte la struttura dell'indirizzo puntata da \param{addr\_ptr}
+in una stringa che viene copiata nel buffer puntato dall'indirizzo
+\param{dest}; questo deve essere preallocato dall'utente e la lunghezza deve
+essere almeno \constd{INET\_ADDRSTRLEN} in caso di indirizzi IPv4 e
+\constd{INET6\_ADDRSTRLEN} per indirizzi IPv6; la lunghezza del buffer deve
+comunque essere specificata con il parametro \param{len}.
+
+Gli indirizzi vengono convertiti da/alle rispettive strutture di indirizzo
+(una struttura \struct{in\_addr} per IPv4, e una struttura \struct{in6\_addr}
+per IPv6), che devono essere precedentemente allocate e passate attraverso il
+puntatore \param{addr\_ptr}; l'argomento \param{dest} di \func{inet\_ntop} non
+può essere nullo e deve essere allocato precedentemente.
+
+
+
+
+
+% LocalWords: socket sez cap BSD SVr XTI Transport Interface TCP stream UDP PF
+% LocalWords: datagram broadcast descriptor sys int domain type protocol errno
+% LocalWords: EPROTONOSUPPORT ENFILE kernel EMFILE EACCES EINVAL ENOBUFS raw
+% LocalWords: ENOMEM table family AF address name glibc UNSPEC LOCAL Local IPv
+% LocalWords: communication INET protocols ip AX Amateur IPX Novell APPLETALK
+% LocalWords: Appletalk ddp NETROM NetROM Multiprotocol ATMPVC Access to ATM
+% LocalWords: PVCs ITU ipv PLP DECnet Reserved for project NETBEUI LLC KEY key
+% LocalWords: SECURITY Security callback NETLINK interface device netlink Low
+% LocalWords: PACKET level packet ASH Ash ECONET Acorn Econet ATMSVC SVCs SNA
+% LocalWords: IRDA PPPOX PPPoX WANPIPE Wanpipe BLUETOOTH Bluetooth POSIX bits
+% LocalWords: dall'header tab SOCK capabilities capability styles DGRAM read
+% LocalWords: SEQPACKET RDM sockaddr reference void fig Header uint socklen at
+% LocalWords: addr netinet port len Stevens unsigned short casting nell'header
+% LocalWords: BIND SERVICE bind union order big endian flowinfo dell'header ll
+% LocalWords: multicast multicasting local socketpair sun path filesystem AARP
+% LocalWords: pathname AppleTalk netatalk personal Apple ATPROTO atalk sat if
+% LocalWords: ANYNET node ANYNODE ATADDR BCAST pcap IEEE linux ether ETH ALL
+% LocalWords: sll ifindex ethernet halen MAC hatype ARP arp pkttype HOST recv
+% LocalWords: OTHERHOST OUTGOING recvfrom recvmsg endianness little endtest Mac
+% LocalWords: Intel Digital Motorola IBM VME PowerPC l'Intel xABCD ptr htonl
+% LocalWords: htons ntohl ntohs long hostlong hostshort netlong
+% LocalWords: sort netshort host inet aton ntoa dotted decimal const char src
+% LocalWords: strptr struct dest addrptr INADDR NULL pton ntop presentation af
+% LocalWords: numeric EAFNOSUPPORT size ENOSPC ENOAFSUPPORT ADDRSTRLEN ROUTE
+% LocalWords: of tcpdump page
+
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "gapil"
+%%% End: