From: Simone Piccardi Date: Mon, 16 Apr 2001 22:17:20 +0000 (+0000) Subject: Iniziate le funzioni di conversione X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=bea3ef3f853bda8591b685fa92a24b34d8cde6d3 Iniziate le funzioni di conversione --- diff --git a/socket.tex b/socket.tex index cff6a7f..7e1f6bd 100644 --- a/socket.tex +++ b/socket.tex @@ -434,7 +434,6 @@ Si noti che questa struttura 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} @@ -478,19 +477,140 @@ della struttura passaggio dipende dalla direzione del medesimo, dal processo al kernel o viceversa. -In particolare le tre funzioni \texttt{bind}, \texttt{connect} e -\texttt{sendto} passano la struttura al kernel, in questo caso è passata -\textsl{per valore} anche la dimensione della medesima +% In particolare le tre funzioni \texttt{bind}, \texttt{connect} e +% \texttt{sendto} passano la struttura al kernel, in questo caso è passata +% \textsl{per valore} anche la dimensione della medesima -Le funzioni \texttt{accept}, \texttt{recvfrom}, \texttt{getsockname} e -\texttt{getpeername} +% Le funzioni \texttt{accept}, \texttt{recvfrom}, \texttt{getsockname} e +% \texttt{getpeername} invece ricevono i valori del kernel \section{Le funzioni di conversione degli indirizzi} \label{sec:sock_addr_func} +Come accennato gli indirizzi internet e i numero di porta espressi in formato +big endian. In genere la rappresentazione di un numbero binario in un computer +può essere fatta in due modi, chiamati rispettivamente \textit{big endian} e +\textit{little endian} a seconda di come i bit sono aggregati per formare le +unità più grandi. + +Si consideri ad esempio un intero a 16 bit scritto in una locazione di memoria +posta ad un certo indirizzo. I singoli bit possono essere disposti un memoria +in due modi, a partire dal più significativo o a partire dal meno +significativo. Così nel primo caso si troverà il byte che contiene i bit più +significativi all'indirizzo menzionato e il byte con i bit meno significativi +nell'indirizzo successivo; questo ordinamento è detto little endian dato che +il dato finale è la parte ``piccola'' del numero. Il caso opposto, in cui si +parte dal bit meno significativo è detto big endian. + +La \textit{endianess} di un computer dipende essenzialmente dalla architettura +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 sistemi che possono scegliere il +tipo di formato e alcuni, come il PowerPC o l'intel i860, possono pure passare +da un tipo all'altro; ma in generale un sistema ha un suo specifico +comportamento a questo riguardo. + +Il problema si pone quando si passano dei dati da un tipo di archiettura +all'altra dato che, con l'eccezione dei tipi numerici ad otto bit, tutti gli +altri si ritrovano rovesciati. + +Per questo motivo si usano le seguenti funzioni di conversione che tengano +conto della differenza delle architetture: +\begin{itemize} +\item \texttt{unsigned long int htonl(unsigned long int hostlong)} + + Converte l'intero a 32 bit \texttt{hostlong} dal formato della macchina a + quello della rete. + +\item \texttt{unsigned sort int htons(unsigned short int hostshort)} + + Converte l'intero a 16 bit \texttt{hostshort} dal formato della macchina a + quello della rete. + +\item \texttt{unsigned long int ntonl(unsigned long int netlong)} + + Converte l'intero a 32 bit \texttt{netlong} dal formato della rete a quello + della macchina. + +\item \texttt{unsigned sort int ntons(unsigned short int netshort)} + + Converte l'intero a 16 bit \texttt{netshort} dal formato della rete a quello + della macchina. +\end{itemize} +in cui la lettera $n$ è uno mnemonico per indicare l'ordinamento usato sulla +rete (da \textit{network order}) e la lettere $h$ uno mnemonico per +l'ordinamento usato sulla macchina locale (da \textit{host order}), mentre le +lettere $s$ e $l$ stanno ad indicare i tipi di dato (riportati anche dai +prototipi). + +Usando queste funzioni si ha la conversione automatica in caso di necessità +(nel caso pure la macchina sia in big endian queste funzioni sono definite +come macro che non fanno nulla). + +A parte i problemi connessi con l'ordinamento dei bit esistono poi altre +funzioni connesse alla manipolazione degli indirizzi internet, in particolare +per convertire indirizzi espressi in forma di stringa (di più immediata +manipolazione ``umana'') nella forma binaria usata nelle strutture degli +indirizzi. + +Le prime tre funzioni riguardano la conversione degli indirizzi IPv4 fra +l'espressione come stringhe \textit{dotted-decimal}, cioè del tipo +\texttt{192.160.0.1} al formato binario ordinato secondo la rete: +\begin{itemize} +\item \texttt{int inet\_aton(const char *strptr, struct in\_addr *addrptr)} + + Converte la stringa puntata da \texttt{strptr} nell'indirizzo binario da + memorizzare all'indirizzo puntato da \texttt{addrptr}, 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 \texttt{addrptr} inizializzato a + \texttt{NULL} effettua la validazione dell'indirizzo. + +\item \texttt{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 + \texttt{INADDR\_NONE} (che tipicamente sono trentadue bit a uno, il che + significa che la stringa \texttt{255.255.255.255} non può essere un + indirizzo valido). Questa funzione è generalmente deprecata in favore della + precedente. + +\item \texttt{char *inet\_ntop(struct in\_addr addrptr)} + + Questa funzione converte il valore a 32 bit in network order dell'indirizzo + in una stringa. La stringe risiede in memoria statica, per cui questa + funzione non è rientrante, inoltre, in maniera abbastanza atipica, prende in + ingresso una struttura e non un puntarore. +\end{itemize} + +Queste funzioni sono limitate solo ad IPv4, per questo motivo è preferibile +usare le due nuove funzioni \texttt{inet\_pton} e \texttt{inet\_ntop} che +funzionano anche per indirizzi IPv6. In questo caso le lettere $n$ e $p$ sono +gli mnemonici per ricordare il tipo di conversione effettuato e stanno per +\textit{presentation} e \textit{numeric}. + +\begin{itemize} +\item \texttt{int inet\_pton(int family, const char *strptr, void *addrptr)} + + Converte la stringa puntata da \texttt{strptr} nell'indirizzo binario da + memorizzare all'indirizzo puntato da \texttt{addrptr}, 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 \texttt{addrptr} inizializzato a + \texttt{NULL} effettua la validazione dell'indirizzo. + + +\item \texttt{char *inet\_ntop(int family, const void *addrptr, char *strptr, + size\_t len)} + + Questa funzione converte il valore a 32 bit in network order dell'indirizzo + in una stringa. La stringe risiede in memoria statica, per cui questa + funzione non è rientrante, inoltre, in maniera abbastanza atipica, prende in + ingresso una struttura e non un puntatore. +\end{itemize}