#!/usr/bin/perl5 # dhcp-relay.cgi # # To determine that dhcp_relay is currently enabled, the uncommented line # must exist in inetd.conf and chkconfig proclaim_relayagent must be on. # # To enable, both the above are set, and a sig HUP is sent. # # To disable, the line is commented and chkconfig p... is set off and sig # HUP sent. use CGI; require "/usr/OnRamp/lib/OnRamp.pm"; $title = "DHCP Relay Agent"; $query = new CGI; print $query->header; $help = $ENV{"DOCUMENT_ROOT"} . $ENV{"SCRIPT_NAME"}; $help =~ s/cgi$/hlp/; exec $help if ($query->param('help') eq "Help"); &title_block($title); $def_config_dir = "/var/dhcp/config"; $rly_off = system ("/etc/chkconfig", "proclaim_relayagent"); $srv_off = system ("/etc/chkconfig", "proclaim_server"); $def_rstate = "No"; if ($rly_off == 0) { $def_rstate = "Yes"; } $inetd_cf = "/etc/inetd.conf"; $dummy = "/etc/inetd.conf.tmp"; # Only look at the option file name in /etc/inetd.conf if the server is # enabled, also need to process it then. if ($rly_off == 0) { # chkconfig proclaim_relayagent is on open(INETD, $inetd_cf) || &error("Cannot open $inetd_cf"); while () { if (/^#/) { next; } # bootp dgram udp wait root /usr/etc/dhcp_relay dhcp_relay -o if (/^bootp/) { chop; @entlist = split(/\s+/); if (($entlist[6] eq "dhcp_relay") && ($entlist[7] eq "-o")) { $osf = $entlist[8]; last; # Break out of the while loop } } } close(INETD); } if (($rly_off == 0) && $osf) { open(OPTIONS, $osf) || &error("Cannot open $osf"); while() { if (/^#/) { next; } chop; @optlist = split(/\s+/); $i = 0; while ($optlist[$i]) { if ($optlist[$i] eq "-c") { $def_config_dir = $optlist[$i+1]; $i += 2; next; } else { print $err_start, "Unknown Option $optlist[$i] in the $osf file."; } $i++; } } close(OPTIONS); } else { $osf = "/etc/config/dhcp_relay.options"; } $srvlist_file = $def_config_dir."\/dhcp_relay.servers"; open(SRVLST, $srvlist_file) || &error("Cannot open $srvlist_file"); $i = 0; while () { if (/^#/) { next; } chop; $_ =~ s/^\s+//; $_ =~ s/\s+$//; $server_list[$i] = $_; $i++; } close(SRVLST); undef @new_list; $addServer = 0; $delServer = 0; if ($query->param) { if ($query->param('add') eq 'Add New Server') { $addList = $query->param('add_list'); &formValid_add; $message = qq|Click "Ok" to save changes.|; $query->param('add_list',''); &generic($addList,1); exit 0; } if ($query->param('delete') eq 'Delete Existing Server') { $delList = $query->param('chosen'); &error("To delete an existing server, first select one from the list, then click the delete button.") if !$delList; $delList =~ /(\w+)/; $delList = $1; $message = qq|Click "Ok" to save changes.|; &generic($delList,2); exit 0; } if ($query->param('doit') eq 'Ok') { if ($query->param('addName')) { push(@server_list,$query->param('addName')); &saveList; $message = "Server added."; } if ($query->param('delName')) { $delName = $query->param('delName'); undef @temp_list; foreach $arg (@server_list) { if ($arg ne $delName) { push(@temp_list,$arg); } } @server_list = @temp_list; &saveList; $message = "Server deleted."; } $new_rstate = $query->param(rstate); if ($new_rstate ne $def_rstate) { # State Changed # Need to make sure that DHCP Server is disabled if ($new_rstate eq "Yes") { # chkconfig on, the system WILL ship with the inetd.conf entry # for dhcp_bootp enabled if ($srv_off == 0) { &error("You Need to Disable the DHCP Server before you can enable the DHCP Relay Agent."); } system ("/etc/chkconfig", "proclaim_relayagent", "on"); &checkForInetd; $message .= " DHCP relay agent enabled."; } else { # chkconfig off system ("/etc/chkconfig", "proclaim_relayagent", "off"); &commentInetd; $message .= " DHCP relay agent disabled."; } `/etc/killall -HUP inetd`; } if (!$message) { $message = "No changes made."; } } } sub commentInetd { open(IN,"< $inetd_cf"); open(OUT,"> $dummy"); while() { @items = split(/\s+/); if ($items[0] eq "bootp" && $items[6] eq "dhcp_relay") { print OUT "# $_"; } else { print OUT $_; } } close(IN); close(OUT); rename($dummy,$inetd_cf); } sub checkForInetd { $line = "bootp\tdgram\tudp\twait\troot\t/usr/etc/dhcp_relay ". "dhcp_relay -o /etc/config/dhcp_relay.options"; $rename = 0; $found = 0; open(IN,"< $inetd_cf"); open(OUT,"> $dummy"); while() { @items = split(/\s+/); if ($items[6] eq "dhcp_relay" || $items[7] eq "dhcp_relay") { $found = 1; if (substr($items[0],0,1) eq "#") { print OUT "$line\n"; $rename = 1; } } else { print OUT $_; } } if (!$found) { print OUT "$line\n"; $rename = 1; } close(IN); close(OUT); if ($rename) { rename($dummy,$inetd_cf); } } sub formValid_add { &error("Server name or address required.") if !$addList; if ($addList =~ /[^0-9.]/) { # assume this is not an IP number &error("Please input IP address in dot notation.") if $addList =~ /0x/; &error("Invalid hostname: $addList.") if &check_hostname($addList); ($name, $aliases, $addrtype, $length, @addrs) = gethostbyname($addList); &error("Host cannot be resolved.") if !@addrs; } else { # IP num &error("Invalid IP address.") if &check_ipaddr($addList); } } sub saveList { open(SRVLST, ">$srvlist_file") || &error("Cannot open file $srvlist_file for writing."); foreach $arg (@server_list) { print SRVLST "$arg\n"; } close(SRVLST); } &generic; sub generic { &header_block($title); print "$message"; print $query->startform; print "
\n"; print ""; print ""; if ($_[1] == 1) { print ""; @locList = @server_list; push(@locList,$_[0]); } elsif ($_[1] == 2) { print ""; undef @locList; foreach $arg (@server_list) { if ($arg ne $_[0]) { push(@locList,$arg); } } } else { @locList = @server_list; } print ""; print "
Enable DHCP relay agent:\n", $query->radio_group(-name=>'rstate', -values=>['Yes','No'], -default=>$def_rstate), "
",$query->submit(-name=>'add', -value=>'Add New Server'), "",$query->textfield(-name=>'add_list', -size=>20),"
",$query->submit(-name=>'delete', -value=>'Delete Existing Server'), "",&choice_list(*locList,"chosen",20),"

"; &button_table($query,"doit", "Ok", "help", "Help"); print $query->endform; } sub oldgeneric { &header_block($title); print "$message"; print $query->startform; print "
\n"; print ""; print "", ""; print ""; print ""; print "", ""; print "
Enable DHCP relay agent:\n", $query->radio_group(-name=>'rstate', -values=>['Yes','No'], -default=>$def_rstate), "
Directory for server configuration files:\n", $query->textfield(-name=>'conf_dir', -default=>$def_config_dir, -size=>20, -maxlength=>256), "
List of DHCP Servers:\n", $query->scrolling_list(-name=>'slist', -values=>\@server_list, -size=>6, -multiple=>'true'), "
Delete Selected Servers from the List:\n", $query->radio_group(-name=>'delstate', -values=>['Yes','No'], -default=>'No'), "
List of new DHCP Servers to Add:", $query->textfield(-name=>'add_list', -size=>20, -maxlength=>256), "

"; &button_table($query,"doit", "Ok", "help", "Help"); print $query->endform; } sub error { &error_block($_[0]); &generic; exit 0; }