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