#include "strv.h"
#include "siphash24.h"
#include "libudev-private.h"
-#include "network-internal.h"
#include "dhcp-lease-internal.h"
#include "log.h"
#include "utf8.h"
#include "util.h"
#include "conf-parser.h"
#include "condition.h"
+#include "network-internal.h"
const char *net_get_name(struct udev_device *device) {
- const char *name = NULL, *field = NULL;
+ const char *name, *field;
assert(device);
/* fetch some persistent data unique (on this machine) to this device */
- FOREACH_STRING(field, "ID_NET_NAME_ONBOARD", "ID_NET_NAME_SLOT",
- "ID_NET_NAME_PATH", "ID_NET_NAME_MAC") {
+ FOREACH_STRING(field, "ID_NET_NAME_ONBOARD", "ID_NET_NAME_SLOT", "ID_NET_NAME_PATH", "ID_NET_NAME_MAC") {
name = udev_device_get_property_value(device, field);
if (name)
- break;
+ return name;
}
- return name;
+ return NULL;
}
#define HASH_KEY SD_ID128_MAKE(d3,1e,48,fa,90,fe,4b,4c,9d,af,d5,d7,a1,b1,2e,8a)
return 1;
}
-unsigned net_netmask_to_prefixlen(const struct in_addr *addr) {
- assert(addr);
-
- return 32 - u32ctz(be32toh(addr->s_addr));
-}
-
int config_parse_net_condition(const char *unit,
const char *filename,
unsigned line,
return 0;
}
-int net_parse_inaddr(const char *address, int *family, void *dst) {
- int r;
-
- assert(address);
- assert(family);
- assert(dst);
-
- /* IPv4 */
- r = inet_pton(AF_INET, address, dst);
- if (r > 0) {
- /* succsefully parsed IPv4 address */
- if (*family == AF_UNSPEC)
- *family = AF_INET;
- else if (*family != AF_INET)
- return -EINVAL;
- } 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) {
- /* successfully parsed IPv6 address */
- if (*family == AF_UNSPEC)
- *family = AF_INET6;
- else if (*family != AF_INET6)
- return -EINVAL;
- } else if (r < 0)
- return -errno;
- else
- return -EINVAL;
- }
-
- return 0;
-}
-
void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size) {
unsigned i;
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+#pragma once
+
/***
This file is part of systemd.
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include <netinet/ether.h>
#include <netinet/in.h>
#include <stdbool.h>
const char *dev_type,
const char *dev_name);
-unsigned net_netmask_to_prefixlen(const struct in_addr *netmask);
-
int config_parse_net_condition(const char *unit, const char *filename, unsigned line,
const char *section, unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data, void *userdata);
const char *section, unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data, void *userdata);
-int net_parse_inaddr(const char *address, int *family, void *dst);
-
int net_get_unique_predictable_data(struct udev_device *device, uint8_t result[8]);
const char *net_get_name(struct udev_device *device);
return 0;
}
-int config_parse_broadcast(const char *unit,
+int config_parse_broadcast(
+ const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *rvalue,
void *data,
void *userdata) {
+
Network *network = userdata;
_cleanup_address_free_ Address *n = NULL;
- _cleanup_free_ char *address = NULL;
int r;
assert(filename);
if (n->family == AF_INET6) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Broadcast is not valid for IPv6 addresses, "
- "ignoring assignment: %s", address);
+ "Broadcast is not valid for IPv6 addresses, ignoring assignment: %s", rvalue);
return 0;
}
- r = net_parse_inaddr(address, &n->family, &n->broadcast);
+ r = in_addr_from_string(AF_INET, rvalue, (union in_addr_union*) &n->broadcast);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Broadcast is invalid, ignoring assignment: %s", address);
+ "Broadcast is invalid, ignoring assignment: %s", rvalue);
return 0;
}
+ n->family = AF_INET;
n = NULL;
return 0;
const char *rvalue,
void *data,
void *userdata) {
+
Network *network = userdata;
_cleanup_address_free_ Address *n = NULL;
- _cleanup_free_ char *address = NULL;
- union in_addr_union *addr;
- const char *e;
- int r;
+ const char *address, *e;
+ union in_addr_union buffer;
+ int r, f;
assert(filename);
assert(section);
if (r < 0)
return r;
- if (streq(lvalue, "Address"))
- addr = &n->in_addr;
- else
- addr = &n->in_addr_peer;
-
/* Address=address/prefixlen */
/* prefixlen */
r = safe_atou(e + 1, &i);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Interface prefix length is invalid, "
- "ignoring assignment: %s", e + 1);
+ "Interface prefix length is invalid, ignoring assignment: %s", e + 1);
return 0;
}
n->prefixlen = (unsigned char) i;
- address = strndup(rvalue, e - rvalue);
- if (!address)
- return log_oom();
- } else {
- address = strdup(rvalue);
- if (!address)
- return log_oom();
- }
+ address = strndupa(rvalue, e - rvalue);
+ } else
+ address = rvalue;
- r = net_parse_inaddr(address, &n->family, addr);
+ r = in_addr_from_string_auto(address, &f, &buffer);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Address is invalid, ignoring assignment: %s", address);
return 0;
}
- if (n->family == AF_INET && !n->broadcast.s_addr)
- n->broadcast.s_addr = n->in_addr.in.s_addr |
- htonl(0xfffffffflu >> n->prefixlen);
+ if (n->family != AF_UNSPEC && f != n->family) {
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+ "Address is incompatible, ignoring assignment: %s", address);
+ return 0;
+ }
+
+ n->family = f;
+
+ if (streq(lvalue, "Address"))
+ n->in_addr = buffer;
+ else
+ n->in_addr_peer = buffer;
+
+ if (n->family == AF_INET && n->broadcast.s_addr == 0)
+ n->broadcast.s_addr = n->in_addr.in.s_addr | htonl(0xfffffffflu >> n->prefixlen);
n = NULL;
return r;
}
- prefixlen = net_netmask_to_prefixlen(&netmask);
+ prefixlen = in_addr_netmask_to_prefixlen(&netmask);
r = address_new_dynamic(&address);
if (r < 0) {
sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
- prefixlen = net_netmask_to_prefixlen(&netmask);
+ prefixlen = in_addr_netmask_to_prefixlen(&netmask);
address->family = AF_INET;
address->in_addr.in = addr;
return r;
}
- prefixlen = net_netmask_to_prefixlen(&netmask);
+ prefixlen = in_addr_netmask_to_prefixlen(&netmask);
r = sd_dhcp_lease_get_router(lease, &gateway);
if (r < 0 && r != -ENOENT) {
void *data,
void *userdata) {
Tunnel *t = userdata;
- union in_addr_union *addr = data;
- int r;
+ union in_addr_union *addr = data, buffer;
+ int r, f;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
- r = net_parse_inaddr(rvalue, &t->family, addr);
+ r = in_addr_from_string_auto(rvalue, &f, &buffer);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Tunnel address is invalid, ignoring assignment: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel address is invalid, ignoring assignment: %s", rvalue);
return 0;
}
+ if (t->family != AF_UNSPEC && t->family != f) {
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel addresses incompatible, ignoring assignment: %s", rvalue);
+ return 0;
+ }
+
+ t->family = f;
+ *addr = buffer;
+
return 0;
}
const char *rvalue,
void *data,
void *userdata) {
+
Network *network = userdata;
_cleanup_route_free_ Route *n = NULL;
- _cleanup_free_ char *route = NULL;
- int r;
+ union in_addr_union buffer;
+ int r, f;
assert(filename);
assert(section);
if (r < 0)
return r;
- r = net_parse_inaddr(rvalue, &n->family, &n->in_addr);
+ r = in_addr_from_string_auto(rvalue, &f, &buffer);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Route is invalid, ignoring assignment: %s", route);
+ "Route is invalid, ignoring assignment: %s", rvalue);
return 0;
}
+ n->family = f;
+ n->in_addr = buffer;
n = NULL;
return 0;
const char *rvalue,
void *data,
void *userdata) {
+
Network *network = userdata;
_cleanup_route_free_ Route *n = NULL;
- _cleanup_free_ char *address = NULL;
- const char *e;
- int r;
+ const char *address, *e;
+ union in_addr_union buffer;
+ int r, f;
assert(filename);
assert(section);
/* address */
e = strchr(rvalue, '/');
- if (e) {
- address = strndup(rvalue, e - rvalue);
- if (!address)
- return log_oom();
- } else {
- address = strdup(rvalue);
- if (!address)
- return log_oom();
- }
+ if (e)
+ address = strndupa(rvalue, e - rvalue);
+ else
+ address = rvalue;
- r = net_parse_inaddr(address, &n->family, &n->dst_addr);
+ r = in_addr_from_string_auto(address, &f, &buffer);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Destination is invalid, ignoring assignment: %s", address);
r = safe_atou(e + 1, &i);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Route destination prefix length is invalid, "
- "ignoring assignment: %s", e + 1);
+ "Route destination prefix length is invalid, ignoring assignment: %s", e + 1);
return 0;
}
}
}
+ n->family = f;
+ n->dst_addr = buffer;
n = NULL;
return 0;
return -EINVAL;
}
+
+unsigned in_addr_netmask_to_prefixlen(const struct in_addr *addr) {
+ assert(addr);
+
+ return 32 - u32ctz(be32toh(addr->s_addr));
+}
int in_addr_to_string(int family, const union in_addr_union *u, char **ret);
int in_addr_from_string(int family, const char *s, union in_addr_union *ret);
int in_addr_from_string_auto(const char *s, int *family, union in_addr_union *ret);
+unsigned in_addr_netmask_to_prefixlen(const struct in_addr *addr);
static inline size_t FAMILY_ADDRESS_SIZE(int family) {
assert(family == AF_INET || family == AF_INET6);