1 # suse-linux-10.0-lib.pl
2 # Networking functions for SuSE linux 10.0 and above
4 $net_scripts_dir = "/etc/sysconfig/network";
5 $routes_config = "/etc/sysconfig/network/routes";
6 $sysctl_config = "/etc/sysconfig/sysctl";
11 # Returns a list of interfaces brought up at boot time
15 local @active = &active_interfaces();
16 opendir(CONF, &translate_filename($net_scripts_dir));
17 while($f = readdir(CONF)) {
18 if ($f =~ /^ifcfg-eth-id-([a-f0-9:]+)$/i ||
19 $f =~ /^ifcfg-eth-bus-(\S+)\-(\S+)$/) {
20 # An interface identified by MAC or PCI bus address!
22 &read_env_file("$net_scripts_dir/$f", \%conf);
32 ($a) = grep { lc($_->{'ether'}) eq lc($b->{'mac'}) }
36 ($a) = grep { $_->{'address'} eq $conf{'IPADDR'} }
40 $b->{'fullname'} = $a->{'fullname'};
41 $b->{'name'} = $a->{'name'};
42 $b->{'up'} = ($conf{'STARTMODE'} eq 'onboot' ||
43 $conf{'STARTMODE'} eq 'auto');
45 if ($conf{'IPADDR'} =~ /^(\S+)\/(\d+)$/) {
50 $b->{'address'} = $conf{'IPADDR'};
52 $pfx = $conf{'PREFIXLEN'} if (!$pfx);
54 $b->{'netmask'} = &prefix_to_mask($pfx);
57 $b->{'netmask'} = $conf{'NETMASK'};
59 $b->{'broadcast'} = $conf{'BROADCAST'};
60 $b->{'dhcp'} = ($conf{'BOOTPROTO'} eq 'dhcp');
61 $b->{'mtu'} = $conf{'MTU'};
62 $b->{'edit'} = ($b->{'name'} !~ /^ppp|irlan/);
63 $b->{'index'} = scalar(@rv);
64 $b->{'file'} = "$net_scripts_dir/$f";
67 # Also find aliases in same file
68 foreach my $k (keys %conf) {
69 if ($k =~ /^IPADDR_(\d+)$/) {
72 local $label = $conf{"LABEL_$n"};
73 local $ab = { 'address' => $conf{$k},
74 'netmask' => $conf{"NETMASK_$n"},
75 'broadcast' => &compute_broadcast(
80 'index' => scalar(@rv),
81 'name' => $b->{'name'},
83 'fullname' => $b->{'name'}.
86 'file' => "$net_scripts_dir/$f",
92 elsif ($f =~ /^ifcfg-([a-z0-9:\.]+)$/) {
93 # A normal interface file
95 $b->{'fullname'} = $1;
96 &read_env_file("$net_scripts_dir/$f", \%conf);
97 if ($b->{'fullname'} =~ /(\S+):(\d+)/) {
101 else { $b->{'name'} = $b->{'fullname'}; }
102 $b->{'up'} = ($conf{'STARTMODE'} eq 'onboot' ||
103 $conf{'STARTMODE'} eq 'auto');
105 if ($conf{'IPADDR'} =~ /^(\S+)\/(\d+)$/) {
106 $b->{'address'} = $1;
110 $b->{'address'} = $conf{'IPADDR'};
112 $pfx = $conf{'PREFIXLEN'} if (!$pfx);
114 $b->{'netmask'} = &prefix_to_mask($pfx);
117 $b->{'netmask'} = $conf{'NETMASK'};
119 $b->{'broadcast'} = $conf{'BROADCAST'};
120 $b->{'dhcp'} = ($conf{'BOOTPROTO'} eq 'dhcp');
121 $b->{'mtu'} = $conf{'MTU'};
122 $b->{'edit'} = ($b->{'name'} !~ /^ppp|irlan/);
123 $b->{'index'} = scalar(@rv);
124 $b->{'file'} = "$net_scripts_dir/$f";
132 # save_interface(&details)
133 # Create or update a boot-time interface
137 if ($_[0]->{'code'} || !$_[0]->{'file'} && $_[0]->{'virtual'} ne '') {
138 # An alias interface in the main interface's file
139 local $file = $_[0]->{'file'};
141 # Get file from parent
142 local @boot = &boot_interfaces();
143 local ($parent) = grep { $_->{'virtual'} eq '' &&
144 $_->{'name'} eq $_[0]->{'name'} } @boot;
145 $file = $parent->{'file'};
148 &read_env_file($file, \%conf);
149 if (!$_[0]->{'code'}) {
150 # Choose a Unique code
151 $_[0]->{'code'} = $_[0]->{'virtual'};
153 $conf{'IPADDR_'.$_[0]->{'code'}} = $_[0]->{'address'};
154 $conf{'NETMASK_'.$_[0]->{'code'}} = $_[0]->{'netmask'};
155 $conf{'LABEL_'.$_[0]->{'code'}} = $_[0]->{'virtual'};
156 &write_env_file($file, \%conf);
160 # Interface has it's own file
161 local $name = $_[0]->{'virtual'} ne "" ? $_[0]->{'name'}.":".$_[0]->{'virtual'}
163 local $file = $_[0]->{'file'} || "$net_scripts_dir/ifcfg-$name";
165 &read_env_file($file, \%conf);
166 $conf{'IPADDR'} = $_[0]->{'address'};
167 local($ip1, $ip2, $ip3, $ip4) = split(/\./, $_[0]->{'address'});
168 $conf{'NETMASK'} = $_[0]->{'netmask'};
169 local($nm1, $nm2, $nm3, $nm4) = split(/\./, $_[0]->{'netmask'});
170 if ($_[0]->{'address'} && $_[0]->{'netmask'}) {
171 $conf{'NETWORK'} = sprintf "%d.%d.%d.%d",
172 ($ip1 & int($nm1))&0xff,
173 ($ip2 & int($nm2))&0xff,
174 ($ip3 & int($nm3))&0xff,
175 ($ip4 & int($nm4))&0xff;
178 $conf{'NETWORK'} = '';
180 delete($conf{'PREFIXLEN'});
181 $conf{'BROADCAST'} = $_[0]->{'broadcast'};
182 $conf{'STARTMODE'} = $_[0]->{'up'} ? "auto" : "manual";
183 $conf{'BOOTPROTO'} = $_[0]->{'dhcp'} ? "dhcp" : "static";
184 $conf{'MTU'} = $_[0]->{'mtu'};
185 $conf{'UNIQUE'} ||= time();
186 &write_env_file($file, \%conf);
191 # delete_interface(&details)
192 # Delete a boot-time interface
195 if ($_[0]->{'code'}) {
196 # Alias interface in the parent interface's file
197 local $file = $_[0]->{'file'};
199 &read_env_file($file, \%conf);
200 delete($conf{'IPADDR_'.$_[0]->{'code'}});
201 delete($conf{'NETMASK_'.$_[0]->{'code'}});
202 delete($conf{'LABEL_'.$_[0]->{'code'}});
203 &write_env_file($file, \%conf);
208 local $name = $_[0]->{'virtual'} ne "" ? $_[0]->{'name'}.":".$_[0]->{'virtual'}
210 local $file = $_[0]->{'file'} || "$net_scripts_dir/ifcfg-$name";
211 &unlink_logged($file);
215 # can_edit(what, [iface])
216 # Can some boot-time interface parameter be edited?
219 if ($_[0] eq "bootp") {
220 # SuSE doesn't support bootp
223 elsif ($_[1] && $_[0] eq "up" && $_[1]->{'virtual'} ne '' && $_[1]->{'file'}) {
224 # Virtual interfaces are always activated at boot
230 # valid_boot_address(address)
231 # Is some address valid for a bootup interface
232 sub valid_boot_address
234 return &check_ipaddress($_[0]);
240 local $hn = &read_file_contents("/etc/HOSTNAME");
245 return &get_system_hostname(1);
248 # save_hostname(name)
252 &system_logged("hostname $_[0] >/dev/null 2>&1");
253 &open_lock_tempfile(HOST, ">/etc/HOSTNAME");
254 &print_tempfile(HOST, $_[0],"\n");
255 &close_tempfile(HOST);
256 undef(@main::get_system_hostname); # clear cache
259 sub routing_config_files
261 return ( $routes_config, $sysctl_config );
264 # get_routes_config()
265 # Returns the list of save static routes
266 sub get_routes_config
269 &open_readfile(ROUTES, $routes_config);
273 local @r = map { $_ eq '-' ? undef : $_ } split(/\s+/, $_);
274 push(@routes, \@r) if (@r);
280 # save_routes_config(&routes)
281 sub save_routes_config
283 &open_tempfile(ROUTES, ">$routes_config");
284 foreach $r (@{$_[0]}) {
285 &print_tempfile(ROUTES, join(" ",
289 $r->[3] || "-"),"\n");
291 &close_tempfile(ROUTES);
294 # Same as in suse-linux-9.0-lib.pl
297 local @routes = &get_routes_config();
299 # show default router and device
300 local ($def) = grep { $_->[0] eq "default" } @routes;
301 print &ui_table_row($text{'routes_default'},
302 &ui_opt_textbox("gateway", $def->[1], 15, $text{'routes_none'}));
304 print &ui_table_row($text{'routes_device2'},
305 &ui_opt_textbox("gatewaydev", $def->[3], 6, $text{'routes_none'}));
307 # Forwarding enabled?
308 &read_env_file($sysctl_config, \%sysctl);
309 print &ui_table_row($text{'routes_forward'},
310 &ui_yesno_radio("forward", $sysctl{'IP_FORWARD'} eq 'yes'));
312 # show static network routes
315 foreach my $r (@routes, [ ]) {
316 next if ($r eq $def);
317 push(@table, [ &ui_textbox("dev_$i", $r->[3], 6),
318 &ui_textbox("net_$i", $r->[0], 15),
319 &ui_textbox("netmask_$i", $r->[2], 15),
320 &ui_textbox("gw_$i", $r->[1], 15),
321 &ui_textbox("type_$i", $r->[4], 10) ]);
323 print &ui_table_row($text{'routes_static'},
324 &ui_columns_table([ $text{'routes_ifc'}, $text{'routes_net'},
325 $text{'routes_mask'}, $text{'routes_gateway'},
326 $text{'routes_type'} ],
327 undef, \@table, undef, 1));
333 local (@routes, $r, $i);
334 if (!$in{'gateway_def'}) {
335 &to_ipaddress($in{'gateway'}) ||
336 &error(&text('routes_edefault', $in{'gateway'}));
337 local @def = ( "default", $in{'gateway'}, undef, undef );
338 if (!$in{'gatewaydev_def'}) {
339 $in{'gatewaydev'} =~ /^\S+$/ ||
340 &error(&text('routes_edevice', $in{'gatewaydev'}));
341 $def[3] = $in{'gatewaydev'};
343 push(@routes, \@def);
345 for($i=0; defined($in{"dev_$i"}); $i++) {
346 next if (!$in{"net_$i"});
347 &check_ipaddress($in{"net_$i"}) ||
348 $in{"net_$i"} =~ /^(\S+)\/(\d+)$/ && &check_ipaddress($1) ||
349 &error(&text('routes_enet', $in{"net_$i"}));
350 $in{"dev_$i"} =~ /^\S*$/ || &error(&text('routes_edevice', $dev));
351 !$in{"netmask_$i"} || &check_ipaddress($in{"netmask_$i"}) ||
352 &error(&text('routes_emask', $in{"netmask_$i"}));
353 !$in{"gw_$i"} || &check_ipaddress($in{"gw_$i"}) ||
354 &error(&text('routes_egateway', $in{"gw_$i"}));
355 $in{"type_$i"} =~ /^\S*$/ ||
356 &error(&text('routes_etype', $in{"type_$i"}));
357 push(@routes, [ $in{"net_$i"}, $in{"gw_$i"}, $in{"netmask_$i"},
358 $in{"dev_$i"}, $in{"type_$i"} ] );
361 # Save routes and routing option
362 &save_routes_config(\@routes);
363 local $lref = &read_file_lines($sysctl_config);
364 for($i=0; $i<@$lref; $i++) {
365 if ($lref->[$i] =~ /^\s*IP_FORWARD\s*=/) {
366 $lref->[$i] = "IP_FORWARD=".($in{'forward'} ? "yes" : "no");
372 # get_default_gateway()
373 # Returns the default gateway IP (if one is set) and device (if set) boot time
375 sub get_default_gateway
377 local @routes = &get_routes_config();
378 local ($def) = grep { $_->[0] eq "default" } @routes;
380 return ( $def->[1], $def->[3] );
387 # set_default_gateway(gateway, device)
388 # Sets the default gateway to the given IP accessible via the given device,
389 # in the boot time settings.
390 sub set_default_gateway
392 local @routes = &get_routes_config();
393 local ($def) = grep { $_->[0] eq "default" } @routes;
398 elsif ($def && !$_[0]) {
399 @routes = grep { $_ ne $def } @routes;
401 elsif (!$def && $_[0]) {
402 splice(@routes, 0, 0, [ "default", $_[0], undef, $_[1] ]);
404 &save_routes_config(\@routes);
407 sub os_feedback_files
409 opendir(DIR, $net_scripts_dir);
410 local @f = readdir(DIR);
412 return ( (map { "$net_scripts_dir/$_" } grep { /^ifcfg-/ } @f),
413 $network_config, $static_route_config, "/etc/resolv.conf",
414 "/etc/nsswitch.conf", "/etc/HOSTNAME" );
418 # Apply the interface and routing settings
421 &system_logged("(cd / ; /etc/init.d/network stop ; /etc/init.d/network start) >/dev/null 2>&1");
424 # supports_address6([&iface])
425 # Returns 1 if managing IPv6 interfaces is supported
426 sub supports_address6