--- /dev/null
+#!/usr/bin/perl\r
+#\r
+# IPCop CGI's - aliases.cgi\r
+#\r
+# This code is distributed under the terms of the GPL\r
+#\r
+# (c) Steve Bootes 2002/04/13 - Manage IP Aliases\r
+#\r
+# $Id: aliases.cgi,v 1.5.2.18 2006/12/08 21:59:59 eoberlander Exp $\r
+\r
+\r
+# to fully troubleshot your code, uncomment diagnostics, Carp and cluck lines\r
+#use diagnostics; # need to add the file /usr/lib/perl5/5.8.x/pods/perldiag.pod before to work\r
+# next look at /var/log/httpd/error_log , http://www.perl.com/pub/a/2002/05/07/mod_perl.html may help\r
+#use warnings;\r
+use strict;\r
+#use Carp ();\r
+#local $SIG{__WARN__} = \&Carp::cluck;\r
+\r
+require '/var/ipfire/general-functions.pl'; # replace /var/ipcop with /var/ipcop in case of manual install\r
+require "${General::swroot}/lang.pl";\r
+require "${General::swroot}/header.pl";\r
+\r
+#workaround to suppress a warning when a variable is used only once\r
+my @dummy = ( ${Header::colouryellow} );\r
+ @dummy = ( ${Header::table1colour} );\r
+ @dummy = ( ${Header::table2colour} );\r
+undef (@dummy);\r
+\r
+# Files used\r
+my $setting = "${General::swroot}/ethernet/settings";\r
+our $datafile = "${General::swroot}/ethernet/aliases";\r
+\r
+\r
+our %settings=();\r
+#Settings1\r
+\r
+#Settings2 for editing the multi-line list\r
+#Must not be saved !\r
+$settings{'IP'} = '';\r
+$settings{'ENABLED'} = 'off'; # Every check box must be set to off\r
+$settings{'NAME'} = '';\r
+my @nosaved=('IP','ENABLED','NAME'); # List here ALL setting2 fields. Mandatory\r
+ \r
+$settings{'ACTION'} = ''; # add/edit/remove\r
+$settings{'KEY1'} = ''; # point record for ACTION\r
+\r
+#Define each field that can be used to sort columns\r
+my $sortstring='^IP|^NAME';\r
+my $errormessage = '';\r
+my $warnmessage = '';\r
+\r
+&Header::showhttpheaders();\r
+\r
+# Read needed Ipcop netsettings\r
+my %netsettings=();\r
+$netsettings{'SORT_ALIASES'} = 'NAME'; # default sort\r
+&General::readhash($setting, \%netsettings);\r
+\r
+#Get GUI values\r
+&Header::getcgihash(\%settings);\r
+\r
+# Load multiline data\r
+our @current = ();\r
+if (open(FILE, "$datafile")) {\r
+ @current = <FILE>;\r
+ close (FILE);\r
+}\r
+\r
+#\r
+# Check Settings1 first because they are needed before working on @current\r
+#\r
+# Remove if no Setting1 needed\r
+#\r
+if ($settings{'ACTION'} eq $Lang::tr{'save'}) {\r
+ \r
+ #\r
+ #Validate static Settings1 here\r
+ #\r
+ \r
+ unless ($errormessage) { # Everything is ok, save settings\r
+ #map (delete ($settings{$_}) ,(@nosaved,'ACTION','KEY1'));# Must never be saved \r
+ #&General::writehash($setting, \%settings); # Save good settings\r
+ #$settings{'ACTION'} = $Lang::tr{'save'}; # Recreate 'ACTION'\r
+ #map ($settings{$_}= '',(@nosaved,'KEY1')); # and reinit var to empty\r
+ \r
+ # Rebuild configuration file if needed\r
+ &BuildConfiguration;\r
+ }\r
+\r
+ ERROR: # Leave the faulty field untouched\r
+} else {\r
+ #&General::readhash($setting, \%settings); # Get saved settings and reset to good if needed\r
+}\r
+\r
+## Now manipulate the multi-line list with Settings2\r
+# Basic actions are:\r
+# toggle the check box\r
+# add/update a new line\r
+# begin editing a line\r
+# remove a line\r
+\r
+\r
+# Toggle enable/disable field. Field is in second position\r
+if ($settings{'ACTION'} eq $Lang::tr{'toggle enable disable'}) {\r
+ #move out new line\r
+ chomp(@current[$settings{'KEY1'}]);\r
+ my @temp = split(/\,/,@current[$settings{'KEY1'}]);\r
+ $temp[1] = $temp[1] eq 'on' ? 'off' : 'on'; # Toggle the field\r
+ $temp[2] = '' if ( $temp[2] eq '' );\r
+ @current[$settings{'KEY1'}] = join (',',@temp)."\n";\r
+ $settings{'KEY1'} = ''; # End edit mode\r
+ \r
+ &General::log($Lang::tr{'ip alias changed'});\r
+ \r
+ #Save current\r
+ open(FILE, ">$datafile") or die 'Unable to open aliases file.';\r
+ print FILE @current;\r
+ close(FILE);\r
+ \r
+ # Rebuild configuration file\r
+ &BuildConfiguration;\r
+}\r
+\r
+if ($settings{'ACTION'} eq $Lang::tr{'add'}) {\r
+ # Validate inputs\r
+ if (! &General::validip($settings{'IP'})) {$errormessage = "invalid ip"};\r
+ $settings{'NAME'} = &Header::cleanhtml($settings{'NAME'});\r
+\r
+ # Make sure we haven't duplicated an alias or RED\r
+ my $spacer='';\r
+ if ($settings{'IP'} eq $netsettings{'RED_ADDRESS'}) {\r
+ $errormessage = $Lang::tr{'duplicate ip'} . ' (RED)';\r
+ $spacer=" & ";\r
+ }\r
+ my $idx=0;\r
+ foreach my $line (@current) {\r
+ chomp ($line);\r
+ my @temp = split (/\,/, $line);\r
+ if ( ($settings{'KEY1'} eq '')||(($settings{'KEY1'} ne '') && ($settings{'KEY1'} != $idx))) { # update\r
+ if ($temp[0] eq $settings{'IP'}) {\r
+ $errormessage .= $spacer.$Lang::tr{'duplicate ip'};\r
+ $spacer=" & ";\r
+ }\r
+ if ($temp[2] eq $settings{'NAME'} && $temp[2] ne '') {\r
+ $errormessage .= $spacer.$Lang::tr{'duplicate name'};\r
+ $spacer=" & ";\r
+ }\r
+ }\r
+ $idx++;\r
+ }\r
+ unless ($errormessage) {\r
+ if ($settings{'KEY1'} eq '') { #add or edit ?\r
+ unshift (@current, "$settings{'IP'},$settings{'ENABLED'},$settings{'NAME'}\n");\r
+ &General::log($Lang::tr{'ip alias added'});\r
+ } else {\r
+ @current[$settings{'KEY1'}] = "$settings{'IP'},$settings{'ENABLED'},$settings{'NAME'}\n";\r
+ $settings{'KEY1'} = ''; # End edit mode\r
+ &General::log($Lang::tr{'ip alias changed'});\r
+ }\r
+\r
+ # Write changes to config file.\r
+ &SortDataFile; # sort newly added/modified entry\r
+\r
+ &BuildConfiguration; # then re-build conf which use new data\r
+ \r
+##\r
+## if entering data line is repetitive, choose here to not erase fields between each addition\r
+##\r
+ map ($settings{$_}='' ,@nosaved); # Clear fields\r
+ }\r
+}\r
+\r
+if ($settings{'ACTION'} eq $Lang::tr{'edit'}) {\r
+ #move out new line\r
+ my $line = @current[$settings{'KEY1'}]; # KEY1 is the index in current\r
+ chomp($line);\r
+ my @temp = split(/\,/, $line);\r
+\r
+##\r
+## move data fields to Setting2 for edition\r
+##\r
+ $settings{'IP'}=$temp[0]; # Prepare the screen for editing\r
+ $settings{'ENABLED'}=$temp[1];\r
+ $settings{'NAME'}=$temp[2];\r
+}\r
+\r
+if ($settings{'ACTION'} eq $Lang::tr{'remove'}) {\r
+ splice (@current,$settings{'KEY1'},1); # Delete line \r
+ open(FILE, ">$datafile") or die 'Unable to open aliases file.';\r
+ print FILE @current;\r
+ close(FILE);\r
+ $settings{'KEY1'} = ''; # End remove mode\r
+ &General::log($Lang::tr{'ip alias removed'});\r
+\r
+ &BuildConfiguration; # then re-build conf which use new data\r
+}\r
+\r
+\r
+\r
+## Check if sorting is asked\r
+# If same column clicked, reverse the sort.\r
+if ($ENV{'QUERY_STRING'} =~ /$sortstring/ ) {\r
+ my $newsort=$ENV{'QUERY_STRING'};\r
+ my $actual=$netsettings{'SORT_ALIASES'};\r
+ #Reverse actual sort ?\r
+ if ($actual =~ $newsort) {\r
+ my $Rev='';\r
+ if ($actual !~ 'Rev') {\r
+ $Rev='Rev';\r
+ }\r
+ $newsort.=$Rev;\r
+ }\r
+ $netsettings{'SORT_ALIASES'}=$newsort;\r
+ &General::writehash($setting, \%netsettings);\r
+ &SortDataFile;\r
+ $settings{'ACTION'} = 'SORT'; # Recreate 'ACTION'\r
+}\r
+\r
+# Default initial value\r
+if ($settings{'ACTION'} eq '' ) { # First launch from GUI\r
+ $settings{'ENABLED'} ='on';\r
+}\r
+ \r
+&Header::openpage($Lang::tr{'external aliases configuration'}, 1, '');\r
+&Header::openbigbox('100%', 'left', '', $errormessage);\r
+my %checked =(); # Checkbox manipulations\r
+\r
+if ($errormessage) {\r
+ &Header::openbox('100%', 'left', $Lang::tr{'error messages'});\r
+ print "<font class='base'>$errormessage </font>";\r
+ &Header::closebox();\r
+}\r
+unless (( $netsettings{'CONFIG_TYPE'} =~ /^(1|2|3|4)$/ ) && ($netsettings{'RED_TYPE'} eq 'STATIC'))\r
+{\r
+ &Header::openbox('100%', 'left', $Lang::tr{'capswarning'});\r
+ print <<END\r
+ <table width='100%'>\r
+ <tr>\r
+ <td width='100%' class='boldbase' align='center'><font color='${Header::colourred}'><b>$Lang::tr{'aliases not active'}</b></font></td>\r
+ </tr>\r
+ </table>\r
+END\r
+;\r
+ &Header::closebox();\r
+}\r
+ \r
+#\r
+# Second check box is for editing the list\r
+#\r
+$checked{'ENABLED'}{'on'} = ($settings{'ENABLED'} eq 'on') ? "checked='checked'" : '' ;\r
+\r
+my $buttontext = $Lang::tr{'add'};\r
+if ($settings{'KEY1'} ne '') {\r
+ $buttontext = $Lang::tr{'update'};\r
+ &Header::openbox('100%', 'left', $Lang::tr{'edit an existing alias'});\r
+} else {\r
+ &Header::openbox('100%', 'left', $Lang::tr{'add new alias'});\r
+}\r
+\r
+#Edited line number (KEY1) passed until cleared by 'save' or 'remove' or 'new sort order'\r
+print <<END\r
+<form method='post' action='$ENV{'SCRIPT_NAME'}'>\r
+<input type='hidden' name='KEY1' value='$settings{'KEY1'}' />\r
+<table width='100%'>\r
+<tr>\r
+<td class='base'><font color='${Header::colourred}'>$Lang::tr{'name'}: <img src='/blob.gif' alt='*' /></font></td>\r
+<td><input type='text' name='NAME' value='$settings{'NAME'}' size='32' /></td>\r
+<td class='base' align='right'><font color='${Header::colourred}'>$Lang::tr{'alias ip'}: </font></td>\r
+<td><input type='text' name='IP' value='$settings{'IP'}' size='16' /></td>\r
+<td class='base' align='right'>$Lang::tr{'enabled'} </td>\r
+<td><input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} /></td>\r
+</tr>\r
+</table>\r
+<hr />\r
+<table width='100%'>\r
+<tr>\r
+ <td class='base' width='55%'><img src='/blob.gif' align='top' alt='*' /> $Lang::tr{'this field may be blank'}</td>\r
+ <td width='40%' align='center'><input type='hidden' name='ACTION' value='$Lang::tr{'add'}' /><input type='submit' name='SUBMIT' value='$buttontext' /></td>\r
+ <td width='5%' align='right'> \r
+ <a href='${General::adminmanualurl}/section-dialup.html#services-extalias' target='_blank'><img src='/images/web-support.png' title='$Lang::tr{'online help en'}' /></a>\r
+ </td>\r
+</tr>\r
+</table>\r
+</form>\r
+END\r
+;\r
+&Header::closebox();\r
+\r
+# Add visual indicators to column headings to show sort order - EO\r
+my $sortarrow1 = '';\r
+my $sortarrow2 = '';\r
+\r
+if ($netsettings{'SORT_ALIASES'} eq 'NAMERev') {\r
+ $sortarrow1 = $Header::sortdn;\r
+} elsif ($netsettings{'SORT_ALIASES'} eq 'NAME') {\r
+ $sortarrow1 = $Header::sortup;\r
+} elsif ($netsettings{'SORT_ALIASES'} eq 'IPRev') {\r
+ $sortarrow2 = $Header::sortdn;\r
+} else {\r
+ $sortarrow2 = $Header::sortup;\r
+}\r
+\r
+#\r
+# Third box shows the list, in columns\r
+#\r
+# Columns headers may content a link. In this case it must be named in $sortstring\r
+#\r
+&Header::openbox('100%', 'left', $Lang::tr{'current aliases'});\r
+print <<END\r
+<table width='100%'>\r
+<tr>\r
+ <td width='50%' align='center'><a href='$ENV{'SCRIPT_NAME'}?NAME'><b>$Lang::tr{'name'}</b></a> $sortarrow1</td>\r
+ <td width='45%' align='center'><a href='$ENV{'SCRIPT_NAME'}?IP'><b>$Lang::tr{'alias ip'}</b></a> $sortarrow2</td>\r
+ <td width='5%' colspan='3' class='boldbase' align='center'><b>$Lang::tr{'action'}</b></td>\r
+</tr>\r
+END\r
+;\r
+\r
+#\r
+# Print each line of @current list\r
+#\r
+# each data line is splitted into @temp.\r
+#\r
+\r
+my $key = 0;\r
+foreach my $line (@current) {\r
+ chomp($line);\r
+ my @temp = split(/\,/,$line);\r
+\r
+ #Choose icon for checkbox\r
+ my $gif = '';\r
+ my $gdesc = '';\r
+ if ($temp[1] eq "on") {\r
+ $gif = 'on.gif';\r
+ $gdesc = $Lang::tr{'click to disable'};\r
+ } else {\r
+ $gif = 'off.gif';\r
+ $gdesc = $Lang::tr{'click to enable'}; \r
+ }\r
+\r
+ #Colorize each line\r
+ if ($settings{'KEY1'} eq $key) {\r
+ print "<tr bgcolor='${Header::colouryellow}'>";\r
+ } elsif ($key % 2) {\r
+ print "<tr bgcolor='${Header::table2colour}'>";\r
+ } else {\r
+ print "<tr bgcolor='${Header::table1colour}'>"; \r
+ }\r
+\r
+ print <<END\r
+<td align='center'>$temp[2]</td>\r
+<td align='center'>$temp[0]</td>\r
+\r
+<td align='center'>\r
+<form method='post' action='$ENV{'SCRIPT_NAME'}'>\r
+<input type='hidden' name='ACTION' value='$Lang::tr{'toggle enable disable'}' />\r
+<input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$gif' alt='$gdesc' title='$gdesc' />\r
+<input type='hidden' name='KEY1' value='$key' />\r
+</form>\r
+</td>\r
+\r
+<td align='center'>\r
+<form method='post' action='$ENV{'SCRIPT_NAME'}'>\r
+<input type='hidden' name='ACTION' value='$Lang::tr{'edit'}' />\r
+<input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' />\r
+<input type='hidden' name='KEY1' value='$key' />\r
+</form>\r
+</td>\r
+\r
+<td align='center'>\r
+<form method='post' action='$ENV{'SCRIPT_NAME'}'>\r
+<input type='hidden' name='ACTION' value='$Lang::tr{'remove'}' />\r
+<input type='image' name='$Lang::tr{'remove'}' src='/images/delete.gif' alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' />\r
+<input type='hidden' name='KEY1' value='$key' />\r
+</form>\r
+</td>\r
+</tr>\r
+END\r
+;\r
+ $key++;\r
+}\r
+print "</table>";\r
+\r
+# If table contains entries, print 'Key to action icons'\r
+if ($key) {\r
+print <<END\r
+<table>\r
+<tr>\r
+ <td class='boldbase'> <b>$Lang::tr{'legend'}: </b></td>\r
+ <td><img src='/images/on.gif' alt='$Lang::tr{'click to disable'}' /></td>\r
+ <td class='base'>$Lang::tr{'click to disable'}</td>\r
+ <td> </td>\r
+ <td><img src='/images/off.gif' alt='$Lang::tr{'click to enable'}' /></td>\r
+ <td class='base'>$Lang::tr{'click to enable'}</td>\r
+ <td> </td>\r
+ <td><img src='/images/edit.gif' alt='$Lang::tr{'edit'}' /></td>\r
+ <td class='base'>$Lang::tr{'edit'}</td>\r
+ <td> </td>\r
+ <td><img src='/images/delete.gif' alt='$Lang::tr{'remove'}' /></td>\r
+ <td class='base'>$Lang::tr{'remove'}</td>\r
+</tr>\r
+</table>\r
+END\r
+;\r
+}\r
+\r
+&Header::closebox();\r
+&Header::closebigbox();\r
+&Header::closepage();\r
+\r
+## Ouf it's the end !\r
+\r
+\r
+\r
+# Sort the "current" array according to choices\r
+sub SortDataFile\r
+{\r
+ our %entries = ();\r
+ \r
+ # Sort pair of record received in $a $b special vars.\r
+ # When IP is specified use numeric sort else alpha.\r
+ # If sortname ends with 'Rev', do reverse sort.\r
+ #\r
+ sub fixedleasesort {\r
+ my $qs=''; # The sort field specified minus 'Rev'\r
+ if (rindex ($netsettings{'SORT_ALIASES'},'Rev') != -1) {\r
+ $qs=substr ($netsettings{'SORT_ALIASES'},0,length($netsettings{'SORT_ALIASES'})-3);\r
+ if ($qs eq 'IP') {\r
+ my @a = split(/\./,$entries{$a}->{$qs});\r
+ my @b = split(/\./,$entries{$b}->{$qs});\r
+ ($b[0]<=>$a[0]) ||\r
+ ($b[1]<=>$a[1]) ||\r
+ ($b[2]<=>$a[2]) ||\r
+ ($b[3]<=>$a[3]);\r
+ } else {\r
+ $entries{$b}->{$qs} cmp $entries{$a}->{$qs};\r
+ }\r
+ } else { #not reverse\r
+ $qs=$netsettings{'SORT_ALIASES'};\r
+ if ($qs eq 'IP') {\r
+ my @a = split(/\./,$entries{$a}->{$qs});\r
+ my @b = split(/\./,$entries{$b}->{$qs});\r
+ ($a[0]<=>$b[0]) ||\r
+ ($a[1]<=>$b[1]) ||\r
+ ($a[2]<=>$b[2]) ||\r
+ ($a[3]<=>$b[3]);\r
+ } else {\r
+ $entries{$a}->{$qs} cmp $entries{$b}->{$qs};\r
+ }\r
+ }\r
+ }\r
+\r
+ #Use an associative array (%entries)\r
+ my $key = 0;\r
+ foreach my $line (@current) {\r
+ chomp( $line); #remove newline because can be on field 5 or 6 (addition of REMARK)\r
+ my @temp = split (',',$line);\r
+ \r
+ # Build a pair 'Field Name',value for each of the data dataline.\r
+ # Each SORTABLE field must have is pair.\r
+ # Other data fields (non sortable) can be grouped in one\r
+ \r
+ # Exemple\r
+ # F1,F2,F3,F4,F5 only F1 F2 for sorting\r
+ # my @record = ('KEY',$key++,\r
+ # 'F1',$temp[0],\r
+ # 'F2',$temp[1],\r
+ # 'DATA',join(',',@temp[2..4]) ); #group remainning values, with separator (,)\r
+ \r
+ # The KEY,key record permits doublons. If removed, then F1 becomes the key without doublon permitted.\r
+ \r
+ \r
+ my @record = ('KEY',$key++,'IP',$temp[0],'ENABLED',$temp[1],'NAME',$temp[2]);\r
+ my $record = {}; # create a reference to empty hash\r
+ %{$record} = @record; # populate that hash with @record\r
+ $entries{$record->{KEY}} = $record; # add this to a hash of hashes\r
+ }\r
+ \r
+ open(FILE, ">$datafile") or die 'Unable to open aliases file.';\r
+\r
+ # Each field value is printed , with the newline ! Don't forget separator and order of them.\r
+ foreach my $entry (sort fixedleasesort keys %entries) {\r
+ print FILE "$entries{$entry}->{IP},$entries{$entry}->{ENABLED},$entries{$entry}->{NAME}\n";\r
+ }\r
+\r
+ close(FILE);\r
+ # Reload sorted @current\r
+ open (FILE, "$datafile");\r
+ @current = <FILE>;\r
+ close (FILE);\r
+}\r
+\r
+# \r
+# Build the configuration file for application aliases\r
+#\r
+sub BuildConfiguration {\r
+ # Restart service associated with this\r
+ system '/usr/local/bin/setaliases';\r
+}\r
--- /dev/null
+/*\r
+ * setaliases - configure red aliased interfaces\r
+ *\r
+ * This program is distributed under the terms of the GNU General Public\r
+ * Licence. See the file COPYING for details.\r
+ *\r
+ * (c) Steve Bootes, 2002/04/15\r
+ *\r
+ * 21/04/03 Robert Kerr Changed to link directly to libsmooth rather than\r
+ * using a copy & paste\r
+ *\r
+ * $Id: setaliases.c,v 1.2.2.5 2006/07/25 23:15:20 franck78 Exp $\r
+ *\r
+ */\r
+\r
+#include "libsmooth.h"\r
+#include "setuid.h"\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#include <fcntl.h>\r
+\r
+struct keyvalue *kv = NULL;\r
+FILE *file = NULL;\r
+\r
+void exithandler(void)\r
+{\r
+ if (kv) freekeyvalues(kv);\r
+ if (file) fclose(file);\r
+}\r
+\r
+int main(void)\r
+{\r
+ char s[STRING_SIZE];\r
+ char command[STRING_SIZE];\r
+ char red_netmask[STRING_SIZE];\r
+ char red_broadcast[STRING_SIZE];\r
+ char red_dev[STRING_SIZE];\r
+ char default_gateway[STRING_SIZE];\r
+ char *aliasip;\r
+ char *enabled;\r
+ char *sptr;\r
+ char *comment;\r
+ int alias;\r
+ int count;\r
+\r
+ if (!(initsetuid()))\r
+ {\r
+ fprintf(stderr, "Cannot run setuid\n");\r
+ exit(1);\r
+ }\r
+\r
+ atexit(exithandler);\r
+\r
+ /* Init the keyvalue structure */\r
+ kv=initkeyvalues();\r
+\r
+ /* Read in the current values */\r
+ if (!readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings"))\r
+ {\r
+ fprintf(stderr, "Cannot read ethernet settings\n");\r
+ exit(1);\r
+ }\r
+\r
+ /* Find the CONFIG_TYPE value */\r
+ if (!findkey(kv, "CONFIG_TYPE", s))\r
+ {\r
+ fprintf(stderr, "Cannot read CONFIG_TYPE\n");\r
+ exit(1);\r
+ }\r
+\r
+ /* Check for CONFIG_TYPE=2 or 3 i.e. RED ethernet present. If not,\r
+ * exit gracefully. This is not an error... */\r
+ if (!((strcmp(s, "1")==0) || (strcmp(s, "2")==0) || (strcmp(s, "3")==0) || (strcmp(s, "4")==0)))\r
+ exit(0);\r
+\r
+ /* Now check the RED_TYPE - aliases only work with STATIC.\r
+ * At least, that's what /etc/rc.d/rc.netaddress.up thinks.. */\r
+\r
+ /* Find the RED_TYPE value */\r
+ if (!findkey(kv, "RED_TYPE", s))\r
+ {\r
+ fprintf(stderr, "Cannot read RED_TYPE\n");\r
+ exit(1);\r
+ }\r
+ \r
+ /* Make sure it's the right type */\r
+ if (!(strcmp(s, "STATIC")==0)) \r
+ exit(0);\r
+\r
+ /* Get the RED interface details */\r
+ if((!findkey(kv, "RED_NETMASK", red_netmask)) || (!findkey(kv, "RED_BROADCAST", red_broadcast)) || \r
+ (!findkey(kv, "RED_DEV", red_dev)) || (!findkey(kv, "DEFAULT_GATEWAY", default_gateway)))\r
+ {\r
+ fprintf(stderr, "Cannot read RED settings\n");\r
+ exit(1);\r
+ }\r
+ \r
+ if (!VALID_DEVICE(red_dev))\r
+ {\r
+ fprintf(stderr, "Bad red_dev: %s\n", red_dev);\r
+ exit(1);\r
+ }\r
+\r
+ if (!VALID_IP(red_netmask))\r
+ {\r
+ fprintf(stderr, "Bad red_netmask : %s\n", red_netmask);\r
+ exit(1);\r
+ }\r
+\r
+ if (!VALID_IP(red_broadcast))\r
+ {\r
+ fprintf(stderr, "Bad red_broadcast : %s\n", red_broadcast);\r
+ exit(1);\r
+ }\r
+\r
+ if (!VALID_IP(default_gateway))\r
+ {\r
+ fprintf(stderr, "Bad default_gateway : %s\n", default_gateway);\r
+ exit(1);\r
+ }\r
+\r
+ /* down the aliases in turn until ifconfig complains */\r
+ alias=0;\r
+ do\r
+ {\r
+ memset(command, 0, STRING_SIZE);\r
+ snprintf(command, STRING_SIZE-1, "/sbin/ifconfig %s:%d down 2>/dev/null", red_dev, alias++);\r
+ } while (safe_system(command)==0);\r
+\r
+ /* Now set up the new aliases from the config file */\r
+ if (!(file = fopen(CONFIG_ROOT "/ethernet/aliases", "r")))\r
+ {\r
+ fprintf(stderr, "Unable to open aliases configuration file\n");\r
+ exit(1);\r
+ }\r
+\r
+ alias=0;\r
+ int linecounter = 0;\r
+ while (fgets(s, STRING_SIZE, file) != NULL)\r
+ {\r
+ linecounter++;\r
+ if (s[strlen(s) - 1] == '\n')\r
+ s[strlen(s) - 1] = '\0';\r
+ count = 0;\r
+ aliasip = NULL;\r
+ enabled = NULL;\r
+ comment = NULL;\r
+ sptr = strtok(s, ",");\r
+ while (sptr)\r
+ {\r
+ if (count == 0)\r
+ aliasip = sptr;\r
+ if (count == 1)\r
+ enabled = sptr;\r
+ else\r
+ comment = sptr;\r
+ count++;\r
+ sptr = strtok(NULL, ",");\r
+ }\r
+\r
+ if (!(aliasip && enabled)) {\r
+ fprintf(stderr, "Incomplete data line: in %s(%d)\n",\r
+ CONFIG_ROOT "/ethernet/aliases",\r
+ linecounter);\r
+ exit(1);\r
+ }\r
+ if (!strcmp(enabled, "on") == 0) /* disabled rule? */\r
+ continue;\r
+\r
+ if (!VALID_IP(aliasip))\r
+ {\r
+ fprintf(stderr, "Bad alias : %s in %s(%d)\n",\r
+ aliasip,\r
+ CONFIG_ROOT "/ethernet/aliases",\r
+ linecounter);\r
+ exit(1);\r
+ }\r
+\r
+ memset(command, 0, STRING_SIZE);\r
+ snprintf(command, STRING_SIZE-1,\r
+ "/sbin/ifconfig %s:%d %s netmask %s broadcast %s up",\r
+ red_dev, alias, aliasip, red_netmask, red_broadcast);\r
+ safe_system(command);\r
+ memset(command, 0, STRING_SIZE);\r
+ snprintf(command, STRING_SIZE-1,\r
+ "/usr/sbin/arping -q -c 1 -w 1 -i %s -S %s %s",\r
+ red_dev, aliasip, default_gateway);\r
+ safe_system(command);\r
+ alias++;\r
+ }\r
+ return 0;\r
+}\r