]>
Commit | Line | Data |
---|---|---|
28b7d78a CS |
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 | ||
28b7d78a CS |
16 | #include <stdio.h> |
17 | #include <stdlib.h> | |
18 | #include <string.h> | |
19 | #include <unistd.h> | |
20 | #include <sys/types.h> | |
21 | #include <sys/stat.h> | |
22 | #include <fcntl.h> | |
23 | ||
52e54c1c MT |
24 | #include "libsmooth.h" |
25 | #include "setuid.h" | |
26 | #include "netutil.h" | |
27 | ||
28b7d78a CS |
28 | struct keyvalue *kv = NULL; |
29 | FILE *file = NULL; | |
30 | ||
31 | void exithandler(void) | |
32 | { | |
33 | if (kv) freekeyvalues(kv); | |
34 | if (file) fclose(file); | |
35 | } | |
36 | ||
37 | int main(void) | |
38 | { | |
39 | char s[STRING_SIZE]; | |
40 | char command[STRING_SIZE]; | |
41 | char red_netmask[STRING_SIZE]; | |
28b7d78a CS |
42 | char red_dev[STRING_SIZE]; |
43 | char default_gateway[STRING_SIZE]; | |
44 | char *aliasip; | |
45 | char *enabled; | |
46 | char *sptr; | |
47 | char *comment; | |
6395bed8 | 48 | char* intf = NULL; |
28b7d78a CS |
49 | int alias; |
50 | int count; | |
51 | ||
52 | if (!(initsetuid())) | |
53 | { | |
54 | fprintf(stderr, "Cannot run setuid\n"); | |
55 | exit(1); | |
56 | } | |
57 | ||
58 | atexit(exithandler); | |
59 | ||
60 | /* Init the keyvalue structure */ | |
61 | kv=initkeyvalues(); | |
62 | ||
63 | /* Read in the current values */ | |
64 | if (!readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings")) | |
65 | { | |
66 | fprintf(stderr, "Cannot read ethernet settings\n"); | |
67 | exit(1); | |
68 | } | |
69 | ||
70 | /* Find the CONFIG_TYPE value */ | |
71 | if (!findkey(kv, "CONFIG_TYPE", s)) | |
72 | { | |
73 | fprintf(stderr, "Cannot read CONFIG_TYPE\n"); | |
74 | exit(1); | |
75 | } | |
76 | ||
77 | /* Check for CONFIG_TYPE=2 or 3 i.e. RED ethernet present. If not, | |
78 | * exit gracefully. This is not an error... */ | |
79 | if (!((strcmp(s, "1")==0) || (strcmp(s, "2")==0) || (strcmp(s, "3")==0) || (strcmp(s, "4")==0))) | |
80 | exit(0); | |
81 | ||
82 | /* Now check the RED_TYPE - aliases only work with STATIC. | |
83 | * At least, that's what /etc/rc.d/rc.netaddress.up thinks.. */ | |
84 | ||
85 | /* Find the RED_TYPE value */ | |
86 | if (!findkey(kv, "RED_TYPE", s)) | |
87 | { | |
88 | fprintf(stderr, "Cannot read RED_TYPE\n"); | |
89 | exit(1); | |
90 | } | |
66c36198 | 91 | |
28b7d78a | 92 | /* Make sure it's the right type */ |
66c36198 | 93 | if (!(strcmp(s, "STATIC")==0)) |
28b7d78a CS |
94 | exit(0); |
95 | ||
96 | /* Get the RED interface details */ | |
b67f02d5 | 97 | if((!findkey(kv, "RED_NETMASK", red_netmask)) || |
28b7d78a CS |
98 | (!findkey(kv, "RED_DEV", red_dev)) || (!findkey(kv, "DEFAULT_GATEWAY", default_gateway))) |
99 | { | |
100 | fprintf(stderr, "Cannot read RED settings\n"); | |
101 | exit(1); | |
102 | } | |
66c36198 | 103 | |
28b7d78a CS |
104 | if (!VALID_DEVICE(red_dev)) |
105 | { | |
106 | fprintf(stderr, "Bad red_dev: %s\n", red_dev); | |
107 | exit(1); | |
108 | } | |
109 | ||
110 | if (!VALID_IP(red_netmask)) | |
111 | { | |
112 | fprintf(stderr, "Bad red_netmask : %s\n", red_netmask); | |
113 | exit(1); | |
114 | } | |
115 | ||
28b7d78a CS |
116 | if (!VALID_IP(default_gateway)) |
117 | { | |
118 | fprintf(stderr, "Bad default_gateway : %s\n", default_gateway); | |
119 | exit(1); | |
120 | } | |
121 | ||
6395bed8 MT |
122 | // Flush all previous aliases |
123 | alias = 0; | |
124 | do { | |
125 | snprintf(command, STRING_SIZE - 1, | |
cc826e86 | 126 | "ip addr flush secondary dev red%d 2>/dev/null", alias++); |
6395bed8 | 127 | } while (safe_system(command) == 0); |
28b7d78a CS |
128 | |
129 | /* Now set up the new aliases from the config file */ | |
130 | if (!(file = fopen(CONFIG_ROOT "/ethernet/aliases", "r"))) | |
131 | { | |
132 | fprintf(stderr, "Unable to open aliases configuration file\n"); | |
133 | exit(1); | |
134 | } | |
135 | ||
136 | alias=0; | |
137 | int linecounter = 0; | |
138 | while (fgets(s, STRING_SIZE, file) != NULL) | |
139 | { | |
140 | linecounter++; | |
141 | if (s[strlen(s) - 1] == '\n') | |
142 | s[strlen(s) - 1] = '\0'; | |
143 | count = 0; | |
144 | aliasip = NULL; | |
145 | enabled = NULL; | |
146 | comment = NULL; | |
6395bed8 | 147 | intf = NULL; |
28b7d78a CS |
148 | sptr = strtok(s, ","); |
149 | while (sptr) | |
150 | { | |
151 | if (count == 0) | |
152 | aliasip = sptr; | |
6395bed8 | 153 | else if (count == 1) |
28b7d78a | 154 | enabled = sptr; |
6395bed8 | 155 | else if (count == 2) |
28b7d78a | 156 | comment = sptr; |
6395bed8 MT |
157 | else if (count == 3) |
158 | intf = sptr; | |
28b7d78a CS |
159 | count++; |
160 | sptr = strtok(NULL, ","); | |
161 | } | |
162 | ||
163 | if (!(aliasip && enabled)) { | |
164 | fprintf(stderr, "Incomplete data line: in %s(%d)\n", | |
165 | CONFIG_ROOT "/ethernet/aliases", | |
166 | linecounter); | |
167 | exit(1); | |
168 | } | |
169 | if (!strcmp(enabled, "on") == 0) /* disabled rule? */ | |
170 | continue; | |
171 | ||
172 | if (!VALID_IP(aliasip)) | |
173 | { | |
174 | fprintf(stderr, "Bad alias : %s in %s(%d)\n", | |
175 | aliasip, | |
176 | CONFIG_ROOT "/ethernet/aliases", | |
177 | linecounter); | |
178 | exit(1); | |
179 | } | |
180 | ||
6395bed8 MT |
181 | // Default to RED_DEV if intf isn't set |
182 | if (!intf) | |
183 | intf = red_dev; | |
184 | ||
cc826e86 MT |
185 | snprintf(command, STRING_SIZE - 1, "ip addr add %s/%s secondary dev %s 2>/dev/null", |
186 | aliasip, red_netmask, intf); | |
28b7d78a | 187 | safe_system(command); |
6395bed8 | 188 | |
28b7d78a CS |
189 | alias++; |
190 | } | |
191 | return 0; | |
192 | } |