#include "device-common.h" #include "util.h" #include #include #include #include #include #include static unsigned long strtoul_safe(const char *str) { char *endptr; errno = 0; unsigned long val = strtoul(str, &endptr, 10); if (endptr == str || *endptr) errno = EINVAL; return val; } static bool parse_address(ipaddr_t *addr, const char *str) { if (inet_pton(AF_INET, str, &addr->addr4)) { addr->af = AF_INET; return true; } if (inet_pton(AF_INET6, str, &addr->addr6)) { addr->af = AF_INET6; return true; } return false; } static bool parse_prefix(ipaddr_prefix_t *prefix, const char *str, bool allow_host) { const char *slash = strrchr(str, '/'); if (!slash) return false; size_t len = slash - str; char buf[len+1]; memcpy(buf, str, len); buf[len] = 0; if (!parse_address(&prefix->addr, buf)) return false; long plen = strtoul_safe(slash + 1); if (errno) return false; switch (prefix->addr.af) { case AF_INET: if (plen > 32) return false; break; case AF_INET6: if (plen > 128) return false; break; default: assert(false); __builtin_unreachable(); } prefix->plen = plen; // TODO: Implement allow_host return true; } static bool process_section_device(device_common_t *device, struct json_object *section) { return true; } static bool process_section_static(device_common_t *device, struct json_object *section) { struct json_object *addresses = neco_json_get_value(section, "addresses", json_type_array); if (addresses) { for (size_t i = 0; i < json_object_array_length(addresses); i++) { struct json_object *address = json_object_array_get_idx(addresses, i); if (!json_object_is_type(address, json_type_string)) { fprintf(stderr, "interface: static: invalid address entry of type %s\n", json_type_to_name(json_object_get_type(address))); continue; } ipaddr_prefix_t p; if (!parse_prefix(&p, json_object_get_string(address), true)) { fprintf(stderr, "interface: static: unable to parse Address %s\n", json_object_get_string(address)); break; } if (!VECTOR_ADD(device->addrs, p)) { fprintf(stderr, "interface: static: adding address failed\n"); return false; } } } return true; } bool device_common_process_config(device_common_t *device, struct json_object *config) { struct json_object *sec_device = neco_json_get_value(config, "device", json_type_object); if (sec_device) { if (!process_section_device(device, sec_device)) return false; } struct json_object *sec_static = neco_json_get_value(config, "static", json_type_object); if (sec_static) { if (!process_section_static(device, sec_static)) return false; } return true; }