]>
Commit | Line | Data |
---|---|---|
6f248ce1 TL |
1 | #include <stdio.h> |
2 | #include <stdlib.h> | |
3 | #include <string.h> | |
4 | #include <unistd.h> | |
5 | #include <sys/utsname.h> | |
6 | #include <sys/stat.h> | |
7 | #include <sys/types.h> | |
8 | #include <sys/stat.h> | |
9 | #include <fcntl.h> | |
10 | #include <arpa/inet.h> | |
11 | #include <err.h> | |
12 | ||
13 | #include "archcommon.h" | |
14 | ||
15 | bool _iface_has(const char *iface, const char *delims) { | |
16 | char _iface[80]; | |
17 | ||
18 | strncpy(_iface, iface, sizeof(_iface)); | |
19 | _iface[sizeof(_iface) - 1] = 0; | |
20 | strtok(_iface, delims); | |
21 | void *token = strtok(NULL, delims); | |
22 | ||
23 | return (token != NULL); | |
24 | } | |
25 | ||
26 | bool execable(const char *program) { | |
27 | struct stat buf; | |
28 | ||
29 | if (0 == stat(program, &buf)) | |
30 | if (S_ISREG(buf.st_mode) && (S_IXUSR & buf.st_mode)) | |
31 | return true; | |
32 | ||
33 | return false; | |
34 | } | |
35 | ||
36 | void cleanup_hwaddress(interface_defn *ifd, char **pparam, int argc, char **argv) { | |
37 | /* replace "random" with a random MAC address */ | |
38 | if (strcmp(*pparam, "random") == 0) { | |
39 | uint8_t mac[6]; | |
40 | int fd = open("/dev/urandom", O_RDONLY); | |
41 | if(!fd) { | |
42 | warn("/dev/urandom"); | |
43 | return; | |
44 | } | |
45 | if(read(fd, mac, sizeof mac) != sizeof mac) { | |
46 | warn("/dev/urandom"); | |
47 | return; | |
48 | } | |
49 | close(fd); | |
50 | mac[0] |= 0x2; // locally administered | |
51 | mac[0] &= ~0x1; // unicast | |
52 | *pparam = realloc(*pparam, 18); | |
53 | if (!*pparam) | |
54 | err(1, "realloc"); | |
55 | snprintf(*pparam, 18, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); | |
56 | return; | |
57 | } | |
58 | ||
59 | char *rest = *pparam; | |
60 | ||
61 | /* we're shrinking the text, so no realloc needed */ | |
62 | char *space = strchr(rest, ' '); | |
63 | if (space == NULL) | |
64 | return; | |
65 | *space = '\0'; | |
66 | ||
67 | if (strcasecmp(rest, "ether") == 0 || strcasecmp(rest, "ax25") == 0 || strcasecmp(rest, "ARCnet") == 0 || strcasecmp(rest, "netrom") == 0) | |
68 | /* found deprecated <class> attribute */ | |
69 | memmove(rest, space + 1, strlen(space + 1) + 1); | |
70 | else | |
71 | *space = ' '; | |
72 | } | |
73 | ||
74 | void make_hex_address(interface_defn *ifd, char **pparam, int argc, char **argv) { | |
75 | char addrcomp[4]; | |
76 | int maxlen = strlen("0000:0000"); | |
77 | ||
78 | int ret = sscanf(*pparam, "%3hhu.%3hhu.%3hhu.%3hhu", &addrcomp[0], &addrcomp[1], &addrcomp[2], &addrcomp[3]); | |
79 | if (ret != 4) | |
80 | return; | |
81 | ||
82 | *pparam = realloc(*pparam, maxlen + 1); | |
83 | if (*pparam == NULL) | |
84 | return; | |
85 | snprintf(*pparam, maxlen + 1, "%.2hhx%.2hhx:%.2hhx%.2hhx", addrcomp[0], addrcomp[1], addrcomp[2], addrcomp[3]); | |
86 | } | |
87 | ||
88 | void compute_v4_addr(interface_defn *ifd, char **pparam, int argc, char **argv) { | |
89 | char s[INET_ADDRSTRLEN * 2 + 2]; /* 2 is for slash and \0 */ | |
90 | ||
91 | strncpy(s, *pparam, sizeof(s)); | |
92 | s[sizeof(s) - 1] = 0; | |
93 | ||
94 | char *token = strtok(s, "/"); | |
95 | if (!token) | |
96 | return; | |
97 | ||
98 | *pparam = realloc(*pparam, strlen(token) + 1); | |
99 | if (*pparam == NULL) | |
100 | return; | |
101 | strcpy(*pparam, token); | |
102 | } | |
103 | ||
104 | void compute_v4_mask(interface_defn *ifd, char **pparam, int argc, char **argv) { | |
105 | char s[INET_ADDRSTRLEN * 2 + 2]; /* 2 is for slash and \0 */ | |
106 | ||
107 | strncpy(s, *pparam, sizeof(s)); | |
108 | s[sizeof(s) - 1] = 0; | |
109 | ||
110 | char *token = strtok(s, "/"); | |
111 | if (!token) | |
112 | return; | |
113 | ||
114 | uint8_t addr[sizeof(struct in_addr)]; | |
115 | struct in_addr mask; | |
116 | ||
117 | if (inet_pton(AF_INET, token, &addr) != 1) | |
118 | return; | |
119 | ||
120 | token = strtok(NULL, "/"); | |
121 | int maskwidth = -1; | |
122 | ||
123 | if (!token) { | |
124 | if (addr[0] <= 127) | |
125 | maskwidth = 8; | |
126 | else if ((addr[0] >= 128) && (addr[0] <= 191)) | |
127 | maskwidth = 16; | |
128 | else if ((addr[0] >= 192) && (addr[0] <= 223)) | |
129 | maskwidth = 24; | |
130 | else | |
131 | maskwidth = 32; | |
132 | } else { | |
133 | switch (inet_pton(AF_INET, token, &mask)) { | |
134 | case -1: | |
135 | return; | |
136 | ||
137 | case 0: | |
138 | if (sscanf(token, "%d", &maskwidth) != 1) | |
139 | return; | |
140 | } | |
141 | } | |
142 | ||
143 | if (maskwidth != -1) | |
144 | mask.s_addr = htonl(~((1L << (32 - maskwidth)) - 1)); | |
145 | ||
146 | if (inet_ntop(AF_INET, &mask, s, sizeof(s)) == NULL) | |
147 | return; | |
148 | ||
149 | *pparam = realloc(*pparam, strlen(s) + 1); | |
150 | if (*pparam == NULL) | |
151 | return; | |
152 | strcpy(*pparam, s); | |
153 | } | |
154 | ||
155 | void compute_v4_broadcast(interface_defn *ifd, char **pparam, int argc, char **argv) { | |
156 | /* If we don't get special value don't do anything */ | |
157 | if (strcmp(*pparam, "+") && strcmp(*pparam, "-")) | |
158 | return; | |
159 | ||
160 | struct in_addr addr; | |
161 | struct in_addr mask; | |
162 | ||
163 | char *s = get_var("address", strlen("address"), ifd); | |
164 | if (!s) | |
165 | return; | |
166 | ||
167 | int r = inet_pton(AF_INET, s, &addr); | |
168 | free(s); | |
169 | if (r != 1) | |
170 | return; | |
171 | ||
172 | s = get_var("netmask", strlen("netmask"), ifd); | |
173 | if (!s) | |
174 | return; | |
175 | ||
176 | r = inet_pton(AF_INET, s, &mask); | |
177 | free(s); | |
178 | if (r != 1) | |
179 | return; | |
180 | ||
181 | if (mask.s_addr != htonl(0xfffffffe)) { | |
182 | if (!strcmp(*pparam, "+")) | |
183 | addr.s_addr |= ~mask.s_addr; | |
184 | ||
185 | if (!strcmp(*pparam, "-")) | |
186 | addr.s_addr &= mask.s_addr; | |
187 | } else { | |
188 | if (!strcmp(*pparam, "+")) | |
189 | addr.s_addr = 0xffffffff; | |
190 | ||
191 | if (!strcmp(*pparam, "-")) | |
192 | addr.s_addr = 0; | |
193 | } | |
194 | ||
195 | char buffer[INET_ADDRSTRLEN + 1]; | |
196 | ||
197 | if (inet_ntop(AF_INET, &addr, buffer, sizeof(buffer)) == NULL) | |
198 | return; | |
199 | ||
200 | *pparam = realloc(*pparam, strlen(buffer) + 1); | |
201 | if (*pparam == NULL) | |
202 | return; | |
203 | strcpy(*pparam, buffer); | |
204 | } | |
205 | ||
206 | void set_preferred_lft(interface_defn *ifd, char **pparam, int argc, char **argv) { | |
207 | if (!ifd->real_iface) | |
208 | return; | |
209 | ||
210 | if (iface_has(":")) { | |
211 | char s[] = "0"; | |
212 | ||
213 | *pparam = realloc(*pparam, sizeof(s)); | |
214 | if (*pparam == NULL) | |
215 | return; | |
216 | strcpy(*pparam, s); | |
217 | } | |
218 | } | |
219 | ||
220 | void get_token(interface_defn *ifd, char **pparam, int argc, char **argv) { | |
221 | if (argc < 1) | |
222 | return; | |
223 | ||
224 | int token_no = 0; | |
225 | ||
226 | if (argc > 1) | |
227 | token_no = atoi(argv[1]); | |
228 | ||
229 | char *s = strdup(*pparam); | |
230 | char *token = strtok(s, argv[0]); | |
231 | ||
232 | while (token_no > 0) { | |
233 | token = strtok(NULL, argv[0]); | |
234 | token_no--; | |
235 | } | |
236 | ||
237 | if (token) { | |
238 | strcpy(*pparam, token); | |
239 | } else { | |
240 | if (argc == 3) { | |
241 | free(*pparam); | |
242 | *pparam = strdup(argv[2]); | |
243 | if (!*pparam) | |
244 | err(1, "strdup"); | |
245 | } | |
246 | } | |
247 | ||
248 | free(s); | |
249 | } | |
250 | ||
251 | void to_decimal(interface_defn *ifd, char **pparam, int argc, char **argv) { | |
252 | int base = 10; | |
253 | ||
254 | if (argc > 0) | |
255 | base = atoi(argv[0]); | |
256 | ||
257 | char *result; | |
258 | long value = strtol(*pparam, &result, base); | |
259 | ||
260 | if (result == *pparam) | |
261 | return; | |
262 | ||
263 | snprintf(*pparam, strlen(*pparam) + 1, "%ld", value); | |
264 | } | |
265 | ||
266 | void map_value(interface_defn *ifd, char **pparam, int argc, char **argv) { | |
267 | if (argc < 2) | |
268 | return; | |
269 | ||
270 | int value = (atoi(*pparam) || strcasecmp(*pparam, "on") == 0 || strcasecmp(*pparam, "true") == 0 || strcasecmp(*pparam, "yes") == 0); | |
271 | ||
272 | if ((value < argc) && (argv[value] != NULL)) { | |
273 | *pparam = realloc(*pparam, strlen(argv[value]) + 1); | |
274 | if (*pparam == NULL) | |
275 | return; | |
276 | strcpy(*pparam, argv[value]); | |
277 | } else { | |
278 | *pparam = realloc(*pparam, 1); | |
279 | if (*pparam == NULL) | |
280 | return; | |
281 | *pparam[0] = 0; | |
282 | } | |
283 | } | |
284 | ||
285 | void if_set(interface_defn *ifd, char **pparam, int argc, char **argv) { | |
286 | if (argc < 1) | |
287 | return; | |
288 | ||
289 | *pparam = realloc(*pparam, strlen(argv[0]) + 1); | |
290 | if (*pparam == NULL) | |
291 | return; | |
292 | strcpy(*pparam, argv[0]); | |
293 | } |