. */ // ************************************************************************************************************** // // The purpose of this script is to dynamically add hosts to your local network. My local network is locked // down such that known hosts are allocated an IP address in 192.168.0/24 and unknown hosts are allocated an // IP address in 192.168.1/24. These unknown hosts are severely locked down in what they can do. My Web server // and DHCP server are one and the same, to make life easy. This script will programmatically add clients to // the hosts and dhcpd.conf file, making them known hosts. Interestingly, if a client on the local network // accesses this script, their MAC address should be pre-populated to eliminate the most annoying step in the // process. Consequently, it would be wise to require some kind of authentication to access this script. This is // the type of thing that public "hot spots" do, where they allow anyone to connect to the local network but you // have to add yourself to the known hosts pool before you can do anything useful. // // I like to keep my wired clients in the 192.168.0.2-100 range and my wireless clients in the 192.168.0.101-254 // range for organization purposes (it also makes it easier to filter traffic). Thus, this script expects the // hosts and dhcpd.conf files to have a specific format (the file comments and spacing are the important parts!). // hosts: // # Wired Hosts // 192.168.0.2 wired_host1 // 192.168.0.3 wired_host2 // // # Wireless Hosts // 192.168.0.101 wireless_host1 // 192.168.0.102 wireless_host2 // // dhcpd.conf: // ... // host wired_host1 // { // hardware ethernet: 00:11:22:33:44:55; // fixed-address: 192.168.0.2; // } // // host wired_host2 // { // hardware ethernet: 66:77:88:99:AA:BB; // fixed-address: 192.168.0.3; // } // // This script could easily be manipulated to accomodate your own format preferences or do-away with the wired/ // wireless segregation. // // ************************************************************************************************************** // ************************************************************************************************************** // // Apache will need to be able to sudo your dhcpd init script, and write to dhcpd.conf and the hosts file: // visudo: www-data ALL=NOPASSWD: /etc/init.d/dhcp3-server // // ************************************************************************************************************** $dhcpd_conf_path = "/etc/dhcp3/dhcpd.conf"; $dhcpd_init_path = "/etc/init.d/dhcp3-server"; $hosts_path = "/etc/hosts"; $class_c = "192.168.0."; $wireless_start = 100; // Define more connection lengths here if desired $conn_lengths = array("1 days" => "1 Day", "1 weeks" => "1 Week", "1 month" => "1 Month", "never" => "Never"); // Security question/answer for authentication so not just anyone can add themselves to your network $question = "What is the name of the network owner's daughter?"; $answer = "Aubrey"; print "\n"; print "\n"; print "Add Host\n"; print "\n"; print "\n"; print "\n"; if ($_GET["submit"] == "true") { if (stripos($_POST["answer"], $answer) !== false) { $name = $_POST["name"]; $mac = $_POST["mac"]; $conn_length = $_POST["conn_length"]; $_POST["wireless"] == "on" ? $wireless = true : $wireless = false; $dhcpd = $orig_dhcpd = file($dhcpd_conf_path); $divider = array_search("# Wireless Hosts\n", $dhcpd) - 1; foreach ($dhcpd as $line) { if (preg_match("/range $class_c(\d+) $class_c(\d+);/", $line, $match)) { $min_last_octet = (int)$match[1]; $max_last_octet = (int)$match[2]; break; } } if ($wireless) { $last_octet = $wireless_start; $start = $divider; $max = count($dhcpd); } else { $last_octet = $min_last_octet; $start = 0; $max = $divider; } for ($i = $start; $i < $max; $i++) if (preg_match("/fixed-address $class_c(\d+);/", $dhcpd[$i], $match)) $last_octet = max($last_octet, (int)$match[1]); $last_octet++; $ip = $class_c . $last_octet; if ($last_octet > $max_last_octet) die("IP $ip not in range!"); if (!$wireless && $last_octet > $wireless_start) print "Notice: wired IP $ip falls in wireless range.\n

\n"; if ($wireless) $dhcpd[] = "\nhost $name\n{\n\thardware ethernet $mac;\n\tfixed-address $ip;\n}\n"; else { for ($i = count($dhcpd)-1; $i >= $divider; $i--) $dhcpd[$i+1] = $dhcpd[$i]; $dhcpd[$divider] = "\nhost $name\n{\n\thardware ethernet $mac;\n\tfixed-address $ip;\n}\n"; } //die(print_r($dhcpd)); file_put_contents($dhcpd_conf_path, $dhcpd); passthru("sudo $dhcpd_init_path restart", $ret); // Restarting dhcpd failed, probably malformed conf file if ($ret != 0) { // Revert back to previous data, which presumably was working before file_put_contents($dhcpd_conf_path, $orig_dhcpd); passthru("sudo $dhcpd_init_path restart", $ret); die('DHCPD restart failed!'); } if ($conn_length != "never") $name .= " " . $name . "_" . date("m_d_Y_H_i", strtotime("+" . $conn_length)); $hosts = file($hosts_path); if ($wireless) $hosts[] = "$ip\t$name\n"; else { $divider = array_search("# Wireless Hosts\n", $hosts) - 1; for ($i = count($hosts)-1; $i >= $divider; $i--) $hosts[$i+1] = $hosts[$i]; $hosts[$divider] = "$ip\t$name\n"; } file_put_contents($hosts_path, $hosts); print "

Enable/Disable your connection now.\n"; } else print "Security answer incorrect!\n"; } else { // If the remote IP is local, this arp trick will work to get the MAC address $ip = $_SERVER["REMOTE_ADDR"]; $arp = `ping -c 1 $ip > /dev/null && arp -a | grep '$ip'`; preg_match("/at (.*) \[ether\] on eth1/U", $arp, $match); $mac = $match[1]; print "

Welcome to the Garinger wireless network

\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
Security Question:$question
Security Answer:
Computer Name:
MAC: 00:11:22:33:44:55
Expires In:
Wireless Client?
\n"; print "

\n"; print "

\n"; } print "\n"; print "\n"; ?>