summaryrefslogtreecommitdiff
path: root/networking/ifupdown.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/ifupdown.c')
-rw-r--r--networking/ifupdown.c87
1 files changed, 50 insertions, 37 deletions
diff --git a/networking/ifupdown.c b/networking/ifupdown.c
index 8843184..e9f0a64 100644
--- a/networking/ifupdown.c
+++ b/networking/ifupdown.c
@@ -104,31 +104,6 @@ static const char *startup_PATH;
#if ENABLE_FEATURE_IFUPDOWN_IPV4 || ENABLE_FEATURE_IFUPDOWN_IPV6
-#if ENABLE_FEATURE_IFUPDOWN_IP
-
-static unsigned count_bits(unsigned a)
-{
- unsigned result;
- result = (a & 0x55) + ((a >> 1) & 0x55);
- result = (result & 0x33) + ((result >> 2) & 0x33);
- return (result & 0x0F) + ((result >> 4) & 0x0F);
-}
-
-static int count_netmask_bits(char *dotted_quad)
-{
- unsigned result, a, b, c, d;
- /* Found a netmask... Check if it is dotted quad */
- if (sscanf(dotted_quad, "%u.%u.%u.%u", &a, &b, &c, &d) != 4)
- return -1;
- // FIXME: will be confused by e.g. 255.0.255.0
- result = count_bits(a);
- result += count_bits(b);
- result += count_bits(c);
- result += count_bits(d);
- return (int)result;
-}
-#endif
-
static void addstr(char **bufp, const char *str, size_t str_length)
{
/* 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)
return NULL;
}
+#if ENABLE_FEATURE_IFUPDOWN_IP
+static int count_netmask_bits(const char *dotted_quad)
+{
+// int result;
+// unsigned a, b, c, d;
+// /* Found a netmask... Check if it is dotted quad */
+// if (sscanf(dotted_quad, "%u.%u.%u.%u", &a, &b, &c, &d) != 4)
+// return -1;
+// if ((a|b|c|d) >> 8)
+// return -1; /* one of numbers is >= 256 */
+// d |= (a << 24) | (b << 16) | (c << 8); /* IP */
+// d = ~d; /* 11110000 -> 00001111 */
+
+ /* Shorter version */
+ int result;
+ struct in_addr ip;
+ unsigned d;
+
+ if (inet_aton(dotted_quad, &ip) == 0)
+ return -1; /* malformed dotted IP */
+ d = ntohl(ip.s_addr); /* IP in host order */
+ d = ~d; /* 11110000 -> 00001111 */
+ if (d & (d+1)) /* check that it is in 00001111 form */
+ return -1; /* no it is not */
+ result = 32;
+ while (d) {
+ d >>= 1;
+ result--;
+ }
+ return result;
+}
+#endif
+
static char *parse(const char *command, struct interface_defn_t *ifd)
{
size_t old_pos[MAX_OPT_DEPTH] = { 0 };
@@ -246,11 +254,14 @@ static char *parse(const char *command, struct interface_defn_t *ifd)
if (strncmp(command, "bnmask", 6) == 0) {
unsigned res;
varvalue = get_var("netmask", 7, ifd);
- if (varvalue && (res = count_netmask_bits(varvalue)) > 0) {
- const char *argument = utoa(res);
- addstr(&result, argument, strlen(argument));
- command = nextpercent + 1;
- break;
+ if (varvalue) {
+ res = count_netmask_bits(varvalue);
+ if (res > 0) {
+ const char *argument = utoa(res);
+ addstr(&result, argument, strlen(argument));
+ command = nextpercent + 1;
+ break;
+ }
}
}
#endif
@@ -463,7 +474,7 @@ static const struct dhcp_client_t ext_dhcp_clients[] = {
},
{ "udhcpc",
"udhcpc -R -n -p /var/run/udhcpc.%iface%.pid -i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]]",
- "kill -TERM `cat /var/run/udhcpc.%iface%.pid` 2>/dev/null",
+ "kill `cat /var/run/udhcpc.%iface%.pid` 2>/dev/null",
},
};
#endif /* ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCPC */
@@ -498,10 +509,10 @@ static int dhcp_down(struct interface_defn_t *ifd, execfn *exec)
bb_error_msg("no dhcp clients found, using static interface shutdown");
return static_down(ifd, exec);
#elif ENABLE_APP_UDHCPC
- return execute("kill -TERM "
+ return execute("kill "
"`cat /var/run/udhcpc.%iface%.pid` 2>/dev/null", ifd, exec);
#else
- return 0; /* no support for dhcp */
+ return 0; /* no dhcp support */
#endif
}
@@ -834,7 +845,8 @@ static struct interfaces_file_t *read_interfaces(const char *filename)
free(buf);
}
if (ferror(f) != 0) {
- bb_perror_msg_and_die("%s", filename);
+ /* ferror does NOT set errno! */
+ bb_error_msg_and_die("%s: I/O error", filename);
}
fclose(f);
@@ -884,9 +896,10 @@ static void set_environ(struct interface_defn_t *iface, const char *mode)
for (i = 0; i < iface->n_options; i++) {
if (strcmp(iface->option[i].name, "up") == 0
- || strcmp(iface->option[i].name, "down") == 0
- || strcmp(iface->option[i].name, "pre-up") == 0
- || strcmp(iface->option[i].name, "post-down") == 0) {
+ || strcmp(iface->option[i].name, "down") == 0
+ || strcmp(iface->option[i].name, "pre-up") == 0
+ || strcmp(iface->option[i].name, "post-down") == 0
+ ) {
continue;
}
*(environend++) = setlocalenv("IF_%s=%s", iface->option[i].name, iface->option[i].value);