diff options
-rw-r--r-- | networking/ifupdown.c | 87 |
1 files changed, 50 insertions, 37 deletions
diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 8843184bf..e9f0a646c 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c | |||
@@ -104,31 +104,6 @@ static const char *startup_PATH; | |||
104 | 104 | ||
105 | #if ENABLE_FEATURE_IFUPDOWN_IPV4 || ENABLE_FEATURE_IFUPDOWN_IPV6 | 105 | #if ENABLE_FEATURE_IFUPDOWN_IPV4 || ENABLE_FEATURE_IFUPDOWN_IPV6 |
106 | 106 | ||
107 | #if ENABLE_FEATURE_IFUPDOWN_IP | ||
108 | |||
109 | static unsigned count_bits(unsigned a) | ||
110 | { | ||
111 | unsigned result; | ||
112 | result = (a & 0x55) + ((a >> 1) & 0x55); | ||
113 | result = (result & 0x33) + ((result >> 2) & 0x33); | ||
114 | return (result & 0x0F) + ((result >> 4) & 0x0F); | ||
115 | } | ||
116 | |||
117 | static int count_netmask_bits(char *dotted_quad) | ||
118 | { | ||
119 | unsigned result, a, b, c, d; | ||
120 | /* Found a netmask... Check if it is dotted quad */ | ||
121 | if (sscanf(dotted_quad, "%u.%u.%u.%u", &a, &b, &c, &d) != 4) | ||
122 | return -1; | ||
123 | // FIXME: will be confused by e.g. 255.0.255.0 | ||
124 | result = count_bits(a); | ||
125 | result += count_bits(b); | ||
126 | result += count_bits(c); | ||
127 | result += count_bits(d); | ||
128 | return (int)result; | ||
129 | } | ||
130 | #endif | ||
131 | |||
132 | static void addstr(char **bufp, const char *str, size_t str_length) | 107 | static void addstr(char **bufp, const char *str, size_t str_length) |
133 | { | 108 | { |
134 | /* xasprintf trick will be smaller, but we are often | 109 | /* xasprintf trick will be smaller, but we are often |
@@ -177,6 +152,39 @@ static char *get_var(const char *id, size_t idlen, struct interface_defn_t *ifd) | |||
177 | return NULL; | 152 | return NULL; |
178 | } | 153 | } |
179 | 154 | ||
155 | #if ENABLE_FEATURE_IFUPDOWN_IP | ||
156 | static int count_netmask_bits(const char *dotted_quad) | ||
157 | { | ||
158 | // int result; | ||
159 | // unsigned a, b, c, d; | ||
160 | // /* Found a netmask... Check if it is dotted quad */ | ||
161 | // if (sscanf(dotted_quad, "%u.%u.%u.%u", &a, &b, &c, &d) != 4) | ||
162 | // return -1; | ||
163 | // if ((a|b|c|d) >> 8) | ||
164 | // return -1; /* one of numbers is >= 256 */ | ||
165 | // d |= (a << 24) | (b << 16) | (c << 8); /* IP */ | ||
166 | // d = ~d; /* 11110000 -> 00001111 */ | ||
167 | |||
168 | /* Shorter version */ | ||
169 | int result; | ||
170 | struct in_addr ip; | ||
171 | unsigned d; | ||
172 | |||
173 | if (inet_aton(dotted_quad, &ip) == 0) | ||
174 | return -1; /* malformed dotted IP */ | ||
175 | d = ntohl(ip.s_addr); /* IP in host order */ | ||
176 | d = ~d; /* 11110000 -> 00001111 */ | ||
177 | if (d & (d+1)) /* check that it is in 00001111 form */ | ||
178 | return -1; /* no it is not */ | ||
179 | result = 32; | ||
180 | while (d) { | ||
181 | d >>= 1; | ||
182 | result--; | ||
183 | } | ||
184 | return result; | ||
185 | } | ||
186 | #endif | ||
187 | |||
180 | static char *parse(const char *command, struct interface_defn_t *ifd) | 188 | static char *parse(const char *command, struct interface_defn_t *ifd) |
181 | { | 189 | { |
182 | size_t old_pos[MAX_OPT_DEPTH] = { 0 }; | 190 | size_t old_pos[MAX_OPT_DEPTH] = { 0 }; |
@@ -246,11 +254,14 @@ static char *parse(const char *command, struct interface_defn_t *ifd) | |||
246 | if (strncmp(command, "bnmask", 6) == 0) { | 254 | if (strncmp(command, "bnmask", 6) == 0) { |
247 | unsigned res; | 255 | unsigned res; |
248 | varvalue = get_var("netmask", 7, ifd); | 256 | varvalue = get_var("netmask", 7, ifd); |
249 | if (varvalue && (res = count_netmask_bits(varvalue)) > 0) { | 257 | if (varvalue) { |
250 | const char *argument = utoa(res); | 258 | res = count_netmask_bits(varvalue); |
251 | addstr(&result, argument, strlen(argument)); | 259 | if (res > 0) { |
252 | command = nextpercent + 1; | 260 | const char *argument = utoa(res); |
253 | break; | 261 | addstr(&result, argument, strlen(argument)); |
262 | command = nextpercent + 1; | ||
263 | break; | ||
264 | } | ||
254 | } | 265 | } |
255 | } | 266 | } |
256 | #endif | 267 | #endif |
@@ -463,7 +474,7 @@ static const struct dhcp_client_t ext_dhcp_clients[] = { | |||
463 | }, | 474 | }, |
464 | { "udhcpc", | 475 | { "udhcpc", |
465 | "udhcpc -R -n -p /var/run/udhcpc.%iface%.pid -i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]]", | 476 | "udhcpc -R -n -p /var/run/udhcpc.%iface%.pid -i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]]", |
466 | "kill -TERM `cat /var/run/udhcpc.%iface%.pid` 2>/dev/null", | 477 | "kill `cat /var/run/udhcpc.%iface%.pid` 2>/dev/null", |
467 | }, | 478 | }, |
468 | }; | 479 | }; |
469 | #endif /* ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCPC */ | 480 | #endif /* ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCPC */ |
@@ -498,10 +509,10 @@ static int dhcp_down(struct interface_defn_t *ifd, execfn *exec) | |||
498 | bb_error_msg("no dhcp clients found, using static interface shutdown"); | 509 | bb_error_msg("no dhcp clients found, using static interface shutdown"); |
499 | return static_down(ifd, exec); | 510 | return static_down(ifd, exec); |
500 | #elif ENABLE_APP_UDHCPC | 511 | #elif ENABLE_APP_UDHCPC |
501 | return execute("kill -TERM " | 512 | return execute("kill " |
502 | "`cat /var/run/udhcpc.%iface%.pid` 2>/dev/null", ifd, exec); | 513 | "`cat /var/run/udhcpc.%iface%.pid` 2>/dev/null", ifd, exec); |
503 | #else | 514 | #else |
504 | return 0; /* no support for dhcp */ | 515 | return 0; /* no dhcp support */ |
505 | #endif | 516 | #endif |
506 | } | 517 | } |
507 | 518 | ||
@@ -834,7 +845,8 @@ static struct interfaces_file_t *read_interfaces(const char *filename) | |||
834 | free(buf); | 845 | free(buf); |
835 | } | 846 | } |
836 | if (ferror(f) != 0) { | 847 | if (ferror(f) != 0) { |
837 | bb_perror_msg_and_die("%s", filename); | 848 | /* ferror does NOT set errno! */ |
849 | bb_error_msg_and_die("%s: I/O error", filename); | ||
838 | } | 850 | } |
839 | fclose(f); | 851 | fclose(f); |
840 | 852 | ||
@@ -884,9 +896,10 @@ static void set_environ(struct interface_defn_t *iface, const char *mode) | |||
884 | 896 | ||
885 | for (i = 0; i < iface->n_options; i++) { | 897 | for (i = 0; i < iface->n_options; i++) { |
886 | if (strcmp(iface->option[i].name, "up") == 0 | 898 | if (strcmp(iface->option[i].name, "up") == 0 |
887 | || strcmp(iface->option[i].name, "down") == 0 | 899 | || strcmp(iface->option[i].name, "down") == 0 |
888 | || strcmp(iface->option[i].name, "pre-up") == 0 | 900 | || strcmp(iface->option[i].name, "pre-up") == 0 |
889 | || strcmp(iface->option[i].name, "post-down") == 0) { | 901 | || strcmp(iface->option[i].name, "post-down") == 0 |
902 | ) { | ||
890 | continue; | 903 | continue; |
891 | } | 904 | } |
892 | *(environend++) = setlocalenv("IF_%s=%s", iface->option[i].name, iface->option[i].value); | 905 | *(environend++) = setlocalenv("IF_%s=%s", iface->option[i].name, iface->option[i].value); |