# IPv4

IPv4 è uno dei protocolli del network layer e definisce il formato degli indirizzi per la comunicazione tra host. In sostanza, l'IP serve come meccanismo di indirizzamento dei pacchetti, permettendo di identificare univocamente ogni host all'interno di una rete.

## Anatomia del pacchetto IPv4

![ipv4](asset/img/ipv4.png)

Il datagramma o pacchetto IPv4 è composto da due parti principali:

- L'*header*, che contiene le informazioni di controllo e indirizzamento
- Il payload, ossia i dati che vengono incapsulati all'interno del pacchetto

L'header ha una dimensione minima di 20 byte e può estendersi fino a 60 byte, includendo diversi campi importanti, quali:

- `Version`: specifica la versione del protocollo IP
- `Source Address`: l'indirizzo IP del mittente, lungo 32 bit
- `Destination Address`: l'indirizzo IP del destinatario, anch'esso lungo 32 bit
- `Time to Live (TTL)`: campo di 8 bit che rappresenta il *tempo di vita* del pacchetto. Ad ogni passaggio (hop) tra router, il valore del TTL viene decrementato di uno. Quando il TTL raggiunge zero, il pacchetto viene scartato, evitando così che rimanga indefinitamente nella rete in caso di un errore di instradamento. Nel momento in cui un router scarta il pacchetto, ciò può generare un ICMP error message per informare il mittente
- `Protocol`: un codice che indica il protocollo utilizzato per la parte dati incapsulata. Alcuni esempi:
  - ICMP: codice 1
  - TCP: codice 6
  - UDP: codice 17
  - EIGMP: codice 88
  - L2TP: codice 115

## IPv4 Fragmentation

Il livello di data link ha un limite dimensionale noto come `MTU` (`Maximum Transmission Unit`), che di norma è fissato a 1500 byte. Questo significa che il payload che deve essere incapsulato nel livello data link non può superare i 1500 byte. È importante notare che il valore della MTU può essere configurato a livello di switch o router.

Quando si devono inviare dati che superano il limite della MTU, entra in gioco il processo di *frammentazione*. Durante questo processo, i dati vengono suddivisi in pacchetti più piccoli, noti come frammenti, ciascuno dei quali include header IP originario, che contengono informazioni cruciali per l'instradamento e la ricostruzione dei pacchetti.

Ogni frammento è identificato da un campo `Identifier`, che consente di raggruppare i frammenti appartenenti allo stesso datagramma originale. Inoltre, il campo `Fragment Offset` indica la posizione di ciascun frammento all'interno del datagramma originale, permettendo al destinatario di ricostruire correttamente l'ordine dei dati.

## Rappresentazione degli Indirizzi IPv4

Un host in una rete o sottorete viene identificato univocamente attraverso il suo indirizzo IPv4, il quale possiede tre principali rappresentazioni:

- *Binaria*
- *Dot-decimal Annotation*, in cui ogni ottetto assume valori compresi tra 0 e 255
- *Esadecimale*

L'indirizzo IPv4 è composto da due componenti fondamentali: il `prefisso` e il `suffisso`. I primi n bit, denominati prefisso, sono fissi e identificano la rete o sottorete, mentre i rimanenti bit, denominati suffisso, sono variabili e permettono di identificare un host specifico all'interno della rete.

### Annotazione CIDR

Il `CIDR` (*Classless Inter-Domain Routing*), una modalità avanzata di espressione della netmask, rappresenta graficamente la divisione tra i bit di prefisso e quelli di suffisso. Questa notazione si esprime aggiungendo all'indirizzo IPv4 una barra (`/`) seguita da un numero *N*, compreso tra 0 e 32. Tale numero indica quanti dei 32 bit dell'indirizzo sono riservati al prefisso, mentre i restanti bit compongono il suffisso.

## Indirizzi Speciali

Dei 2^32-1 indirizzi IPv4 disponibili, alcuni sono riservati per scopi particolari. La IANA (Internet Assigned Numbers Authority) è responsabile dell'assegnamento degli indirizzi IP a livello globale, con alcuni intervalli destinati all'uso privato o a funzioni specifiche.

### Indirizzi IP Privati

Gli indirizzi IP privati sono destinati all'utilizzo all'interno delle reti locali (LAN) e non sono univoci a livello globale, non consentendo di identificare in modo univoco un host su Internet. Le principali classi di indirizzi privati sono:

- `10.0.0.0/8`
- `172.16.0.0/12`: da 172.16.0.0 a 172.31.255.255
- `192.168.0.0/16`
- `169.254.0.0/16`: questo intervallo è riservato per il protocollo `APIPA` (*Automatic Private IP Addressing*), che permette ad un host di autoconfigurarsi con un indirizzo IP privato quando un server DHCP non è disponibile.

Altri *indirizzi speciali*:

- `0.0.0.0/8`: l'indirizzo 0.0.0.0 è un caso particolare. Non è assegnabile ad un host e, a seconda del contesto, può assumere diversi significati. Ad esempio può essere usato per rappresentare *qualsiasi indirizzo* in certe configurazioni di rete o nelle tabelle di routing
- `127.0.0.0/8`: l'intervallo va da 127.0.0.0 a 127.255.255.255 ed è riservato agli indirizzi di *loopback* (o di ritorno). In particolare, l'indirizzo `127.0.0.1` viene comunemente usato per riferirsi al *localhost*. Questi indirizzi sono impiegati per testare localmente le applicazioni che utilizzano lo stack TCP/IP, permettendo al processo di comunicare con lo stesso host
- `224.0.0.0/4`: questo intervallo, che va da 224.0.0.0 a 239.255.255.255, è riservato agli indirizzi *multicast*, utilizzati per trasmettere pacchetti a un gruppo di host che hanno aderito a un determinato gruppo multicast
- *Indirizzi di broadcast*: ogni subnet possiede un indirizzo di broadcast specifico, noto come `directed broadcast`. Questo è l'ultimo indirizzo della subnet e permette di inviare pacchetti a tutti gli host che vi appartengono. Inoltre, esiste il `limited broadcast`, rappresentato dall'indirizzo `255.255.255.255`, che viene sempre usato per inviare un pacchetto a tutti gli host sulla rete locale. La differenza principale tra il *directed broadcast* e il *limited broadcast* è che il directed broadcast può essere instradato anche su reti differenti, mentre il limited broadcast è confinato esclusivamente alla rete locale e non viene inoltrato dai router.
