diff options
Diffstat (limited to 'networking/udhcp/script.c')
-rw-r--r-- | networking/udhcp/script.c | 59 |
1 files changed, 25 insertions, 34 deletions
diff --git a/networking/udhcp/script.c b/networking/udhcp/script.c index 48ff8e07e..41b680d6b 100644 --- a/networking/udhcp/script.c +++ b/networking/udhcp/script.c | |||
@@ -28,17 +28,15 @@ | |||
28 | #include <arpa/inet.h> | 28 | #include <arpa/inet.h> |
29 | #include <sys/types.h> | 29 | #include <sys/types.h> |
30 | #include <sys/wait.h> | 30 | #include <sys/wait.h> |
31 | #include <errno.h> | ||
32 | 31 | ||
33 | #include "options.h" | 32 | #include "options.h" |
34 | #include "dhcpd.h" | 33 | #include "dhcpd.h" |
35 | #include "dhcpc.h" | 34 | #include "dhcpc.h" |
36 | #include "packet.h" | ||
37 | #include "options.h" | 35 | #include "options.h" |
38 | #include "debug.h" | 36 | #include "common.h" |
39 | 37 | ||
40 | /* get a rough idea of how long an option will be (rounding up...) */ | 38 | /* get a rough idea of how long an option will be (rounding up...) */ |
41 | static int max_option_length[] = { | 39 | static const int max_option_length[] = { |
42 | [OPTION_IP] = sizeof("255.255.255.255 "), | 40 | [OPTION_IP] = sizeof("255.255.255.255 "), |
43 | [OPTION_IP_PAIR] = sizeof("255.255.255.255 ") * 2, | 41 | [OPTION_IP_PAIR] = sizeof("255.255.255.255 ") * 2, |
44 | [OPTION_STRING] = 1, | 42 | [OPTION_STRING] = 1, |
@@ -51,16 +49,21 @@ static int max_option_length[] = { | |||
51 | }; | 49 | }; |
52 | 50 | ||
53 | 51 | ||
54 | static int upper_length(int length, struct dhcp_option *option) | 52 | static inline int upper_length(int length, int opt_index) |
55 | { | 53 | { |
56 | return max_option_length[option->flags & TYPE_MASK] * | 54 | return max_option_length[opt_index] * |
57 | (length / option_lengths[option->flags & TYPE_MASK]); | 55 | (length / option_lengths[opt_index]); |
58 | } | 56 | } |
59 | 57 | ||
60 | 58 | ||
61 | static int sprintip(char *dest, char *pre, unsigned char *ip) | 59 | static int sprintip(char *dest, unsigned char *ip) |
62 | { | 60 | { |
63 | return sprintf(dest, "%s%d.%d.%d.%d", pre, ip[0], ip[1], ip[2], ip[3]); | 61 | return sprintf(dest, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); |
62 | } | ||
63 | |||
64 | static void asprintip(char **dest, char *pre, unsigned char *ip) | ||
65 | { | ||
66 | asprintf(dest, "%s%d.%d.%d.%d", pre, ip[0], ip[1], ip[2], ip[3]); | ||
64 | } | 67 | } |
65 | 68 | ||
66 | 69 | ||
@@ -93,12 +96,12 @@ static void fill_options(char *dest, unsigned char *option, struct dhcp_option * | |||
93 | for(;;) { | 96 | for(;;) { |
94 | switch (type) { | 97 | switch (type) { |
95 | case OPTION_IP_PAIR: | 98 | case OPTION_IP_PAIR: |
96 | dest += sprintip(dest, "", option); | 99 | dest += sprintip(dest, option); |
97 | *(dest++) = '/'; | 100 | *(dest++) = '/'; |
98 | option += 4; | 101 | option += 4; |
99 | optlen = 4; | 102 | optlen = 4; |
100 | case OPTION_IP: /* Works regardless of host byte order. */ | 103 | case OPTION_IP: /* Works regardless of host byte order. */ |
101 | dest += sprintip(dest, "", option); | 104 | dest += sprintip(dest, option); |
102 | break; | 105 | break; |
103 | case OPTION_BOOLEAN: | 106 | case OPTION_BOOLEAN: |
104 | dest += sprintf(dest, *option ? "yes" : "no"); | 107 | dest += sprintf(dest, *option ? "yes" : "no"); |
@@ -137,15 +140,10 @@ static void fill_options(char *dest, unsigned char *option, struct dhcp_option * | |||
137 | 140 | ||
138 | static char *find_env(const char *prefix, char *defaultstr) | 141 | static char *find_env(const char *prefix, char *defaultstr) |
139 | { | 142 | { |
140 | extern char **environ; | 143 | char *ptr; |
141 | char **ptr; | ||
142 | const int len = strlen(prefix); | ||
143 | 144 | ||
144 | for (ptr = environ; *ptr != NULL; ptr++) { | 145 | ptr = getenv(prefix); |
145 | if (strncmp(prefix, *ptr, len) == 0) | 146 | return ptr ? ptr : defaultstr; |
146 | return *ptr; | ||
147 | } | ||
148 | return defaultstr; | ||
149 | } | 147 | } |
150 | 148 | ||
151 | 149 | ||
@@ -174,8 +172,7 @@ static char **fill_envp(struct dhcpMessage *packet) | |||
174 | 172 | ||
175 | envp = xmalloc((num_options + 5) * sizeof(char *)); | 173 | envp = xmalloc((num_options + 5) * sizeof(char *)); |
176 | j = 0; | 174 | j = 0; |
177 | envp[j++] = xmalloc(sizeof("interface=") + strlen(client_config.interface)); | 175 | asprintf(&envp[j++], "interface=%s", client_config.interface); |
178 | sprintf(envp[0], "interface=%s", client_config.interface); | ||
179 | envp[j++] = find_env("PATH", "PATH=/bin:/usr/bin:/sbin:/usr/sbin"); | 176 | envp[j++] = find_env("PATH", "PATH=/bin:/usr/bin:/sbin:/usr/sbin"); |
180 | envp[j++] = find_env("HOME", "HOME=/"); | 177 | envp[j++] = find_env("HOME", "HOME=/"); |
181 | 178 | ||
@@ -184,38 +181,33 @@ static char **fill_envp(struct dhcpMessage *packet) | |||
184 | return envp; | 181 | return envp; |
185 | } | 182 | } |
186 | 183 | ||
187 | envp[j] = xmalloc(sizeof("ip=255.255.255.255")); | 184 | asprintip(&envp[j++], "ip=", (unsigned char *) &packet->yiaddr); |
188 | sprintip(envp[j++], "ip=", (unsigned char *) &packet->yiaddr); | ||
189 | 185 | ||
190 | 186 | ||
191 | for (i = 0; options[i].code; i++) { | 187 | for (i = 0; options[i].code; i++) { |
192 | if (!(temp = get_option(packet, options[i].code))) | 188 | if (!(temp = get_option(packet, options[i].code))) |
193 | continue; | 189 | continue; |
194 | envp[j] = xmalloc(upper_length(temp[OPT_LEN - 2], &options[i]) + strlen(options[i].name) + 2); | 190 | envp[j] = xmalloc(upper_length(temp[OPT_LEN - 2], options[i].flags & TYPE_MASK) + strlen(options[i].name) + 2); |
195 | fill_options(envp[j++], temp, &options[i]); | 191 | fill_options(envp[j++], temp, &options[i]); |
196 | 192 | ||
197 | /* Fill in a subnet bits option for things like /24 */ | 193 | /* Fill in a subnet bits option for things like /24 */ |
198 | if (options[i].code == DHCP_SUBNET) { | 194 | if (options[i].code == DHCP_SUBNET) { |
199 | envp[j] = xmalloc(sizeof("mask=32")); | ||
200 | memcpy(&subnet, temp, 4); | 195 | memcpy(&subnet, temp, 4); |
201 | sprintf(envp[j++], "mask=%d", mton(&subnet)); | 196 | asprintf(&envp[j++], "mask=%d", mton(&subnet)); |
202 | } | 197 | } |
203 | } | 198 | } |
204 | if (packet->siaddr) { | 199 | if (packet->siaddr) { |
205 | envp[j] = xmalloc(sizeof("siaddr=255.255.255.255")); | 200 | asprintip(&envp[j++], "siaddr=", (unsigned char *) &packet->siaddr); |
206 | sprintip(envp[j++], "siaddr=", (unsigned char *) &packet->siaddr); | ||
207 | } | 201 | } |
208 | if (!(over & FILE_FIELD) && packet->file[0]) { | 202 | if (!(over & FILE_FIELD) && packet->file[0]) { |
209 | /* watch out for invalid packets */ | 203 | /* watch out for invalid packets */ |
210 | packet->file[sizeof(packet->file) - 1] = '\0'; | 204 | packet->file[sizeof(packet->file) - 1] = '\0'; |
211 | envp[j] = xmalloc(sizeof("boot_file=") + strlen(packet->file)); | 205 | asprintf(&envp[j++], "boot_file=%s", packet->file); |
212 | sprintf(envp[j++], "boot_file=%s", packet->file); | ||
213 | } | 206 | } |
214 | if (!(over & SNAME_FIELD) && packet->sname[0]) { | 207 | if (!(over & SNAME_FIELD) && packet->sname[0]) { |
215 | /* watch out for invalid packets */ | 208 | /* watch out for invalid packets */ |
216 | packet->sname[sizeof(packet->sname) - 1] = '\0'; | 209 | packet->sname[sizeof(packet->sname) - 1] = '\0'; |
217 | envp[j] = xmalloc(sizeof("sname=") + strlen(packet->sname)); | 210 | asprintf(&envp[j++], "sname=%s", packet->sname); |
218 | sprintf(envp[j++], "sname=%s", packet->sname); | ||
219 | } | 211 | } |
220 | envp[j] = NULL; | 212 | envp[j] = NULL; |
221 | return envp; | 213 | return envp; |
@@ -245,8 +237,7 @@ void run_script(struct dhcpMessage *packet, const char *name) | |||
245 | DEBUG(LOG_INFO, "execle'ing %s", client_config.script); | 237 | DEBUG(LOG_INFO, "execle'ing %s", client_config.script); |
246 | execle(client_config.script, client_config.script, | 238 | execle(client_config.script, client_config.script, |
247 | name, NULL, envp); | 239 | name, NULL, envp); |
248 | LOG(LOG_ERR, "script %s failed: %s", | 240 | LOG(LOG_ERR, "script %s failed: %m", client_config.script); |
249 | client_config.script, strerror(errno)); | ||
250 | exit(1); | 241 | exit(1); |
251 | } | 242 | } |
252 | } | 243 | } |