]>
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]; | |
42 | char red_broadcast[STRING_SIZE]; | |
43 | char red_dev[STRING_SIZE]; | |
44 | char default_gateway[STRING_SIZE]; | |
45 | char *aliasip; | |
46 | char *enabled; | |
47 | char *sptr; | |
48 | char *comment; | |
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 | } | |
91 | ||
92 | /* Make sure it's the right type */ | |
93 | if (!(strcmp(s, "STATIC")==0)) | |
94 | exit(0); | |
95 | ||
96 | /* Get the RED interface details */ | |
97 | if((!findkey(kv, "RED_NETMASK", red_netmask)) || (!findkey(kv, "RED_BROADCAST", red_broadcast)) || | |
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 | } | |
103 | ||
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 | ||
116 | if (!VALID_IP(red_broadcast)) | |
117 | { | |
118 | fprintf(stderr, "Bad red_broadcast : %s\n", red_broadcast); | |
119 | exit(1); | |
120 | } | |
121 | ||
122 | if (!VALID_IP(default_gateway)) | |
123 | { | |
124 | fprintf(stderr, "Bad default_gateway : %s\n", default_gateway); | |
125 | exit(1); | |
126 | } | |
127 | ||
128 | /* down the aliases in turn until ifconfig complains */ | |
129 | alias=0; | |
130 | do | |
131 | { | |
132 | memset(command, 0, STRING_SIZE); | |
133 | snprintf(command, STRING_SIZE-1, "/sbin/ifconfig %s:%d down 2>/dev/null", red_dev, alias++); | |
134 | } while (safe_system(command)==0); | |
135 | ||
136 | /* Now set up the new aliases from the config file */ | |
137 | if (!(file = fopen(CONFIG_ROOT "/ethernet/aliases", "r"))) | |
138 | { | |
139 | fprintf(stderr, "Unable to open aliases configuration file\n"); | |
140 | exit(1); | |
141 | } | |
142 | ||
143 | alias=0; | |
144 | int linecounter = 0; | |
145 | while (fgets(s, STRING_SIZE, file) != NULL) | |
146 | { | |
147 | linecounter++; | |
148 | if (s[strlen(s) - 1] == '\n') | |
149 | s[strlen(s) - 1] = '\0'; | |
150 | count = 0; | |
151 | aliasip = NULL; | |
152 | enabled = NULL; | |
153 | comment = NULL; | |
154 | sptr = strtok(s, ","); | |
155 | while (sptr) | |
156 | { | |
157 | if (count == 0) | |
158 | aliasip = sptr; | |
159 | if (count == 1) | |
160 | enabled = sptr; | |
161 | else | |
162 | comment = sptr; | |
163 | count++; | |
164 | sptr = strtok(NULL, ","); | |
165 | } | |
166 | ||
167 | if (!(aliasip && enabled)) { | |
168 | fprintf(stderr, "Incomplete data line: in %s(%d)\n", | |
169 | CONFIG_ROOT "/ethernet/aliases", | |
170 | linecounter); | |
171 | exit(1); | |
172 | } | |
173 | if (!strcmp(enabled, "on") == 0) /* disabled rule? */ | |
174 | continue; | |
175 | ||
176 | if (!VALID_IP(aliasip)) | |
177 | { | |
178 | fprintf(stderr, "Bad alias : %s in %s(%d)\n", | |
179 | aliasip, | |
180 | CONFIG_ROOT "/ethernet/aliases", | |
181 | linecounter); | |
182 | exit(1); | |
183 | } | |
184 | ||
185 | memset(command, 0, STRING_SIZE); | |
186 | snprintf(command, STRING_SIZE-1, | |
187 | "/sbin/ifconfig %s:%d %s netmask %s broadcast %s up", | |
188 | red_dev, alias, aliasip, red_netmask, red_broadcast); | |
189 | safe_system(command); | |
190 | memset(command, 0, STRING_SIZE); | |
191 | snprintf(command, STRING_SIZE-1, | |
192 | "/usr/sbin/arping -q -c 1 -w 1 -i %s -S %s %s", | |
193 | red_dev, aliasip, default_gateway); | |
194 | safe_system(command); | |
195 | alias++; | |
196 | } | |
197 | return 0; | |
198 | } |