]>
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 | ||
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 | } |