Nel caso di una rete locale (LAN) si devono collegare un numero elevato di utenti abbastanza vicini tra loro, con distanze dell'ordine del km o anche meno. Si potrebbe pensare inizialmente di collegare ogni utente con qualsiasi altro tramite un collegamento punto-punto dedicato, ma questo sarebbe impraticabile e molto costoso, oltre che inutile.
Infatti tipicamente non tutti gli utenti saranno attivi contemporaneamente e ciascun utente avrà in corso solo poche connessioni con altri utenti o servizi, quindi molti collegamenti dedicati rimarrebbero inutilizzati per la maggior parte del tempo. Inoltre ogni utente, anche quando siede davanti al suo personal computer, non ha generalmente bisogno di trasmettere con continuità, ma utilizza la rete solo per brevi periodi (si pensi per esempio allo scaricamento di un grosso file di dati che poi viene analizzato manualmente o alla navigazione in un sito web in cui un trasferimento dati è attivato tramite click). Si dice in tal caso che il tipo di trasmissione dati o "servizio" richiesto da un utente è "a burst", ovvero serve sì avere una elevata velocità (ad esempio per non dover aspettare troppo che si carichi un grosso documento su cui lavorare), ma solo per brevi periodi di tempo.
Le soluzioni economicamente accettabili prevedono l'utilizzo di strutture di rete non completamente connesse e di conseguenza la condivisione del canale trasmissivo in modo da poter mettere in comunicazione ogni nodo con qualsiasi altro nodo. Ne sono state proposte varie e differiscono sostanzialmente per il tipo di canale di diffusione (broadcast) adottato e il meccanismo di arbitraggio del medesimo, necessario per evitare interferenze, in quanto evidentemente su un canale condiviso può avvenire una sola trasmissione per volta. Ethernet è la soluzione che ha avuto il maggior successo commerciale ed è stata in grado di evolversi per tenersi al passo coi tempi.
Nella rappresentazione grafica in cnet, ogni segmento di rete Ethernet è formato da almeno due o più schede di rete (dette anche NIC, Network Interface Cards) connesse tramite una topologia a bus che è fisicamente di tipo broadcast, cioè il segnale trasmesso da un nodo si propaga naturalmente verso tutti gli altri nodi attestati sullo stesso segmento. In realtà oggi questo tipo di topologia è in disuso: si preferisce connettere tutti i computer in modo da formare una stella con un ripetitore (hub) centrale. Quello che si ottiene in questo modo è ancora un canale broadcast su cui si può applicare il protocollo di Ethernet, ma non di tipo fisico, bensì logico, ossia simulato tramite più collegamenti di tipo punto punto, in quanto l'hub ripete il segnale che riceve da un host verso tutti gli altri host ad esso connessi. La topologia stellare ha alcuni vantaggi: utilizza il doppino intrecciato anziché il cavo coassiale della vecchia topologia a bus e questo semplifica il cablaggio e ne riduce i costi; inoltre la struttura stellare permette di isolare più facilmente i possibili guasti.
Ciascuna scheda ha un indirizzo del sottolivello MAC (Medium Access Control, controllo di accesso al mezzo) unico, definito nel file che descrive la topologia della rete, nel formato tradizionale di Ethernet (ovvero espresso in esadecimale su 6-byte, ad es. 00:E0:4B:39:05:E1).
La simulazione di segmenti di rete Ethernet (standard IEEE 802.3) con cnet non è perfetta, in quanto cnet non è pensato come uno strumento per la progettazione di reti reali, ma più semplicemente come un simulatore per scopi didattici. Vengono ben simulate tutte le principali caratteristiche del protocollo distribuito non deterministico su cui si basa Ethernet (il CSMA/CD): il rilevamento delle collisioni, le sequenze di jamming (raffiche di rumore usate per annullare una trasmissione in corso dopo che è avvenuta una collisione) e il backoff binario esponenziale (l'algoritmo non deterministico utilizzato per tentare la ripresa delle trasmissioni dopo una collisione che garantisce buoni tempi di risoluzione indipendentemente dal numero di stazioni entrate in collisione). Alcuni parametri della rete sono fissi e non possono essere modificati. La velocità con cui vengono trasmessi i bit, ad esempio, può essere solo di 10 Mbps, quindi non si possono simulare le moderne evoluzioni della rete Ethernet (le Fast Ethernet, che hanno una velocità trasmissiva di 100 Mbps e le Gigabit Ethernet con 1 Gb/s). Il tempo di slot è fissato a 52usecs. Ogni segmento viene considerato della lunghezza massima ammessa dallo standard per questo tipo di rete, 2.5 km, e tutti i nodi vengono distribuiti ad uguale distanza lungo il segmento stesso.
Inoltre cnet non supporta il multicast addressing (detto anche group addressing, ovvero la possibilità di inviare un pacchetto ad un gruppo prefissato di stazioni sul mezzo broadcast tramite una sola trasmissione) e il jitter control.
Si possono comunque creare delle reti complesse congiungendo diversi segmenti Ethernet tramite dei nodi gateway (detti anche router). Un gateway è connesso a ciascuno dei segmenti che mette in comunicazione esattamente come è connesso un qualsiasi host di quel segmento, ovvero, per ogni segmento, il gateway ha una NIC connessa al segmento stesso. I gateway possono poi essere connessi tra loro tramite dei link di tipo WAN punto-punto, analoghi a quelli studiati nella simulazione precedente.
Infine in cnet si può impostare una NIC in modalità "promiscua", in modo che riceva una copia di tutti i frame che transitano sul segmento (anche se non sono frame di tipo broadcast o esplicitamente indirizzati alla scheda di rete) e sia quindi in grado di monitorare l'intero segmento.
compile = "ethertest.c" minmessagesize = 40bytes maxmessagesize = 1000bytes messagerate = 10ms
Gli attributi compile e messagerate hanno lo stesso significato spiegato nella simulazione di un link punto-punto. Gli altri due attributi di nodo usati sono nuovi, in quanto erano stati lasciati al valore di default nella simulazione precedente, che per entrambi è 100 byte. Indicano la dimensione minima e massima misurata in byte dei messaggi generati dallo strato applicativo. Notare che maxmessagesize è limitato dalla costante MAX_MESSAGE_SIZE definita a tempo di compilazione di cnet (il file header cnet.h rivela che è stata posta ad 8 KB).
ethernet CSSE { nicaddr 00:90:27:62:58:84 host budgie { } nicaddr 00:90:27:41:D7:42 host dibbler { } nicaddr 00:02:B3:3C:34:C5 host dunnart { } nicaddr 00:0A:27:7D:41:C6 host emu { } nicaddr 00:D0:B7:83:97:E7 host galah { } nicaddr 00:90:27:41:B0:BE host kanga { } nicaddr 00:AA:00:BC:C0:73 host kidna { } nicaddr 00:90:27:62:83:F5 host koala { } nicaddr 00:D0:B7:90:DD:85 host numbat { } nicaddr 00:A0:C9:AF:9E:81 host quokka { } nicaddr 00:90:27:34:B6:D8 host wombat { } }
Questo blocco definisce un segmento Ethernet con 11 nodi, tutti di tipo host (nessun router). CSSE è il nome del segmento e viene visualizzato all'estremità sinistra del bus nella rappresentazione grafica. Può essere scelto a piacere; in questo caso corrisponde alla sigla del Dipartimento in cui lavora l'autore di cnet all'Università dell'Australia Occidentale. All'interno di un blocco ethernet viene poi definita la connessione di ciascun nodo al segmento tramite l'indicazione dell'indirizzo della sua scheda di rete (NIC). Ognuno di questi indirizzi MAC viene fatto seguire da una dichiarazione di host o router dello stesso tipo di quelle usate per la definizione delle topologie punto-punto. In questo esempio tra le parentesi graffe dopo il nome del nodo, che sono comunque obbligatorie, non viene ridefinito alcun attributo del nodo e del link, ma volendo si potrebbero cambiare parametri come il messagerate o anche definire ulteriori link di tipo punto-punto posseduti da questo nodo verso altri nodi tramite la keyword link to.
Se due indirizzi NIC definiti nello stesso file di topologia sono uguali, cnet non considera questo fatto un errore e si limita ad emettere un avvertimento. Questo è stato fatto apposta per permettere di sviluppare dei protocolli che praticano lo snooping/sniffing: è sufficiente che un nodo abbia settato il proprio indirizzo NIC allo stesso valore di quello di un altro nodo e sarà quindi in grado di rubare i pacchetti che sono diretti a quest'ultimo. In realtà, non si tratta di un vero e proprio furto: essendo la rete di tipo broadcast, quella che in realtà viene ``rubata'' è solo una copia del pacchetto: in altri termini, i pacchetti arriveranno anche al vero di nodo di destinazione.
La definizione del formato di un frame non è imposta da cnet, ma va decisa nel file che implementa il protocollo. L'unico vincolo che occorre rispettare è che i primi LEN_NICADDR byte di ciascun frame devono contenere l'indirizzo della scheda di rete (NIC) destinataria. LEN_NICADDR è una costante definita in cnet.h e vale 6, che corrisponde ad indirizzi di 48 bit. cnet interpreta l'indirizzo formato da byte tutti uguali al valore 255, che corrisponde nel formato stringa a ff:ff:ff:ff:ff:ff, come l'indirizzo di broadcast. Un frame che ha come indirizzo di destinazione quello di broadcast verrà considerato come diretto all'host da tutte le NIC sullo stesso segmento Ethernet, ad eccezione naturalmente del mittente.
Il resto della struttura è stato definito in modo da rispettare il formato del pacchetto secondo lo standard 802.3, eccetto che non sono presenti i campi di delimitazione iniziali utilizzati a livello fisico per la sincronizzazione tra trasmettitore e ricevitore (non necessari in cnet) e per semplicità è stata omessa anche la checksum finale.
header | payload +---------------------------+---------------------------+---------+------- ... -------+ | destination | source | type | data | | unsigned char[6] | unsigned char[6] | char[2] | char [] | +---------------------------+---------------------------+---------+------- ... -------+ byte: 0 6 12 14 14+type
Notare che il campo type, lungo 2 byte, indica la lunghezza del campo data (il nome len o length sarebbe stato più appropriato). Quest'ultimo, secondo lo standard, non può essere più lungo di ETH_MAXDATA (=1500) byte, che quindi è anche il limite superiore per il valore di type. Inoltre lo standard, per garantire il riconoscimento delle collisioni anche nel caso peggiore (ovvero tra le due stazioni più distanti della rete, tenendo conto che ogni stazione può rilevare una eventuale collisione solo mentre sta trasmettendo), stabilisce che l'intero pacchetto (come da noi rappresentato in C, quindi delimitatori esclusi) debba essere lungo almeno ETH_MINPACKET (=64) byte. Perciò se 14+type < ETH_MINPACKET vengono aggiunti dei byte di padding al campo data in modo che l'intero frame sia lungo giusto ETH_MINPACKET byte.
Segue la versione in pseudocodice di ethertest.c, il cui codice è suddiviso tra diversi gestori degli eventi.
- Imposta l'indirizzo NIC di ciascun link Ethernet ad un valore globalmente noto.
- Registra tutti gli altri handler per rispondere ai rispettivi eventi.
- Abilita lo strato di Applicazione a generare dei messaggi.
- packet.data = messaggio prelevato dallo strato applicativo.
- packet.type = lunghezza reale del messaggio.
- packet.dest = indirizzo MAC della scheda di destinazione.
- packet.src = indirizzo MAC del primo link di questo nodo.
- Se packet è troppo corto effettua il riempimento fino alla lunghezza minima.
- Trasmetti il frame packet sul link 1 di questo nodo.
- packet = frame ricevuto sul link 1 del livello Fisico.
- Trasmetti una copia dei primi packet.type byte di packet.data allo strato Applicativo.
Note:
Ecco in dettaglio come funziona: nel momento in cui ogni nodo viene inizializzato dall'event handler reboot_node l'indirizzo NIC di ciascun link di tipo Ethernet viene cambiato rispetto a quanto stabilito nel file di topologia in modo che abbia un valore globalmente noto. Ad esempio l'indirizzo MAC del nodo koala, che inizialmente è 00:90:27:62:83:F5, viene cambiato in 07:00:00:00:00:01 e similmente per tutti gli altri nodi. Notate che i primi quattro byte coincidono con l'indirizzo globale del nodo (ricordo che i nodi sono numerati da cnet a partire da 0) come rappresentato in forma numerica all'interno della memoria del calcolatore: in questo caso il nodo koala è il numero 7; si noti che siccome la simulazione girava su un processore Intel la rappresentazione è di tipo little-endian; se invece avessi usato, ad es., una Sparc, avrei ottenuto come nuovo MAC address 00:00:00:07:00:01 a causa del fatto che la rappresentazione su quest'altro tipo di macchina è di tipo big-endian. Il quinto byte viene posto a zero e l'ultimo, cioè il sesto byte viene posto uguale al numero del link ethernet a cui si vuole assegnare il nuovo MAC address. Tutti i nodi hanno in tal caso solo due link: il link 0, che corrisponde all'interfaccia di loopback e il link numero 1, che corrisponde all'interfaccia Ethernet. Quando nell'handler application_ready si preleva un messaggio dallo strato applicativo esso fornisce anche il numero del nodo destinatario (ad es. 5 o kanga); in base a questo viene costruito con la stessa convenzione l'indirizzo MAC (nell'esempio sarà 05:00:00:00:00:01 su una macchina little-endian) e il frame avente questo indirizzo di destinazione viene trasmesso sempre sul link numero 1.
Avviando cnet con il comando:
$ cnet ETHERTESTapparirà la mappa della rete, come quella mostrata in figura:
La rete Ethernet simulata per circa 2 minuti.
Come al solito cliccando su un nodo si può vedere la sua finestra di output con le statistiche di trasmissione per quel nodo. Invece cliccando sul bus appare la finestra con le statistiche relative all'intero segmento di rete, compreso il numero di collisioni verificatosi. Questi e altri dati statistici sono disponibili anche nella subwindow statistics.
Le statistiche del bus.
Le statistiche dettagliate.
Le statistiche riferite al solo nodo koala.