diff options
-rw-r--r-- | proto-static.c | 44 | ||||
-rw-r--r-- | proto.c | 57 | ||||
-rw-r--r-- | proto.h | 1 |
3 files changed, 60 insertions, 42 deletions
diff --git a/proto-static.c b/proto-static.c index 57da77d..17cff0a 100644 --- a/proto-static.c +++ b/proto-static.c @@ -46,53 +46,13 @@ struct static_proto_state { }; static bool -split_netmask(char *str, unsigned int *netmask) -{ - char *delim, *err = NULL; - - delim = strchr(str, '/'); - if (delim) { - *(delim++) = 0; - - *netmask = strtoul(delim, &err, 10); - if (err && *err) - return false; - } - return true; -} - -static int -parse_ip_and_netmask(int af, const char *str, void *addr, unsigned int *netmask) -{ - char *astr = alloca(strlen(str) + 1); - - strcpy(astr, str); - if (!split_netmask(astr, netmask)) - return 0; - - if (af == AF_INET6) { - if (*netmask > 128) - return 0; - } else { - if (*netmask > 32) - return 0; - } - - return inet_pton(af, str, addr); -} - -static bool parse_addr(struct interface *iface, const char *str, bool v6, int mask) { struct device_addr *addr; - int af = v6 ? AF_INET6 : AF_INET; - addr = calloc(1, sizeof(*addr)); - addr->flags = v6 ? DEVADDR_INET6 : DEVADDR_INET4; - addr->mask = mask; - if (!parse_ip_and_netmask(af, str, &addr->addr, &addr->mask)) { + addr = proto_parse_ip_addr_string(str, v6, mask); + if (!addr) { interface_add_error(iface, "proto-static", "INVALID_ADDRESS", &str, 1); - free(addr); return false; } vlist_add(&iface->proto_addr, &addr->node); @@ -2,12 +2,69 @@ #include <stdlib.h> #include <stdio.h> +#include <arpa/inet.h> +#include <netinet/in.h> + #include "netifd.h" #include "interface.h" +#include "interface-ip.h" #include "proto.h" static struct avl_tree handlers; +static bool +split_netmask(char *str, unsigned int *netmask) +{ + char *delim, *err = NULL; + + delim = strchr(str, '/'); + if (delim) { + *(delim++) = 0; + + *netmask = strtoul(delim, &err, 10); + if (err && *err) + return false; + } + return true; +} + +static int +parse_ip_and_netmask(int af, const char *str, void *addr, unsigned int *netmask) +{ + char *astr = alloca(strlen(str) + 1); + + strcpy(astr, str); + if (!split_netmask(astr, netmask)) + return 0; + + if (af == AF_INET6) { + if (*netmask > 128) + return 0; + } else { + if (*netmask > 32) + return 0; + } + + return inet_pton(af, str, addr); +} + +struct device_addr * +proto_parse_ip_addr_string(const char *str, bool v6, int mask) +{ + struct device_addr *addr; + int af = v6 ? AF_INET6 : AF_INET; + + addr = calloc(1, sizeof(*addr)); + addr->flags = v6 ? DEVADDR_INET6 : DEVADDR_INET4; + addr->mask = mask; + if (!parse_ip_and_netmask(af, str, &addr->addr, &addr->mask)) { + free(addr); + return NULL; + } + return addr; +} + + void add_proto_handler(struct proto_handler *p) { if (!handlers.comp) @@ -52,5 +52,6 @@ void proto_init_interface(struct interface *iface, struct blob_attr *attr); void proto_attach_interface(struct interface *iface, const char *proto_name); int interface_proto_event(struct interface_proto_state *proto, enum interface_proto_cmd cmd, bool force); +struct device_addr *proto_parse_ip_addr_string(const char *str, bool v6, int mask); #endif |