]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-dhcp-server: use struct hw_addr_data to manage client hardware address parsed...
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 4 May 2026 19:55:03 +0000 (04:55 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 21 May 2026 19:30:34 +0000 (04:30 +0900)
Then, this drops garbage in DHCP server lease in DBus and Varlink message.

This also drops fallback to use client ID as hardware address when chaddr
field is not set. In that case, we should broadcast reply.

src/libsystemd-network/dhcp-server-lease-internal.h
src/libsystemd-network/dhcp-server-request.c
src/libsystemd-network/dhcp-server-request.h
src/libsystemd-network/dhcp-server-send.c
src/libsystemd-network/fuzz-dhcp-server.c
src/libsystemd-network/sd-dhcp-server-lease.c
src/libsystemd-network/test-dhcp-server.c
src/network/networkd-dhcp-server-bus.c

index 6d7eb4c21368a343954afb03aab6c2e53cb082ca..024279ccbd3fa90f7028beb21d44d43a93054bb2 100644 (file)
@@ -6,6 +6,7 @@
 #include "dhcp-client-id-internal.h"
 #include "dhcp-server-internal.h"
 #include "dhcp-server-request.h"
+#include "ether-addr-util.h"
 #include "sd-forward.h"
 
 typedef struct sd_dhcp_server_lease {
@@ -16,10 +17,9 @@ typedef struct sd_dhcp_server_lease {
         sd_dhcp_client_id client_id;
 
         uint8_t htype; /* e.g. ARPHRD_ETHER */
-        uint8_t hlen;  /* e.g. ETH_ALEN */
+        struct hw_addr_data hw_addr;
         be32_t address;
         be32_t gateway;
-        uint8_t chaddr[16];
         usec_t expiration;
         char *hostname;
 } sd_dhcp_server_lease;
index 39c11e69c868e099820f4c1ba60043bca4ed3dde..768677e65e52a34ac500d4d2e506a22acab16cd1 100644 (file)
@@ -54,8 +54,6 @@ int dhcp_request_get_lifetime_timestamp(DHCPRequest *req, clockid_t clock, usec_
 }
 
 static int ensure_sane_request(sd_dhcp_server *server, DHCPRequest *req, DHCPMessage *message) {
-        int r;
-
         assert(req);
         assert(message);
 
@@ -64,41 +62,26 @@ static int ensure_sane_request(sd_dhcp_server *server, DHCPRequest *req, DHCPMes
         if (message->hlen > sizeof(message->chaddr))
                 return -EBADMSG;
 
-        /* set client id based on MAC address if client did not send an explicit one */
-        if (!sd_dhcp_client_id_is_set(&req->client_id)) {
-                if (!client_id_data_size_is_valid(message->hlen))
-                        return -EBADMSG;
-
-                r = sd_dhcp_client_id_set(&req->client_id, /* type= */ 1, message->chaddr, message->hlen);
-                if (r < 0)
-                        return r;
-        }
-
-        if (message->hlen == 0 || memeqzero(message->chaddr, message->hlen)) {
-                uint8_t type;
-                const void *data;
-                size_t size;
-
-                /* See RFC2131 section 4.1.1.
-                 * hlen and chaddr may not be set for non-ethernet interface.
-                 * Let's try to retrieve it from the client ID. */
-
-                if (!sd_dhcp_client_id_is_set(&req->client_id))
-                        return -EBADMSG;
-
-                r = sd_dhcp_client_id_get(&req->client_id, &type, &data, &size);
-                if (r < 0)
-                        return r;
-
-                if (type != 1)
-                        return -EBADMSG;
-
-                if (size > sizeof(message->chaddr))
-                        return -EBADMSG;
-
-                memcpy(message->chaddr, data, size);
-                message->hlen = size;
-        }
+        req->hw_addr.length = req->message->hlen;
+        memcpy_safe(req->hw_addr.bytes, message->chaddr, message->hlen);
+
+        /* Fake client ID generated from the DHCP header.
+         * The client ID type 0 and 255 are special. So do not use if htype is 0 or 255.
+         * Note, Some hardware type (e.g. Infiniband) may not set chaddr field. */
+        if (!IN_SET(req->message->htype, 0, UINT8_MAX))
+                (void) sd_dhcp_client_id_set(
+                                &req->client_id_by_header,
+                                req->message->htype,
+                                req->message->chaddr,
+                                req->message->hlen);
+
+        /* If Client Identifier option is unspecified, use the generated one. */
+        if (!sd_dhcp_client_id_is_set(&req->client_id))
+                req->client_id = req->client_id_by_header;
+
+        /* We manage bound leases by client ID. Hence, at least one of them is necessary. */
+        if (!sd_dhcp_client_id_is_set(&req->client_id))
+                return -EBADMSG;
 
         if (req->max_optlen < DHCP_MIN_OPTIONS_SIZE)
                 req->max_optlen = DHCP_MIN_OPTIONS_SIZE;
index f1e827a0e13d09d020c4f9283500109bebcdaa43..c9ffe2aba8ee8814fd774c5bddeb0af715bd3eb4 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "dhcp-client-id-internal.h"
 #include "dhcp-protocol.h"
+#include "ether-addr-util.h"
 #include "sd-forward.h"
 #include "sparse-endian.h"
 #include "time-util.h"
 typedef struct DHCPRequest {
         /* received message */
         DHCPMessage *message;
+        /* sender hardware address, may not be set for non-ethernet interface */
+        struct hw_addr_data hw_addr;
         triple_timestamp timestamp;
 
         /* options */
         sd_dhcp_client_id client_id;
+        sd_dhcp_client_id client_id_by_header;
         size_t max_optlen;
         be32_t server_id;
         be32_t requested_ip;
index a7b827f56e63666a02cc4967e630beb794a21f36..3fd548392da9e9bb955e57d4213710d856741670 100644 (file)
@@ -44,8 +44,7 @@ static int server_acquire_raw_socket(sd_dhcp_server *server) {
 
 static int dhcp_server_send_unicast_raw(
                 sd_dhcp_server *server,
-                uint8_t hlen,
-                const uint8_t *chaddr,
+                const struct hw_addr_data *hw_addr,
                 DHCPPacket *packet,
                 size_t len) {
 
@@ -54,8 +53,7 @@ static int dhcp_server_send_unicast_raw(
         assert(server);
         assert(server->ifindex > 0);
         assert(server->address != 0);
-        assert(hlen > 0);
-        assert(chaddr);
+        assert(hw_addr);
         assert(packet);
         assert(len > sizeof(DHCPPacket));
 
@@ -81,10 +79,10 @@ static int dhcp_server_send_unicast_raw(
                 .ll.sll_family = AF_PACKET,
                 .ll.sll_protocol = htobe16(ETH_P_IP),
                 .ll.sll_ifindex = server->ifindex,
-                .ll.sll_halen = hlen,
+                .ll.sll_halen = hw_addr->length,
         };
 
-        memcpy(sa.ll.sll_addr, chaddr, hlen);
+        memcpy_safe(sa.ll.sll_addr, hw_addr->bytes, hw_addr->length);
 
         struct msghdr mh = {
                 .msg_name = &sa.sa,
@@ -192,7 +190,7 @@ static int dhcp_server_send_message(
          * InfiniBand. In that case, we cannot unicast in the below, so need to broadcast. Also, broadcast
          * the message if 'yiaddr' is zero.) */
         if (FLAGS_SET(be16toh(req->message->flags), 0x8000) ||
-            req->message->hlen == 0 || memeqzero(req->message->chaddr, req->message->hlen) ||
+            hw_addr_is_null(&req->hw_addr) ||
             packet->dhcp.yiaddr == INADDR_ANY)
                 return dhcp_server_send_udp(
                                 server,
@@ -205,8 +203,7 @@ static int dhcp_server_send_message(
          * unicasts DHCPOFFER and DHCPACK messages to the client’s hardware address and ’yiaddr’ address. */
         return dhcp_server_send_unicast_raw(
                         server,
-                        req->message->hlen,
-                        req->message->chaddr,
+                        &req->hw_addr,
                         packet,
                         sizeof(DHCPPacket) + optoffset);
 }
@@ -269,7 +266,7 @@ static int server_message_init(
 
         r = dhcp_message_init(&packet->dhcp, BOOTREPLY,
                               be32toh(req->message->xid),
-                              req->message->htype, req->message->hlen, req->message->chaddr,
+                              req->message->htype, req->hw_addr.length, req->hw_addr.bytes,
                               type, req->max_optlen, &optoffset);
         if (r < 0)
                 return r;
@@ -534,28 +531,23 @@ int server_send_nak_or_ignore(sd_dhcp_server *server, bool init_reboot, DHCPRequ
         return DHCP_NAK;
 }
 
-static int server_send_forcerenew(
+static int dhcp_server_send_forcerenew(
                 sd_dhcp_server *server,
-                be32_t address,
-                be32_t gateway,
-                uint8_t htype,
-                uint8_t hlen,
-                const uint8_t *chaddr) {
+                sd_dhcp_server_lease *lease) {
 
         _cleanup_free_ DHCPPacket *packet = NULL;
         size_t optoffset = 0;
         int r;
 
         assert(server);
-        assert(address != INADDR_ANY);
-        assert(chaddr);
+        assert(lease);
 
         packet = malloc0(sizeof(DHCPPacket) + DHCP_MIN_OPTIONS_SIZE);
         if (!packet)
                 return -ENOMEM;
 
         r = dhcp_message_init(&packet->dhcp, BOOTREPLY, 0,
-                              htype, hlen, chaddr, DHCP_FORCERENEW,
+                              lease->htype, lease->hw_addr.length, lease->hw_addr.bytes, DHCP_FORCERENEW,
                               DHCP_MIN_OPTIONS_SIZE, &optoffset);
         if (r < 0)
                 return r;
@@ -565,7 +557,7 @@ static int server_send_forcerenew(
         if (r < 0)
                 return r;
 
-        return dhcp_server_send_udp(server, address, DHCP_PORT_CLIENT,
+        return dhcp_server_send_udp(server, lease->address, DHCP_PORT_CLIENT,
                                     &packet->dhcp,
                                     sizeof(DHCPMessage) + optoffset);
 }
@@ -579,8 +571,6 @@ int sd_dhcp_server_forcerenew(sd_dhcp_server *server) {
         log_dhcp_server(server, "FORCERENEW");
 
         HASHMAP_FOREACH(lease, server->bound_leases_by_client_id)
-                RET_GATHER(r,
-                           server_send_forcerenew(server, lease->address, lease->gateway,
-                                                  lease->htype, lease->hlen, lease->chaddr));
+                RET_GATHER(r, dhcp_server_send_forcerenew(server, lease));
         return r;
 }
index ac006bc2aa54f620af24676ad2168469f71b19ff..34c1f8371a9fd1e160c1feb164587d00d3052b88 100644 (file)
@@ -27,10 +27,10 @@ static int add_lease(sd_dhcp_server *server, const struct in_addr *server_addres
         *lease = (sd_dhcp_server_lease) {
                 .n_ref = 1,
                 .address = htobe32(UINT32_C(10) << 24 | i),
-                .chaddr = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
+                .hw_addr.length = ETH_ALEN,
+                .hw_addr.bytes = { 3, 3, 3, 3, 3, 3, },
                 .expiration = usec_add(now(CLOCK_BOOTTIME), USEC_PER_DAY),
                 .gateway = server_address->s_addr,
-                .hlen = ETH_ALEN,
                 .htype = ARPHRD_ETHER,
 
                 .client_id.size = 2,
index a7d9947c294c03318751e95823e297bf0b394cc6..58b5831e4411922cb9e025d10ca884fec02cd7db 100644 (file)
@@ -16,7 +16,6 @@
 #include "iovec-util.h"
 #include "json-util.h"
 #include "mkdir.h"
-#include "string-util.h"
 #include "tmpfile-util.h"
 
 static sd_dhcp_server_lease* dhcp_server_lease_free(sd_dhcp_server_lease *lease) {
@@ -103,12 +102,11 @@ int dhcp_server_set_lease(sd_dhcp_server *server, be32_t address, DHCPRequest *r
                 .address = address,
                 .client_id = req->client_id,
                 .htype = req->message->htype,
-                .hlen = req->message->hlen,
                 .gateway = req->message->giaddr,
                 .expiration = expiration,
         };
 
-        memcpy(lease->chaddr, req->message->chaddr, req->message->hlen);
+        lease->hw_addr = req->hw_addr;
 
         if (req->hostname) {
                 lease->hostname = strdup(req->hostname);
@@ -146,27 +144,17 @@ int dhcp_server_cleanup_expired_leases(sd_dhcp_server *server) {
 
 sd_dhcp_server_lease* dhcp_server_get_static_lease(sd_dhcp_server *server, const DHCPRequest *req) {
         sd_dhcp_server_lease *static_lease;
-        sd_dhcp_client_id client_id;
 
         assert(server);
         assert(req);
 
         static_lease = hashmap_get(server->static_leases_by_client_id, &req->client_id);
-        if (static_lease)
-                goto verify;
-
-        /* when no lease is found based on the client id fall back to chaddr */
-        if (!client_id_data_size_is_valid(req->message->hlen))
-                return NULL;
-
-        if (sd_dhcp_client_id_set(&client_id, /* type= */ 1, req->message->chaddr, req->message->hlen) < 0)
-                return NULL;
-
-        static_lease = hashmap_get(server->static_leases_by_client_id, &client_id);
+        if (!static_lease && sd_dhcp_client_id_is_set(&req->client_id_by_header))
+                /* when no lease is found, fall back to use the fake client ID generated from the header. */
+                static_lease = hashmap_get(server->static_leases_by_client_id, &req->client_id_by_header);
         if (!static_lease)
                 return NULL;
 
-verify:
         /* Check if the address is in the same subnet. */
         if ((static_lease->address & server->netmask) != server->subnet)
                 return NULL;
@@ -247,8 +235,8 @@ static int dhcp_server_lease_build_json(sd_dhcp_server_lease *lease, sd_json_var
                         JSON_BUILD_PAIR_IN4_ADDR_WITH_STRING_NON_NULL("Address", &(struct in_addr) { .s_addr = lease->address }),
                         JSON_BUILD_PAIR_STRING_NON_EMPTY("Hostname", lease->hostname),
                         SD_JSON_BUILD_PAIR_UNSIGNED("HardwareAddressType", lease->htype),
-                        SD_JSON_BUILD_PAIR_UNSIGNED("HardwareAddressLength", lease->hlen),
-                        SD_JSON_BUILD_PAIR_BYTE_ARRAY("HardwareAddress", lease->chaddr, sizeof(lease->chaddr)));
+                        SD_JSON_BUILD_PAIR_UNSIGNED("HardwareAddressLength", lease->hw_addr.length),
+                        SD_JSON_BUILD_PAIR_BYTE_ARRAY("HardwareAddress", lease->hw_addr.bytes, lease->hw_addr.length));
 }
 
 int dhcp_server_bound_leases_append_json(sd_dhcp_server *server, sd_json_variant **v) {
@@ -376,70 +364,67 @@ int dhcp_server_save_leases(sd_dhcp_server *server) {
         return 0;
 }
 
-static int json_dispatch_chaddr(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
-        uint8_t* address = ASSERT_PTR(userdata);
-        _cleanup_(iovec_done) struct iovec iov = {};
-        int r;
-
-        r = json_dispatch_byte_array_iovec(name, variant, flags, &iov);
-        if (r < 0)
-                return r;
+typedef struct LeaseParam {
+        sd_dhcp_client_id client_id;
+        uint8_t htype;
+        uint8_t hlen;
+        struct iovec hw_addr;
+        struct in_addr address;
+        usec_t exp_b;
+        usec_t exp_r;
+        char *hostname;
+} LeaseParam;
 
-        if (iov.iov_len != 16)
-                return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is array of unexpected size.", strna(name));
+static void lease_param_done(LeaseParam *p) {
+        assert(p);
 
-        memcpy(address, iov.iov_base, iov.iov_len);
-        return 0;
+        iovec_done(&p->hw_addr);
+        free(p->hostname);
 }
 
 static int json_dispatch_dhcp_lease(sd_dhcp_server *server, sd_json_variant *v, bool use_boottime) {
-        static const sd_json_dispatch_field dispatch_table_boottime[] = {
-                { "ClientId",               SD_JSON_VARIANT_ARRAY,         json_dispatch_client_id, offsetof(sd_dhcp_server_lease, client_id),  SD_JSON_MANDATORY },
-                { "Address",                SD_JSON_VARIANT_ARRAY,         json_dispatch_in_addr,   offsetof(sd_dhcp_server_lease, address),    SD_JSON_MANDATORY },
-                { "Hostname",               SD_JSON_VARIANT_STRING,        sd_json_dispatch_string, offsetof(sd_dhcp_server_lease, hostname),   0                 },
-                { "HardwareAddressType",    _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint8,  offsetof(sd_dhcp_server_lease, htype),      0                 },
-                { "HardwareAddressLength",  _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint8,  offsetof(sd_dhcp_server_lease, hlen),       0                 },
-                { "HardwareAddress",        SD_JSON_VARIANT_ARRAY,         json_dispatch_chaddr,    offsetof(sd_dhcp_server_lease, chaddr),     0                 },
-                { "ExpirationUSec",         _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(sd_dhcp_server_lease, expiration), SD_JSON_MANDATORY },
-                { "ExpirationRealtimeUSec", _SD_JSON_VARIANT_TYPE_INVALID, NULL,                    0,                                          SD_JSON_MANDATORY },
-                {}
-        }, dispatch_table_realtime[] = {
-                { "ClientId",               SD_JSON_VARIANT_ARRAY,         json_dispatch_client_id, offsetof(sd_dhcp_server_lease, client_id),  SD_JSON_MANDATORY },
-                { "Address",                SD_JSON_VARIANT_ARRAY,         json_dispatch_in_addr,   offsetof(sd_dhcp_server_lease, address),    SD_JSON_MANDATORY },
-                { "Hostname",               SD_JSON_VARIANT_STRING,        sd_json_dispatch_string, offsetof(sd_dhcp_server_lease, hostname),   0                 },
-                { "HardwareAddressType",    _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint8,  offsetof(sd_dhcp_server_lease, htype),      0                 },
-                { "HardwareAddressLength",  _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint8,  offsetof(sd_dhcp_server_lease, hlen),       0                 },
-                { "HardwareAddress",        SD_JSON_VARIANT_ARRAY,         json_dispatch_chaddr,    offsetof(sd_dhcp_server_lease, chaddr),     0                 },
-                { "ExpirationUSec",         _SD_JSON_VARIANT_TYPE_INVALID, NULL,                    0,                                          SD_JSON_MANDATORY },
-                { "ExpirationRealtimeUSec", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(sd_dhcp_server_lease, expiration), SD_JSON_MANDATORY },
+        static const sd_json_dispatch_field dispatch_table[] = {
+                { "ClientId",               SD_JSON_VARIANT_ARRAY,         json_dispatch_client_id,        offsetof(LeaseParam, client_id),  SD_JSON_MANDATORY },
+                { "HardwareAddressType",    _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint8,         offsetof(LeaseParam, htype),      0                 },
+                { "HardwareAddressLength",  _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint8,         offsetof(LeaseParam, hlen),       0                 },
+                { "HardwareAddress",        SD_JSON_VARIANT_ARRAY,         json_dispatch_byte_array_iovec, offsetof(LeaseParam, hw_addr),    0                 },
+                { "Address",                SD_JSON_VARIANT_ARRAY,         json_dispatch_in_addr,          offsetof(LeaseParam, address),    SD_JSON_MANDATORY },
+                { "AddressString",          SD_JSON_VARIANT_STRING,        NULL,                           0,                                0                 },
+                { "ExpirationUSec",         _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64,        offsetof(LeaseParam, exp_b),      SD_JSON_MANDATORY },
+                { "ExpirationRealtimeUSec", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64,        offsetof(LeaseParam, exp_r),      SD_JSON_MANDATORY },
+                { "Hostname",               SD_JSON_VARIANT_STRING,        sd_json_dispatch_string,        offsetof(LeaseParam, hostname),   0                 },
                 {}
         };
 
-        _cleanup_(sd_dhcp_server_lease_unrefp) sd_dhcp_server_lease *lease = NULL;
-        usec_t now_b;
         int r;
 
         assert(server);
         assert(v);
 
-        lease = new(sd_dhcp_server_lease, 1);
-        if (!lease)
-                return -ENOMEM;
-
-        *lease = (sd_dhcp_server_lease) {
-                .n_ref = 1,
-        };
-
-        r = sd_json_dispatch(v, use_boottime ? dispatch_table_boottime : dispatch_table_realtime, SD_JSON_ALLOW_EXTENSIONS, lease);
+        _cleanup_(lease_param_done) LeaseParam p = {};
+        r = sd_json_dispatch(v, dispatch_table, SD_JSON_ALLOW_EXTENSIONS, &p);
         if (r < 0)
                 return r;
 
+        if (p.hlen > HW_ADDR_MAX_SIZE)
+                return -EINVAL;
+
+        if (p.hlen > p.hw_addr.iov_len)
+                return -EINVAL;
+
+        if (!in4_addr_is_set(&p.address))
+                return -EINVAL;
+
+        if (!sd_dhcp_client_id_is_set(&p.client_id))
+                return -EINVAL;
+
+        usec_t now_b;
         r = sd_event_now(server->event, CLOCK_BOOTTIME, &now_b);
         if (r < 0)
                 return r;
 
         if (use_boottime) {
-                if (lease->expiration < now_b)
+                if (p.exp_b < now_b)
                         return 0; /* already expired */
         } else {
                 usec_t now_r;
@@ -448,12 +433,29 @@ static int json_dispatch_dhcp_lease(sd_dhcp_server *server, sd_json_variant *v,
                 if (r < 0)
                         return r;
 
-                if (lease->expiration < now_r)
+                if (p.exp_r < now_r)
                         return 0; /* already expired */
 
-                lease->expiration = map_clock_usec_raw(lease->expiration, now_r, now_b);
+                p.exp_b = map_clock_usec_raw(p.exp_r, now_r, now_b);
         }
 
+        _cleanup_(sd_dhcp_server_lease_unrefp) sd_dhcp_server_lease *lease = new(sd_dhcp_server_lease, 1);
+        if (!lease)
+                return -ENOMEM;
+
+        *lease = (sd_dhcp_server_lease) {
+                .n_ref = 1,
+
+                .client_id = p.client_id,
+                .htype = p.htype,
+                .hw_addr.length = p.hlen,
+                .address = p.address.s_addr,
+                .expiration = p.exp_b,
+                .hostname = TAKE_PTR(p.hostname),
+        };
+
+        memcpy_safe(lease->hw_addr.bytes, p.hw_addr.iov_base, p.hlen);
+
         r = dhcp_server_put_lease(server, lease, /* is_static= */ false);
         if (r == -EEXIST)
                 return 0;
index bc9ab1e9ac2d80471b08c95a297ad57425d6b6f0..a4f025bd412b1503b1c3960a6d1e2499296fd1d8 100644 (file)
@@ -152,8 +152,9 @@ TEST(dhcp_server_handle_message) {
         test.header.op = BOOTREQUEST;
         ASSERT_OK_EQ(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL), DHCP_OFFER);
 
+        /* Neither client ID nor hardware type is set. There is no way to manage the bound lease for the request. */
         test.header.htype = 0;
-        ASSERT_OK_EQ(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL), DHCP_OFFER);
+        ASSERT_ERROR(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL), EBADMSG);
         test.header.htype = ARPHRD_ETHER;
         ASSERT_OK_EQ(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL), DHCP_OFFER);
 
index 58e0a26f22fc11420bc83ee14c23326a5ae530d8..d5829b6dfbb3f84f07bc50c2bc92cbc05b011f25 100644 (file)
@@ -55,7 +55,7 @@ static int property_get_leases(
                 if (r < 0)
                         return r;
 
-                r = sd_bus_message_append_array(reply, 'y', &lease->chaddr, sizeof(lease->chaddr));
+                r = sd_bus_message_append_array(reply, 'y', &lease->hw_addr.bytes, lease->hw_addr.length);
                 if (r < 0)
                         return r;