]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/misc-progs/setaliases.c
Merge branch 'master' of git://git.ipfire.org/ipfire-2.x
[people/teissler/ipfire-2.x.git] / src / misc-progs / setaliases.c
1 /*
2 * setaliases - configure red aliased interfaces
3 *
4 * This program is distributed under the terms of the GNU General Public
5 * Licence. See the file COPYING for details.
6 *
7 * (c) Steve Bootes, 2002/04/15
8 *
9 * 21/04/03 Robert Kerr Changed to link directly to libsmooth rather than
10 * using a copy & paste
11 *
12 * $Id: setaliases.c,v 1.2.2.5 2006/07/25 23:15:20 franck78 Exp $
13 *
14 */
15
16 #include "libsmooth.h"
17 #include "setuid.h"
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <unistd.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25
26 struct keyvalue *kv = NULL;
27 FILE *file = NULL;
28
29 void exithandler(void)
30 {
31 if (kv) freekeyvalues(kv);
32 if (file) fclose(file);
33 }
34
35 int main(void)
36 {
37 char s[STRING_SIZE];
38 char command[STRING_SIZE];
39 char red_netmask[STRING_SIZE];
40 char red_broadcast[STRING_SIZE];
41 char red_dev[STRING_SIZE];
42 char default_gateway[STRING_SIZE];
43 char *aliasip;
44 char *enabled;
45 char *sptr;
46 char *comment;
47 int alias;
48 int count;
49
50 if (!(initsetuid()))
51 {
52 fprintf(stderr, "Cannot run setuid\n");
53 exit(1);
54 }
55
56 atexit(exithandler);
57
58 /* Init the keyvalue structure */
59 kv=initkeyvalues();
60
61 /* Read in the current values */
62 if (!readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings"))
63 {
64 fprintf(stderr, "Cannot read ethernet settings\n");
65 exit(1);
66 }
67
68 /* Find the CONFIG_TYPE value */
69 if (!findkey(kv, "CONFIG_TYPE", s))
70 {
71 fprintf(stderr, "Cannot read CONFIG_TYPE\n");
72 exit(1);
73 }
74
75 /* Check for CONFIG_TYPE=2 or 3 i.e. RED ethernet present. If not,
76 * exit gracefully. This is not an error... */
77 if (!((strcmp(s, "1")==0) || (strcmp(s, "2")==0) || (strcmp(s, "3")==0) || (strcmp(s, "4")==0)))
78 exit(0);
79
80 /* Now check the RED_TYPE - aliases only work with STATIC.
81 * At least, that's what /etc/rc.d/rc.netaddress.up thinks.. */
82
83 /* Find the RED_TYPE value */
84 if (!findkey(kv, "RED_TYPE", s))
85 {
86 fprintf(stderr, "Cannot read RED_TYPE\n");
87 exit(1);
88 }
89
90 /* Make sure it's the right type */
91 if (!(strcmp(s, "STATIC")==0))
92 exit(0);
93
94 /* Get the RED interface details */
95 if((!findkey(kv, "RED_NETMASK", red_netmask)) || (!findkey(kv, "RED_BROADCAST", red_broadcast)) ||
96 (!findkey(kv, "RED_DEV", red_dev)) || (!findkey(kv, "DEFAULT_GATEWAY", default_gateway)))
97 {
98 fprintf(stderr, "Cannot read RED settings\n");
99 exit(1);
100 }
101
102 if (!VALID_DEVICE(red_dev))
103 {
104 fprintf(stderr, "Bad red_dev: %s\n", red_dev);
105 exit(1);
106 }
107
108 if (!VALID_IP(red_netmask))
109 {
110 fprintf(stderr, "Bad red_netmask : %s\n", red_netmask);
111 exit(1);
112 }
113
114 if (!VALID_IP(red_broadcast))
115 {
116 fprintf(stderr, "Bad red_broadcast : %s\n", red_broadcast);
117 exit(1);
118 }
119
120 if (!VALID_IP(default_gateway))
121 {
122 fprintf(stderr, "Bad default_gateway : %s\n", default_gateway);
123 exit(1);
124 }
125
126 /* down the aliases in turn until ifconfig complains */
127 alias=0;
128 do
129 {
130 memset(command, 0, STRING_SIZE);
131 snprintf(command, STRING_SIZE-1, "/sbin/ifconfig %s:%d down 2>/dev/null", red_dev, alias++);
132 } while (safe_system(command)==0);
133
134 /* Now set up the new aliases from the config file */
135 if (!(file = fopen(CONFIG_ROOT "/ethernet/aliases", "r")))
136 {
137 fprintf(stderr, "Unable to open aliases configuration file\n");
138 exit(1);
139 }
140
141 alias=0;
142 int linecounter = 0;
143 while (fgets(s, STRING_SIZE, file) != NULL)
144 {
145 linecounter++;
146 if (s[strlen(s) - 1] == '\n')
147 s[strlen(s) - 1] = '\0';
148 count = 0;
149 aliasip = NULL;
150 enabled = NULL;
151 comment = NULL;
152 sptr = strtok(s, ",");
153 while (sptr)
154 {
155 if (count == 0)
156 aliasip = sptr;
157 if (count == 1)
158 enabled = sptr;
159 else
160 comment = sptr;
161 count++;
162 sptr = strtok(NULL, ",");
163 }
164
165 if (!(aliasip && enabled)) {
166 fprintf(stderr, "Incomplete data line: in %s(%d)\n",
167 CONFIG_ROOT "/ethernet/aliases",
168 linecounter);
169 exit(1);
170 }
171 if (!strcmp(enabled, "on") == 0) /* disabled rule? */
172 continue;
173
174 if (!VALID_IP(aliasip))
175 {
176 fprintf(stderr, "Bad alias : %s in %s(%d)\n",
177 aliasip,
178 CONFIG_ROOT "/ethernet/aliases",
179 linecounter);
180 exit(1);
181 }
182
183 memset(command, 0, STRING_SIZE);
184 snprintf(command, STRING_SIZE-1,
185 "/sbin/ifconfig %s:%d %s netmask %s broadcast %s up",
186 red_dev, alias, aliasip, red_netmask, red_broadcast);
187 safe_system(command);
188 memset(command, 0, STRING_SIZE);
189 snprintf(command, STRING_SIZE-1,
190 "/usr/sbin/arping -q -c 1 -w 1 -i %s -S %s %s",
191 red_dev, aliasip, default_gateway);
192 safe_system(command);
193 alias++;
194 }
195 return 0;
196 }