diff options
Diffstat (limited to 'networking/udhcp/script.c')
-rw-r--r-- | networking/udhcp/script.c | 99 |
1 files changed, 39 insertions, 60 deletions
diff --git a/networking/udhcp/script.c b/networking/udhcp/script.c index 1c6f1bd33..2eb4459dd 100644 --- a/networking/udhcp/script.c +++ b/networking/udhcp/script.c | |||
@@ -37,8 +37,6 @@ | |||
37 | #include "options.h" | 37 | #include "options.h" |
38 | #include "debug.h" | 38 | #include "debug.h" |
39 | 39 | ||
40 | #include "config.h" | ||
41 | |||
42 | /* get a rough idea of how long an option will be (rounding up...) */ | 40 | /* get a rough idea of how long an option will be (rounding up...) */ |
43 | static int max_option_length[] = { | 41 | static int max_option_length[] = { |
44 | [OPTION_IP] = sizeof("255.255.255.255 "), | 42 | [OPTION_IP] = sizeof("255.255.255.255 "), |
@@ -60,41 +58,22 @@ static int upper_length(int length, struct dhcp_option *option) | |||
60 | } | 58 | } |
61 | 59 | ||
62 | 60 | ||
63 | static int sprintip(char *dest, char *pre, unsigned char *ip) { | 61 | static int sprintip(char *dest, char *pre, unsigned char *ip) |
64 | return sprintf(dest, "%s%d.%d.%d.%d ", pre, ip[0], ip[1], ip[2], ip[3]); | ||
65 | } | ||
66 | |||
67 | #ifdef CONFIG_FEATURE_UDHCPC_IP | ||
68 | /* convert a netmask (255.255.255.0) into the length (24) */ | ||
69 | static int inet_ntom (const char *src, short *dst) | ||
70 | { | 62 | { |
71 | in_addr_t mask, num; | 63 | return sprintf(dest, "%s%d.%d.%d.%d", pre, ip[0], ip[1], ip[2], ip[3]); |
72 | 64 | } | |
73 | mask = ntohl(*(unsigned int *)src); | ||
74 | |||
75 | for (num = mask; num & 1; num >>= 1); | ||
76 | |||
77 | if (num != 0 && mask != 0) | ||
78 | { | ||
79 | for (num = ~mask; num & 1; num >>= 1); | ||
80 | if (num) | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | for (num = 0; mask; mask <<= 1) | ||
85 | num++; | ||
86 | 65 | ||
87 | *dst = num; | ||
88 | 66 | ||
89 | return 1; | 67 | /* really simple implementation, just count the bits */ |
68 | static int mton(struct in_addr *mask) | ||
69 | { | ||
70 | int i; | ||
71 | /* note: mask will always be in network byte order, so | ||
72 | * there are no endian issues */ | ||
73 | for (i = 31; i >= 0 && !((mask->s_addr >> i) & 1); i--); | ||
74 | return i + 1; | ||
90 | } | 75 | } |
91 | 76 | ||
92 | static int sprintprefix(char *dest, char *pre, unsigned char *ip) { | ||
93 | short sdest = 0; | ||
94 | inet_ntom(ip, &sdest); | ||
95 | return sprintf(dest, "%s%hd ", pre, sdest); | ||
96 | } | ||
97 | #endif | ||
98 | 77 | ||
99 | /* Fill dest with the text of option 'option'. */ | 78 | /* Fill dest with the text of option 'option'. */ |
100 | static void fill_options(char *dest, unsigned char *option, struct dhcp_option *type_p) | 79 | static void fill_options(char *dest, unsigned char *option, struct dhcp_option *type_p) |
@@ -117,41 +96,30 @@ static void fill_options(char *dest, unsigned char *option, struct dhcp_option * | |||
117 | *(dest++) = '/'; | 96 | *(dest++) = '/'; |
118 | option += 4; | 97 | option += 4; |
119 | optlen = 4; | 98 | optlen = 4; |
120 | #ifndef CONFIG_FEATURE_UDHCPC_IP | ||
121 | case OPTION_IP: /* Works regardless of host byte order. */ | 99 | case OPTION_IP: /* Works regardless of host byte order. */ |
122 | #endif | ||
123 | dest += sprintip(dest, "", option); | 100 | dest += sprintip(dest, "", option); |
124 | break; | 101 | break; |
125 | #ifdef CONFIG_FEATURE_UDHCPC_IP | ||
126 | case OPTION_IP: /* Works regardless of host byte order. */ | ||
127 | if (type_p->flags & OPTION_PREFIX) { | ||
128 | dest += sprintprefix(dest, "", option); | ||
129 | } else { | ||
130 | dest += sprintip(dest, "", option); | ||
131 | } | ||
132 | break; | ||
133 | #endif | ||
134 | case OPTION_BOOLEAN: | 102 | case OPTION_BOOLEAN: |
135 | dest += sprintf(dest, *option ? "yes " : "no "); | 103 | dest += sprintf(dest, *option ? "yes" : "no"); |
136 | break; | 104 | break; |
137 | case OPTION_U8: | 105 | case OPTION_U8: |
138 | dest += sprintf(dest, "%u ", *option); | 106 | dest += sprintf(dest, "%u", *option); |
139 | break; | 107 | break; |
140 | case OPTION_U16: | 108 | case OPTION_U16: |
141 | memcpy(&val_u16, option, 2); | 109 | memcpy(&val_u16, option, 2); |
142 | dest += sprintf(dest, "%u ", ntohs(val_u16)); | 110 | dest += sprintf(dest, "%u", ntohs(val_u16)); |
143 | break; | 111 | break; |
144 | case OPTION_S16: | 112 | case OPTION_S16: |
145 | memcpy(&val_s16, option, 2); | 113 | memcpy(&val_s16, option, 2); |
146 | dest += sprintf(dest, "%d ", ntohs(val_s16)); | 114 | dest += sprintf(dest, "%d", ntohs(val_s16)); |
147 | break; | 115 | break; |
148 | case OPTION_U32: | 116 | case OPTION_U32: |
149 | memcpy(&val_u32, option, 4); | 117 | memcpy(&val_u32, option, 4); |
150 | dest += sprintf(dest, "%lu ", (unsigned long) ntohl(val_u32)); | 118 | dest += sprintf(dest, "%lu", (unsigned long) ntohl(val_u32)); |
151 | break; | 119 | break; |
152 | case OPTION_S32: | 120 | case OPTION_S32: |
153 | memcpy(&val_s32, option, 4); | 121 | memcpy(&val_s32, option, 4); |
154 | dest += sprintf(dest, "%ld ", (long) ntohl(val_s32)); | 122 | dest += sprintf(dest, "%ld", (long) ntohl(val_s32)); |
155 | break; | 123 | break; |
156 | case OPTION_STRING: | 124 | case OPTION_STRING: |
157 | memcpy(dest, option, len); | 125 | memcpy(dest, option, len); |
@@ -161,6 +129,7 @@ static void fill_options(char *dest, unsigned char *option, struct dhcp_option * | |||
161 | option += optlen; | 129 | option += optlen; |
162 | len -= optlen; | 130 | len -= optlen; |
163 | if (len <= 0) break; | 131 | if (len <= 0) break; |
132 | dest += sprintf(dest, " "); | ||
164 | } | 133 | } |
165 | } | 134 | } |
166 | 135 | ||
@@ -186,6 +155,7 @@ static char **fill_envp(struct dhcpMessage *packet) | |||
186 | int i, j; | 155 | int i, j; |
187 | char **envp; | 156 | char **envp; |
188 | unsigned char *temp; | 157 | unsigned char *temp; |
158 | struct in_addr subnet; | ||
189 | char over = 0; | 159 | char over = 0; |
190 | 160 | ||
191 | if (packet == NULL) | 161 | if (packet == NULL) |
@@ -202,23 +172,32 @@ static char **fill_envp(struct dhcpMessage *packet) | |||
202 | } | 172 | } |
203 | 173 | ||
204 | envp = xmalloc((num_options + 5) * sizeof(char *)); | 174 | envp = xmalloc((num_options + 5) * sizeof(char *)); |
205 | envp[0] = xmalloc(sizeof("interface=") + strlen(client_config.interface)); | 175 | j = 0; |
176 | envp[j++] = xmalloc(sizeof("interface=") + strlen(client_config.interface)); | ||
206 | sprintf(envp[0], "interface=%s", client_config.interface); | 177 | sprintf(envp[0], "interface=%s", client_config.interface); |
207 | envp[1] = find_env("PATH", "PATH=/bin:/usr/bin:/sbin:/usr/sbin"); | 178 | envp[j++] = find_env("PATH", "PATH=/bin:/usr/bin:/sbin:/usr/sbin"); |
208 | envp[2] = find_env("HOME", "HOME=/"); | 179 | envp[j++] = find_env("HOME", "HOME=/"); |
209 | 180 | ||
210 | if (packet == NULL) { | 181 | if (packet == NULL) { |
211 | envp[3] = NULL; | 182 | envp[j++] = NULL; |
212 | return envp; | 183 | return envp; |
213 | } | 184 | } |
214 | 185 | ||
215 | envp[3] = xmalloc(sizeof("ip=255.255.255.255")); | 186 | envp[j] = xmalloc(sizeof("ip=255.255.255.255")); |
216 | sprintip(envp[3], "ip=", (unsigned char *) &packet->yiaddr); | 187 | sprintip(envp[j++], "ip=", (unsigned char *) &packet->yiaddr); |
217 | for (i = 0, j = 4; options[i].code; i++) { | 188 | |
218 | if ((temp = get_option(packet, options[i].code))) { | 189 | |
219 | envp[j] = xmalloc(upper_length(temp[OPT_LEN - 2], &options[i]) + strlen(options[i].name) + 2); | 190 | for (i = 0; options[i].code; i++) { |
220 | fill_options(envp[j], temp, &options[i]); | 191 | if (!(temp = get_option(packet, options[i].code))) |
221 | j++; | 192 | continue; |
193 | envp[j] = xmalloc(upper_length(temp[OPT_LEN - 2], &options[i]) + strlen(options[i].name) + 2); | ||
194 | fill_options(envp[j++], temp, &options[i]); | ||
195 | |||
196 | /* Fill in a subnet bits option for things like /24 */ | ||
197 | if (options[i].code == DHCP_SUBNET) { | ||
198 | envp[j] = xmalloc(sizeof("mask=32")); | ||
199 | memcpy(&subnet, temp, 4); | ||
200 | sprintf(envp[j++], "mask=%d", mton(&subnet)); | ||
222 | } | 201 | } |
223 | } | 202 | } |
224 | if (packet->siaddr) { | 203 | if (packet->siaddr) { |