I puristi si staranno già scandalizzando: “un server DHCP in PHP ?!?!?” sarà la loro prima reazione, con un misto di incredulità e sdegno.
Ma perché no ?
Il PHP, oltre ad essere un meraviglioso linguaggio per la programmazione web, può efficacemente sostituirsi -con tutti i suoi limiti- anche ad altri linguaggi interpretati “shell-based” come Perl o Python. Certo, non mi aspetto prestazioni eccezionali ma ad un server DHCP serve essenzialmente stabilità e, per quanto riguarda ad esempio il contesto VoIP dove vorrei implementarlo, tanta tanta flessibilità.
L’idea nasce, è giusto ammetterlo, da un progetto già avviato da un’altro italiano nel 2009, Angelo DiNardi, che sul suo blog (https://angelo.dinardi.name/2009/09/09/a-dhcp-server-in-php-why-not/) scriveva:
I had planned on making the DHCP server part have a plug in system of changing the storage system backing the server so that it could run off a database and do things that the normal ISC DHCP server can’t be configured to do.
Già, tutte quelle cose che il server DHCP de-facto, ISC DHCPD, non può fare. Una di queste è l’interfacciamento con un DBMS, quale MySQL, anche se l’ISC, attraverso il nuovo progetto KEA, ha risolto questo limite (attualmente è in fase di sviluppo).
DHCP handshaking
Torniamo a noi. Essenzialmente un server DHCP deve rispondere alle richieste DHCPREQUEST, offrire un indirizzo IP disponibile (DHCPOFFER), attendere la risposta da parte del nuovo dispositivo (DHCPREQUEST) e confermarne la “registrazione” (DHCPACK).
Oltre a questo, ovviamente, c’è tutta la parte strategia di allocazione degli IP, filtro e pre-allocazione sul MAC address, controllo della scadenza dei LEASE, opzioni…
Tutto questo tramite pacchetti UDP sulla porta 67 e 68 perché, lo ricordo, un dispositivo che viene connesso ad una rete e non ha un IP assegnato non può –ovviamente– stabilire connessioni TCP…
Basandomi sul codice già sviluppato e disponibile su GitHub (https://github.com/adinardi/phpdhcp), ho aggiunto alcune funzionalità e creato un fork su GitHub, da dove potete scaricare il codice: https://github.com/michelep/phpdhcp
In particolare ho aggiunto l’uso di un database MySQL come backend per la configurazione della rete e gestione dei leases, oltre alla possibilità di “demonizzare” il programma (usando PHP System Daemon). Lo schema del DB, contenuto nel file schema.sql, è il seguente:
CREATE TABLE IF NOT EXISTS `DHCPLeases` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `PoolID` int(11) NOT NULL, `IP` varchar(16) NOT NULL, `ChgDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`ID`), KEY `PoolID` (`PoolID`), KEY `IP` (`IP`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; CREATE TABLE IF NOT EXISTS `DHCPPools` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `IPStart` varchar(16) NOT NULL, `IPEnd` varchar(16) NOT NULL, `SubnetMask` varchar(16) NOT NULL, `Router` varchar(16) NOT NULL, `DNSServers` varchar(64) NOT NULL, `Domain` varchar(32) NOT NULL, `Note` text NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
In fase di configurazione è necessario aggiungere le righe a descrizione del lotto (“pool”) di IP disponibili. Ad esempio:
La tabella DHCPLeases viene automaticamente popolata man mano che vengono assegnati IP ai dispositivi collegati.
1 comment
Ciao Michele,
sto provando la tua version e del PHPDHCP e sono bloccato a un problema. Mi daresti un piccolo aiuto per capire?
Grazie,
Giuseppe
—
Processing packet type: discover
[Oct 29 17:41:36] warning: MAC 001174901cff unknown [l:]
PHP Warning: pack(): Type H: not enough characters in string in /var/www/phpdhcp-master/packet.php on line 212
Sending response
Switching to broadcast address…
Attempting to send response packet to 255.255.255.255
Response packet sent.
—