Files
bpfire/src/misc-progs/setaliases.c
Michael Tremer cc826e8628 setaliases: Use "secondary" flag instead of scope
The scope option does not seem to work at all now, which is surprising
since I tested it quite well.

The secondary flag cannot be set from userspace (aparently), but it
works, so I would prefer to go with this option for now.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
2022-09-11 07:40:46 +00:00

193 lines
4.5 KiB
C

/*
* setaliases - configure red aliased interfaces
*
* This program is distributed under the terms of the GNU General Public
* Licence. See the file COPYING for details.
*
* (c) Steve Bootes, 2002/04/15
*
* 21/04/03 Robert Kerr Changed to link directly to libsmooth rather than
* using a copy & paste
*
* $Id: setaliases.c,v 1.2.2.5 2006/07/25 23:15:20 franck78 Exp $
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "libsmooth.h"
#include "setuid.h"
#include "netutil.h"
struct keyvalue *kv = NULL;
FILE *file = NULL;
void exithandler(void)
{
if (kv) freekeyvalues(kv);
if (file) fclose(file);
}
int main(void)
{
char s[STRING_SIZE];
char command[STRING_SIZE];
char red_netmask[STRING_SIZE];
char red_dev[STRING_SIZE];
char default_gateway[STRING_SIZE];
char *aliasip;
char *enabled;
char *sptr;
char *comment;
char* intf = NULL;
int alias;
int count;
if (!(initsetuid()))
{
fprintf(stderr, "Cannot run setuid\n");
exit(1);
}
atexit(exithandler);
/* Init the keyvalue structure */
kv=initkeyvalues();
/* Read in the current values */
if (!readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings"))
{
fprintf(stderr, "Cannot read ethernet settings\n");
exit(1);
}
/* Find the CONFIG_TYPE value */
if (!findkey(kv, "CONFIG_TYPE", s))
{
fprintf(stderr, "Cannot read CONFIG_TYPE\n");
exit(1);
}
/* Check for CONFIG_TYPE=2 or 3 i.e. RED ethernet present. If not,
* exit gracefully. This is not an error... */
if (!((strcmp(s, "1")==0) || (strcmp(s, "2")==0) || (strcmp(s, "3")==0) || (strcmp(s, "4")==0)))
exit(0);
/* Now check the RED_TYPE - aliases only work with STATIC.
* At least, that's what /etc/rc.d/rc.netaddress.up thinks.. */
/* Find the RED_TYPE value */
if (!findkey(kv, "RED_TYPE", s))
{
fprintf(stderr, "Cannot read RED_TYPE\n");
exit(1);
}
/* Make sure it's the right type */
if (!(strcmp(s, "STATIC")==0))
exit(0);
/* Get the RED interface details */
if((!findkey(kv, "RED_NETMASK", red_netmask)) ||
(!findkey(kv, "RED_DEV", red_dev)) || (!findkey(kv, "DEFAULT_GATEWAY", default_gateway)))
{
fprintf(stderr, "Cannot read RED settings\n");
exit(1);
}
if (!VALID_DEVICE(red_dev))
{
fprintf(stderr, "Bad red_dev: %s\n", red_dev);
exit(1);
}
if (!VALID_IP(red_netmask))
{
fprintf(stderr, "Bad red_netmask : %s\n", red_netmask);
exit(1);
}
if (!VALID_IP(default_gateway))
{
fprintf(stderr, "Bad default_gateway : %s\n", default_gateway);
exit(1);
}
// Flush all previous aliases
alias = 0;
do {
snprintf(command, STRING_SIZE - 1,
"ip addr flush secondary dev red%d 2>/dev/null", alias++);
} while (safe_system(command) == 0);
/* Now set up the new aliases from the config file */
if (!(file = fopen(CONFIG_ROOT "/ethernet/aliases", "r")))
{
fprintf(stderr, "Unable to open aliases configuration file\n");
exit(1);
}
alias=0;
int linecounter = 0;
while (fgets(s, STRING_SIZE, file) != NULL)
{
linecounter++;
if (s[strlen(s) - 1] == '\n')
s[strlen(s) - 1] = '\0';
count = 0;
aliasip = NULL;
enabled = NULL;
comment = NULL;
intf = NULL;
sptr = strtok(s, ",");
while (sptr)
{
if (count == 0)
aliasip = sptr;
else if (count == 1)
enabled = sptr;
else if (count == 2)
comment = sptr;
else if (count == 3)
intf = sptr;
count++;
sptr = strtok(NULL, ",");
}
if (!(aliasip && enabled)) {
fprintf(stderr, "Incomplete data line: in %s(%d)\n",
CONFIG_ROOT "/ethernet/aliases",
linecounter);
exit(1);
}
if (!strcmp(enabled, "on") == 0) /* disabled rule? */
continue;
if (!VALID_IP(aliasip))
{
fprintf(stderr, "Bad alias : %s in %s(%d)\n",
aliasip,
CONFIG_ROOT "/ethernet/aliases",
linecounter);
exit(1);
}
// Default to RED_DEV if intf isn't set
if (!intf)
intf = red_dev;
snprintf(command, STRING_SIZE - 1, "ip addr add %s/%s secondary dev %s 2>/dev/null",
aliasip, red_netmask, intf);
safe_system(command);
alias++;
}
return 0;
}