systemd: merge branch 'systemd' into master

This commit is contained in:
Thomas Haller
2016-01-26 17:22:54 +01:00
40 changed files with 909 additions and 536 deletions

View File

@@ -77,6 +77,8 @@ libsystemd_nm_la_SOURCES = \
systemd/src/basic/fileio.h \
systemd/src/basic/fs-util.c \
systemd/src/basic/fs-util.h \
systemd/src/basic/hash-funcs.c \
systemd/src/basic/hash-funcs.h \
systemd/src/basic/hashmap.c \
systemd/src/basic/hashmap.h \
systemd/src/basic/hexdecoct.c \
@@ -106,6 +108,7 @@ libsystemd_nm_la_SOURCES = \
systemd/src/basic/set.h \
systemd/src/basic/socket-util.h \
systemd/src/basic/sparse-endian.h \
systemd/src/basic/stdio-util.h \
systemd/src/basic/string-table.c \
systemd/src/basic/string-table.h \
systemd/src/basic/string-util.c \

View File

@@ -37,18 +37,15 @@
#include "sd-dhcp-client.h"
#include "sd-dhcp6-client.h"
#include "dhcp-protocol.h"
#include "dhcp-lease-internal.h"
#include "dhcp6-protocol.h"
#include "dhcp6-lease-internal.h"
G_DEFINE_TYPE (NMDhcpSystemd, nm_dhcp_systemd, NM_TYPE_DHCP_CLIENT)
#define NM_DHCP_SYSTEMD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_SYSTEMD, NMDhcpSystemdPrivate))
typedef struct {
struct sd_dhcp_client *client4;
struct sd_dhcp6_client *client6;
sd_dhcp_client *client4;
sd_dhcp6_client *client6;
char *lease_file;
guint request_count;
@@ -61,7 +58,6 @@ typedef struct {
#define DHCP_OPTION_NIS_DOMAIN 40
#define DHCP_OPTION_NIS_SERVERS 41
#define DHCP_OPTION_DOMAIN_SEARCH 119
#define DHCP_OPTION_RFC3442_ROUTES 121
#define DHCP_OPTION_MS_ROUTES 249
#define DHCP_OPTION_WPAD 252
@@ -87,42 +83,42 @@ typedef struct {
#define REQPREFIX "requested_"
static const ReqOption dhcp4_requests[] = {
{ DHCP_OPTION_SUBNET_MASK, REQPREFIX "subnet_mask", TRUE },
{ DHCP_OPTION_TIME_OFFSET, REQPREFIX "time_offset", TRUE },
{ DHCP_OPTION_ROUTER, REQPREFIX "routers", TRUE },
{ DHCP_OPTION_DOMAIN_NAME_SERVER, REQPREFIX "domain_name_servers", TRUE },
{ DHCP_OPTION_HOST_NAME, REQPREFIX "host_name", TRUE },
{ DHCP_OPTION_DOMAIN_NAME, REQPREFIX "domain_name", TRUE },
{ DHCP_OPTION_INTERFACE_MTU, REQPREFIX "interface_mtu", TRUE },
{ DHCP_OPTION_BROADCAST, REQPREFIX "broadcast_address", TRUE },
{ DHCP_OPTION_STATIC_ROUTE, REQPREFIX "static_routes", TRUE },
{ SD_DHCP_OPTION_SUBNET_MASK, REQPREFIX "subnet_mask", TRUE },
{ SD_DHCP_OPTION_TIME_OFFSET, REQPREFIX "time_offset", TRUE },
{ SD_DHCP_OPTION_ROUTER, REQPREFIX "routers", TRUE },
{ SD_DHCP_OPTION_DOMAIN_NAME_SERVER, REQPREFIX "domain_name_servers", TRUE },
{ SD_DHCP_OPTION_HOST_NAME, REQPREFIX "host_name", TRUE },
{ SD_DHCP_OPTION_DOMAIN_NAME, REQPREFIX "domain_name", TRUE },
{ SD_DHCP_OPTION_INTERFACE_MTU, REQPREFIX "interface_mtu", TRUE },
{ SD_DHCP_OPTION_BROADCAST, REQPREFIX "broadcast_address", TRUE },
{ SD_DHCP_OPTION_STATIC_ROUTE, REQPREFIX "static_routes", TRUE },
{ DHCP_OPTION_NIS_DOMAIN, REQPREFIX "nis_domain", TRUE },
{ DHCP_OPTION_NIS_SERVERS, REQPREFIX "nis_servers", TRUE },
{ DHCP_OPTION_NTP_SERVER, REQPREFIX "ntp_servers", TRUE },
{ DHCP_OPTION_SERVER_IDENTIFIER, REQPREFIX "dhcp_server_identifier", TRUE },
{ SD_DHCP_OPTION_NTP_SERVER, REQPREFIX "ntp_servers", TRUE },
{ SD_DHCP_OPTION_SERVER_IDENTIFIER, REQPREFIX "dhcp_server_identifier", TRUE },
{ DHCP_OPTION_DOMAIN_SEARCH, REQPREFIX "domain_search", TRUE },
{ DHCP_OPTION_CLASSLESS_STATIC_ROUTE, REQPREFIX "rfc3442_classless_static_routes", TRUE },
{ SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE, REQPREFIX "rfc3442_classless_static_routes", TRUE },
{ DHCP_OPTION_MS_ROUTES, REQPREFIX "ms_classless_static_routes", TRUE },
{ DHCP_OPTION_WPAD, REQPREFIX "wpad", TRUE },
/* Internal values */
{ DHCP_OPTION_IP_ADDRESS_LEASE_TIME, REQPREFIX "expiry", FALSE },
{ DHCP_OPTION_CLIENT_IDENTIFIER, REQPREFIX "dhcp_client_identifier", FALSE },
{ SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME, REQPREFIX "expiry", FALSE },
{ SD_DHCP_OPTION_CLIENT_IDENTIFIER, REQPREFIX "dhcp_client_identifier", FALSE },
{ DHCP_OPTION_IP_ADDRESS, REQPREFIX "ip_address", FALSE },
{ 0, NULL, FALSE }
};
static const ReqOption dhcp6_requests[] = {
{ DHCP6_OPTION_CLIENTID, REQPREFIX "dhcp6_client_id", TRUE },
{ SD_DHCP6_OPTION_CLIENTID, REQPREFIX "dhcp6_client_id", TRUE },
/* Don't request server ID by default; some servers don't reply to
* Information Requests that request the Server ID.
*/
{ DHCP6_OPTION_SERVERID, REQPREFIX "dhcp6_server_id", FALSE },
{ SD_DHCP6_OPTION_SERVERID, REQPREFIX "dhcp6_server_id", FALSE },
{ DHCP6_OPTION_DNS_SERVERS, REQPREFIX "dhcp6_name_servers", TRUE },
{ DHCP6_OPTION_DOMAIN_LIST, REQPREFIX "dhcp6_domain_search", TRUE },
{ DHCP6_OPTION_SNTP_SERVERS, REQPREFIX "dhcp6_sntp_servers", TRUE },
{ SD_DHCP6_OPTION_DNS_SERVERS, REQPREFIX "dhcp6_name_servers", TRUE },
{ SD_DHCP6_OPTION_DOMAIN_LIST, REQPREFIX "dhcp6_domain_search", TRUE },
{ SD_DHCP6_OPTION_SNTP_SERVERS, REQPREFIX "dhcp6_sntp_servers", TRUE },
/* Internal values */
{ DHCP6_OPTION_IP_ADDRESS, REQPREFIX "ip6_address", FALSE },
@@ -215,7 +211,7 @@ lease_to_ip4_config (const char *iface,
guint32 lifetime = 0, i;
NMPlatformIP4Address address;
GString *l;
struct sd_dhcp_route *routes;
gs_free sd_dhcp_route **routes = NULL;
guint16 mtu;
int r, num;
guint64 end_time;
@@ -242,7 +238,7 @@ lease_to_ip4_config (const char *iface,
LOG_LEASE (LOGD_DHCP4, " plen %d", address.plen);
add_option (options,
dhcp4_requests,
DHCP_OPTION_SUBNET_MASK,
SD_DHCP_OPTION_SUBNET_MASK,
nm_utils_inet4_ntop (tmp_addr.s_addr, NULL));
/* Lease time */
@@ -253,7 +249,7 @@ lease_to_ip4_config (const char *iface,
LOG_LEASE (LOGD_DHCP4, " expires in %" G_GUINT32_FORMAT " seconds", lifetime);
add_option_u64 (options,
dhcp4_requests,
DHCP_OPTION_IP_ADDRESS_LEASE_TIME,
SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME,
end_time);
address.source = NM_IP_CONFIG_SOURCE_DHCP;
@@ -265,7 +261,7 @@ lease_to_ip4_config (const char *iface,
nm_ip4_config_set_gateway (ip4_config, tmp_addr.s_addr);
str = nm_utils_inet4_ntop (tmp_addr.s_addr, NULL);
LOG_LEASE (LOGD_DHCP4, " gateway %s", str);
add_option (options, dhcp4_requests, DHCP_OPTION_ROUTER, str);
add_option (options, dhcp4_requests, SD_DHCP_OPTION_ROUTER, str);
}
/* DNS Servers */
@@ -281,7 +277,7 @@ lease_to_ip4_config (const char *iface,
}
}
if (l->len)
add_option (options, dhcp4_requests, DHCP_OPTION_DOMAIN_NAME_SERVER, l->str);
add_option (options, dhcp4_requests, SD_DHCP_OPTION_DOMAIN_NAME_SERVER, l->str);
g_string_free (l, TRUE);
}
@@ -297,14 +293,14 @@ lease_to_ip4_config (const char *iface,
nm_ip4_config_add_domain (ip4_config, *s);
}
g_strfreev (domains);
add_option (options, dhcp4_requests, DHCP_OPTION_DOMAIN_NAME, str);
add_option (options, dhcp4_requests, SD_DHCP_OPTION_DOMAIN_NAME, str);
}
/* Hostname */
r = sd_dhcp_lease_get_hostname (lease, &str);
if (r == 0) {
LOG_LEASE (LOGD_DHCP4, " hostname '%s'", str);
add_option (options, dhcp4_requests, DHCP_OPTION_HOST_NAME, str);
add_option (options, dhcp4_requests, SD_DHCP_OPTION_HOST_NAME, str);
}
/* Routes */
@@ -312,13 +308,23 @@ lease_to_ip4_config (const char *iface,
if (num > 0) {
l = g_string_sized_new (30);
for (i = 0; i < num; i++) {
NMPlatformIP4Route route;
NMPlatformIP4Route route = { 0 };
const char *gw_str;
guint8 plen;
struct in_addr a;
if (sd_dhcp_route_get_destination (routes[i], &a) < 0)
continue;
route.network = a.s_addr;
if (sd_dhcp_route_get_destination_prefix_length (routes[i], &plen) < 0)
continue;
route.plen = plen;
if (sd_dhcp_route_get_gateway (routes[i], &a) < 0)
continue;
route.gateway = a.s_addr;
memset (&route, 0, sizeof (route));
route.network = routes[i].dst_addr.s_addr;
route.plen = routes[i].dst_prefixlen;
route.gateway = routes[i].gw_addr.s_addr;
route.source = NM_IP_CONFIG_SOURCE_DHCP;
route.metric = default_priority;
nm_ip4_config_add_route (ip4_config, &route);
@@ -329,7 +335,7 @@ lease_to_ip4_config (const char *iface,
g_string_append_printf (l, "%s%s/%d %s", l->len ? " " : "", str, route.plen, gw_str);
}
add_option (options, dhcp4_requests, DHCP_OPTION_RFC3442_ROUTES, l->str);
add_option (options, dhcp4_requests, SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE, l->str);
g_string_free (l, TRUE);
}
@@ -337,7 +343,7 @@ lease_to_ip4_config (const char *iface,
r = sd_dhcp_lease_get_mtu (lease, &mtu);
if (r == 0 && mtu) {
nm_ip4_config_set_mtu (ip4_config, mtu, NM_IP_CONFIG_SOURCE_DHCP);
add_option_u32 (options, dhcp4_requests, DHCP_OPTION_INTERFACE_MTU, mtu);
add_option_u32 (options, dhcp4_requests, SD_DHCP_OPTION_INTERFACE_MTU, mtu);
LOG_LEASE (LOGD_DHCP4, " mtu %u", mtu);
}
@@ -350,7 +356,7 @@ lease_to_ip4_config (const char *iface,
LOG_LEASE (LOGD_DHCP4, " ntp server '%s'", str);
g_string_append_printf (l, "%s%s", l->len ? " " : "", str);
}
add_option (options, dhcp4_requests, DHCP_OPTION_NTP_SERVER, l->str);
add_option (options, dhcp4_requests, SD_DHCP_OPTION_NTP_SERVER, l->str);
g_string_free (l, TRUE);
}

View File

@@ -121,16 +121,18 @@ char *cescape(const char *s) {
return cescape_length(s, strlen(s));
}
int cunescape_one(const char *p, size_t length, char *ret, uint32_t *ret_unicode) {
int cunescape_one(const char *p, size_t length, uint32_t *ret, bool *eight_bit) {
int r = 1;
assert(p);
assert(*p);
assert(ret);
/* Unescapes C style. Returns the unescaped character in ret,
* unless we encountered a \u sequence in which case the full
* unicode character is returned in ret_unicode, instead. */
/* Unescapes C style. Returns the unescaped character in ret.
* Sets *eight_bit to true if the escaped sequence either fits in
* one byte in UTF-8 or is a non-unicode literal byte and should
* instead be copied directly.
*/
if (length != (size_t) -1 && length < 1)
return -EINVAL;
@@ -192,7 +194,8 @@ int cunescape_one(const char *p, size_t length, char *ret, uint32_t *ret_unicode
if (a == 0 && b == 0)
return -EINVAL;
*ret = (char) ((a << 4U) | b);
*ret = (a << 4U) | b;
*eight_bit = true;
r = 3;
break;
}
@@ -219,16 +222,7 @@ int cunescape_one(const char *p, size_t length, char *ret, uint32_t *ret_unicode
if (c == 0)
return -EINVAL;
if (c < 128)
*ret = c;
else {
if (!ret_unicode)
return -EINVAL;
*ret = 0;
*ret_unicode = c;
}
r = 5;
break;
}
@@ -260,16 +254,7 @@ int cunescape_one(const char *p, size_t length, char *ret, uint32_t *ret_unicode
if (!unichar_is_valid(c))
return -EINVAL;
if (c < 128)
*ret = c;
else {
if (!ret_unicode)
return -EINVAL;
*ret = 0;
*ret_unicode = c;
}
r = 9;
break;
}
@@ -311,6 +296,7 @@ int cunescape_one(const char *p, size_t length, char *ret, uint32_t *ret_unicode
return -EINVAL;
*ret = m;
*eight_bit = true;
r = 3;
break;
}
@@ -344,7 +330,7 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi
for (f = s, t = r + pl; f < s + length; f++) {
size_t remaining;
uint32_t u;
char c;
bool eight_bit = false;
int k;
remaining = s + length - f;
@@ -367,7 +353,7 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi
return -EINVAL;
}
k = cunescape_one(f + 1, remaining - 1, &c, &u);
k = cunescape_one(f + 1, remaining - 1, &u, &eight_bit);
if (k < 0) {
if (flags & UNESCAPE_RELAX) {
/* Invalid escape code, let's take it literal then */
@@ -379,14 +365,13 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi
return k;
}
if (c != 0)
/* Non-Unicode? Let's encode this directly */
*(t++) = c;
else
/* Unicode? Then let's encode this in UTF-8 */
t += utf8_encode_unichar(t, u);
f += k;
if (eight_bit)
/* One byte? Set directly as specified */
*(t++) = u;
else
/* Otherwise encode as multi-byte UTF-8 */
t += utf8_encode_unichar(t, u);
}
*t = 0;

View File

@@ -47,7 +47,7 @@ size_t cescape_char(char c, char *buf);
int cunescape(const char *s, UnescapeFlags flags, char **ret);
int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret);
int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret);
int cunescape_one(const char *p, size_t length, char *ret, uint32_t *ret_unicode);
int cunescape_one(const char *p, size_t length, uint32_t *ret, bool *eight_bit);
char *xescape(const char *s, const char *bad);

View File

@@ -75,3 +75,7 @@ int same_fd(int a, int b);
void cmsg_close_all(struct msghdr *mh);
bool fdname_is_valid(const char *s);
/* Hint: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5 */
#define ERRNO_IS_DISCONNECT(r) \
IN_SET(r, ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, ENETUNREACH)

View File

@@ -169,7 +169,7 @@ int read_one_line_file(const char *fn, char **line) {
if (!fgets(t, sizeof(t), f)) {
if (ferror(f))
return errno ? -errno : -EIO;
return errno > 0 ? -errno : -EIO;
t[0] = 0;
}
@@ -1070,7 +1070,7 @@ int fflush_and_check(FILE *f) {
fflush(f);
if (ferror(f))
return errno ? -errno : -EIO;
return errno > 0 ? -errno : -EIO;
return 0;
}

View File

@@ -492,7 +492,7 @@ int get_files_in_directory(const char *path, char ***list) {
errno = 0;
de = readdir(d);
if (!de && errno != 0)
if (!de && errno > 0)
return -errno;
if (!de)
break;

View File

@@ -0,0 +1,85 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2010 Lennart Poettering
Copyright 2014 Michal Schmidt
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "nm-sd-adapt.h"
#include "hash-funcs.h"
void string_hash_func(const void *p, struct siphash *state) {
siphash24_compress(p, strlen(p) + 1, state);
}
int string_compare_func(const void *a, const void *b) {
return strcmp(a, b);
}
const struct hash_ops string_hash_ops = {
.hash = string_hash_func,
.compare = string_compare_func
};
void trivial_hash_func(const void *p, struct siphash *state) {
siphash24_compress(&p, sizeof(p), state);
}
int trivial_compare_func(const void *a, const void *b) {
return a < b ? -1 : (a > b ? 1 : 0);
}
const struct hash_ops trivial_hash_ops = {
.hash = trivial_hash_func,
.compare = trivial_compare_func
};
void uint64_hash_func(const void *p, struct siphash *state) {
siphash24_compress(p, sizeof(uint64_t), state);
}
int uint64_compare_func(const void *_a, const void *_b) {
uint64_t a, b;
a = *(const uint64_t*) _a;
b = *(const uint64_t*) _b;
return a < b ? -1 : (a > b ? 1 : 0);
}
const struct hash_ops uint64_hash_ops = {
.hash = uint64_hash_func,
.compare = uint64_compare_func
};
#if SIZEOF_DEV_T != 8
void devt_hash_func(const void *p, struct siphash *state) {
siphash24_compress(p, sizeof(dev_t), state);
}
int devt_compare_func(const void *_a, const void *_b) {
dev_t a, b;
a = *(const dev_t*) _a;
b = *(const dev_t*) _b;
return a < b ? -1 : (a > b ? 1 : 0);
}
const struct hash_ops devt_hash_ops = {
.hash = devt_hash_func,
.compare = devt_compare_func
};
#endif

View File

@@ -0,0 +1,69 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
This file is part of systemd.
Copyright 2010 Lennart Poettering
Copyright 2014 Michal Schmidt
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "nm-sd-adapt.h"
#include "macro.h"
#include "siphash24.h"
typedef void (*hash_func_t)(const void *p, struct siphash *state);
typedef int (*compare_func_t)(const void *a, const void *b);
struct hash_ops {
hash_func_t hash;
compare_func_t compare;
};
void string_hash_func(const void *p, struct siphash *state);
int string_compare_func(const void *a, const void *b) _pure_;
extern const struct hash_ops string_hash_ops;
/* This will compare the passed pointers directly, and will not
* dereference them. This is hence not useful for strings or
* suchlike. */
void trivial_hash_func(const void *p, struct siphash *state);
int trivial_compare_func(const void *a, const void *b) _const_;
extern const struct hash_ops trivial_hash_ops;
/* 32bit values we can always just embed in the pointer itself, but
* in order to support 32bit archs we need store 64bit values
* indirectly, since they don't fit in a pointer. */
void uint64_hash_func(const void *p, struct siphash *state);
int uint64_compare_func(const void *a, const void *b) _pure_;
extern const struct hash_ops uint64_hash_ops;
/* On some archs dev_t is 32bit, and on others 64bit. And sometimes
* it's 64bit on 32bit archs, and sometimes 32bit on 64bit archs. Yuck! */
#if SIZEOF_DEV_T != 8
void devt_hash_func(const void *p, struct siphash *state) _pure_;
int devt_compare_func(const void *a, const void *b) _pure_;
extern const struct hash_ops devt_hash_ops = {
.hash = devt_hash_func,
.compare = devt_compare_func
};
#else
#define devt_hash_func uint64_hash_func
#define devt_compare_func uint64_compare_func
#define devt_hash_ops uint64_hash_ops
#endif

View File

@@ -284,66 +284,6 @@ static const struct hashmap_type_info hashmap_type_info[_HASHMAP_TYPE_MAX] = {
},
};
void string_hash_func(const void *p, struct siphash *state) {
siphash24_compress(p, strlen(p) + 1, state);
}
int string_compare_func(const void *a, const void *b) {
return strcmp(a, b);
}
const struct hash_ops string_hash_ops = {
.hash = string_hash_func,
.compare = string_compare_func
};
void trivial_hash_func(const void *p, struct siphash *state) {
siphash24_compress(&p, sizeof(p), state);
}
int trivial_compare_func(const void *a, const void *b) {
return a < b ? -1 : (a > b ? 1 : 0);
}
const struct hash_ops trivial_hash_ops = {
.hash = trivial_hash_func,
.compare = trivial_compare_func
};
void uint64_hash_func(const void *p, struct siphash *state) {
siphash24_compress(p, sizeof(uint64_t), state);
}
int uint64_compare_func(const void *_a, const void *_b) {
uint64_t a, b;
a = *(const uint64_t*) _a;
b = *(const uint64_t*) _b;
return a < b ? -1 : (a > b ? 1 : 0);
}
const struct hash_ops uint64_hash_ops = {
.hash = uint64_hash_func,
.compare = uint64_compare_func
};
#if SIZEOF_DEV_T != 8
void devt_hash_func(const void *p, struct siphash *state) {
siphash24_compress(p, sizeof(dev_t), state);
}
int devt_compare_func(const void *_a, const void *_b) {
dev_t a, b;
a = *(const dev_t*) _a;
b = *(const dev_t*) _b;
return a < b ? -1 : (a > b ? 1 : 0);
}
const struct hash_ops devt_hash_ops = {
.hash = devt_hash_func,
.compare = devt_compare_func
};
#endif
static unsigned n_buckets(HashmapBase *h) {
return h->has_indirect ? h->indirect.n_buckets
: hashmap_type_info[h->type].n_direct_buckets;

View File

@@ -28,8 +28,8 @@
#include <stdbool.h>
#include <stddef.h>
#include "hash-funcs.h"
#include "macro.h"
#include "siphash24.h"
#include "util.h"
/*
@@ -72,47 +72,6 @@ typedef struct {
#define _IDX_ITERATOR_FIRST (UINT_MAX - 1)
#define ITERATOR_FIRST ((Iterator) { .idx = _IDX_ITERATOR_FIRST, .next_key = NULL })
typedef void (*hash_func_t)(const void *p, struct siphash *state);
typedef int (*compare_func_t)(const void *a, const void *b);
struct hash_ops {
hash_func_t hash;
compare_func_t compare;
};
void string_hash_func(const void *p, struct siphash *state);
int string_compare_func(const void *a, const void *b) _pure_;
extern const struct hash_ops string_hash_ops;
/* This will compare the passed pointers directly, and will not
* dereference them. This is hence not useful for strings or
* suchlike. */
void trivial_hash_func(const void *p, struct siphash *state);
int trivial_compare_func(const void *a, const void *b) _const_;
extern const struct hash_ops trivial_hash_ops;
/* 32bit values we can always just embedd in the pointer itself, but
* in order to support 32bit archs we need store 64bit values
* indirectly, since they don't fit in a pointer. */
void uint64_hash_func(const void *p, struct siphash *state);
int uint64_compare_func(const void *a, const void *b) _pure_;
extern const struct hash_ops uint64_hash_ops;
/* On some archs dev_t is 32bit, and on others 64bit. And sometimes
* it's 64bit on 32bit archs, and sometimes 32bit on 64bit archs. Yuck! */
#if SIZEOF_DEV_T != 8
void devt_hash_func(const void *p, struct siphash *state) _pure_;
int devt_compare_func(const void *a, const void *b) _pure_;
extern const struct hash_ops devt_hash_ops = {
.hash = devt_hash_func,
.compare = devt_compare_func
};
#else
#define devt_hash_func uint64_hash_func
#define devt_compare_func uint64_compare_func
#define devt_hash_ops uint64_hash_ops
#endif
/* Macros for type checking */
#define PTR_COMPATIBLE_WITH_HASHMAP_BASE(h) \
(__builtin_types_compatible_p(typeof(h), HashmapBase*) || \

View File

@@ -221,7 +221,7 @@ int in_addr_to_string(int family, const union in_addr_union *u, char **ret) {
errno = 0;
if (!inet_ntop(family, u, x, l)) {
free(x);
return errno ? -errno : -EINVAL;
return errno > 0 ? -errno : -EINVAL;
}
*ret = x;
@@ -238,7 +238,7 @@ int in_addr_from_string(int family, const char *s, union in_addr_union *ret) {
errno = 0;
if (inet_pton(family, s, ret) <= 0)
return errno ? -errno : -EINVAL;
return errno > 0 ? -errno : -EINVAL;
return 0;
}

View File

@@ -35,6 +35,11 @@ union in_addr_union {
struct in6_addr in6;
};
struct in_addr_data {
int family;
union in_addr_union address;
};
int in_addr_is_null(int family, const union in_addr_union *u);
int in_addr_is_link_local(int family, const union in_addr_union *u);
int in_addr_is_localhost(int family, const union in_addr_union *u);

View File

@@ -28,6 +28,7 @@
#include <stdbool.h>
#include <stdlib.h>
#include <sys/signalfd.h>
#include <sys/socket.h>
#include <syslog.h>
#include "sd-id128.h"
@@ -130,6 +131,15 @@ int log_oom_internal(
int line,
const char *func);
int log_format_iovec(
struct iovec *iovec,
unsigned iovec_len,
unsigned *n,
bool newline_separator,
int error,
const char *format,
va_list ap);
/* This modifies the buffer passed! */
int log_dump_internal(
int level,

View File

@@ -331,16 +331,45 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
#define SET_FLAG(v, flag, b) \
(v) = (b) ? ((v) | (flag)) : ((v) & ~(flag))
#define IN_SET(x, y, ...) \
#define CASE_F(X) case X:
#define CASE_F_1(CASE, X) CASE_F(X)
#define CASE_F_2(CASE, X, ...) CASE(X) CASE_F_1(CASE, __VA_ARGS__)
#define CASE_F_3(CASE, X, ...) CASE(X) CASE_F_2(CASE, __VA_ARGS__)
#define CASE_F_4(CASE, X, ...) CASE(X) CASE_F_3(CASE, __VA_ARGS__)
#define CASE_F_5(CASE, X, ...) CASE(X) CASE_F_4(CASE, __VA_ARGS__)
#define CASE_F_6(CASE, X, ...) CASE(X) CASE_F_5(CASE, __VA_ARGS__)
#define CASE_F_7(CASE, X, ...) CASE(X) CASE_F_6(CASE, __VA_ARGS__)
#define CASE_F_8(CASE, X, ...) CASE(X) CASE_F_7(CASE, __VA_ARGS__)
#define CASE_F_9(CASE, X, ...) CASE(X) CASE_F_8(CASE, __VA_ARGS__)
#define CASE_F_10(CASE, X, ...) CASE(X) CASE_F_9(CASE, __VA_ARGS__)
#define CASE_F_11(CASE, X, ...) CASE(X) CASE_F_10(CASE, __VA_ARGS__)
#define CASE_F_12(CASE, X, ...) CASE(X) CASE_F_11(CASE, __VA_ARGS__)
#define CASE_F_13(CASE, X, ...) CASE(X) CASE_F_12(CASE, __VA_ARGS__)
#define CASE_F_14(CASE, X, ...) CASE(X) CASE_F_13(CASE, __VA_ARGS__)
#define CASE_F_15(CASE, X, ...) CASE(X) CASE_F_14(CASE, __VA_ARGS__)
#define CASE_F_16(CASE, X, ...) CASE(X) CASE_F_15(CASE, __VA_ARGS__)
#define CASE_F_17(CASE, X, ...) CASE(X) CASE_F_16(CASE, __VA_ARGS__)
#define CASE_F_18(CASE, X, ...) CASE(X) CASE_F_17(CASE, __VA_ARGS__)
#define CASE_F_19(CASE, X, ...) CASE(X) CASE_F_18(CASE, __VA_ARGS__)
#define CASE_F_20(CASE, X, ...) CASE(X) CASE_F_19(CASE, __VA_ARGS__)
#define GET_CASE_F(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,NAME,...) NAME
#define FOR_EACH_MAKE_CASE(...) \
GET_CASE_F(__VA_ARGS__,CASE_F_20,CASE_F_19,CASE_F_18,CASE_F_17,CASE_F_16,CASE_F_15,CASE_F_14,CASE_F_13,CASE_F_12,CASE_F_11, \
CASE_F_10,CASE_F_9,CASE_F_8,CASE_F_7,CASE_F_6,CASE_F_5,CASE_F_4,CASE_F_3,CASE_F_2,CASE_F_1) \
(CASE_F,__VA_ARGS__)
#define IN_SET(x, ...) \
({ \
static const typeof(y) _array[] = { (y), __VA_ARGS__ }; \
const typeof(y) _x = (x); \
unsigned _i; \
bool _found = false; \
for (_i = 0; _i < ELEMENTSOF(_array); _i++) \
if (_array[_i] == _x) { \
/* If the build breaks in the line below, you need to extend the case macros */ \
static _unused_ char _static_assert__macros_need_to_be_extended[20 - sizeof((int[]){__VA_ARGS__})/sizeof(int)]; \
switch(x) { \
FOR_EACH_MAKE_CASE(__VA_ARGS__) \
_found = true; \
break; \
default: \
break; \
} \
_found; \
})

View File

@@ -85,7 +85,7 @@ int parse_mode(const char *s, mode_t *ret) {
errno = 0;
l = strtol(s, &x, 8);
if (errno != 0)
if (errno > 0)
return -errno;
if (!x || x == s || *x)
return -EINVAL;
@@ -180,7 +180,7 @@ int parse_size(const char *t, uint64_t base, uint64_t *size) {
errno = 0;
l = strtoull(p, &e, 10);
if (errno != 0)
if (errno > 0)
return -errno;
if (e == p)
return -EINVAL;
@@ -196,7 +196,7 @@ int parse_size(const char *t, uint64_t base, uint64_t *size) {
char *e2;
l2 = strtoull(e, &e2, 10);
if (errno != 0)
if (errno > 0)
return -errno;
/* Ignore failure. E.g. 10.M is valid */
@@ -336,7 +336,7 @@ int safe_atou(const char *s, unsigned *ret_u) {
errno = 0;
l = strtoul(s, &x, 0);
if (errno != 0)
if (errno > 0)
return -errno;
if (!x || x == s || *x)
return -EINVAL;
@@ -358,7 +358,7 @@ int safe_atoi(const char *s, int *ret_i) {
errno = 0;
l = strtol(s, &x, 0);
if (errno != 0)
if (errno > 0)
return -errno;
if (!x || x == s || *x)
return -EINVAL;
@@ -380,7 +380,7 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) {
errno = 0;
l = strtoull(s, &x, 0);
if (errno != 0)
if (errno > 0)
return -errno;
if (!x || x == s || *x)
return -EINVAL;
@@ -400,7 +400,7 @@ int safe_atolli(const char *s, long long int *ret_lli) {
errno = 0;
l = strtoll(s, &x, 0);
if (errno != 0)
if (errno > 0)
return -errno;
if (!x || x == s || *x)
return -EINVAL;
@@ -420,7 +420,7 @@ int safe_atou8(const char *s, uint8_t *ret) {
errno = 0;
l = strtoul(s, &x, 0);
if (errno != 0)
if (errno > 0)
return -errno;
if (!x || x == s || *x)
return -EINVAL;
@@ -444,7 +444,7 @@ int safe_atou16(const char *s, uint16_t *ret) {
errno = 0;
l = strtoul(s, &x, 0);
if (errno != 0)
if (errno > 0)
return -errno;
if (!x || x == s || *x)
return -EINVAL;
@@ -466,7 +466,7 @@ int safe_atoi16(const char *s, int16_t *ret) {
errno = 0;
l = strtol(s, &x, 0);
if (errno != 0)
if (errno > 0)
return -errno;
if (!x || x == s || *x)
return -EINVAL;
@@ -491,7 +491,7 @@ int safe_atod(const char *s, double *ret_d) {
errno = 0;
d = strtod_l(s, &x, loc);
if (errno != 0) {
if (errno > 0) {
freelocale(loc);
return -errno;
}

View File

@@ -111,7 +111,7 @@ int path_make_absolute_cwd(const char *p, char **ret) {
cwd = get_current_dir_name();
if (!cwd)
return -errno;
return negative_errno();
c = strjoin(cwd, "/", p, NULL);
}

View File

@@ -18,6 +18,8 @@ struct siphash {
void siphash24_init(struct siphash *state, const uint8_t k[16]);
void siphash24_compress(const void *in, size_t inlen, struct siphash *state);
#define siphash24_compress_byte(byte, state) siphash24_compress((const uint8_t[]) { (byte) }, 1, (state))
uint64_t siphash24_finalize(struct siphash *state);
uint64_t siphash24(const void *in, size_t inlen, const uint8_t k[16]);

View File

@@ -91,7 +91,7 @@ int socket_address_listen(
mode_t directory_mode,
mode_t socket_mode,
const char *label);
int make_socket_fd(int log_level, const char* address, int flags);
int make_socket_fd(int log_level, const char* address, int type, int flags);
bool socket_address_is(const SocketAddress *a, const char *s, int type);
bool socket_address_is_netlink(const SocketAddress *a, const char *s);
@@ -107,7 +107,7 @@ bool socket_ipv6_is_supported(void);
int sockaddr_port(const struct sockaddr *_sa) _pure_;
int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret);
int getpeername_pretty(int fd, char **ret);
int getpeername_pretty(int fd, bool include_port, char **ret);
int getsockname_pretty(int fd, char **ret);
int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret);

View File

@@ -0,0 +1,80 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
This file is part of systemd.
Copyright 2010 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "nm-sd-adapt.h"
#include <printf.h>
#include <stdarg.h>
#include <stdio.h>
#include <sys/types.h>
#include "macro.h"
#define xsprintf(buf, fmt, ...) \
assert_message_se((size_t) snprintf(buf, ELEMENTSOF(buf), fmt, __VA_ARGS__) < ELEMENTSOF(buf), "xsprintf: " #buf "[] must be big enough")
#define VA_FORMAT_ADVANCE(format, ap) \
do { \
int _argtypes[128]; \
size_t _i, _k; \
_k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
assert(_k < ELEMENTSOF(_argtypes)); \
for (_i = 0; _i < _k; _i++) { \
if (_argtypes[_i] & PA_FLAG_PTR) { \
(void) va_arg(ap, void*); \
continue; \
} \
\
switch (_argtypes[_i]) { \
case PA_INT: \
case PA_INT|PA_FLAG_SHORT: \
case PA_CHAR: \
(void) va_arg(ap, int); \
break; \
case PA_INT|PA_FLAG_LONG: \
(void) va_arg(ap, long int); \
break; \
case PA_INT|PA_FLAG_LONG_LONG: \
(void) va_arg(ap, long long int); \
break; \
case PA_WCHAR: \
(void) va_arg(ap, wchar_t); \
break; \
case PA_WSTRING: \
case PA_STRING: \
case PA_POINTER: \
(void) va_arg(ap, void*); \
break; \
case PA_FLOAT: \
case PA_DOUBLE: \
(void) va_arg(ap, double); \
break; \
case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: \
(void) va_arg(ap, long double); \
break; \
default: \
assert_not_reached("Unknown format string argument."); \
} \
} \
} while(false)

View File

@@ -49,16 +49,34 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k
return (type) string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \
}
#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) \
scope type name##_from_string(const char *s) { \
int b; \
b = parse_boolean(s); \
if (b == 0) \
return (type) 0; \
else if (b > 0) \
return yes; \
return (type) string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \
}
#define _DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \
_DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
_DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope) \
struct __useless_struct_to_allow_trailing_semicolon__
#define _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,scope) \
_DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
_DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) \
struct __useless_struct_to_allow_trailing_semicolon__
#define DEFINE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,)
#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,static)
#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,static)
#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,static)
#define DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes) _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,)
/* For string conversions where numbers are also acceptable */
#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max) \
int name##_to_string_alloc(type i, char **str) { \

View File

@@ -321,18 +321,67 @@ char *truncate_nl(char *s) {
return s;
}
char ascii_tolower(char x) {
if (x >= 'A' && x <= 'Z')
return x - 'A' + 'a';
return x;
}
char *ascii_strlower(char *t) {
char *p;
assert(t);
for (p = t; *p; p++)
if (*p >= 'A' && *p <= 'Z')
*p = *p - 'A' + 'a';
*p = ascii_tolower(*p);
return t;
}
char *ascii_strlower_n(char *t, size_t n) {
size_t i;
if (n <= 0)
return t;
for (i = 0; i < n; i++)
t[i] = ascii_tolower(t[i]);
return t;
}
int ascii_strcasecmp_n(const char *a, const char *b, size_t n) {
for (; n > 0; a++, b++, n--) {
int x, y;
x = (int) (uint8_t) ascii_tolower(*a);
y = (int) (uint8_t) ascii_tolower(*b);
if (x != y)
return x - y;
}
return 0;
}
int ascii_strcasecmp_nn(const char *a, size_t n, const char *b, size_t m) {
int r;
r = ascii_strcasecmp_n(a, b, MIN(n, m));
if (r != 0)
return r;
if (n < m)
return -1;
else if (n > m)
return 1;
else
return 0;
}
bool chars_intersect(const char *a, const char *b) {
const char *p;

View File

@@ -132,7 +132,12 @@ char *strstrip(char *s);
char *delete_chars(char *s, const char *bad);
char *truncate_nl(char *s);
char *ascii_strlower(char *path);
char ascii_tolower(char x);
char *ascii_strlower(char *s);
char *ascii_strlower_n(char *s, size_t n);
int ascii_strcasecmp_n(const char *a, const char *b, size_t n);
int ascii_strcasecmp_nn(const char *a, size_t n, const char *b, size_t m);
bool chars_intersect(const char *a, const char *b) _pure_;

View File

@@ -530,7 +530,7 @@ int on_ac_power(void) {
errno = 0;
de = readdir(d);
if (!de && errno != 0)
if (!de && errno > 0)
return -errno;
if (!de)

View File

@@ -36,14 +36,14 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
assert(options);
assert(offset);
if (code != DHCP_OPTION_END)
if (code != SD_DHCP_OPTION_END)
/* always make sure there is space for an END option */
size --;
switch (code) {
case DHCP_OPTION_PAD:
case DHCP_OPTION_END:
case SD_DHCP_OPTION_PAD:
case SD_DHCP_OPTION_END:
if (size < *offset + 1)
return -ENOBUFS;
@@ -93,7 +93,7 @@ int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset,
else if (r == -ENOBUFS && (file || sname)) {
/* did not fit, but we have more buffers to try
close the options array and move the offset to its end */
r = option_append(message->options, size, offset, DHCP_OPTION_END, 0, NULL);
r = option_append(message->options, size, offset, SD_DHCP_OPTION_END, 0, NULL);
if (r < 0)
return r;
@@ -114,7 +114,7 @@ int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset,
} else if (r == -ENOBUFS && sname) {
/* did not fit, but we have more buffers to try
close the file array and move the offset to its end */
r = option_append(message->options, size, offset, DHCP_OPTION_END, 0, NULL);
r = option_append(message->options, size, offset, SD_DHCP_OPTION_END, 0, NULL);
if (r < 0)
return r;
@@ -154,10 +154,10 @@ static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overlo
code = options[offset ++];
switch (code) {
case DHCP_OPTION_PAD:
case SD_DHCP_OPTION_PAD:
continue;
case DHCP_OPTION_END:
case SD_DHCP_OPTION_END:
return 0;
}
@@ -172,7 +172,7 @@ static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overlo
option = &options[offset];
switch (code) {
case DHCP_OPTION_MESSAGE_TYPE:
case SD_DHCP_OPTION_MESSAGE_TYPE:
if (len != 1)
return -EINVAL;
@@ -181,7 +181,7 @@ static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overlo
break;
case DHCP_OPTION_ERROR_MESSAGE:
case SD_DHCP_OPTION_ERROR_MESSAGE:
if (len == 0)
return -EINVAL;
@@ -205,7 +205,7 @@ static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overlo
}
break;
case DHCP_OPTION_OVERLOAD:
case SD_DHCP_OPTION_OVERLOAD:
if (len != 1)
return -EINVAL;

View File

@@ -46,7 +46,7 @@ int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid,
message->magic = htobe32(DHCP_MAGIC_COOKIE);
r = dhcp_option_append(message, optlen, &offset, 0,
DHCP_OPTION_MESSAGE_TYPE, 1, &type);
SD_DHCP_OPTION_MESSAGE_TYPE, 1, &type);
if (r < 0)
return r;

View File

@@ -107,48 +107,6 @@ enum {
DHCP_OVERLOAD_SNAME = 2,
};
enum {
DHCP_OPTION_PAD = 0,
DHCP_OPTION_SUBNET_MASK = 1,
DHCP_OPTION_TIME_OFFSET = 2,
DHCP_OPTION_ROUTER = 3,
DHCP_OPTION_DOMAIN_NAME_SERVER = 6,
DHCP_OPTION_HOST_NAME = 12,
DHCP_OPTION_BOOT_FILE_SIZE = 13,
DHCP_OPTION_DOMAIN_NAME = 15,
DHCP_OPTION_ROOT_PATH = 17,
DHCP_OPTION_ENABLE_IP_FORWARDING = 19,
DHCP_OPTION_ENABLE_IP_FORWARDING_NL = 20,
DHCP_OPTION_POLICY_FILTER = 21,
DHCP_OPTION_INTERFACE_MDR = 22,
DHCP_OPTION_INTERFACE_TTL = 23,
DHCP_OPTION_INTERFACE_MTU_AGING_TIMEOUT = 24,
DHCP_OPTION_INTERFACE_MTU = 26,
DHCP_OPTION_BROADCAST = 28,
DHCP_OPTION_STATIC_ROUTE = 33,
DHCP_OPTION_NTP_SERVER = 42,
DHCP_OPTION_VENDOR_SPECIFIC = 43,
DHCP_OPTION_REQUESTED_IP_ADDRESS = 50,
DHCP_OPTION_IP_ADDRESS_LEASE_TIME = 51,
DHCP_OPTION_OVERLOAD = 52,
DHCP_OPTION_MESSAGE_TYPE = 53,
DHCP_OPTION_SERVER_IDENTIFIER = 54,
DHCP_OPTION_PARAMETER_REQUEST_LIST = 55,
DHCP_OPTION_ERROR_MESSAGE = 56,
DHCP_OPTION_MAXIMUM_MESSAGE_SIZE = 57,
DHCP_OPTION_RENEWAL_T1_TIME = 58,
DHCP_OPTION_REBINDING_T2_TIME = 59,
DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60,
DHCP_OPTION_CLIENT_IDENTIFIER = 61,
DHCP_OPTION_FQDN = 81,
DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
DHCP_OPTION_NEW_TZDB_TIMEZONE = 101,
DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
DHCP_OPTION_PRIVATE_BASE = 224,
DHCP_OPTION_PRIVATE_LAST = 254,
DHCP_OPTION_END = 255,
};
#define DHCP_MAX_FQDN_LENGTH 255
enum {

View File

@@ -25,6 +25,8 @@
#include <netinet/in.h>
#include <string.h>
#include "sd-dhcp6-client.h"
#include "alloc-util.h"
#include "dhcp6-internal.h"
#include "dhcp6-protocol.h"
@@ -92,11 +94,11 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
assert_return(buf && *buf && buflen && ia, -EINVAL);
switch (ia->type) {
case DHCP6_OPTION_IA_NA:
case SD_DHCP6_OPTION_IA_NA:
len = DHCP6_OPTION_IA_NA_LEN;
break;
case DHCP6_OPTION_IA_TA:
case SD_DHCP6_OPTION_IA_TA:
len = DHCP6_OPTION_IA_TA_LEN;
break;
@@ -119,7 +121,7 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
*buflen -= len;
LIST_FOREACH(addresses, addr, ia->addresses) {
r = option_append_hdr(buf, buflen, DHCP6_OPTION_IAADDR,
r = option_append_hdr(buf, buflen, SD_DHCP6_OPTION_IAADDR,
sizeof(addr->iaaddr));
if (r < 0)
return r;
@@ -198,7 +200,7 @@ int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
assert_return(!ia->addresses, -EINVAL);
switch (iatype) {
case DHCP6_OPTION_IA_NA:
case SD_DHCP6_OPTION_IA_NA:
if (*buflen < DHCP6_OPTION_IA_NA_LEN + sizeof(DHCP6Option) +
sizeof(addr->iaaddr)) {
@@ -221,7 +223,7 @@ int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
break;
case DHCP6_OPTION_IA_TA:
case SD_DHCP6_OPTION_IA_TA:
if (*buflen < DHCP6_OPTION_IA_TA_LEN + sizeof(DHCP6Option) +
sizeof(addr->iaaddr)) {
r = -ENOBUFS;
@@ -249,7 +251,7 @@ int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
while ((r = option_parse_hdr(buf, buflen, &opt, &optlen)) >= 0) {
switch (opt) {
case DHCP6_OPTION_IAADDR:
case SD_DHCP6_OPTION_IAADDR:
addr = new0(DHCP6Address, 1);
if (!addr) {
@@ -276,7 +278,7 @@ int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
break;
case DHCP6_OPTION_STATUS_CODE:
case SD_DHCP6_OPTION_STATUS_CODE:
if (optlen < sizeof(status))
break;

View File

@@ -100,41 +100,6 @@ enum {
_DHCP6_MESSAGE_MAX = 14,
};
enum {
DHCP6_OPTION_CLIENTID = 1,
DHCP6_OPTION_SERVERID = 2,
DHCP6_OPTION_IA_NA = 3,
DHCP6_OPTION_IA_TA = 4,
DHCP6_OPTION_IAADDR = 5,
DHCP6_OPTION_ORO = 6,
DHCP6_OPTION_PREFERENCE = 7,
DHCP6_OPTION_ELAPSED_TIME = 8,
DHCP6_OPTION_RELAY_MSG = 9,
/* option code 10 is unassigned */
DHCP6_OPTION_AUTH = 11,
DHCP6_OPTION_UNICAST = 12,
DHCP6_OPTION_STATUS_CODE = 13,
DHCP6_OPTION_RAPID_COMMIT = 14,
DHCP6_OPTION_USER_CLASS = 15,
DHCP6_OPTION_VENDOR_CLASS = 16,
DHCP6_OPTION_VENDOR_OPTS = 17,
DHCP6_OPTION_INTERFACE_ID = 18,
DHCP6_OPTION_RECONF_MSG = 19,
DHCP6_OPTION_RECONF_ACCEPT = 20,
DHCP6_OPTION_DNS_SERVERS = 23, /* RFC 3646 */
DHCP6_OPTION_DOMAIN_LIST = 24, /* RFC 3646 */
DHCP6_OPTION_SNTP_SERVERS = 31, /* RFC 4075, deprecated */
/* option code 35 is unassigned */
DHCP6_OPTION_NTP_SERVER = 56, /* RFC 5908 */
/* option codes 89-142 are unassigned */
/* option codes 144-65535 are unassigned */
};
enum {
DHCP6_NTP_SUBOPTION_SRV_ADDR = 1,
DHCP6_NTP_SUBOPTION_MC_ADDR = 2,

View File

@@ -443,7 +443,7 @@ int deserialize_in6_addrs(struct in6_addr **ret, const char *string) {
return size;
}
void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *routes, size_t size) {
void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, size_t size) {
unsigned i;
assert(f);
@@ -454,10 +454,15 @@ void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *route
fprintf(f, "%s=", key);
for (i = 0; i < size; i++) {
fprintf(f, "%s/%" PRIu8, inet_ntoa(routes[i].dst_addr),
routes[i].dst_prefixlen);
fprintf(f, ",%s%s", inet_ntoa(routes[i].gw_addr),
(i < (size - 1)) ? " ": "");
struct in_addr dest, gw;
uint8_t length;
assert_se(sd_dhcp_route_get_destination(routes[i], &dest) >= 0);
assert_se(sd_dhcp_route_get_gateway(routes[i], &gw) >= 0);
assert_se(sd_dhcp_route_get_destination_prefix_length(routes[i], &length) >= 0);
fprintf(f, "%s/%" PRIu8, inet_ntoa(dest), length);
fprintf(f, ",%s%s", inet_ntoa(gw), (i < (size - 1)) ? " ": "");
}
fputs("\n", f);

View File

@@ -25,6 +25,8 @@
#include <stdbool.h>
#include "sd-dhcp-lease.h"
#if 0 /* NM_IGNORED */
#include "condition.h"
#include "udev.h"
@@ -78,7 +80,7 @@ int deserialize_in6_addrs(struct in6_addr **addresses, const char *string);
/* don't include "dhcp-lease-internal.h" as it causes conflicts between netinet/ip.h and linux/ip.h */
struct sd_dhcp_route;
void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *routes, size_t size);
void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, size_t size);
int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string);
int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size);

View File

@@ -106,11 +106,11 @@ struct sd_dhcp_client {
};
static const uint8_t default_req_opts[] = {
DHCP_OPTION_SUBNET_MASK,
DHCP_OPTION_ROUTER,
DHCP_OPTION_HOST_NAME,
DHCP_OPTION_DOMAIN_NAME,
DHCP_OPTION_DOMAIN_NAME_SERVER,
SD_DHCP_OPTION_SUBNET_MASK,
SD_DHCP_OPTION_ROUTER,
SD_DHCP_OPTION_HOST_NAME,
SD_DHCP_OPTION_DOMAIN_NAME,
SD_DHCP_OPTION_DOMAIN_NAME_SERVER,
};
static int client_receive_message_raw(sd_event_source *s, int fd,
@@ -145,11 +145,11 @@ int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) {
DHCP_STATE_STOPPED), -EBUSY);
switch(option) {
case DHCP_OPTION_PAD:
case DHCP_OPTION_OVERLOAD:
case DHCP_OPTION_MESSAGE_TYPE:
case DHCP_OPTION_PARAMETER_REQUEST_LIST:
case DHCP_OPTION_END:
case SD_DHCP_OPTION_PAD:
case SD_DHCP_OPTION_OVERLOAD:
case SD_DHCP_OPTION_MESSAGE_TYPE:
case SD_DHCP_OPTION_PARAMETER_REQUEST_LIST:
case SD_DHCP_OPTION_END:
return -EINVAL;
default:
@@ -488,7 +488,7 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
Identifier option is not set */
if (client->client_id_len) {
r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
DHCP_OPTION_CLIENT_IDENTIFIER,
SD_DHCP_OPTION_CLIENT_IDENTIFIER,
client->client_id_len,
&client->client_id);
if (r < 0)
@@ -504,7 +504,7 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
messages.
*/
r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
DHCP_OPTION_PARAMETER_REQUEST_LIST,
SD_DHCP_OPTION_PARAMETER_REQUEST_LIST,
client->req_opts_size, client->req_opts);
if (r < 0)
return r;
@@ -533,7 +533,7 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
*/
max_size = htobe16(size);
r = dhcp_option_append(&packet->dhcp, client->mtu, &optoffset, 0,
DHCP_OPTION_MAXIMUM_MESSAGE_SIZE,
SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE,
2, &max_size);
if (r < 0)
return r;
@@ -559,7 +559,7 @@ static int client_append_fqdn_option(DHCPMessage *message, size_t optlen, size_t
r = dns_name_to_wire_format(fqdn, buffer + 3, sizeof(buffer) - 3, false);
if (r > 0)
r = dhcp_option_append(message, optlen, optoffset, 0,
DHCP_OPTION_FQDN, 3 + r, buffer);
SD_DHCP_OPTION_FQDN, 3 + r, buffer);
return r;
}
@@ -595,7 +595,7 @@ static int client_send_discover(sd_dhcp_client *client) {
*/
if (client->last_addr != INADDR_ANY) {
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
DHCP_OPTION_REQUESTED_IP_ADDRESS,
SD_DHCP_OPTION_REQUESTED_IP_ADDRESS,
4, &client->last_addr);
if (r < 0)
return r;
@@ -611,7 +611,7 @@ static int client_send_discover(sd_dhcp_client *client) {
DHCPDISCOVER but dhclient does and so we do as well
*/
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
DHCP_OPTION_HOST_NAME,
SD_DHCP_OPTION_HOST_NAME,
strlen(client->hostname), client->hostname);
} else
r = client_append_fqdn_option(&discover->dhcp, optlen, &optoffset,
@@ -622,7 +622,7 @@ static int client_send_discover(sd_dhcp_client *client) {
if (client->vendor_class_identifier) {
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
strlen(client->vendor_class_identifier),
client->vendor_class_identifier);
if (r < 0)
@@ -630,7 +630,7 @@ static int client_send_discover(sd_dhcp_client *client) {
}
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
DHCP_OPTION_END, 0, NULL);
SD_DHCP_OPTION_END, 0, NULL);
if (r < 0)
return r;
@@ -669,13 +669,13 @@ static int client_send_request(sd_dhcp_client *client) {
*/
r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
DHCP_OPTION_SERVER_IDENTIFIER,
SD_DHCP_OPTION_SERVER_IDENTIFIER,
4, &client->lease->server_address);
if (r < 0)
return r;
r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
DHCP_OPTION_REQUESTED_IP_ADDRESS,
SD_DHCP_OPTION_REQUESTED_IP_ADDRESS,
4, &client->lease->address);
if (r < 0)
return r;
@@ -688,7 +688,7 @@ static int client_send_request(sd_dhcp_client *client) {
assigned address. ciaddr MUST be zero.
*/
r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
DHCP_OPTION_REQUESTED_IP_ADDRESS,
SD_DHCP_OPTION_REQUESTED_IP_ADDRESS,
4, &client->last_addr);
if (r < 0)
return r;
@@ -723,7 +723,7 @@ static int client_send_request(sd_dhcp_client *client) {
if (client->hostname) {
if (dns_name_is_single_label(client->hostname))
r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
DHCP_OPTION_HOST_NAME,
SD_DHCP_OPTION_HOST_NAME,
strlen(client->hostname), client->hostname);
else
r = client_append_fqdn_option(&request->dhcp, optlen, &optoffset,
@@ -733,7 +733,7 @@ static int client_send_request(sd_dhcp_client *client) {
}
r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
DHCP_OPTION_END, 0, NULL);
SD_DHCP_OPTION_END, 0, NULL);
if (r < 0)
return r;

View File

@@ -39,6 +39,7 @@
#include "in-addr-util.h"
#include "network-internal.h"
#include "parse-util.h"
#include "stdio-util.h"
#include "string-util.h"
#include "unaligned.h"
@@ -207,14 +208,28 @@ int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr) {
return 0;
}
int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routes) {
/*
* The returned routes array must be freed by the caller.
* Route objects have the same lifetime of the lease and must not be freed.
*/
int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes) {
sd_dhcp_route **ret;
unsigned i;
assert_return(lease, -EINVAL);
assert_return(routes, -EINVAL);
if (lease->static_route_size <= 0)
return -ENODATA;
*routes = lease->static_route;
ret = new(sd_dhcp_route *, lease->static_route_size);
if (!ret)
return -ENOMEM;
for (i = 0; i < lease->static_route_size; i++)
ret[i] = &lease->static_route[i];
*routes = ret;
return (int) lease->static_route_size;
}
@@ -454,7 +469,7 @@ static int lease_parse_classless_routes(
if (len < 4)
return -EINVAL;
lease_parse_be32(option, 4, &route->gw_addr.s_addr);
assert_se(lease_parse_be32(option, 4, &route->gw_addr.s_addr) >= 0);
option += 4;
len -= 4;
@@ -472,21 +487,21 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
switch(code) {
case DHCP_OPTION_IP_ADDRESS_LEASE_TIME:
case SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME:
r = lease_parse_u32(option, len, &lease->lifetime, 1);
if (r < 0)
log_debug_errno(r, "Failed to parse lease time, ignoring: %m");
break;
case DHCP_OPTION_SERVER_IDENTIFIER:
case SD_DHCP_OPTION_SERVER_IDENTIFIER:
r = lease_parse_be32(option, len, &lease->server_address);
if (r < 0)
log_debug_errno(r, "Failed to parse server identifier, ignoring: %m");
break;
case DHCP_OPTION_SUBNET_MASK:
case SD_DHCP_OPTION_SUBNET_MASK:
r = lease_parse_be32(option, len, &lease->subnet_mask);
if (r < 0)
log_debug_errno(r, "Failed to parse subnet mask, ignoring: %m");
@@ -494,7 +509,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
lease->have_subnet_mask = true;
break;
case DHCP_OPTION_BROADCAST:
case SD_DHCP_OPTION_BROADCAST:
r = lease_parse_be32(option, len, &lease->broadcast);
if (r < 0)
log_debug_errno(r, "Failed to parse broadcast address, ignoring: %m");
@@ -502,7 +517,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
lease->have_broadcast = true;
break;
case DHCP_OPTION_ROUTER:
case SD_DHCP_OPTION_ROUTER:
if (len >= 4) {
r = lease_parse_be32(option, 4, &lease->router);
if (r < 0)
@@ -510,31 +525,31 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
}
break;
case DHCP_OPTION_DOMAIN_NAME_SERVER:
case SD_DHCP_OPTION_DOMAIN_NAME_SERVER:
r = lease_parse_in_addrs(option, len, &lease->dns, &lease->dns_size);
if (r < 0)
log_debug_errno(r, "Failed to parse DNS server, ignoring: %m");
break;
case DHCP_OPTION_NTP_SERVER:
case SD_DHCP_OPTION_NTP_SERVER:
r = lease_parse_in_addrs(option, len, &lease->ntp, &lease->ntp_size);
if (r < 0)
log_debug_errno(r, "Failed to parse NTP server, ignoring: %m");
break;
case DHCP_OPTION_STATIC_ROUTE:
case SD_DHCP_OPTION_STATIC_ROUTE:
r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated);
if (r < 0)
log_debug_errno(r, "Failed to parse static routes, ignoring: %m");
break;
case DHCP_OPTION_INTERFACE_MTU:
case SD_DHCP_OPTION_INTERFACE_MTU:
r = lease_parse_u16(option, len, &lease->mtu, 68);
if (r < 0)
log_debug_errno(r, "Failed to parse MTU, ignoring: %m");
break;
case DHCP_OPTION_DOMAIN_NAME: {
case SD_DHCP_OPTION_DOMAIN_NAME: {
_cleanup_free_ char *domainname = NULL, *normalized = NULL;
r = lease_parse_string(option, len, &domainname);
@@ -561,7 +576,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
break;
}
case DHCP_OPTION_HOST_NAME: {
case SD_DHCP_OPTION_HOST_NAME: {
_cleanup_free_ char *hostname = NULL, *normalized = NULL;
r = lease_parse_string(option, len, &hostname);
@@ -588,25 +603,25 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
break;
}
case DHCP_OPTION_ROOT_PATH:
case SD_DHCP_OPTION_ROOT_PATH:
r = lease_parse_string(option, len, &lease->root_path);
if (r < 0)
log_debug_errno(r, "Failed to parse root path, ignoring: %m");
break;
case DHCP_OPTION_RENEWAL_T1_TIME:
case SD_DHCP_OPTION_RENEWAL_T1_TIME:
r = lease_parse_u32(option, len, &lease->t1, 1);
if (r < 0)
log_debug_errno(r, "Failed to parse T1 time, ignoring: %m");
break;
case DHCP_OPTION_REBINDING_T2_TIME:
case SD_DHCP_OPTION_REBINDING_T2_TIME:
r = lease_parse_u32(option, len, &lease->t2, 1);
if (r < 0)
log_debug_errno(r, "Failed to parse T2 time, ignoring: %m");
break;
case DHCP_OPTION_CLASSLESS_STATIC_ROUTE:
case SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE:
r = lease_parse_classless_routes(
option, len,
&lease->static_route,
@@ -616,7 +631,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
log_debug_errno(r, "Failed to parse classless routes, ignoring: %m");
break;
case DHCP_OPTION_NEW_TZDB_TIMEZONE: {
case SD_DHCP_OPTION_NEW_TZDB_TIMEZONE: {
_cleanup_free_ char *tz = NULL;
r = lease_parse_string(option, len, &tz);
@@ -637,7 +652,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
break;
}
case DHCP_OPTION_VENDOR_SPECIFIC:
case SD_DHCP_OPTION_VENDOR_SPECIFIC:
if (len <= 0)
lease->vendor_specific = mfree(lease->vendor_specific);
@@ -655,7 +670,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
lease->vendor_specific_len = len;
break;
case DHCP_OPTION_PRIVATE_BASE ... DHCP_OPTION_PRIVATE_LAST:
case SD_DHCP_OPTION_PRIVATE_BASE ... SD_DHCP_OPTION_PRIVATE_LAST:
r = dhcp_lease_insert_private_option(lease, code, option, len);
if (r < 0)
return r;
@@ -724,7 +739,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
size_t client_id_len, data_len;
const char *string;
uint16_t mtu;
struct sd_dhcp_route *routes;
_cleanup_free_ sd_dhcp_route **routes = NULL;
uint32_t t1, t2, lifetime;
int r;
@@ -841,7 +856,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
LIST_FOREACH(options, option, lease->private_options) {
char key[strlen("OPTION_000")+1];
snprintf(key, sizeof(key), "OPTION_%"PRIu8, option->tag);
xsprintf(key, "OPTION_%" PRIu8, option->tag);
r = serialize_dhcp_option(f, key, option->data, option->length);
if (r < 0)
goto fail;
@@ -884,7 +899,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
*lifetime = NULL,
*t1 = NULL,
*t2 = NULL,
*options[DHCP_OPTION_PRIVATE_LAST - DHCP_OPTION_PRIVATE_BASE + 1] = {};
*options[SD_DHCP_OPTION_PRIVATE_LAST - SD_DHCP_OPTION_PRIVATE_BASE + 1] = {};
int r, i;
@@ -1052,7 +1067,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
log_debug_errno(r, "Failed to parse vendor specific data %s, ignoring: %m", vendor_specific_hex);
}
for (i = 0; i <= DHCP_OPTION_PRIVATE_LAST - DHCP_OPTION_PRIVATE_BASE; i++) {
for (i = 0; i <= SD_DHCP_OPTION_PRIVATE_LAST - SD_DHCP_OPTION_PRIVATE_BASE; i++) {
_cleanup_free_ void *data = NULL;
size_t len;
@@ -1065,7 +1080,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
continue;
}
r = dhcp_lease_insert_private_option(lease, DHCP_OPTION_PRIVATE_BASE + i, data, len);
r = dhcp_lease_insert_private_option(lease, SD_DHCP_OPTION_PRIVATE_BASE + i, data, len);
if (r < 0)
return r;
}
@@ -1143,3 +1158,27 @@ int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **tz) {
*tz = lease->timezone;
return 0;
}
int sd_dhcp_route_get_destination(sd_dhcp_route *route, struct in_addr *destination) {
assert_return(route, -EINVAL);
assert_return(destination, -EINVAL);
*destination = route->dst_addr;
return 0;
}
int sd_dhcp_route_get_destination_prefix_length(sd_dhcp_route *route, uint8_t *length) {
assert_return(route, -EINVAL);
assert_return(length, -EINVAL);
*length = route->dst_prefixlen;
return 0;
}
int sd_dhcp_route_get_gateway(sd_dhcp_route *route, struct in_addr *gateway) {
assert_return(route, -EINVAL);
assert_return(gateway, -EINVAL);
*gateway = route->gw_addr;
return 0;
}

View File

@@ -74,10 +74,10 @@ struct sd_dhcp6_client {
};
static const uint16_t default_req_opts[] = {
DHCP6_OPTION_DNS_SERVERS,
DHCP6_OPTION_DOMAIN_LIST,
DHCP6_OPTION_NTP_SERVER,
DHCP6_OPTION_SNTP_SERVERS,
SD_DHCP6_OPTION_DNS_SERVERS,
SD_DHCP6_OPTION_DOMAIN_LIST,
SD_DHCP6_OPTION_NTP_SERVER,
SD_DHCP6_OPTION_SNTP_SERVERS,
};
const char * dhcp6_message_type_table[_DHCP6_MESSAGE_MAX] = {
@@ -247,10 +247,10 @@ int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, uint16_t option)
assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
switch(option) {
case DHCP6_OPTION_DNS_SERVERS:
case DHCP6_OPTION_DOMAIN_LIST:
case DHCP6_OPTION_SNTP_SERVERS:
case DHCP6_OPTION_NTP_SERVER:
case SD_DHCP6_OPTION_DNS_SERVERS:
case SD_DHCP6_OPTION_DOMAIN_LIST:
case SD_DHCP6_OPTION_SNTP_SERVERS:
case SD_DHCP6_OPTION_NTP_SERVER:
break;
default:
@@ -364,7 +364,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
message->type = DHCP6_SOLICIT;
r = dhcp6_option_append(&opt, &optlen,
DHCP6_OPTION_RAPID_COMMIT, 0, NULL);
SD_DHCP6_OPTION_RAPID_COMMIT, 0, NULL);
if (r < 0)
return r;
@@ -382,7 +382,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
else
message->type = DHCP6_RENEW;
r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_SERVERID,
r = dhcp6_option_append(&opt, &optlen, SD_DHCP6_OPTION_SERVERID,
client->lease->serverid_len,
client->lease->serverid);
if (r < 0)
@@ -408,14 +408,14 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
return -EINVAL;
}
r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_ORO,
r = dhcp6_option_append(&opt, &optlen, SD_DHCP6_OPTION_ORO,
client->req_opts_len * sizeof(be16_t),
client->req_opts);
if (r < 0)
return r;
assert (client->duid_len);
r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_CLIENTID,
r = dhcp6_option_append(&opt, &optlen, SD_DHCP6_OPTION_CLIENTID,
client->duid_len, &client->duid);
if (r < 0)
return r;
@@ -426,7 +426,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
else
elapsed_time = 0xffff;
r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_ELAPSED_TIME,
r = dhcp6_option_append(&opt, &optlen, SD_DHCP6_OPTION_ELAPSED_TIME,
sizeof(elapsed_time), &elapsed_time);
if (r < 0)
return r;
@@ -689,7 +689,7 @@ static int client_parse_message(sd_dhcp6_client *client,
while ((r = dhcp6_option_parse(&option, &len, &optcode, &optlen,
&optval)) >= 0) {
switch (optcode) {
case DHCP6_OPTION_CLIENTID:
case SD_DHCP6_OPTION_CLIENTID:
if (clientid) {
log_dhcp6_client(client, "%s contains multiple clientids",
dhcp6_message_type_to_string(message->type));
@@ -707,7 +707,7 @@ static int client_parse_message(sd_dhcp6_client *client,
break;
case DHCP6_OPTION_SERVERID:
case SD_DHCP6_OPTION_SERVERID:
r = dhcp6_lease_get_serverid(lease, &id, &id_len);
if (r >= 0 && id) {
log_dhcp6_client(client, "%s contains multiple serverids",
@@ -721,7 +721,7 @@ static int client_parse_message(sd_dhcp6_client *client,
break;
case DHCP6_OPTION_PREFERENCE:
case SD_DHCP6_OPTION_PREFERENCE:
if (optlen != 1)
return -EINVAL;
@@ -731,7 +731,7 @@ static int client_parse_message(sd_dhcp6_client *client,
break;
case DHCP6_OPTION_STATUS_CODE:
case SD_DHCP6_OPTION_STATUS_CODE:
if (optlen < 2)
return -EINVAL;
@@ -745,7 +745,7 @@ static int client_parse_message(sd_dhcp6_client *client,
break;
case DHCP6_OPTION_IA_NA:
case SD_DHCP6_OPTION_IA_NA:
if (client->state == DHCP6_STATE_INFORMATION_REQUEST) {
log_dhcp6_client(client, "Information request ignoring IA NA option");
@@ -769,35 +769,35 @@ static int client_parse_message(sd_dhcp6_client *client,
break;
case DHCP6_OPTION_RAPID_COMMIT:
case SD_DHCP6_OPTION_RAPID_COMMIT:
r = dhcp6_lease_set_rapid_commit(lease);
if (r < 0)
return r;
break;
case DHCP6_OPTION_DNS_SERVERS:
case SD_DHCP6_OPTION_DNS_SERVERS:
r = dhcp6_lease_set_dns(lease, optval, optlen);
if (r < 0)
return r;
break;
case DHCP6_OPTION_DOMAIN_LIST:
case SD_DHCP6_OPTION_DOMAIN_LIST:
r = dhcp6_lease_set_domains(lease, optval, optlen);
if (r < 0)
return r;
break;
case DHCP6_OPTION_NTP_SERVER:
case SD_DHCP6_OPTION_NTP_SERVER:
r = dhcp6_lease_set_ntp(lease, optval, optlen);
if (r < 0)
return r;
break;
case DHCP6_OPTION_SNTP_SERVERS:
case SD_DHCP6_OPTION_SNTP_SERVERS:
r = dhcp6_lease_set_sntp(lease, optval, optlen);
if (r < 0)
return r;
@@ -1287,7 +1287,7 @@ int sd_dhcp6_client_new(sd_dhcp6_client **ret) {
client->n_ref = 1;
client->ia_na.type = DHCP6_OPTION_IA_NA;
client->ia_na.type = SD_DHCP6_OPTION_IA_NA;
client->index = -1;

View File

@@ -258,7 +258,7 @@ int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) {
assert_return(lease, -EINVAL);
assert_return(optval, -EINVAL);
free(lease->ntp);
lease->ntp = mfree(lease->ntp);
lease->ntp_count = 0;
lease->ntp_allocated = 0;

View File

@@ -265,7 +265,6 @@ int dns_label_escape(const char *p, size_t l, char *dest, size_t sz) {
*(q++) = '0' + (char) ((uint8_t) *p % 10);
sz -= 4;
}
p++;
@@ -416,7 +415,6 @@ int dns_name_concat(const char *a, const char *b, char **_ret) {
for (;;) {
char label[DNS_LABEL_MAX];
int k;
r = dns_label_unescape(&p, label, sizeof(label));
if (r < 0)
@@ -435,12 +433,6 @@ int dns_name_concat(const char *a, const char *b, char **_ret) {
break;
}
k = dns_label_undo_idna(label, r, label, sizeof(label));
if (k < 0)
return k;
if (k > 0)
r = k;
if (_ret) {
if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
return -ENOMEM;
@@ -489,27 +481,18 @@ void dns_name_hash_func(const void *s, struct siphash *state) {
assert(p);
while (*p) {
for (;;) {
char label[DNS_LABEL_MAX+1];
int k;
r = dns_label_unescape(&p, label, sizeof(label));
if (r < 0)
break;
k = dns_label_undo_idna(label, r, label, sizeof(label));
if (k < 0)
break;
if (k > 0)
r = k;
if (r == 0)
break;
label[r] = 0;
ascii_strlower(label);
string_hash_func(label, state);
ascii_strlower_n(label, r);
siphash24_compress(label, r, state);
siphash24_compress_byte(0, state); /* make sure foobar and foo.bar result in different hashes */
}
/* enforce that all names are terminated by the empty label */
@@ -518,7 +501,7 @@ void dns_name_hash_func(const void *s, struct siphash *state) {
int dns_name_compare_func(const void *a, const void *b) {
const char *x, *y;
int r, q, k, w;
int r, q;
assert(a);
assert(b);
@@ -527,7 +510,7 @@ int dns_name_compare_func(const void *a, const void *b) {
y = (const char *) b + strlen(b);
for (;;) {
char la[DNS_LABEL_MAX+1], lb[DNS_LABEL_MAX+1];
char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX];
if (x == NULL && y == NULL)
return 0;
@@ -537,17 +520,7 @@ int dns_name_compare_func(const void *a, const void *b) {
if (r < 0 || q < 0)
return r - q;
k = dns_label_undo_idna(la, r, la, sizeof(la));
w = dns_label_undo_idna(lb, q, lb, sizeof(lb));
if (k < 0 || w < 0)
return k - w;
if (k > 0)
r = k;
if (w > 0)
q = w;
la[r] = lb[q] = 0;
r = strcasecmp(la, lb);
r = ascii_strcasecmp_nn(la, r, lb, q);
if (r != 0)
return r;
}
@@ -559,53 +532,35 @@ const struct hash_ops dns_name_hash_ops = {
};
int dns_name_equal(const char *x, const char *y) {
int r, q, k, w;
int r, q;
assert(x);
assert(y);
for (;;) {
char la[DNS_LABEL_MAX+1], lb[DNS_LABEL_MAX+1];
if (*x == 0 && *y == 0)
return true;
char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX];
r = dns_label_unescape(&x, la, sizeof(la));
if (r < 0)
return r;
if (r > 0) {
k = dns_label_undo_idna(la, r, la, sizeof(la));
if (k < 0)
return k;
if (k > 0)
r = k;
}
q = dns_label_unescape(&y, lb, sizeof(lb));
if (q < 0)
return q;
if (q > 0) {
w = dns_label_undo_idna(lb, q, lb, sizeof(lb));
if (w < 0)
return w;
if (w > 0)
q = w;
}
/* If one name had fewer labels than the other, this
* will show up as empty label here, which the
* strcasecmp() below will properly consider different
* from a non-empty label. */
if (r != q)
return false;
if (r == 0)
return true;
la[r] = lb[q] = 0;
if (strcasecmp(la, lb) != 0)
if (ascii_strcasecmp_n(la, lb, r) != 0)
return false;
}
}
int dns_name_endswith(const char *name, const char *suffix) {
const char *n, *s, *saved_n = NULL;
int r, q, k, w;
int r, q;
assert(name);
assert(suffix);
@@ -614,18 +569,11 @@ int dns_name_endswith(const char *name, const char *suffix) {
s = suffix;
for (;;) {
char ln[DNS_LABEL_MAX+1], ls[DNS_LABEL_MAX+1];
char ln[DNS_LABEL_MAX], ls[DNS_LABEL_MAX];
r = dns_label_unescape(&n, ln, sizeof(ln));
if (r < 0)
return r;
if (r > 0) {
k = dns_label_undo_idna(ln, r, ln, sizeof(ln));
if (k < 0)
return k;
if (k > 0)
r = k;
}
if (!saved_n)
saved_n = n;
@@ -633,22 +581,13 @@ int dns_name_endswith(const char *name, const char *suffix) {
q = dns_label_unescape(&s, ls, sizeof(ls));
if (q < 0)
return q;
if (q > 0) {
w = dns_label_undo_idna(ls, q, ls, sizeof(ls));
if (w < 0)
return w;
if (w > 0)
q = w;
}
if (r == 0 && q == 0)
return true;
if (r == 0 && saved_n == n)
return false;
ln[r] = ls[q] = 0;
if (r != q || strcasecmp(ln, ls)) {
if (r != q || ascii_strcasecmp_n(ln, ls, r) != 0) {
/* Not the same, let's jump back, and try with the next label again */
s = suffix;
@@ -658,9 +597,39 @@ int dns_name_endswith(const char *name, const char *suffix) {
}
}
int dns_name_startswith(const char *name, const char *prefix) {
const char *n, *p;
int r, q;
assert(name);
assert(prefix);
n = name;
p = prefix;
for (;;) {
char ln[DNS_LABEL_MAX], lp[DNS_LABEL_MAX];
r = dns_label_unescape(&p, lp, sizeof(lp));
if (r < 0)
return r;
if (r == 0)
return true;
q = dns_label_unescape(&n, ln, sizeof(ln));
if (q < 0)
return q;
if (r != q)
return false;
if (ascii_strcasecmp_n(ln, lp, r) != 0)
return false;
}
}
int dns_name_change_suffix(const char *name, const char *old_suffix, const char *new_suffix, char **ret) {
const char *n, *s, *saved_before = NULL, *saved_after = NULL, *prefix;
int r, q, k, w;
int r, q;
assert(name);
assert(old_suffix);
@@ -671,7 +640,7 @@ int dns_name_change_suffix(const char *name, const char *old_suffix, const char
s = old_suffix;
for (;;) {
char ln[DNS_LABEL_MAX+1], ls[DNS_LABEL_MAX+1];
char ln[DNS_LABEL_MAX], ls[DNS_LABEL_MAX];
if (!saved_before)
saved_before = n;
@@ -679,13 +648,6 @@ int dns_name_change_suffix(const char *name, const char *old_suffix, const char
r = dns_label_unescape(&n, ln, sizeof(ln));
if (r < 0)
return r;
if (r > 0) {
k = dns_label_undo_idna(ln, r, ln, sizeof(ln));
if (k < 0)
return k;
if (k > 0)
r = k;
}
if (!saved_after)
saved_after = n;
@@ -693,13 +655,6 @@ int dns_name_change_suffix(const char *name, const char *old_suffix, const char
q = dns_label_unescape(&s, ls, sizeof(ls));
if (q < 0)
return q;
if (q > 0) {
w = dns_label_undo_idna(ls, q, ls, sizeof(ls));
if (w < 0)
return w;
if (w > 0)
q = w;
}
if (r == 0 && q == 0)
break;
@@ -708,9 +663,7 @@ int dns_name_change_suffix(const char *name, const char *old_suffix, const char
return 0;
}
ln[r] = ls[q] = 0;
if (r != q || strcasecmp(ln, ls)) {
if (r != q || ascii_strcasecmp_n(ln, ls, r) != 0) {
/* Not the same, let's jump back, and try with the next label again */
s = old_suffix;
@@ -879,12 +832,11 @@ bool dns_name_is_root(const char *name) {
}
bool dns_name_is_single_label(const char *name) {
char label[DNS_LABEL_MAX+1];
int r;
assert(name);
r = dns_label_unescape(&name, label, sizeof(label));
r = dns_name_parent(&name);
if (r <= 0)
return false;
@@ -917,19 +869,11 @@ int dns_name_to_wire_format(const char *domain, uint8_t *buffer, size_t len, boo
if (r < 0)
return r;
if (canonical) {
size_t i;
/* Optionally, output the name in DNSSEC
* canonical format, as described in RFC 4034,
* section 6.2. Or in other words: in
* lower-case. */
for (i = 0; i < (size_t) r; i++) {
if (out[i] >= 'A' && out[i] <= 'Z')
out[i] = out[i] - 'A' + 'a';
}
}
/* Optionally, output the name in DNSSEC canonical
* format, as described in RFC 4034, section 6.2. Or
* in other words: in lower-case. */
if (canonical)
ascii_strlower_n((char*) out, (size_t) r);
/* Fill label length, move forward */
*label_length = r;
@@ -1114,17 +1058,15 @@ int dns_service_split(const char *joined, char **_name, char **_type, char **_do
if (x >= 3 && srv_type_label_is_valid(c, cn)) {
if (dns_service_name_label_is_valid(a, an)) {
/* OK, got <name> . <type> . <type2> . <domain> */
name = strndup(a, an);
if (!name)
return -ENOMEM;
type = new(char, bn+1+cn+1);
type = strjoin(b, ".", c, NULL);
if (!type)
return -ENOMEM;
strcpy(stpcpy(stpcpy(type, b), "."), c);
d = p;
goto finish;
@@ -1136,10 +1078,9 @@ int dns_service_split(const char *joined, char **_name, char **_type, char **_do
name = NULL;
type = new(char, an+1+bn+1);
type = strjoin(a, ".", b, NULL);
if (!type)
return -ENOMEM;
strcpy(stpcpy(stpcpy(type, a), "."), b);
d = q;
goto finish;
@@ -1173,22 +1114,20 @@ finish:
return 0;
}
int dns_name_suffix(const char *name, unsigned n_labels, const char **ret) {
const char* labels[DNS_N_LABELS_MAX+1];
unsigned n = 0;
static int dns_name_build_suffix_table(const char *name, const char*table[]) {
const char *p;
unsigned n = 0;
int r;
assert(name);
assert(ret);
assert(table);
p = name;
for (;;) {
if (n > DNS_N_LABELS_MAX)
return -EINVAL;
labels[n] = p;
table[n] = p;
r = dns_name_parent(&p);
if (r < 0)
return r;
@@ -1198,13 +1137,47 @@ int dns_name_suffix(const char *name, unsigned n_labels, const char **ret) {
n++;
}
if (n < n_labels)
return (int) n;
}
int dns_name_suffix(const char *name, unsigned n_labels, const char **ret) {
const char* labels[DNS_N_LABELS_MAX+1];
int n;
assert(name);
assert(ret);
n = dns_name_build_suffix_table(name, labels);
if (n < 0)
return n;
if ((unsigned) n < n_labels)
return -EINVAL;
*ret = labels[n - n_labels];
return (int) (n - n_labels);
}
int dns_name_skip(const char *a, unsigned n_labels, const char **ret) {
int r;
assert(a);
assert(ret);
for (; n_labels > 0; n_labels --) {
r = dns_name_parent(&a);
if (r < 0)
return r;
if (r == 0) {
*ret = "";
return 0;
}
}
*ret = a;
return 1;
}
int dns_name_count_labels(const char *name) {
unsigned n = 0;
const char *p;
@@ -1235,15 +1208,108 @@ int dns_name_equal_skip(const char *a, unsigned n_labels, const char *b) {
assert(a);
assert(b);
while (n_labels > 0) {
r = dns_name_parent(&a);
r = dns_name_skip(a, n_labels, &a);
if (r <= 0)
return r;
n_labels --;
}
return dns_name_equal(a, b);
}
int dns_name_common_suffix(const char *a, const char *b, const char **ret) {
const char *a_labels[DNS_N_LABELS_MAX+1], *b_labels[DNS_N_LABELS_MAX+1];
int n = 0, m = 0, k = 0, r, q;
assert(a);
assert(b);
assert(ret);
/* Determines the common suffix of domain names a and b */
n = dns_name_build_suffix_table(a, a_labels);
if (n < 0)
return n;
m = dns_name_build_suffix_table(b, b_labels);
if (m < 0)
return m;
for (;;) {
char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX];
const char *x, *y;
if (k >= n || k >= m) {
*ret = a_labels[n - k];
return 0;
}
x = a_labels[n - 1 - k];
r = dns_label_unescape(&x, la, sizeof(la));
if (r < 0)
return r;
y = b_labels[m - 1 - k];
q = dns_label_unescape(&y, lb, sizeof(lb));
if (q < 0)
return q;
if (r != q || ascii_strcasecmp_n(la, lb, r) != 0) {
*ret = a_labels[n - k];
return 0;
}
k++;
}
}
int dns_name_apply_idna(const char *name, char **ret) {
_cleanup_free_ char *buf = NULL;
size_t n = 0, allocated = 0;
bool first = true;
int r, q;
assert(name);
assert(ret);
for (;;) {
char label[DNS_LABEL_MAX];
r = dns_label_unescape(&name, label, sizeof(label));
if (r < 0)
return r;
if (r == 0)
break;
q = dns_label_apply_idna(label, r, label, sizeof(label));
if (q < 0)
return q;
if (q > 0)
r = q;
if (!GREEDY_REALLOC(buf, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
return -ENOMEM;
r = dns_label_escape(label, r, buf + n + !first, DNS_LABEL_ESCAPED_MAX);
if (r < 0)
return r;
if (first)
first = false;
else
buf[n++] = '.';
n +=r;
}
if (n > DNS_HOSTNAME_MAX)
return -EINVAL;
if (!GREEDY_REALLOC(buf, allocated, n + 1))
return -ENOMEM;
buf[n] = 0;
*ret = buf;
buf = NULL;
return (int) n;
}
#endif /* NM_IGNORED */

View File

@@ -84,6 +84,7 @@ extern const struct hash_ops dns_name_hash_ops;
int dns_name_between(const char *a, const char *b, const char *c);
int dns_name_equal(const char *x, const char *y);
int dns_name_endswith(const char *name, const char *suffix);
int dns_name_startswith(const char *name, const char *prefix);
int dns_name_change_suffix(const char *name, const char *old_suffix, const char *new_suffix, char **ret);
@@ -104,4 +105,9 @@ int dns_service_split(const char *joined, char **name, char **type, char **domai
int dns_name_suffix(const char *name, unsigned n_labels, const char **ret);
int dns_name_count_labels(const char *name);
int dns_name_skip(const char *a, unsigned n_labels, const char **ret);
int dns_name_equal_skip(const char *a, unsigned n_labels, const char *b);
int dns_name_common_suffix(const char *a, const char *b, const char **ret);
int dns_name_apply_idna(const char *name, char **ret);

View File

@@ -44,6 +44,48 @@ enum {
SD_DHCP_CLIENT_EVENT_RENEW = 4,
};
enum {
SD_DHCP_OPTION_PAD = 0,
SD_DHCP_OPTION_SUBNET_MASK = 1,
SD_DHCP_OPTION_TIME_OFFSET = 2,
SD_DHCP_OPTION_ROUTER = 3,
SD_DHCP_OPTION_DOMAIN_NAME_SERVER = 6,
SD_DHCP_OPTION_HOST_NAME = 12,
SD_DHCP_OPTION_BOOT_FILE_SIZE = 13,
SD_DHCP_OPTION_DOMAIN_NAME = 15,
SD_DHCP_OPTION_ROOT_PATH = 17,
SD_DHCP_OPTION_ENABLE_IP_FORWARDING = 19,
SD_DHCP_OPTION_ENABLE_IP_FORWARDING_NL = 20,
SD_DHCP_OPTION_POLICY_FILTER = 21,
SD_DHCP_OPTION_INTERFACE_MDR = 22,
SD_DHCP_OPTION_INTERFACE_TTL = 23,
SD_DHCP_OPTION_INTERFACE_MTU_AGING_TIMEOUT = 24,
SD_DHCP_OPTION_INTERFACE_MTU = 26,
SD_DHCP_OPTION_BROADCAST = 28,
SD_DHCP_OPTION_STATIC_ROUTE = 33,
SD_DHCP_OPTION_NTP_SERVER = 42,
SD_DHCP_OPTION_VENDOR_SPECIFIC = 43,
SD_DHCP_OPTION_REQUESTED_IP_ADDRESS = 50,
SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME = 51,
SD_DHCP_OPTION_OVERLOAD = 52,
SD_DHCP_OPTION_MESSAGE_TYPE = 53,
SD_DHCP_OPTION_SERVER_IDENTIFIER = 54,
SD_DHCP_OPTION_PARAMETER_REQUEST_LIST = 55,
SD_DHCP_OPTION_ERROR_MESSAGE = 56,
SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE = 57,
SD_DHCP_OPTION_RENEWAL_T1_TIME = 58,
SD_DHCP_OPTION_REBINDING_T2_TIME = 59,
SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60,
SD_DHCP_OPTION_CLIENT_IDENTIFIER = 61,
SD_DHCP_OPTION_FQDN = 81,
SD_DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
SD_DHCP_OPTION_NEW_TZDB_TIMEZONE = 101,
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
SD_DHCP_OPTION_PRIVATE_BASE = 224,
SD_DHCP_OPTION_PRIVATE_LAST = 254,
SD_DHCP_OPTION_END = 255,
};
typedef struct sd_dhcp_client sd_dhcp_client;
typedef void (*sd_dhcp_client_cb_t)(sd_dhcp_client *client, int event,

View File

@@ -35,7 +35,7 @@
_SD_BEGIN_DECLARATIONS;
typedef struct sd_dhcp_lease sd_dhcp_lease;
struct sd_dhcp_route;
typedef struct sd_dhcp_route sd_dhcp_route;
sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease);
sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease);
@@ -55,11 +55,15 @@ int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname);
int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path);
int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routes);
int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes);
int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len);
int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const void **client_id, size_t *client_id_len);
int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **timezone);
int sd_dhcp_route_get_destination(sd_dhcp_route *route, struct in_addr *destination);
int sd_dhcp_route_get_destination_prefix_length(sd_dhcp_route *route, uint8_t *length);
int sd_dhcp_route_get_gateway(sd_dhcp_route *route, struct in_addr *gateway);
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_lease, sd_dhcp_lease_unref);
_SD_END_DECLARATIONS;

View File

@@ -43,6 +43,41 @@ enum {
SD_DHCP6_CLIENT_EVENT_INFORMATION_REQUEST = 13,
};
enum {
SD_DHCP6_OPTION_CLIENTID = 1,
SD_DHCP6_OPTION_SERVERID = 2,
SD_DHCP6_OPTION_IA_NA = 3,
SD_DHCP6_OPTION_IA_TA = 4,
SD_DHCP6_OPTION_IAADDR = 5,
SD_DHCP6_OPTION_ORO = 6,
SD_DHCP6_OPTION_PREFERENCE = 7,
SD_DHCP6_OPTION_ELAPSED_TIME = 8,
SD_DHCP6_OPTION_RELAY_MSG = 9,
/* option code 10 is unassigned */
SD_DHCP6_OPTION_AUTH = 11,
SD_DHCP6_OPTION_UNICAST = 12,
SD_DHCP6_OPTION_STATUS_CODE = 13,
SD_DHCP6_OPTION_RAPID_COMMIT = 14,
SD_DHCP6_OPTION_USER_CLASS = 15,
SD_DHCP6_OPTION_VENDOR_CLASS = 16,
SD_DHCP6_OPTION_VENDOR_OPTS = 17,
SD_DHCP6_OPTION_INTERFACE_ID = 18,
SD_DHCP6_OPTION_RECONF_MSG = 19,
SD_DHCP6_OPTION_RECONF_ACCEPT = 20,
SD_DHCP6_OPTION_DNS_SERVERS = 23, /* RFC 3646 */
SD_DHCP6_OPTION_DOMAIN_LIST = 24, /* RFC 3646 */
SD_DHCP6_OPTION_SNTP_SERVERS = 31, /* RFC 4075, deprecated */
/* option code 35 is unassigned */
SD_DHCP6_OPTION_NTP_SERVER = 56, /* RFC 5908 */
/* option codes 89-142 are unassigned */
/* option codes 144-65535 are unassigned */
};
typedef struct sd_dhcp6_client sd_dhcp6_client;
typedef void (*sd_dhcp6_client_cb_t)(sd_dhcp6_client *client, int event,