---- Changes since 1.500 ----
Added a field for editing the MAC address to apply at boot time on Redhat and Debian-based systems.
Include hostname configuration files in backups, thanks to Caspar Smit.
+---- Changes since 1.530 ----
+Static IPv6 addresses on Linux systems can now be viewed and managed.
}
}
+# supports_address6([&iface])
+# Returns 1 if managing IPv6 interfaces is supported
+sub supports_address6
+{
+local ($iface) = @_;
+return 0;
+}
+
1;
return $_[0] =~ /^eth/;
}
+# supports_address6([&iface])
+# Returns 1 if managing IPv6 interfaces is supported
+sub supports_address6
+{
+local ($iface) = @_;
+return !$iface || $iface->{'virtual'} eq '';
+}
+
1;
# Edit or create an active interface
require './net-lib.pl';
+@act = &active_interfaces();
&ReadParse();
if ($in{'new'}) {
+ # New real or virtual interface
&ui_print_header(undef, $text{'aifc_create'}, "");
&can_create_iface() || &error($text{'ifcs_ecannot'});
+ if ($in{'virtual'}) {
+ # Pick a virtual number
+ $vmax = int($net::min_virtual_number);
+ foreach my $e (@act) {
+ $vmax = $e->{'virtual'}
+ if ($e->{'name'} eq $in{'virtual'} &&
+ $e->{'virtual'} > $vmax);
+ }
+ }
}
else {
- @act = &active_interfaces();
+ # Editing existing interface
$a = $act[$in{'idx'}];
&can_iface($a) || &error($text{'ifcs_ecannot_this'});
&ui_print_header(undef, $text{'aifc_edit'}, "");
# Interface name, perhaps editable
if ($in{'new'} && $in{'virtual'}) {
$namefield = $in{'virtual'}.":".
- &ui_textbox("virtual", undef, 3).
+ &ui_textbox("virtual", $vmax+1, 3).
&ui_hidden("name", $in{'virtual'});
}
elsif ($in{'new'}) {
require './net-lib.pl';
&ReadParse();
!$in{'new'} || &can_create_iface() || &error($text{'ifcs_ecannot'});
+@boot = &boot_interfaces();
# Show page title and get interface
if ($in{'new'} && $in{'bond'}) {
+ # New bonding interface
&ui_print_header(undef, $text{'bonding_create'}, "");
}
elsif ($in{'new'} && $in{'vlan'}) {
+ # New VLAN
&ui_print_header(undef, $text{'vlan_create'}, "");
}
elsif ($in{'new'}) {
+ # New real or virtual interface
&ui_print_header(undef, $text{'bifc_create'}, "");
+ if ($in{'virtual'}) {
+ # Pick a virtual number
+ $vmax = int($net::min_virtual_number);
+ foreach my $e (@boot) {
+ $vmax = $e->{'virtual'}
+ if ($e->{'name'} eq $in{'virtual'} &&
+ $e->{'virtual'} > $vmax);
+ }
+ }
}
else {
- @boot = &boot_interfaces();
+ # Editing existing
$b = $boot[$in{'idx'}];
&can_iface($b) || &error($text{'ifcs_ecannot_this'});
&ui_print_header(undef, $text{'bifc_edit'}, "");
# Interface name
if ($in{'new'} && $in{'virtual'}) {
# New virtual interface
- $namefield = $in{'virtual'}.":".&ui_textbox("virtual", undef, 3).
+ $namefield = $in{'virtual'}.":".
+ &ui_textbox("virtual", $vmax+1, 3).
&ui_hidden("name", $in{'virtual'});
}
elsif ($in{'new'}) {
print &ui_table_row($opts[0]->[1], $opts[0]->[2]);
}
+# Show the IPv6 field
+if (&supports_address6($b)) {
+ $table6 = &ui_columns_start([ $text{'ifcs_address6'},
+ $text{'ifcs_netmask6'} ], 50);
+ for($i=0; $i<=@{$b->{'address6'}}; $i++) {
+ $table6 .= &ui_columns_row([
+ &ui_textbox("address6_$i",
+ $b->{'address6'}->[$i], 40),
+ &ui_textbox("netmask6_$i",
+ $b->{'netmask6'}->[$i] || 64, 10) ]);
+ }
+ $table6 .= &ui_columns_end();
+ print &ui_table_row($text{'ifcs_mode6'}, $table6, 3);
+ }
+
# MTU
if (&can_edit("mtu", $b) && $access{'mtu'}) {
$mtufield = &ui_opt_textbox(
(!$in{'new'} && $b->{'virtual'} eq "" &&
defined(&boot_iface_hardware) &&
&boot_iface_hardware($b->{'name'}))) {
- $hardfield = &ui_opt_textbox("ether", $b->{'ether'}, 18,
+ $hardfield = &ui_opt_textbox("ether", $b->{'ether'}, 30,
$text{'aifc_default'});
print &ui_table_row($text{'aifc_hard'}, $hardfield);
}
"/etc/resolv.conf" );
}
+# supports_address6([&iface])
+# Returns 1 if managing IPv6 interfaces is supported
+sub supports_address6
+{
+local ($iface) = @_;
+return 0;
+}
+
1;
&unlock_file($gentoo_net_config);
}
+# supports_address6([&iface])
+# Returns 1 if managing IPv6 interfaces is supported
+sub supports_address6
+{
+local ($iface) = @_;
+return 0;
+}
+
ifcs_bootdesc=Interfaces listed in this table will be activated when the system boots up, and will generally be active now too.
ifcs_name=Name
ifcs_type=Type
-ifcs_ip=IP Address
+ifcs_ip=IPv4 address
+ifcs_ip6=IPv6 address
ifcs_desc=Interface description
ifcs_mask=Netmask
ifcs_status=Status
ifcs_add=Add a new interface.
ifcs_radd=Add a new address range.
ifcs_boot=Activated at Boot
-ifcs_act=Activate at boot?
+ifcs_act=Activate
ifcs_bootp=From BOOTP
ifcs_dhcp=From DHCP
ifcs_broad=Broadcast
ifcs_ecannot_this=You are not allowed to edit this network interface
ifcs_range=Range $1
ifcs_static2=Static configuration
-ifcs_mode=Address source
+ifcs_mode=IPv4 address
+ifcs_mode6=Static IPv6 addresses
+ifcs_address6=IPv6 address
+ifcs_netmask6=Netmask
aifc_create=Create Active Interface
aifc_edit=Edit Active Interface
aifc_ehard='$1' is not a valid hardware address
aifc_eexist=Interface '$1' does not exist
aifc_eclash=The interface $1 is already using this IP address
+aifc_eaddress6=IPv6 address in row $1 is not valid
+aifc_enetmask6=IPv6 netmask in row $1 must be an integer between 1 and 128
+aifc_eclash6=IPv6 address in row $1 is already in use by interface $2
bifc_create=Create Bootup Interface
bifc_edit=Edit Bootup Interface
if (/^\S+/) { push(@lines, $_); }
else { $lines[$#lines] .= $_; }
}
- close(IFC);
- foreach $l (@lines) {
- local %ifc;
- $l =~ /^([^:\s]+)/; $ifc{'name'} = $1;
- $l =~ /^(\S+)/; $ifc{'fullname'} = $1;
- if ($l =~ /^(\S+):(\d+)/) { $ifc{'virtual'} = $2; }
- if ($l =~ /inet addr:(\S+)/) { $ifc{'address'} = $1; }
- elsif (!$_[0]) { next; }
- if ($l =~ /Mask:(\S+)/) { $ifc{'netmask'} = $1; }
- if ($l =~ /Bcast:(\S+)/) { $ifc{'broadcast'} = $1; }
- if ($l =~ /HWaddr (\S+)/) { $ifc{'ether'} = $1; }
- if ($l =~ /MTU:(\d+)/) { $ifc{'mtu'} = $1; }
- if ($l =~ /P-t-P:(\S+)/) { $ifc{'ptp'} = $1; }
- $ifc{'up'}++ if ($l =~ /\sUP\s/);
- $ifc{'promisc'}++ if ($l =~ /\sPROMISC\s/);
- $ifc{'edit'} = ($ifc{'name'} !~ /^ppp/);
- $ifc{'index'} = scalar(@rv);
- push(@rv, \%ifc);
-
-
- # We detect IPV6 adresses. An interface can have multiple IPv6
- # addresses. So we have to scan the entire line to extract each
- # of them.
- if ($l =~ /inet6 addr:\s+(\S+)\/(\S+)/) {
- local($fin)=0;
- local($ic)=0;
- local $j=1;
- while (!$fin) {
- local %ifc;
- local $where;
- $where=index($l,"inet6 addr:",$ic);
- if ($where != -1) {
- local $sub_l = substr($l, $where, (length($l) - $where));
- $sub_l =~ /inet6 addr: (\S+)\/(\S+)/;
- $ifc{'address'} = $1;
- $ifc{'netmask'} = $2;
- $l =~ /^([^:\s]+)/; $ifc{'name'} = $1;
-
- # An IPv6 address has to be up
- $ifc{'up'}++;
-
- # The fe80 type IPV6 adresses and the IPv6 loopback interface address
- # are set to be non-modifiable (for "security" reason)
- if (index($ifc{'address'},"fe80") != -1 ) {
- }
- elsif ($ifc{'address'} eq "::1") {
- }
- else {
- $l =~ /^(\S+)/; $ifc{'fullname'} = $1 . "-IPV6-" . $j;
- $ifc{'edit'} = ($ifc{'name'} !~ /^ppp/);
- }
- $ifc{'ether'}=$rv[-1]{'ether'};
- #printf "$ifc{'ether'}\n";
- $ifc{'index'} = scalar(@rv);
- push(@rv, \%ifc);
-
-# We add an offset to look for another possible IPv6 address ot he interface
- $ic=$where+1;
- $j++;
- }
- else
- {
- $fin=1;
- }
- }
- }
+close(IFC);
+foreach $l (@lines) {
+ local %ifc;
+ $l =~ /^([^:\s]+)/; $ifc{'name'} = $1;
+ $l =~ /^(\S+)/; $ifc{'fullname'} = $1;
+ if ($l =~ /^(\S+):(\d+)/) { $ifc{'virtual'} = $2; }
+ if ($l =~ /inet addr:(\S+)/) { $ifc{'address'} = $1; }
+ elsif (!$_[0]) { next; }
+ if ($l =~ /Mask:(\S+)/) { $ifc{'netmask'} = $1; }
+ if ($l =~ /Bcast:(\S+)/) { $ifc{'broadcast'} = $1; }
+ if ($l =~ /HWaddr (\S+)/) { $ifc{'ether'} = $1; }
+ if ($l =~ /MTU:(\d+)/) { $ifc{'mtu'} = $1; }
+ if ($l =~ /P-t-P:(\S+)/) { $ifc{'ptp'} = $1; }
+ $ifc{'up'}++ if ($l =~ /\sUP\s/);
+ $ifc{'promisc'}++ if ($l =~ /\sPROMISC\s/);
+ local (@address6, @netmask6, @scope6);
+ while($l =~ s/inet6 addr:\s*(\S+)\/(\d+)\s+Scope:(\S+)//) {
+ local ($address6, $netmask6, $scope6) = ($1, $2, $3);
+ push(@address6, $address6);
+ push(@netmask6, $netmask6);
+ push(@scope6, $scope6);
+ }
+ $ifc{'address6'} = \@address6;
+ $ifc{'netmask6'} = \@netmask6;
+ $ifc{'scope6'} = \@scope6;
+ $ifc{'edit'} = ($ifc{'name'} !~ /^ppp/);
+ $ifc{'index'} = scalar(@rv);
+ push(@rv, \%ifc);
}
return @rv;
}
print &ui_form_start("delete_aifcs.cgi", "post");
push(@links, &select_all_link("d"),
&select_invert_link("d") );
- push(@tds, "width=5");
+ push(@tds, "width=5 valign=top");
}
- push(@tds, "width=20%", "width=20%", "width=20%", "width=20%");
+ push(@tds, "width=20% valign=top", "width=20% valign=top",
+ "width=20% valign=top", "width=20% valign=top");
+ push(@tds, "width=20% valign=top") if (&supports_address6());
if ($allow_add) {
push(@links,
"<a href='edit_aifc.cgi?new=1'>$text{'ifcs_add'}</a>");
$text{'ifcs_type'},
$text{'ifcs_ip'},
$text{'ifcs_mask'},
+ &supports_address6() ?
+ ( $text{'ifcs_ip6'} ) : ( ),
$text{'ifcs_status'} ], 100, 0, \@tds);
# Show table of interfaces
(%minfo ? " ($minfo{'desc'})" : ""));
push(@cols, &html_escape($a->{'address'}));
push(@cols, &html_escape($a->{'netmask'}));
+ if (&supports_address6()) {
+ push(@cols, join("<br>\n", map { &html_escape($_) }
+ @{$a->{'address6'}}));
+ }
push(@cols, $a->{'up'} ? $text{'ifcs_up'} :
"<font color=#ff0000>$text{'ifcs_down'}</font>");
if ($a->{'edit'} && &can_iface($a)) {
push(@links, "<a href='edit_range.cgi?new=1'>$text{'ifcs_radd'}</a>");
}
print &ui_links_row(\@links);
-@tds = ( "width=5", "width=20%", "width=20%", "width=20%",
- "width=20%", "width=20%");
+@tds = ( "width=5 valign=top", "width=20% valign=top", "width=20% valign=top",
+ "width=20% valign=top", "width=20% valign=top",
+ "width=20% valign=top");
+push(@tds, "width=20% valign=top") if (&supports_address6());
print &ui_columns_start([ "",
$text{'ifcs_name'},
$text{'ifcs_type'},
$text{'ifcs_ip'},
$text{'ifcs_mask'},
+ &supports_address6() ? ( $text{'ifcs_ip6'} ) : ( ),
$text{'ifcs_act'} ], 100, 0, \@tds);
@boot = &boot_interfaces();
}
push(@cols, &iface_type($a->{'name'}));
push(@cols, "$a->{'start'} - $a->{'end'}");
- splice(@mytds, 3, 2, "colspan=2 width=40%");
+ if (&supports_address6()) {
+ # IPv6 not possible for ranges
+ push(@cols, "");
+ }
+ splice(@mytds, 3, 2, "colspan=2 width=40% valign=top");
}
else {
# A normal single interface
$text{'ifcs_auto'});
push(@cols, $a->{'netmask'} ? &html_escape($a->{'netmask'})
: $text{'ifcs_auto'});
+ if (&supports_address6()) {
+ push(@cols, join("<br>\n", map { &html_escape($_) }
+ @{$a->{'address6'}}));
+ }
}
push(@cols, $a->{'up'} ? $text{'yes'} : $text{'no'});
if ($can) {
#system("killall -HUP lookupd >/dev/null 2>&1");
#}
+# supports_address6([&iface])
+# Returns 1 if managing IPv6 interfaces is supported
+sub supports_address6
+{
+local ($iface) = @_;
+return 0;
+}
+
1;
}
}
+# supports_address6([&iface])
+# Returns 1 if managing IPv6 interfaces is supported
+sub supports_address6
+{
+local ($iface) = @_;
+return 0;
+}
+
1;
closedir(CONF);
}
+# supports_address6([&iface])
+# Returns 1 if managing IPv6 interfaces is supported
+sub supports_address6
+{
+local ($iface) = @_;
+return 0;
+}
+
1;
"/etc/sysctl.conf" );
}
+# supports_address6([&iface])
+# Returns 1 if managing IPv6 interfaces is supported
+sub supports_address6
+{
+local ($iface) = @_;
+return 0;
+}
+
1;
$b->{'ether'} = $conf{'MACADDR'};
$b->{'dhcp'} = ($conf{'BOOTPROTO'} eq 'dhcp');
$b->{'bootp'} = ($conf{'BOOTPROTO'} eq 'bootp');
+ local @ip6s;
+ push(@ip6s, [ split(/\//, $conf{'IPV6ADDR'}) ])
+ if ($conf{'IPV6ADDR'});
+ push(@ip6s, map { [ split(/\//, $_) ] }
+ split(/\s+/, $conf{'IPV6ADDR_SECONDARIES'}));
+ $b->{'address6'} = [ map { $_->[0] } @ip6s ];
+ $b->{'netmask6'} = [ map { $_->[1] } @ip6s ];
$b->{'edit'} = ($b->{'name'} !~ /^ppp|irlan/);
$b->{'desc'} = $conf{'NAME'};
$b->{'index'} = scalar(@rv);
if ($_[0]->{'virtual'} ne '');
$conf{'BOOTPROTO'} = $_[0]->{'bootp'} ? "bootp" :
$_[0]->{'dhcp'} ? "dhcp" : "none";
+ delete($conf{'IPV6ADDR'});
+ delete($conf{'IPV6ADDR_SECONDARIES'});
+ local @ip6s;
+ for(my $i=0; $i<@{$b->{'address6'}}; $b++) {
+ push(@ip6s, $b->{'address6'}->[$i]."/".
+ $b->{'netmask6'}->[$i]);
+ }
+ $conf{'IPV6ADDR'} = shift(@ip6s);
+ $conf{'IPV6ADDR_SECONDARIES'} = join(" ", @ip6s);
}
$conf{'NAME'} = $_[0]->{'desc'};
&write_env_file("$net_scripts_dir/ifcfg-$name", \%conf);
return $_[0] =~ /^eth/;
}
+# supports_address6([&iface])
+# Returns 1 if managing IPv6 interfaces is supported
+sub supports_address6
+{
+local ($iface) = @_;
+return !$iface || $iface->{'virtual'} eq '';
+}
+
1;
$b->{'ether'} = $in{'ether'};
}
+ # Activate at boot flag
if ($in{'new'} && !$access{'up'} ||
&can_edit("up", $b) && $in{'up'} && $access{'up'}) {
$b->{'up'}++;
$b->{'up'} = $oldb->{'up'};
}
+ # Save IPv6 addresses
+ if (&supports_address6($b) && defined($in{'address6_0'})) {
+ @address6 = ( );
+ @netmask6 = ( );
+ %clash6 = ( );
+ foreach $e (@boot) {
+ if ($e->{'fullname'} ne $b->{'fullname'}) {
+ foreach $a6 (@{$e->{'address6'}}) {
+ $clash6{$a6} = $e;
+ }
+ }
+ }
+ for($i=0; defined($in{'address6_'.$i}); $i++) {
+ next if ($in{'address6_'.$i} !~ /\S/);
+ &check_ip6address($in{'address6_'.$i}) ||
+ &error(&text('aifc_eaddress6', $i+1));
+ $c = $clash6{$in{'address6_'.$i}};
+ $c && &error(&text('aifc_eclash6', $i+1, $c->{'name'}));
+ push(@address6, $in{'address6_'.$i});
+ $in{'netmask6_'.$i} =~ /^\d+$/ &&
+ $in{'netmask6_'.$i} > 0 &&
+ $in{'netmask6_'.$i} <= 128 ||
+ &error(&text('aifc_enetmask6', $i+1));
+ push(@netmask6, $in{'netmask6_'.$i});
+ $clash6{$in{'address6_'.$i}} = $b;
+ }
+ $b->{'address6'} = \@address6;
+ $b->{'netmask6'} = \@netmask6;
+ }
+
if ($in{'bond'}) {
$b->{'bond'} = 1;
if ($in{'partner'}) {
&unlock_file($inet_conf);
}
+# supports_address6([&iface])
+# Returns 1 if managing IPv6 interfaces is supported
+sub supports_address6
+{
+local ($iface) = @_;
+return 0;
+}
+
}
+# supports_address6([&iface])
+# Returns 1 if managing IPv6 interfaces is supported
+sub supports_address6
+{
+local ($iface) = @_;
+return 0;
+}
+
1;
return $netmask;
}
+# supports_address6([&iface])
+# Returns 1 if managing IPv6 interfaces is supported
+sub supports_address6
+{
+local ($iface) = @_;
+return 0;
+}
+
1;
&system_logged("(cd / ; /etc/init.d/network stop ; /etc/init.d/network start) >/dev/null 2>&1");
}
+# supports_address6([&iface])
+# Returns 1 if managing IPv6 interfaces is supported
+sub supports_address6
+{
+local ($iface) = @_;
+return 0;
+}
+
1;
&system_logged("(cd / ; /etc/init.d/network stop ; /etc/init.d/network start) >/dev/null 2>&1");
}
+# supports_address6([&iface])
+# Returns 1 if managing IPv6 interfaces is supported
+sub supports_address6
+{
+local ($iface) = @_;
+return 0;
+}
+
1;
return ( $rc_config, $route_conf, "/etc/resolv.conf", "/etc/nsswitch.conf" );
}
+# supports_address6([&iface])
+# Returns 1 if managing IPv6 interfaces is supported
+sub supports_address6
+{
+local ($iface) = @_;
+return 0;
+}
+
1;
&system_logged("(cd / ; /etc/init.d/network stop ; /etc/init.d/network start) >/dev/null 2>&1");
}
+# supports_address6([&iface])
+# Returns 1 if managing IPv6 interfaces is supported
+sub supports_address6
+{
+local ($iface) = @_;
+return 0;
+}
+
1;
"/etc/defaultrouter", "/etc/notrouter", "/etc/gateways" );
}
+# supports_address6([&iface])
+# Returns 1 if managing IPv6 interfaces is supported
+sub supports_address6
+{
+local ($iface) = @_;
+return 0;
+}
+
1;