121 lines
2.7 KiB
C
121 lines
2.7 KiB
C
#include "device-common.h"
|
|
#include "util.h"
|
|
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
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;
|
|
}
|