]>
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; | |
48 | int alias; | |
49 | int count; | |
50 | ||
51 | if (!(initsetuid())) | |
52 | { | |
53 | fprintf(stderr, "Cannot run setuid\n"); | |
54 | exit(1); | |
55 | } | |
56 | ||
57 | atexit(exithandler); | |
58 | ||
59 | /* Init the keyvalue structure */ | |
60 | kv=initkeyvalues(); | |
61 | ||
62 | /* Read in the current values */ | |
63 | if (!readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings")) | |
64 | { | |
65 | fprintf(stderr, "Cannot read ethernet settings\n"); | |
66 | exit(1); | |
67 | } | |
68 | ||
69 | /* Find the CONFIG_TYPE value */ | |
70 | if (!findkey(kv, "CONFIG_TYPE", s)) | |
71 | { | |
72 | fprintf(stderr, "Cannot read CONFIG_TYPE\n"); | |
73 | exit(1); | |
74 | } | |
75 | ||
76 | /* Check for CONFIG_TYPE=2 or 3 i.e. RED ethernet present. If not, | |
77 | * exit gracefully. This is not an error... */ | |
78 | if (!((strcmp(s, "1")==0) || (strcmp(s, "2")==0) || (strcmp(s, "3")==0) || (strcmp(s, "4")==0))) | |
79 | exit(0); | |
80 | ||
81 | /* Now check the RED_TYPE - aliases only work with STATIC. | |
82 | * At least, that's what /etc/rc.d/rc.netaddress.up thinks.. */ | |
83 | ||
84 | /* Find the RED_TYPE value */ | |
85 | if (!findkey(kv, "RED_TYPE", s)) | |
86 | { | |
87 | fprintf(stderr, "Cannot read RED_TYPE\n"); | |
88 | exit(1); | |
89 | } | |
90 | ||
91 | /* Make sure it's the right type */ | |
92 | if (!(strcmp(s, "STATIC")==0)) | |
93 | exit(0); | |
94 | ||
95 | /* Get the RED interface details */ | |
b67f02d5 | 96 | if((!findkey(kv, "RED_NETMASK", red_netmask)) || |
28b7d78a CS |
97 | (!findkey(kv, "RED_DEV", red_dev)) || (!findkey(kv, "DEFAULT_GATEWAY", default_gateway))) |
98 | { | |
99 | fprintf(stderr, "Cannot read RED settings\n"); | |
100 | exit(1); | |
101 | } | |
102 | ||
103 | if (!VALID_DEVICE(red_dev)) | |
104 | { | |
105 | fprintf(stderr, "Bad red_dev: %s\n", red_dev); | |
106 | exit(1); | |
107 | } | |
108 | ||
109 | if (!VALID_IP(red_netmask)) | |
110 | { | |
111 | fprintf(stderr, "Bad red_netmask : %s\n", red_netmask); | |
112 | exit(1); | |
113 | } | |
114 | ||
28b7d78a CS |
115 | if (!VALID_IP(default_gateway)) |
116 | { | |
117 | fprintf(stderr, "Bad default_gateway : %s\n", default_gateway); | |
118 | exit(1); | |
119 | } | |
120 | ||
121 | /* down the aliases in turn until ifconfig complains */ | |
122 | alias=0; | |
123 | do | |
124 | { | |
125 | memset(command, 0, STRING_SIZE); | |
126 | snprintf(command, STRING_SIZE-1, "/sbin/ifconfig %s:%d down 2>/dev/null", red_dev, alias++); | |
127 | } while (safe_system(command)==0); | |
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; | |
147 | sptr = strtok(s, ","); | |
148 | while (sptr) | |
149 | { | |
150 | if (count == 0) | |
151 | aliasip = sptr; | |
152 | if (count == 1) | |
153 | enabled = sptr; | |
154 | else | |
155 | comment = sptr; | |
156 | count++; | |
157 | sptr = strtok(NULL, ","); | |
158 | } | |
159 | ||
160 | if (!(aliasip && enabled)) { | |
161 | fprintf(stderr, "Incomplete data line: in %s(%d)\n", | |
162 | CONFIG_ROOT "/ethernet/aliases", | |
163 | linecounter); | |
164 | exit(1); | |
165 | } | |
166 | if (!strcmp(enabled, "on") == 0) /* disabled rule? */ | |
167 | continue; | |
168 | ||
169 | if (!VALID_IP(aliasip)) | |
170 | { | |
171 | fprintf(stderr, "Bad alias : %s in %s(%d)\n", | |
172 | aliasip, | |
173 | CONFIG_ROOT "/ethernet/aliases", | |
174 | linecounter); | |
175 | exit(1); | |
176 | } | |
177 | ||
178 | memset(command, 0, STRING_SIZE); | |
179 | snprintf(command, STRING_SIZE-1, | |
b67f02d5 MT |
180 | "/sbin/ifconfig %s:%d %s netmask %s up", |
181 | red_dev, alias, aliasip, red_netmask); | |
28b7d78a CS |
182 | safe_system(command); |
183 | memset(command, 0, STRING_SIZE); | |
184 | snprintf(command, STRING_SIZE-1, | |
185 | "/usr/sbin/arping -q -c 1 -w 1 -i %s -S %s %s", | |
186 | red_dev, aliasip, default_gateway); | |
187 | safe_system(command); | |
188 | alias++; | |
189 | } | |
190 | return 0; | |
191 | } |