network-internal.c revision c6f7c917a1b494d4455800823472227463f87438
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek/***
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek This file is part of systemd.
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek Copyright (C) 2013 Tom Gundersen <teg@jklm.no>
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek systemd is free software; you can redistribute it and/or modify it
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek under the terms of the GNU Lesser General Public License as published by
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek the Free Software Foundation; either version 2.1 of the License, or
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek (at your option) any later version.
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek systemd is distributed in the hope that it will be useful, but
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek WITHOUT ANY WARRANTY; without even the implied warranty of
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek Lesser General Public License for more details.
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek You should have received a copy of the GNU Lesser General Public License
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek along with systemd; If not, see <http://www.gnu.org/licenses/>.
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek***/
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek#include <netinet/ether.h>
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek#include <linux/if.h>
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek#include <arpa/inet.h>
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek#include <fnmatch.h>
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek#include "strv.h"
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek#include "siphash24.h"
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek#include "libudev-private.h"
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek#include "network-internal.h"
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek#include "log.h"
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek#include "utf8.h"
50c9d542e8bf641412debaa82a4dcf67ddb72258Lukas Slebodnik#include "util.h"
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek#include "conf-parser.h"
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek#include "condition.h"
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek#define HASH_KEY SD_ID128_MAKE(d3,1e,48,fa,90,fe,4b,4c,9d,af,d5,d7,a1,b1,2e,8a)
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozekint net_get_unique_predictable_data(struct udev_device *device, uint8_t result[8]) {
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek size_t l, sz = 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *name, *field = NULL;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek int r;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek uint8_t *v;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek /* fetch some persistent data unique (on this machine) to this device */
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek FOREACH_STRING(field, "ID_NET_NAME_ONBOARD", "ID_NET_NAME_SLOT", "ID_NET_NAME_PATH", "ID_NET_NAME_MAC") {
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek name = udev_device_get_property_value(device, field);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (name)
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek break;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek }
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (!name)
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return -ENOENT;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek l = strlen(name);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek sz = sizeof(sd_id128_t) + l;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek v = alloca(sz);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek /* fetch some persistent data unique to this machine */
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek r = sd_id128_get_machine((sd_id128_t*) v);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (r < 0)
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return r;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek memcpy(v + sizeof(sd_id128_t), name, l);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek /* Let's hash the machine ID plus the device name. We
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek * use a fixed, but originally randomly created hash
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek * key here. */
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek siphash24(result, v, sz, HASH_KEY.bytes);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek}
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozekbool net_match_config(const struct ether_addr *match_mac,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *match_path,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *match_driver,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *match_type,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *match_name,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek Condition *match_host,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek Condition *match_virt,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek Condition *match_kernel,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek Condition *match_arch,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *dev_mac,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *dev_path,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *dev_parent_driver,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *dev_driver,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *dev_type,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *dev_name) {
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (match_host && !condition_test_host(match_host))
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (match_virt && !condition_test_virtualization(match_virt))
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (match_kernel && !condition_test_kernel_command_line(match_kernel))
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (match_arch && !condition_test_architecture(match_arch))
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (match_mac && (!dev_mac || memcmp(match_mac, ether_aton(dev_mac), ETH_ALEN)))
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (match_path && (!dev_path || fnmatch(match_path, dev_path, 0)))
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (match_driver) {
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (dev_parent_driver && !streq(match_driver, dev_parent_driver))
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek else if (!streq_ptr(match_driver, dev_driver))
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek }
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (match_type && !streq_ptr(match_type, dev_type))
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (match_name && (!dev_name || fnmatch(match_name, dev_name, 0)))
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 1;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek}
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozekunsigned net_netmask_to_prefixlen(const struct in_addr *addr) {
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek assert(addr);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 32 - u32ctz(be32toh(addr->s_addr));
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek}
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozekint config_parse_net_condition(const char *unit,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *filename,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek unsigned line,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *section,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek unsigned section_line,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *lvalue,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek int ltype,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *rvalue,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek void *data,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek void *userdata) {
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek ConditionType cond = ltype;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek Condition **ret = data;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek bool negate;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek Condition *c;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek _cleanup_free_ char *s = NULL;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek assert(filename);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek assert(lvalue);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek assert(rvalue);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek assert(data);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek negate = rvalue[0] == '!';
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (negate)
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek rvalue++;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek s = strdup(rvalue);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (!s)
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return log_oom();
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek c = condition_new(cond, s, false, negate);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (!c)
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return log_oom();
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (*ret)
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek condition_free(*ret);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek *ret = c;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek}
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozekint config_parse_ifname(const char *unit,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *filename,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek unsigned line,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *section,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek unsigned section_line,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *lvalue,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek int ltype,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *rvalue,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek void *data,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek void *userdata) {
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek char **s = data;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek char *n;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek assert(filename);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek assert(lvalue);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek assert(rvalue);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek assert(data);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek n = strdup(rvalue);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (!n)
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return log_oom();
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (!ascii_is_valid(n) || strlen(n) >= IFNAMSIZ) {
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek log_syntax(unit, LOG_ERR, filename, line, EINVAL,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek "Interface name is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek free(n);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek }
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek free(*s);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (*n)
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek *s = n;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek else {
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek free(n);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek *s = NULL;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek }
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek}
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozekint config_parse_ifalias(const char *unit,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *filename,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek unsigned line,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *section,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek unsigned section_line,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *lvalue,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek int ltype,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *rvalue,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek void *data,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek void *userdata) {
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek char **s = data;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek char *n;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
a95c006f748fa9df0dd81509b51974133d2786afLukas Slebodnik assert(filename);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek assert(lvalue);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek assert(rvalue);
919cfb623e9b725eaa654c6e1b513d1305057314Jakub Hrozek assert(data);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek n = strdup(rvalue);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (!n)
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return log_oom();
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (!ascii_is_valid(n) || strlen(n) >= IFALIASZ) {
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek log_syntax(unit, LOG_ERR, filename, line, EINVAL,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek "Interface alias is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek free(n);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek }
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek free(*s);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (*n)
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek *s = n;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek else {
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek free(n);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek *s = NULL;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek }
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek}
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozekint config_parse_hwaddr(const char *unit,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *filename,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek unsigned line,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *section,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek unsigned section_line,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *lvalue,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek int ltype,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek const char *rvalue,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek void *data,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek void *userdata) {
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek struct ether_addr **hwaddr = data;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek struct ether_addr *n;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek int r;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek assert(filename);
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek assert(lvalue);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek assert(rvalue);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek assert(data);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek n = new0(struct ether_addr, 1);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (!n)
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return log_oom();
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek r = sscanf(rvalue, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek &n->ether_addr_octet[0],
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek &n->ether_addr_octet[1],
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek &n->ether_addr_octet[2],
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek &n->ether_addr_octet[3],
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek &n->ether_addr_octet[4],
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek &n->ether_addr_octet[5]);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (r != 6) {
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek log_syntax(unit, LOG_ERR, filename, line, EINVAL,
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek "Not a valid MAC address, ignoring assignment: %s", rvalue);
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek free(n);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek }
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek free(*hwaddr);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek *hwaddr = n;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek}
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozekint net_parse_inaddr(const char *address, unsigned char *family, void *dst) {
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek int r;
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek assert(address);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek assert(family);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek assert(dst);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek /* IPv4 */
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek r = inet_pton(AF_INET, address, dst);
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek if (r > 0) {
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek /* succsefully parsed IPv4 address */
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek if (*family == AF_UNSPEC)
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek *family = AF_INET;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek else if (*family != AF_INET)
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return -EINVAL;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek } else if (r < 0)
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return -errno;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek else {
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek /* not an IPv4 address, so let's try IPv6 */
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek r = inet_pton(AF_INET6, address, dst);
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek if (r > 0) {
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek /* successfully parsed IPv6 address */
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek if (*family == AF_UNSPEC)
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek *family = AF_INET6;
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek else if (*family != AF_INET6)
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek return -EINVAL;
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek } else if (r < 0)
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek return -errno;
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek else
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return -EINVAL;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek }
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek return 0;
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek}
b3d110fbc424a03674a6e50e489a7cbab9702f0bJakub Hrozek