\n";
}
sub parse_routing
{
local (%conf, @st, %sysctl, %st, @boot);
&lock_file($network_config);
&read_env_file($network_config, \%conf);
if (!$supports_dev_gateway) {
# Just update a single file
if ($in{'gateway_def'}) { delete($conf{'GATEWAY'}); }
elsif (!gethostbyname($in{'gateway'})) {
&error(&text('routes_edefault', $in{'gateway'}));
}
else { $conf{'GATEWAY'} = $in{'gateway'}; }
if ($in{'gatewaydev_def'}) { delete($conf{'GATEWAYDEV'}); }
elsif ($in{'gatewaydev'} !~ /^\S+$/) {
&error(&text('routes_edevice', $in{'gatewaydev'}));
}
else { $conf{'GATEWAYDEV'} = $in{'gatewaydev'}; }
}
else {
# Multiple defaults can be specified!
local ($r, $b);
@boot = grep { $->{'virtual'} eq '' } &boot_interfaces();
foreach $b (@boot) {
delete($b->{'gateway'});
}
delete($conf{'GATEWAY'});
delete($conf{'GATEWAYDEV'});
for($r=0; defined($in{"gatewaydev$r"}); $r++) {
next if (!$in{"gatewaydev$r"});
&check_ipaddress($in{"gateway$r"}) ||
&error(&text('routes_edefault2', $r+1));
if ($in{"gatewaydev$r"} eq "*") {
# For any interface
$conf{'GATEWAY'} && &error(&text('routes_eclash'));
$conf{'GATEWAY'} = $in{"gateway$r"};
}
else {
# For a specific interface
local ($b) = grep { $_->{'fullname'} eq $in{"gatewaydev$r"} } @boot;
$b->{'gateway'} && &error(&text('routes_eclash2',
$in{"gatewaydev$r"}));
$b->{'gateway'} = $in{"gateway$r"};
}
}
}
if ($gconfig{'os_version'} < 7.0) {
if ($in{'forward'}) { $conf{'FORWARD_IPV4'} = 'yes'; }
else { $conf{'FORWARD_IPV4'} = 'no'; }
}
else {
&lock_file($sysctl_config);
&read_env_file($sysctl_config, \%sysctl);
$sysctl{'net.ipv4.ip_forward'} = $in{'forward'};
}
# Parse static and local routes
for($i=0; defined($dev = $in{"dev_$i"}); $i++) {
next if (!$dev);
$net = $in{"net_$i"}; $netmask = $in{"netmask_$i"}; $gw = $in{"gw_$i"};
$dev =~ /^\S+$/ || &error(&text('routes_edevice', $dev));
gethostbyname($net) || &error(&text('routes_enet', $net));
&check_ipaddress($netmask) || &error(&text('routes_emask', $netmask));
gethostbyname($gw) || &error(&text('routes_egateway', $gw));
if ($netmask eq "255.255.255.255") {
push(@st, "$dev host $net gw $gw\n");
}
else {
push(@st, "$dev net $net netmask $netmask gw $gw\n");
}
push(@{$st{$dev}}, [ $net, $netmask, $gw ]);
}
for($i=0; defined($dev = $in{"ldev_$i"}); $i++) {
$net = $in{"lnet_$i"}; $netmask = $in{"lnetmask_$i"};
next if (!$dev && !$net);
$dev =~ /^\S+$/ || &error(&text('routes_edevice', $dev));
gethostbyname($net) || $net =~ /^(\S+)\/(\d+)$/ && gethostbyname($1) ||
&error(&text('routes_enet', $net));
&check_ipaddress($netmask) || &error(&text('routes_emask', $netmask));
if ($netmask eq "255.255.255.255") {
push(@st, "$dev host $net\n");
}
else {
push(@st, "$dev net $net netmask $netmask\n");
}
push(@{$st{$dev}}, [ $net, $netmask ]);
}
if (!$supports_dev_routes) {
# Write to a single file
&open_lock_tempfile(STATIC, ">$static_route_config");
&print_tempfile(STATIC, @st);
&close_tempfile(STATIC);
}
else {
# Write to one file per interface (delete old, then save new/updated)
local $f;
opendir(DIR, &translate_filename($devices_dir));
while($f = readdir(DIR)) {
if (($f =~ /^([a-z]+\d*(\.\d+)?(:\d+)?)\.route$/ ||
$f =~ /^route\-([a-z]+\d*(\.\d+)?(:\d+)?)$/) && !$st{$1}) {
&unlink_logged("$devices_dir/$f");
&unlink_logged("$net_scripts_dir/$f");
}
}
closedir(DIR);
foreach $dev (keys %st) {
$f = $supports_route_dev ? "route-$dev" : "$dev.route";
local (%rfile, $i);
for($i=0; $i<@{$st{$dev}}; $i++) {
$rfile{"ADDRESS$i"} = $st{$dev}->[$i]->[0];
$rfile{"NETMASK$i"} = $st{$dev}->[$i]->[1];
$rfile{"GATEWAY$i"} = $st{$dev}->[$i]->[2];
}
&lock_file("$devices_dir/$f");
&write_env_file("$devices_dir/$f", \%rfile);
&unlock_file("$devices_dir/$f");
&lock_file("$net_scripts_dir/$f");
&link_file("$devices_dir/$f", "$net_scripts_dir/$f");
&unlock_file("$net_scripts_dir/$f");
}
}
&write_env_file($network_config, \%conf);
&unlock_file($network_config);
if (%sysctl) {
&write_env_file($sysctl_config, \%sysctl);
&unlock_file($sysctl_config);
}
if (@boot) {
local $b;
foreach $b (@boot) {
&save_interface($b);
}
}
}
sub os_feedback_files
{
opendir(DIR, $net_scripts_dir);
local @f = readdir(DIR);
closedir(DIR);
return ( (map { "$net_scripts_dir/$_" } grep { /^ifconfig-/ } @f),
$network_config, $static_route_config, "/etc/resolv.conf",
"/etc/nsswitch.conf", "/etc/HOSTNAME" );
}
# interface_sel(name, value)
# Returns a menu for all boot-time interfaces
sub interface_sel
{
local $rv = "\n";
return $rv;
}
# apply_network()
# Apply the interface and routing settings
sub apply_network
{
&system_logged("(cd / ; /etc/init.d/network stop ; /etc/init.d/network start) >/dev/null 2>&1");
}
# apply_interface(&iface)
# Calls an OS-specific function to make a boot-time interface active
sub apply_interface
{
local $out = &backquote_logged("cd / ; ifdown '$_[0]->{'fullname'}' >/dev/null 2>&1 {'fullname'}' 2>&1 {'fullname'}' 2>&1 {'gateway'} && $_->{'virtual'} eq '' } @boot;
return ( $gifc->{'gateway'}, $gifc->{'fullname'} ) if ($gifc);
return $conf{'GATEWAY'} ? ( $conf{'GATEWAY'}, $conf{'GATEWAYDEV'} ) : ( );
}
# set_default_gateway(gateway, device)
# Sets the default gateway to the given IP accessible via the given device,
# in the boot time settings.
sub set_default_gateway
{
&lock_file($network_config);
&read_env_file($network_config, \%conf);
if (!$supports_dev_gateway) {
# Just update the network config file
local %conf;
if ($_[0]) {
$conf{'GATEWAY'} = $_[0];
$conf{'GATEWAYDEV'} = $_[1];
}
else {
delete($conf{'GATEWAY'});
delete($conf{'GATEWAYDEV'});
}
}
else {
# Set the gateway in the specified interface file, and clear the rest
local @boot = grep { $->{'virtual'} eq '' } &boot_interfaces();
foreach $b (@boot) {
delete($b->{'gateway'});
if ($_[0] && $b->{'fullname'} eq $_[1]) {
$b->{'gateway'} = $_[0];
&save_interface($b);
}
}
delete($conf{'GATEWAY'});
delete($conf{'GATEWAYDEV'});
}
&write_env_file($network_config, \%conf);
&unlock_file($network_config);
}
# supports_ranges()
# Returns 1 for newer redhat versions
sub supports_ranges
{
return ($gconfig{'os_type'} eq 'redhat-linux' &&
$gconfig{'os_version'} >= 7.3) ||
($gconfig{'os_type'} eq 'mandrake-linux' &&
$gconfig{'os_version'} >= 8.0) ||
($gconfig{'os_type'} eq 'coherant-linux' &&
$gconfig{'os_version'} >= 3.0);
}
# range_input([&interface])
# Print HTML for a IP range interface
sub range_input
{
local $new = !$_[0];
# Base interface
print "
$text{'range_iface'}
\n";
if ($new) {
print "
\n";
}
else {
print "
$_[0]->{'name'}
\n";
}
# Name for this range
print "
$text{'range_name'}
\n";
if ($new) {
print "
\n";
}
else {
print "
$_[0]->{'range'}
\n";
}
# Start
print "
$text{'range_start'}
\n";
printf "
\n",
$_[0]->{'start'};
# Stop
print "
$text{'range_end'}
\n";
printf "
\n",
$_[0]->{'end'};
# Base number
print "
$text{'range_num'}
\n";
printf "
\n",
$_[0]->{'num'};
}
# parse_range(&range, &in)
sub parse_range
{
local %in = %{$_[1]};
if ($in{'new'}) {
$_[0]->{'name'} = $in{'iface'};
$in{'range'} =~ /^[a-z0-9\.\_]+$/ || &error($text{'range_ename'});
$_[0]->{'range'} = $in{'range'};
$_[0]->{'fullname'} = $in{'iface'}."-range".$in{'range'};
}
&check_ipaddress($in{'start'}) || &error($text{'range_estart'});
$_[0]->{'start'} = $in{'start'};
&check_ipaddress($in{'end'}) || &error($text{'range_eend'});
$_[0]->{'end'} = $in{'end'};
local @sip = split(/\./, $in{'start'});
local @eip = split(/\./, $in{'end'});
$sip[0] == $eip[0] && $sip[1] == $eip[1] && $sip[2] == $eip[2] ||
&error($text{'range_eclass'});
$sip[3] <= $eip[3] || &error($text{'range_ebefore'});
$in{'num'} =~ /^\d+$/ || &error($text{'range_enum'});
$_[0]->{'num'} = $in{'num'};
}
# get_dhcp_hostname()
# Returns 0 if the hostname is not set by DHCP, 1 if it is, or -1 if this
# feature is not supported on this OS.
sub get_dhcp_hostname
{
return -1 if ($gconfig{'os_type'} ne 'redhat-linux' ||
$gconfig{'os_version'} < 11);
local @boot = &boot_interfaces();
local ($eth) = grep { $_->{'fullname'} =~ /^eth\d+$/ } @boot;
return -1 if (!$eth);
local %eth;
&read_env_file($eth->{'file'}, \%eth);
return $eth{'DHCP_HOSTNAME'} ne &get_system_hostname();
}
# save_dhcp_hostname(set)
# If called with a parameter of 0, the hostname is fixed and not set by
# DHCP. If called with 1, the hostname is chosen by DHCP.
sub save_dhcp_hostname
{
}
1;