Compare commits
10 Commits
b3753406c0
...
0ce8092109
Author | SHA1 | Date |
---|---|---|
Zbigniew Jędrzejewski-Szmek | 0ce8092109 | |
Marc-André Lureau | d9ce1c2493 | |
Marc-André Lureau | 090c923b4d | |
Marc-André Lureau | 7be3261222 | |
Marc-André Lureau | aaec2d7b9b | |
Marc-André Lureau | 00ebe01156 | |
Marc-André Lureau | cf72a78660 | |
Marc-André Lureau | 38ee31a6e4 | |
Marc-André Lureau | 36d35f2259 | |
Marc-André Lureau | 5b03043a75 |
|
@ -448,6 +448,8 @@ static inline int __coverity_check_and_return__(int condition) {
|
||||||
|
|
||||||
#define char_array_0(x) x[sizeof(x)-1] = 0;
|
#define char_array_0(x) x[sizeof(x)-1] = 0;
|
||||||
|
|
||||||
|
#define sizeof_field(struct_type, member) sizeof(((struct_type *) 0)->member)
|
||||||
|
|
||||||
/* Returns the number of chars needed to format variables of the
|
/* Returns the number of chars needed to format variables of the
|
||||||
* specified type as a decimal string. Adds in extra space for a
|
* specified type as a decimal string. Adds in extra space for a
|
||||||
* negative '-' prefix (hence works correctly on signed
|
* negative '-' prefix (hence works correctly on signed
|
||||||
|
|
|
@ -68,6 +68,9 @@ struct sd_dhcp_server {
|
||||||
DHCPLease invalid_lease;
|
DHCPLease invalid_lease;
|
||||||
|
|
||||||
uint32_t max_lease_time, default_lease_time;
|
uint32_t max_lease_time, default_lease_time;
|
||||||
|
|
||||||
|
sd_dhcp_server_callback_t callback;
|
||||||
|
void *callback_userdata;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct DHCPRequest {
|
typedef struct DHCPRequest {
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "random-util.h"
|
#include "random-util.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
|
#include "utf8.h"
|
||||||
#include "web-util.h"
|
#include "web-util.h"
|
||||||
|
|
||||||
#define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
|
#define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
|
||||||
|
@ -35,28 +36,7 @@
|
||||||
#define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
|
#define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
|
||||||
#define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
|
#define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
|
||||||
|
|
||||||
struct sd_dhcp_client {
|
typedef struct sd_dhcp_client_id {
|
||||||
unsigned n_ref;
|
|
||||||
|
|
||||||
DHCPState state;
|
|
||||||
sd_event *event;
|
|
||||||
int event_priority;
|
|
||||||
sd_event_source *timeout_resend;
|
|
||||||
int ifindex;
|
|
||||||
int fd;
|
|
||||||
uint16_t port;
|
|
||||||
union sockaddr_union link;
|
|
||||||
sd_event_source *receive_message;
|
|
||||||
bool request_broadcast;
|
|
||||||
uint8_t *req_opts;
|
|
||||||
size_t req_opts_allocated;
|
|
||||||
size_t req_opts_size;
|
|
||||||
bool anonymize;
|
|
||||||
be32_t last_addr;
|
|
||||||
uint8_t mac_addr[MAX_MAC_ADDR_LEN];
|
|
||||||
size_t mac_addr_len;
|
|
||||||
uint16_t arp_type;
|
|
||||||
struct {
|
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
|
@ -80,7 +60,30 @@ struct sd_dhcp_client {
|
||||||
uint8_t data[MAX_CLIENT_ID_LEN];
|
uint8_t data[MAX_CLIENT_ID_LEN];
|
||||||
} _packed_ raw;
|
} _packed_ raw;
|
||||||
};
|
};
|
||||||
} _packed_ client_id;
|
} _packed_ sd_dhcp_client_id;
|
||||||
|
|
||||||
|
struct sd_dhcp_client {
|
||||||
|
unsigned n_ref;
|
||||||
|
|
||||||
|
DHCPState state;
|
||||||
|
sd_event *event;
|
||||||
|
int event_priority;
|
||||||
|
sd_event_source *timeout_resend;
|
||||||
|
int ifindex;
|
||||||
|
int fd;
|
||||||
|
uint16_t port;
|
||||||
|
union sockaddr_union link;
|
||||||
|
sd_event_source *receive_message;
|
||||||
|
bool request_broadcast;
|
||||||
|
uint8_t *req_opts;
|
||||||
|
size_t req_opts_allocated;
|
||||||
|
size_t req_opts_size;
|
||||||
|
bool anonymize;
|
||||||
|
be32_t last_addr;
|
||||||
|
uint8_t mac_addr[MAX_MAC_ADDR_LEN];
|
||||||
|
size_t mac_addr_len;
|
||||||
|
uint16_t arp_type;
|
||||||
|
sd_dhcp_client_id client_id;
|
||||||
size_t client_id_len;
|
size_t client_id_len;
|
||||||
char *hostname;
|
char *hostname;
|
||||||
char *vendor_class_identifier;
|
char *vendor_class_identifier;
|
||||||
|
@ -151,6 +154,60 @@ static int client_receive_message_udp(
|
||||||
void *userdata);
|
void *userdata);
|
||||||
static void client_stop(sd_dhcp_client *client, int error);
|
static void client_stop(sd_dhcp_client *client, int error);
|
||||||
|
|
||||||
|
int sd_dhcp_client_id_to_string(const void *data, size_t len, char **ret) {
|
||||||
|
const sd_dhcp_client_id *client_id = data;
|
||||||
|
_cleanup_free_ char *t = NULL;
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
assert_return(data, -EINVAL);
|
||||||
|
assert_return(len >= 1, -EINVAL);
|
||||||
|
assert_return(ret, -EINVAL);
|
||||||
|
|
||||||
|
len -= 1;
|
||||||
|
if (len > MAX_CLIENT_ID_LEN)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
switch (client_id->type) {
|
||||||
|
case 0:
|
||||||
|
if (utf8_is_printable((char *) client_id->gen.data, len))
|
||||||
|
r = asprintf(&t, "%.*s", (int) len, client_id->gen.data);
|
||||||
|
else
|
||||||
|
r = asprintf(&t, "DATA");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (len != sizeof_field(sd_dhcp_client_id, eth))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
r = asprintf(&t, "%x:%x:%x:%x:%x:%x",
|
||||||
|
client_id->eth.haddr[0],
|
||||||
|
client_id->eth.haddr[1],
|
||||||
|
client_id->eth.haddr[2],
|
||||||
|
client_id->eth.haddr[3],
|
||||||
|
client_id->eth.haddr[4],
|
||||||
|
client_id->eth.haddr[5]);
|
||||||
|
break;
|
||||||
|
case 2 ... 254:
|
||||||
|
r = asprintf(&t, "ARP/LL");
|
||||||
|
break;
|
||||||
|
case 255:
|
||||||
|
if (len < 6)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
uint32_t iaid = be32toh(client_id->ns.iaid);
|
||||||
|
uint16_t duid_type = be16toh(client_id->ns.duid.type);
|
||||||
|
if (dhcp_validate_duid_len(duid_type, len - 6, true) < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
r = asprintf(&t, "IAID:0x%x/DUID", iaid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
*ret = TAKE_PTR(t);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int sd_dhcp_client_set_callback(
|
int sd_dhcp_client_set_callback(
|
||||||
sd_dhcp_client *client,
|
sd_dhcp_client *client,
|
||||||
sd_dhcp_client_callback_t cb,
|
sd_dhcp_client_callback_t cb,
|
||||||
|
|
|
@ -98,6 +98,9 @@ int sd_dhcp_server_configure_pool(
|
||||||
|
|
||||||
/* Drop any leases associated with the old address range */
|
/* Drop any leases associated with the old address range */
|
||||||
hashmap_clear(server->leases_by_client_id);
|
hashmap_clear(server->leases_by_client_id);
|
||||||
|
|
||||||
|
if (server->callback)
|
||||||
|
server->callback(server, SD_DHCP_SERVER_EVENT_LEASE_CHANGED, server->callback_userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -899,6 +902,9 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
|
||||||
hashmap_put(server->leases_by_client_id,
|
hashmap_put(server->leases_by_client_id,
|
||||||
&lease->client_id, lease);
|
&lease->client_id, lease);
|
||||||
|
|
||||||
|
if (server->callback)
|
||||||
|
server->callback(server, SD_DHCP_SERVER_EVENT_LEASE_CHANGED, server->callback_userdata);
|
||||||
|
|
||||||
return DHCP_ACK;
|
return DHCP_ACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -935,6 +941,9 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
|
||||||
server->bound_leases[pool_offset] = NULL;
|
server->bound_leases[pool_offset] = NULL;
|
||||||
hashmap_remove(server->leases_by_client_id, existing_lease);
|
hashmap_remove(server->leases_by_client_id, existing_lease);
|
||||||
dhcp_lease_free(existing_lease);
|
dhcp_lease_free(existing_lease);
|
||||||
|
|
||||||
|
if (server->callback)
|
||||||
|
server->callback(server, SD_DHCP_SERVER_EVENT_LEASE_CHANGED, server->callback_userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1202,3 +1211,12 @@ int sd_dhcp_server_add_vendor_option(sd_dhcp_server *server, sd_dhcp_option *v)
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sd_dhcp_server_set_callback(sd_dhcp_server *server, sd_dhcp_server_callback_t cb, void *userdata) {
|
||||||
|
assert_return(server, -EINVAL);
|
||||||
|
|
||||||
|
server->callback = cb;
|
||||||
|
server->callback_userdata = userdata;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -61,6 +61,8 @@ sources = files('''
|
||||||
networkd-conf.h
|
networkd-conf.h
|
||||||
networkd-dhcp-common.c
|
networkd-dhcp-common.c
|
||||||
networkd-dhcp-common.h
|
networkd-dhcp-common.h
|
||||||
|
networkd-dhcp-server-bus.c
|
||||||
|
networkd-dhcp-server-bus.h
|
||||||
networkd-dhcp-server.c
|
networkd-dhcp-server.c
|
||||||
networkd-dhcp-server.h
|
networkd-dhcp-server.h
|
||||||
networkd-dhcp4.c
|
networkd-dhcp4.c
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include "sd-bus.h"
|
#include "sd-bus.h"
|
||||||
#include "sd-device.h"
|
#include "sd-device.h"
|
||||||
|
#include "sd-dhcp-client.h"
|
||||||
#include "sd-hwdb.h"
|
#include "sd-hwdb.h"
|
||||||
#include "sd-lldp.h"
|
#include "sd-lldp.h"
|
||||||
#include "sd-netlink.h"
|
#include "sd-netlink.h"
|
||||||
|
@ -471,9 +472,13 @@ static int decode_link(sd_netlink_message *m, LinkInfo *info, char **patterns, b
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int acquire_link_bitrates(sd_bus *bus, LinkInfo *link) {
|
static int link_get_property(
|
||||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
sd_bus *bus,
|
||||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
const LinkInfo *link,
|
||||||
|
sd_bus_error *error,
|
||||||
|
sd_bus_message **reply,
|
||||||
|
const char *iface,
|
||||||
|
const char *propname) {
|
||||||
_cleanup_free_ char *path = NULL, *ifindex_str = NULL;
|
_cleanup_free_ char *path = NULL, *ifindex_str = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -484,17 +489,25 @@ static int acquire_link_bitrates(sd_bus *bus, LinkInfo *link) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_bus_call_method(
|
return sd_bus_call_method(
|
||||||
bus,
|
bus,
|
||||||
"org.freedesktop.network1",
|
"org.freedesktop.network1",
|
||||||
path,
|
path,
|
||||||
"org.freedesktop.DBus.Properties",
|
"org.freedesktop.DBus.Properties",
|
||||||
"Get",
|
"Get",
|
||||||
&error,
|
error,
|
||||||
&reply,
|
reply,
|
||||||
"ss",
|
"ss",
|
||||||
"org.freedesktop.network1.Link",
|
iface,
|
||||||
"BitRates");
|
propname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int acquire_link_bitrates(sd_bus *bus, LinkInfo *link) {
|
||||||
|
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||||
|
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = link_get_property(bus, link, &error, &reply, "org.freedesktop.network1.Link", "BitRates");
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
bool quiet = sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_PROPERTY) ||
|
bool quiet = sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_PROPERTY) ||
|
||||||
sd_bus_error_has_name(&error, BUS_ERROR_SPEED_METER_INACTIVE);
|
sd_bus_error_has_name(&error, BUS_ERROR_SPEED_METER_INACTIVE);
|
||||||
|
@ -1150,6 +1163,96 @@ static int dump_lldp_neighbors(Table *table, const char *prefix, int ifindex) {
|
||||||
return dump_list(table, prefix, buf);
|
return dump_list(table, prefix, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dump_dhcp_leases(Table *table, const char *prefix, sd_bus *bus, const LinkInfo *link) {
|
||||||
|
_cleanup_strv_free_ char **buf = NULL;
|
||||||
|
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||||
|
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = link_get_property(bus, link, &error, &reply, "org.freedesktop.network1.DHCPServer", "Leases");
|
||||||
|
if (r < 0) {
|
||||||
|
bool quiet = sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_PROPERTY);
|
||||||
|
|
||||||
|
log_full_errno(quiet ? LOG_DEBUG : LOG_WARNING,
|
||||||
|
r, "Failed to query link DHCP leases: %s", bus_error_message(&error, r));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_bus_message_enter_container(reply, 'v', "a(uayayayayt)");
|
||||||
|
if (r < 0)
|
||||||
|
return bus_log_parse_error(r);
|
||||||
|
|
||||||
|
r = sd_bus_message_enter_container(reply, 'a', "(uayayayayt)");
|
||||||
|
if (r < 0)
|
||||||
|
return bus_log_parse_error(r);
|
||||||
|
|
||||||
|
while ((r = sd_bus_message_enter_container(reply, 'r', "uayayayayt")) > 0) {
|
||||||
|
_cleanup_free_ char *id = NULL, *ip = NULL;
|
||||||
|
const void *client_id, *addr, *gtw, *hwaddr;
|
||||||
|
size_t client_id_sz, sz;
|
||||||
|
uint64_t expiration;
|
||||||
|
uint32_t family;
|
||||||
|
|
||||||
|
r = sd_bus_message_read(reply, "u", &family);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_log_parse_error(r);
|
||||||
|
|
||||||
|
r = sd_bus_message_read_array(reply, 'y', &client_id, &client_id_sz);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_log_parse_error(r);
|
||||||
|
|
||||||
|
r = sd_bus_message_read_array(reply, 'y', &addr, &sz);
|
||||||
|
if (r < 0 || sz != 4)
|
||||||
|
return bus_log_parse_error(r);
|
||||||
|
|
||||||
|
r = sd_bus_message_read_array(reply, 'y', >w, &sz);
|
||||||
|
if (r < 0 || sz != 4)
|
||||||
|
return bus_log_parse_error(r);
|
||||||
|
|
||||||
|
r = sd_bus_message_read_array(reply, 'y', &hwaddr, &sz);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_log_parse_error(r);
|
||||||
|
|
||||||
|
r = sd_bus_message_read_basic(reply, 't', &expiration);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_log_parse_error(r);
|
||||||
|
|
||||||
|
r = sd_dhcp_client_id_to_string(client_id, client_id_sz, &id);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_log_parse_error(r);
|
||||||
|
|
||||||
|
r = in_addr_to_string(family, addr, &ip);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_log_parse_error(r);
|
||||||
|
|
||||||
|
r = strv_extendf(&buf, "%s (to %s)", ip, id);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
r = sd_bus_message_exit_container(reply);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_log_parse_error(r);
|
||||||
|
}
|
||||||
|
if (r < 0)
|
||||||
|
return bus_log_parse_error(r);
|
||||||
|
|
||||||
|
r = sd_bus_message_exit_container(reply);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_log_parse_error(r);
|
||||||
|
|
||||||
|
r = sd_bus_message_exit_container(reply);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_log_parse_error(r);
|
||||||
|
|
||||||
|
if (strv_isempty(buf)) {
|
||||||
|
r = strv_extendf(&buf, "none");
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
|
return dump_list(table, prefix, buf);
|
||||||
|
}
|
||||||
|
|
||||||
static int dump_ifindexes(Table *table, const char *prefix, const int *ifindexes) {
|
static int dump_ifindexes(Table *table, const char *prefix, const int *ifindexes) {
|
||||||
unsigned c;
|
unsigned c;
|
||||||
int r;
|
int r;
|
||||||
|
@ -1270,6 +1373,7 @@ static int show_logs(const LinkInfo *info) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int link_status_one(
|
static int link_status_one(
|
||||||
|
sd_bus *bus,
|
||||||
sd_netlink *rtnl,
|
sd_netlink *rtnl,
|
||||||
sd_hwdb *hwdb,
|
sd_hwdb *hwdb,
|
||||||
const LinkInfo *info) {
|
const LinkInfo *info) {
|
||||||
|
@ -1973,6 +2077,10 @@ static int link_status_one(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
r = dump_dhcp_leases(table, "Offered DHCP leases:", bus, info);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
r = dump_statistics(table, info);
|
r = dump_statistics(table, info);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -2090,7 +2198,7 @@ static int link_status(int argc, char *argv[], void *userdata) {
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
fputc('\n', stdout);
|
fputc('\n', stdout);
|
||||||
|
|
||||||
link_status_one(rtnl, hwdb, links + i);
|
link_status_one(bus, rtnl, hwdb, links + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
|
||||||
|
#include "sd-dhcp-server.h"
|
||||||
|
|
||||||
|
#include "alloc-util.h"
|
||||||
|
#include "bus-common-errors.h"
|
||||||
|
#include "bus-util.h"
|
||||||
|
#include "dhcp-server-internal.h"
|
||||||
|
#include "networkd-dhcp-server-bus.h"
|
||||||
|
#include "networkd-link-bus.h"
|
||||||
|
#include "networkd-manager.h"
|
||||||
|
#include "strv.h"
|
||||||
|
|
||||||
|
static int property_get_leases(
|
||||||
|
sd_bus *bus,
|
||||||
|
const char *path,
|
||||||
|
const char *interface,
|
||||||
|
const char *property,
|
||||||
|
sd_bus_message *reply,
|
||||||
|
void *userdata,
|
||||||
|
sd_bus_error *error) {
|
||||||
|
Link *l = userdata;
|
||||||
|
sd_dhcp_server *s;
|
||||||
|
DHCPLease *lease;
|
||||||
|
Iterator i;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(reply);
|
||||||
|
assert(l);
|
||||||
|
|
||||||
|
s = l->dhcp_server;
|
||||||
|
if (!s)
|
||||||
|
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Link %s has no DHCP server.", l->ifname);
|
||||||
|
|
||||||
|
r = sd_bus_message_open_container(reply, 'a', "(uayayayayt)");
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
HASHMAP_FOREACH(lease, s->leases_by_client_id, i) {
|
||||||
|
r = sd_bus_message_open_container(reply, 'r', "uayayayayt");
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_bus_message_append(reply, "u", (uint32_t)AF_INET);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_bus_message_append_array(reply, 'y', lease->client_id.data, lease->client_id.length);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_bus_message_append_array(reply, 'y', &lease->address, sizeof(lease->address));
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_bus_message_append_array(reply, 'y', &lease->gateway, sizeof(lease->gateway));
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_bus_message_append_array(reply, 'y', &lease->chaddr, sizeof(lease->chaddr));
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_bus_message_append_basic(reply, 't', &lease->expiration);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_bus_message_close_container(reply);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sd_bus_message_close_container(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dhcp_server_emit_changed(Link *link, const char *property, ...) {
|
||||||
|
_cleanup_free_ char *path = NULL;
|
||||||
|
char **l;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
|
||||||
|
path = link_bus_path(link);
|
||||||
|
if (!path)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
l = strv_from_stdarg_alloca(property);
|
||||||
|
|
||||||
|
return sd_bus_emit_properties_changed_strv(
|
||||||
|
link->manager->bus,
|
||||||
|
path,
|
||||||
|
"org.freedesktop.network1.DHCPServer",
|
||||||
|
l);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dhcp_server_callback(sd_dhcp_server *s, uint64_t event, void *data) {
|
||||||
|
Link *l = data;
|
||||||
|
|
||||||
|
assert(l);
|
||||||
|
|
||||||
|
if (event & SD_DHCP_SERVER_EVENT_LEASE_CHANGED)
|
||||||
|
(void) dhcp_server_emit_changed(l, "Leases", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const sd_bus_vtable dhcp_server_vtable[] = {
|
||||||
|
SD_BUS_VTABLE_START(0),
|
||||||
|
|
||||||
|
SD_BUS_PROPERTY("Leases", "a(uayayayayt)", property_get_leases, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
|
|
||||||
|
SD_BUS_VTABLE_END
|
||||||
|
};
|
|
@ -0,0 +1,9 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "sd-bus.h"
|
||||||
|
#include "networkd-link.h"
|
||||||
|
|
||||||
|
extern const sd_bus_vtable dhcp_server_vtable[];
|
||||||
|
|
||||||
|
void dhcp_server_callback(sd_dhcp_server *server, uint64_t event, void *data);
|
|
@ -760,6 +760,9 @@ int link_object_find(sd_bus *bus, const char *path, const char *interface, void
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (streq(interface, "org.freedesktop.network1.DHCPServer") && !link->dhcp_server)
|
||||||
|
return 0;
|
||||||
|
|
||||||
*found = link;
|
*found = link;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "local-addresses.h"
|
#include "local-addresses.h"
|
||||||
#include "netlink-util.h"
|
#include "netlink-util.h"
|
||||||
#include "network-internal.h"
|
#include "network-internal.h"
|
||||||
|
#include "networkd-dhcp-server-bus.h"
|
||||||
#include "networkd-dhcp6.h"
|
#include "networkd-dhcp6.h"
|
||||||
#include "networkd-link-bus.h"
|
#include "networkd-link-bus.h"
|
||||||
#include "networkd-manager-bus.h"
|
#include "networkd-manager-bus.h"
|
||||||
|
@ -154,6 +155,10 @@ int manager_connect_bus(Manager *m) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to add link object vtable: %m");
|
return log_error_errno(r, "Failed to add link object vtable: %m");
|
||||||
|
|
||||||
|
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/link", "org.freedesktop.network1.DHCPServer", dhcp_server_vtable, link_object_find, m);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to add link object vtable: %m");
|
||||||
|
|
||||||
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/link", link_node_enumerator, m);
|
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/link", link_node_enumerator, m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to add link enumerator: %m");
|
return log_error_errno(r, "Failed to add link enumerator: %m");
|
||||||
|
|
|
@ -205,6 +205,8 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client);
|
||||||
* options when using RFC7844 Anonymity Profiles */
|
* options when using RFC7844 Anonymity Profiles */
|
||||||
int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize);
|
int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize);
|
||||||
|
|
||||||
|
int sd_dhcp_client_id_to_string(const void *data, size_t len, char **ret);
|
||||||
|
|
||||||
int sd_dhcp_client_attach_event(
|
int sd_dhcp_client_attach_event(
|
||||||
sd_dhcp_client *client,
|
sd_dhcp_client *client,
|
||||||
sd_event *event,
|
sd_event *event,
|
||||||
|
|
|
@ -31,6 +31,10 @@ _SD_BEGIN_DECLARATIONS;
|
||||||
|
|
||||||
typedef struct sd_dhcp_server sd_dhcp_server;
|
typedef struct sd_dhcp_server sd_dhcp_server;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SD_DHCP_SERVER_EVENT_LEASE_CHANGED = 1 << 0,
|
||||||
|
};
|
||||||
|
|
||||||
int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex);
|
int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex);
|
||||||
|
|
||||||
sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server);
|
sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server);
|
||||||
|
@ -40,6 +44,10 @@ int sd_dhcp_server_attach_event(sd_dhcp_server *client, sd_event *event, int64_t
|
||||||
int sd_dhcp_server_detach_event(sd_dhcp_server *client);
|
int sd_dhcp_server_detach_event(sd_dhcp_server *client);
|
||||||
sd_event *sd_dhcp_server_get_event(sd_dhcp_server *client);
|
sd_event *sd_dhcp_server_get_event(sd_dhcp_server *client);
|
||||||
|
|
||||||
|
typedef void (*sd_dhcp_server_callback_t)(sd_dhcp_server *server, uint64_t event, void *userdata);
|
||||||
|
|
||||||
|
int sd_dhcp_server_set_callback(sd_dhcp_server *server, sd_dhcp_server_callback_t cb, void *userdata);
|
||||||
|
|
||||||
int sd_dhcp_server_is_running(sd_dhcp_server *server);
|
int sd_dhcp_server_is_running(sd_dhcp_server *server);
|
||||||
|
|
||||||
int sd_dhcp_server_start(sd_dhcp_server *server);
|
int sd_dhcp_server_start(sd_dhcp_server *server);
|
||||||
|
|
Loading…
Reference in New Issue