net-util.c revision d2df0d0ed3a88e491405b403e6022e6619750130
cac0964f155bdb6daba7ecf5628ed2fec3763275orlikowski/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
7238b345c345cb79d81cf01fedc311bff001444ctrawick
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb/***
7e27b1d417fa94db6e8c798a36c68de3a22f3937ianh This file is part of systemd.
cb5d3f2f217d457dada4883addb1dc9f3f17bb85fielding
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb Copyright (C) 2013 Tom Gundersen <teg@jklm.no>
c8d61b81105661b9ba169482e418929fcf0cfec4trawick
87a87c1e1afc7eb004bc10594a9de98411866a20jerenkrantz systemd is free software; you can redistribute it and/or modify it
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb under the terms of the GNU Lesser General Public License as published by
1ddf25b77b03f7f4fd7a7676b62755da90cd3e0crbb the Free Software Foundation; either version 2.1 of the License, or
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb (at your option) any later version.
7aae0c3ef8e7f18f57e2712815c7b48358e5ff68rbb
4b34d6a5b70303010612df6c87da3ee91ae86078rbb systemd is distributed in the hope that it will be useful, but
4b34d6a5b70303010612df6c87da3ee91ae86078rbb WITHOUT ANY WARRANTY; without even the implied warranty of
4b34d6a5b70303010612df6c87da3ee91ae86078rbb MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4b34d6a5b70303010612df6c87da3ee91ae86078rbb Lesser General Public License for more details.
bcf78e5a1193beb9a93b9e0199d6a10e8937b244rbb
d66260b801a953237f71d6a4b26d8fd9ea419e3brbb You should have received a copy of the GNU Lesser General Public License
4b34d6a5b70303010612df6c87da3ee91ae86078rbb along with systemd; If not, see <http://www.gnu.org/licenses/>.
4b34d6a5b70303010612df6c87da3ee91ae86078rbb***/
d66260b801a953237f71d6a4b26d8fd9ea419e3brbb
d66260b801a953237f71d6a4b26d8fd9ea419e3brbb#include <netinet/ether.h>
d472f67198d6b15dd1270136f180cca9c9263243trawick#include <linux/if.h>
4b34d6a5b70303010612df6c87da3ee91ae86078rbb#include <arpa/inet.h>
4b34d6a5b70303010612df6c87da3ee91ae86078rbb
4b34d6a5b70303010612df6c87da3ee91ae86078rbb#include "net-util.h"
d472f67198d6b15dd1270136f180cca9c9263243trawick#include "log.h"
d472f67198d6b15dd1270136f180cca9c9263243trawick#include "utf8.h"
7aae0c3ef8e7f18f57e2712815c7b48358e5ff68rbb#include "util.h"
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb#include "conf-parser.h"
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb
8a3a703eae0e35f674b189181609545c6fc77a09rbbbool net_match_config(const struct ether_addr *match_mac,
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb const char *match_path,
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb const char *match_driver,
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb const char *match_type,
8a3a703eae0e35f674b189181609545c6fc77a09rbb const char *match_name,
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb const char *dev_mac,
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb const char *dev_path,
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb const char *dev_driver,
8a3a703eae0e35f674b189181609545c6fc77a09rbb const char *dev_type,
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb const char *dev_name) {
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb if (match_mac) {
8a3a703eae0e35f674b189181609545c6fc77a09rbb if (!dev_mac || memcmp(match_mac, ether_aton(dev_mac), ETH_ALEN)) {
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb log_debug("Interface MAC address (%s) did not match MACAddress=%s",
7e27b1d417fa94db6e8c798a36c68de3a22f3937ianh dev_mac, ether_ntoa(match_mac));
7e27b1d417fa94db6e8c798a36c68de3a22f3937ianh return 0;
7e27b1d417fa94db6e8c798a36c68de3a22f3937ianh }
7e27b1d417fa94db6e8c798a36c68de3a22f3937ianh }
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb if (match_path) {
8a3a703eae0e35f674b189181609545c6fc77a09rbb if (!streq_ptr(match_path, dev_path)) {
05b7ad99e5d197b06c761fef0e06a44e353cbc54rbb log_debug("Interface persistent path (%s) did not match Path=%s",
cee52fb06eb61191ce5d495abda58a75a9bb1c4fcoar dev_path, match_path);
cee52fb06eb61191ce5d495abda58a75a9bb1c4fcoar return 0;
cee52fb06eb61191ce5d495abda58a75a9bb1c4fcoar }
cee52fb06eb61191ce5d495abda58a75a9bb1c4fcoar }
2f9a515433d924e700a7752e9e50ce322438171daaron
2f9a515433d924e700a7752e9e50ce322438171daaron if (match_driver) {
bb7f455a6c49400b3dfcb3dfb84f9c3a32947a08rbb if (!streq_ptr(match_driver, dev_driver)) {
bb7f455a6c49400b3dfcb3dfb84f9c3a32947a08rbb log_debug("Interface device driver (%s) did not match Driver=%s",
2f9a515433d924e700a7752e9e50ce322438171daaron dev_driver, match_driver);
bb7f455a6c49400b3dfcb3dfb84f9c3a32947a08rbb return 0;
}
}
if (match_type) {
if (!streq_ptr(match_type, dev_type)) {
log_debug("Interface type (%s) did not match Type=%s",
dev_type, match_type);
return 0;
}
}
if (match_name) {
if (!streq_ptr(match_name, dev_name)) {
log_debug("Interface name (%s) did not match Name=%s",
dev_name, match_name);
return 0;
}
}
return 1;
}
int config_parse_ifname(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
char **s = data;
char *n;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
n = strdup(rvalue);
if (!n)
return log_oom();
if (!ascii_is_valid(n) || strlen(n) >= IFNAMSIZ) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Interface name is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
free(n);
return 0;
}
free(*s);
if (*n)
*s = n;
else {
free(n);
*s = NULL;
}
return 0;
}
int config_parse_ifalias(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
char **s = data;
char *n;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
n = strdup(rvalue);
if (!n)
return log_oom();
if (!ascii_is_valid(n) || strlen(n) >= IFALIASZ) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Interface alias is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
free(n);
return 0;
}
free(*s);
if (*n)
*s = n;
else {
free(n);
*s = NULL;
}
return 0;
}
int config_parse_hwaddr(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
struct ether_addr **hwaddr = data;
struct ether_addr *n;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
n = new0(struct ether_addr, 1);
if (!n)
return log_oom();
r = sscanf(rvalue, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
&n->ether_addr_octet[0],
&n->ether_addr_octet[1],
&n->ether_addr_octet[2],
&n->ether_addr_octet[3],
&n->ether_addr_octet[4],
&n->ether_addr_octet[5]);
if (r != 6) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Not a valid MAC address, ignoring assignment: %s", rvalue);
free(n);
return 0;
}
free(*hwaddr);
*hwaddr = n;
return 0;
}
int net_parse_inaddr(const char *address, unsigned char *family, void *dst) {
int r;
assert(address);
assert(family);
assert(dst);
/* IPv4 */
r = inet_pton(AF_INET, address, dst);
if (r > 0)
*family = AF_INET; /* successfully parsed IPv4 address */
else if (r < 0)
return -errno;
else {
/* not an IPv4 address, so let's try IPv6 */
r = inet_pton(AF_INET6, address, dst);
if (r > 0)
*family = AF_INET6; /* successfully parsed IPv6 address */
else if (r < 0)
return -errno;
else
return -EINVAL;
}
return 0;
}