Network Working Group Bill Croft (Stanford University) Request for Comments: 951 John Gilmore (Sun Microsystems) September 1985 BOOTSTRAP PROTOCOL (BOOTP) tradotto da Therbium (therbium@supereva.it) ver 0.01 Distribuita da .::http://www.rfc.altervista.org::. 1. Stato di questo promemoria Questo RFC illustra un protocollo proposto per la comunità ARPA, e richiede discussioni e suggerimenti per migliorie. La distribuzione di questo file è senza limiti. 2. Descrizione Questo RFC descrive il protocollo di bootstrap IP/UDP (BOOTP) che permette ad una macchina senza dischi di scoprire il proprio indirizzo IP, l'indirizzo del server e il nome del file che deve essere caricato nella memoria ed eseguito. L'operazione di bootstrap può essere pensata come costituita da due fasi. Questo RFC descrive la prima fase, che potrebbe essere intitolata 'determinazione dell'indirizzo e selezione del file di bootstrap'. Quando si conosce sia l'indirizzo che l'informazione del nome del file, il controllo passa alla seconda fase di bootstrap dove occorre un trasferimento di file. Il trasferimento di file userà tipicamente il protocollo TFTP [9], entrambe le fasi risiedono nella PROM (Programmable ROM) del computer. Comunque il BOOTP potrebbe anche funzionare con altri protocolli come l'SFTP [3] o l'FTP [6]. Si informa che la PROM del computer client provvede un modo per un bootstrap completo senza l'intervento dell'utente. Questo è un tipo di boot che potrebbe occorrere durante un'accensione inattesa. Un modo dovrebbe essere dato all'utente per inserire manualmente l'indirizzo ed entrare direttamente nel trasferimento di file. Se è disponibile un dispositivo di massa non volatile, suggeriamo di mantenere le impostazioni di default e bypassare il protocollo BOOTP, a meno che queste impostazioni siano sbagliate. Se l'informazione memorizzata fallisce, il bootstrap dovrebbe tornare indietro alla fase 1 e usare BOOTP. Ecco un breve riassunto del protocollo: 1. E' eseguito un singolo scambio di pacchetti. I timeout sono usati per ritrasmettere fino a che è ricevuta una risposta. Lo stesso pacchetto è utilizzato in entrambe le direzioni. Sono utilizzati campi a lunghezza fissa (fino ad un massimo ragionevole) per semplificare la definizione della struttura e il parsing (interpretazione). 2. Il campo del codice operativo (opcode) esiste con due valori. Il client trasmette un pacchetto di richiesta boot (bootrequest). Quindi il server invia un pacchetto di risposta di boot (bootreply). Il bootrequest contiene l'indirizzo hardware del client e il suo indirizzo IP, se conosciuto. 3. La richiesta può a volte contenere il nome del server dal quale il client vuole aver risposta. Questo è per forzare il boot su uno specifico host (es. se esistono versioni multiple del file di boot o se il server è in un domino molto distante). Il client non dovrebbe avere a che fare con servizi di nome/ dominio; questo dovrebbe essere inviato dal server di BOOTP. 4. La richiesta può a volte contenere il nome del file generico da lanciare. Per esempio 'unix' o 'ethertip'. Quando il server invia la risposta bootreply, rimpiazza questo campo con il nome di file completo di path. Per determinare questo nome, il server potrebbe consultare il proprio database correlato con l'indirizzo del client e il nome del file richiesto, per fornire il file appropriato. Se il nome di file di boot è lasciato vuoto, il server dovrebbe rispondere con il file di boot di default per quel client. 5. Nel caso che i client non abbiano il proprio indirizzo IP, il server deve inoltre avere un database che correli l'indirizzo hardware all'IP. Quindi il client userà l'indirizzo IP e lo inserirà nel campo del bootreply. 6. Alcune topologie di rete (come la Stanford) potrebbero non avere un server TFTP direttamente disponibile per ogni collegamento fisico (es. tutti i gateways e gli host su un certo cavo possono essere senza dischi). Con la cooperazione delle gateway vicine, BOOTP può permettere ai client di partire da server distanti molti nodi, attraverso queste vie. Guardare la sezione 'Booting attraverso gateways'. Questa parte del protocollo non richiede azioni speciali da parte del client. L'implementazione è opzionale e richiede solo l'aggiunta di poco codice nelle gateway e nei server. 3. Formato dei pacchetti Tutti i numeri sono in decimale, se non indicati diversamente. Il pacchetto BOOTP è racchiuso in uno standard IP [8] o UDP [7]. Per semplicità è assunto che il pacchetto BOOTP non è mai frammentato. Tutti i campi numerici sono nell'ordine di byte standard per le reti (i bit di ordine più grande sono trasmessi prima). Nell'intestazione (header) dell'IP del bootrequest, il client riempe il campo dell'IP col proprio se noto, altrimenti lo pone a zero. Quando l'indirizzo del server è sconosciuto, l'IP di destinazione sarà l'indirizzo di 'broadcast' 255.255.255.255. Questo indirizzo significa trasmetti sul cavo locale [4]. L'header UDP contiene i numeri delle porte della sorgente e destinazione. Il protocollo BOOTP usa due numeri di porte riservate, 'BOOTP client' (68) e 'BOOTP server' (67). Il client invia la richiesta usando 'BOOTP server' come porta di destinazione. Il server invia le risposte usando 'BOOTP client' come porta di destinazione; dipendentemente dal kernel o driver del server, questo potrebbe essere o no una trasmissione (broadcast) (questo è spiegato dopo nella sezione 'Gallina/Uovo'). La ragione dell'uso di due porte è per evitare il risveglio (waking up) e la schedulazione del daemon del server BOOTP, quando la richiesta deve essere trasmessa al client. Se il server e gli altri host non ascolteranno la porta 'BOOTP client', ogni trasmissione di questo tipo sarà filtrata a livello di kernel. Non potremmo semplicemente permettere al client di prendere un numero di porta casuale per la sorgente UDP, perchè la risposta del server sulla porta casuale potrebbe confondere gli altri host che ascoltano quella porta. La lunghezza del campo UDP è impostata alla lunghezza dell'UDP più la porzione BOOTP del pacchetto. Il campo del checksum UDP deve essere settato a zero dal client (o server) se desiderato, per evitare il sovraccarico (overhead) nell'implementazione su PROM. Nella sezione sotto di 'Processamento dei pacchetti' la frase '[UDP checksum]' è usata ogni volta che il checksum potrebbe essere verificato/calcolato. CAMPO BYTES DESCRIZIONE ----- ----- ----------- op 1 codice operativo del pacchetto/tipo di messaggio. 1 = richiesta di BOOT, 2 = risposta di BOOT htype 1 Tipo di indirizzo hardware guardare la sezione 'numeri assegnati' RFC. '1' = 10mb ethernet hlen 1 lunghezza di indirizzo hardware (esempio '6' per un ethernet a 10mb). hops 1 client settati a zero, usato opzionalmente dai gateways in boot attraverso di esse xid 4 Identificativo (ID) di transazione, un numero casuale usato per identificare questa richiesta di boot con le risposte che genera. secs 2 riempito dal client, secondi trascorsi da quando il client ha iniziato il boot. -- 2 inutilizzati ciaddr 4 indirizzo IP del client riempito dal client durante il bootrequest (se noto) yiaddr 4 'il tuo' indirizzo IP del client riempito dal server se il client non conosce l'indirizzo siaddr 4 indirizzo IP del server ritorna durante il bootreply dal server giaddr 4 indirizzo IP del gateway usato nei boot opzionali attraverso il gateway chaddr 16 indirizzo hardware del client riempito dal client sname 64 indirizzo opzionale del server stringa terminata dal carattere null file 128 nome del file di boot, (terminata con null) il nome è generico nel bootrequest ma comprensivo di path nel bootreply vend 64 opzionale area riservata al venditore (es. versione hardware ecc..) 4. Gallina/Uovo Come può il server inviare un dato IP (datagram) al client, se il client non conosce (ancora) il proprio indirizzo IP? Ogni volta che si invia un bootreply la macchina che trasmette compie le seguenti azioni: 1. Se il client conosce il proprio IP (ciaddr non è a zero), allora la trasmissione avverrà con l'ARP [5]. 2. Se il client non conosce ancora il proprio IP (ciaddr =0), allora il client non può rispondere con l'ARP; ci sono quindi due possibilità: a. Se chi trasmette ha il kernel o i driver necessari per costruire 'manualmente' l'ARP, allora può riempire i campi chaddr e yiaddr. Naturalmente questa modifica deve avere un timeout, proprio come ogni altro codice ARP. Quello che trasmette il bootreply può allora semplicemente inviarlo all'IP del client. UNIX (4.2 BSD) ha questa capacità. b. Se chi trasmette non ha invece questa possibilità, può semplicemente inviare il bootreply alla trasmissione IP (broadcast) sull'interfaccia appropriata. 5. Come il client usa ARP La PROM del client deve contenere un'implementazione semplice dell'ARP, ovvero la memoria dell'indirizzo dovrebbe essere grande come un entry. Questo permetterà al boot di seconda fase (TFTP) di essere eseguito quando il client conosce l'IP e il nome del file di boot. Ogni volta che il client sta aspettando di ricevere una risposta TFTP o BOOTP, dovrebbe essere preparato a rispondere ad una richiesta ARP per il proprio IP. Il bootreply conterrà (nello stream hardware) l'indirizzo hardware sorgente del server o gateway, il client dovrebbe essere in grado di evitare l'invio di una richiesta ARP per lindirizzo IP del server o gateway da usare nella fase seguente di TFTP. Comunque dovrebbe essere trattato solo come caso speciale, perchè è meglio permettere un boot seconda fase come descritto sopra. 6. Confronto con RARP Un protocollo più vecchio, il protocollo Reverse Address Resolution Protocol (RARP) [1] fu proposto per permettere ad un client di determinare il proprio IP, dato che l'indirizzo hardware è noto. Comunque il RARP ha lo svantaggio che era un protocollo di collegamento hardware (non basato su IP/UDP). Questo significa che il RARP potrebbe essere implementato solo su host che contengano kernel o driver speciali per accedere a questi pacchetti 'raw'. Poichè ci sono molti kernel di reti esistenti oggi, con ogni programma sorgente mantenuto da differenti organizzazioni, un protocollo di boot che non richiede una modifica al kernel è decisamente un vantaggio. BOOTP fornisce a questo hardware la funzione di ricerca dell'IP, oltre alle altre caratteristiche utili descritte nelle sezioni sopra. 7. Processamento dei pacchetti 7.1 Trasmissione del client Prima di impostare il pacchetto per la prima volta, è una buona idea cancellare l'intero buffer del pacchetto mettendolo a zero; questo metterà tutti i campi nel loro stato di default. Il client poi crea un pacchetto con i seguenti campi. L'indirizzo IP di destinazione è settato a 255.255.255.255. (l'indirizzo broadcast) o all'indirizzo IP del server (se noto). L'indirizzo IP della sorgente e 'ciaddr' sono settati con l'IP del client se noti, altrimenti a zero. L'header UDP è impostato con la lunghezza opportuna; porta sorgente a 'BOOTP client' e la porta di destinazione a 'BOOTP server'. 'op' è impostato ad 1, cioè BOOTREQUEST. 'htype' è impostato con l'indirizzo hardware come assegnato nella sezione ARP dei 'NUMERI ASSEGNATI' RFC. 'hlen' è impostato alla lunghezza dell'indirizzo hardware (es. 6 per ethernet a 10Mb). 'xid' è impostato ad un valore casuale. 'secs' è impostato al numero di secondi che sono passati da quando il client ha iniziato il boot. Questo permetterà al server di conoscere da quanto tempo un client sta provando. Se questo numero sale, il server potrà decidere di processarlo prima di altri. Se il client non possiede un orologio preciso, potrebbe costruirne uno con un ciclo di loop. O potrebbe semplicemente scegliere di inviare un numero fisso in questo campo, diciamo 100 secondi. Se il client conosce il proprio IP, 'ciaddr' (e l'indirizzo IP sorgente) vengono settati a questo valore. 'chaddr' è riempito con l'indirizzo hardware del client. Se il client desidera restringere il boot ad un particolare nome di server, può metterlo in 'sname' seguito da un carattere null. Il nome deve essere uno di quelli disponibili per l'host desiderato. Il client ha molte possibilità per riempire il campo 'file'. Se lasciato vuoto, il significato è 'voglio usare il nome di default per la mia macchina'. Un nome vuoto può anche significare 'sono solo interessato a conoscere l'indirizzo IP del client/server/gateway, non mi interessa il nome del file'. Il campo può anche essere un nome generico come 'unix' o 'gateway'; questo significa 'forniscimi il nome del file di boot adeguato alla mia richiesta'. Finalmente il campo può essere un nome di file comprensivo del path. Il campo 'vend' può essere riempito dal client con stringhe o strutture fornite dal venditore. Per esempio il tipo di hardware o il numero di serie viene impostato qui. Comunque l'operazione di BOOTP non dipende da questa informazione. Se viene usato il campo 'vend', è raccomandato che i primi 4 byte siano appunto la stringa 'vend'. Questo permette ad un server di determinare che tipo di informazione è contenuta in questo campo. I numeri possono essere assegnati dal processo solito dei 'numeri magici' --- ne prendi uno e questo è magico. Un numero magico diverso potrebbe essere usato per permettere al client di avere azioni speciali. [UDP checksum] 7.2 Strategia di ritrasmissione del client Se non è ricevuta una risposta dopo un certo periodo di tempo, il client dovrebbe ritrasmettere la richiesta. L'intervallo di tempo deve essere scelto con cautela per non sovraccaricare la rete (flood). Considera un cavo a cui sono collegate 100 macchine che stanno ripartendo dopo un blackout. Semplicemente ritrasmettendo la richiesta ogni quattro secondi innonderà la rete. Come possibile strategia, bisognerebbe considerare il back off esponenzialmente, come il modo che ethernet tratta una collisione. Per esempio se il primo pacchetto è a tempo 0:00, il secondo sarà a :04, poi :08, :16, :32... Bisogna anche randomizzare ogni tempo, questo può essere fatto come indicato nelle specifiche ethernet: iniziando con una maschera e facendo delle AND logiche con un numero casuale per prendere il primo backoff. Ad ogni backoff successivo, la maschera è aumentata in lunghezza da un bit. Questo raddoppia il ritardo medio a ciascun backoff. Dopo che il backoff medio raggiunge circa 60 secondi, non dovrebbe venire incrementato ulteriormente, ma randomizzato. Prima di ogni ritrasmissione, il client dovrebbe aggiornare il campo 'secs' [UDP checksum] 7.3 Il server riceve BOOTREQUEST [UDP checksum] Se la porta di destinazione UDP non coincide con la porta 'BOOTP server', scartare il pacchetto. Se il campo del nome del server è vuoto o coincide con il nome o soprannome di questo server, allora continua. Se il campo 'sname' è specificato, ma non coincide con questo server, allora ci sono altre possibilità: 1. Si può scegliere di scaricare semplicemente il pacchetto. 2. Se il nome mostra essere su questo cavo, allora trascura il pacchetto. 3. Se il nome è su una rete differente, si può scegliere di inviare il pacchetto a quell'indirizzo. Se così, bisogna controllare il campo 'giaddr' (indirizzo gateway). Se 'giaddr' è zero, riempilo con questo indirizzo o con l'indirizzo di un gateway che può essere usato per accedere a quella rete. Quindi inoltra il pacchetto. Se l'indirizzo del client (ciaddr) è zero, allora il client non conosce il proprio IP. Cerca di trovare l'indirizzo hardware del client (chaddr, hlen,htype) nel proprio database. Se non c'è ignora il pacchetto. Altrimenti metti l'indirizzo IP del client trovato e mettilo in 'yiaddr'. Ora controlliamo il nome del file di boot. Il campo sarà vuoto se il client non è interessato al nome del file o vuole sapere il nome del proprio file di boot di default. Se il campo non è vuoto ma non corrisponde ad un nome di file noto o valido, si scarta il pacchetto, forse qualche altro server BOOTP avrà il file corretto. Il campo 'vend' potrebbe essere controllato ora e se viene riconosciuto un certo codice si possono effettuare operazioni dipendenti dal client. Per esempio una workstation client potrebbe fornire una chiave di autenticazione e ricevere dal server una capacità di accesso remoto a file, o un'impostazione delle opzioni di configurazione che possono essere passate al sistema operativo che sta eseguendo il boot. Metti il mio indirizzo IP nel campo 'siaddr. Imposta il campo 'op' a BOOTREPLY. La porta di destinazione UDP è messa a 'BOOTP client'. Se l'indirizzo del client 'ciaddr' non è zero, manda il pacchetto là; altrimenti se l'indirizzo del gateway 'giaddr' non è zero, metti la porta UDP di destinazione a 'BOOTP server' a manda il pacchetto a 'giaddr'; altrimenti il client è su uno dei nostri cavi ma non conosce ancora il proprio IP -- usa il metodo descritto nella sezione 'Uovo' vista prima e invialo al client. Se è utilizzato il metodo 'uovo' e abbiamo molte interfacce a questo host, usa 'yiaddr' (il nostro IP) per sapere in quale rete inviare il pacchetto [UDP checksum] 7.4 Il server/gateway riceve BOOTREPLY [UDP checksum] Se 'yiaddr' (il tuo IP [del tuo cliente]) si riferisce ad uno dei nostri cavi, usa uno dei metodi 'uovo' descritti sopra per inviarlo al client. Assicurati di inviarlo alla porta di destinazione UDP 'BOOTP client'. 7.5 Ricezione del client Non dimenticarti di processare le richieste ARP per il mio IP (se lo conosco). [UDP checksum] Il client dovrebbe ignorare pacchetti che: non sono indirizzati IP/UDP alla porta di boot; non sono BOOTREPLY, non coincidono con il mio IP (se lo so) o il mio indirizzo hardware; non sono uguali al mio ID di transazione. Altrimenti abbiamo ricevuto una risposta al nostro bootreply. 'yiaddr' conterrà il mio IP, se non lo conoscevo. 'file' è il nome del file da usare con la richiesta di file TFTP. L'indirizzo del server è in 'siaddr'. Se 'giaddr' (indirizzo di gateway) è diverso da zero, allora il pacchetto dovrebbe essere prima inviato là, per poter collegarsi al server. 8. Il boot attraverso le gateway Questa parte del protocollo è opzionale e richiede del codice addizionale in cooperazione con gateway e server, ma è permesso il boot tra gateway (cross-gateway), potrebbe girare bene sui propri server BOOTP/TFTP. I gateway che ascoltano la trasmissione BOOTREQUEST possono decidere di inoltrare o ritrasmettere queste richieste quando è opportuno. Per esempio il gateway potrebbe avere, come parte della sua tabella di configurazione, una lista di altre reti o host per ricevere qualsiasi richiesta BOOTREQUEST. Anche quando esiste il campo 'hops', non è una buona idea ritrasmettere solo le richieste, poichè dei cicli di ritrasmissione si creeranno sicuramente. La ritrasmissione può iniziare immediatamente, o aspettare che i secondi del campo 'secs' (secondi che il client ha atteso) superino una certa soglia. Se un gateway decide di inoltrare la richiesta, dovrebbe osservare il campo 'giaddr' (indirizzo IP del gateway). Se zero, deve mettere il proprio IP (IP di gateway) in questo campo. Deve anche usare il campo 'hops' per controllare quanto distante deve forwardare il pacchetto. Il campo 'hops' dovrebbe essere incrementato a ciascun inoltro. Per esempio, se 'hops' supera '3' il pacchetto dovrebbe probabilmente essere scartato. [UDP checksum] Qui abbiamo raccomandato di mettere questa funzione speciale di forward nei gateway. Ma quello non deve essere il caso. Fino a quando alcuni agenti di forward BOOTP esistono sulla rete con il client del boot, l'agente può fare il forward quando appropriato. Allora questo servizio può essere o no nel gateway. Nel caso che un agente di forward non sia localizzato nel gateway, l'agente potrebbe salvare da solo qualche lavoro mettendo l'indirizzo di trasmissione dell'interfaccia ricevente il bootrequest nel campo 'giaddr'. Allora la risposta verrebbe trasferita con i normali gateway, senza usare l'agente di forward. Naturalmente lo svantaggio qui è che si perde la possibilita' di usare un metodo intelligente non di trasmissione per inviare la risposta, causando un carico extra per ogni host sul cavo client. 9. Esempio di database di un server BOOTP Come suggerimento, mostriamo un esempio di un database testuale che il programma di BOOTP potrebbe usare. Il database ha due sezioni, delimitate da una linea contenente un percento nella colonna 1. La prima sezione contiene una directory di default e mappature da un file generico a uno directory/path. Il primo nome generico in questa sezione è il file di default che si da quando il bootrequest contiene un campo 'file' nullo. La seconda sezione mappa l'indirizzo hardware in un indirizzo IP. Opzionalmente si può anche ignorare il nome di file generico dandone uno specifico. Può essere inoltre definito un 'suffisso', se dato, qualsiasi nome generico specificato dal client sara' modificato con l'aggiunta di questo dato alla fine. Se questo campo non c'è, sara' impostato solo il nome del file. Questa opzione di suffisso permette ad un intero insieme di file di essere impostati senza molta fatica. Sotto è mostrato il formato generale; i campi sono delimitati da uno o più spazi o tab; campi vuoti possono essere omessi; linee vuote e/o che iniziano col cancelletto saranno ignorate. # Linea di commento directory_di_partenza nomegenerico1 path1 nomegenerico2 path2 ... % fine dei nomi generici, inizia la mappatura degli indirizzi nomehost1 tipohardware indirizzohardware1 ipaddr1 nomegenerico suffisso nomehost2 tipohardware indirizzohardware2 ipaddr2 nomegenerico suffisso ... Questo è un esempio specifico. Notare che il numero del 'tipohardware' è lo stesso mostrato nella sezione ARP dei 'Numeri Assegnati' RFC. Il 'tipohardware' e 'ipaddr' sono in decimale; 'indirizzohardware' è in esadecimale. # ultima modifica Pippo /usr/boot vmunix vmunix tip ethertip watch /user/diag/etherwatch gate gate % fine dei nomi generici, inizia la mappatura degli indirizzi hamilton 1 02.60.8c.06.34.98 36.19.0.5 burr 1 02.60.8c.34.11.78 36.44.0.12 101-gateway 1 02.60.8c.23.ab.35 36.44.0.32 gate 101 mjh-gateway 1 02.60.8c.12.32.bc 36.42.0.64 gate mjh welch-tipa 1 02.60.8c.22.65.32 36.47.0.14 tip welch-tipb 1 02.60.8c.12.15.c8 36.46.0.12 tip Nell'esempio sopra, se 'mjh-gateway' fara' un boot di default, carichera' il file 'usr/boot/gate.mjh. 10. Ringraziamenti Ross Finlayson (et al) che hanno prodotto i primi due RFC sul TFTP bootstraping usando [2] RAPP [1]. Vogliamo anche ringraziare il lavoro precedente e i commenti di Noel Chiappa, Bob Lyon, Jeff Mogul, Mark Lewis, e David Plummer. RIFERIMENTI 1. Ross Finlayson, Timothy Mann, Jeffrey Mogul, Marvin Theimer. A Reverse Address Resolution Protocol. RFC 903, NIC, June, 1984. 2. Ross Finlayson. Bootstrap Loading using TFTP. RFC 906, NIC, June, 1984. 3. Mark Lottor. Simple File Transfer Protocol. RFC 913, NIC, September, 1984. 4. Jeffrey Mogul. Broadcasting Internet Packets. RFC 919, NIC, October, 1984. 5. David Plummer. An Ethernet Address Resolution Protocol. RFC 826, NIC, September, 1982. 6. Jon Postel. File Transfer Protocol. RFC 765, NIC, June, 1980. 7. Jon Postel. User Datagram Protocol. RFC 768, NIC, August, 1980. 8. Jon Postel. Internet Protocol. RFC 791, NIC, September, 1981. 9. K. R. Sollins, Noel Chiappa. The TFTP Protocol. RFC 783, NIC, June, 1981.