Commit e2e4637c authored by Dan Winship's avatar Dan Winship
Browse files

dhcp: update systemd DHCP code

This is a direct dump from systemd git on 2014-11-19, git commit
a4962513.  Only relevant files were included.

    SYSTEMD_DIR=../systemd
    COMMIT=a4962513c555fe3ac4b5bebf97a71701361a45b0

    (
       cd "$SYSTEMD_DIR"
       git checkout "$COMMIT"
       git clean -fdx
    )
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-internal.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-internal.h
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-lease-internal.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-lease-internal.h
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-network.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-network.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-option.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-option.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-packet.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-packet.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-protocol.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-protocol.h
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp6-internal.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-internal.h
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp6-lease-internal.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-lease-internal.h
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp6-network.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-network.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp6-option.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp6-protocol.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-protocol.h
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/network-internal.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/network-internal.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.h
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/sd-dhcp-client.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/sd-dhcp-lease.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/sd-dhcp6-client.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/sd-dhcp6-lease.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-lease.c
    /bin/cp "$SYSTEMD_DIR"/src/shared/async.h ./src/dhcp-manager/systemd-dhcp/src/shared/async.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/fileio.c ./src/dhcp-manager/systemd-dhcp/src/shared/fileio.c
    /bin/cp "$SYSTEMD_DIR"/src/shared/fileio.h ./src/dhcp-manager/systemd-dhcp/src/shared/fileio.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/list.h ./src/dhcp-manager/systemd-dhcp/src/shared/list.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/macro.h ./src/dhcp-manager/systemd-dhcp/src/shared/macro.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/refcnt.h ./src/dhcp-manager/systemd-dhcp/src/shared/refcnt.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/siphash24.c ./src/dhcp-manager/systemd-dhcp/src/shared/siphash24.c
    /bin/cp "$SYSTEMD_DIR"/src/shared/siphash24.h ./src/dhcp-manager/systemd-dhcp/src/shared/siphash24.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/socket-util.h ./src/dhcp-manager/systemd-dhcp/src/shared/socket-util.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/sparse-endian.h ./src/dhcp-manager/systemd-dhcp/src/shared/sparse-endian.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/strv.c ./src/dhcp-manager/systemd-dhcp/src/shared/strv.c
    /bin/cp "$SYSTEMD_DIR"/src/shared/strv.h ./src/dhcp-manager/systemd-dhcp/src/shared/strv.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/time-util.c ./src/dhcp-manager/systemd-dhcp/src/shared/time-util.c
    /bin/cp "$SYSTEMD_DIR"/src/shared/time-util.h ./src/dhcp-manager/systemd-dhcp/src/shared/time-util.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/utf8.c ./src/dhcp-manager/systemd-dhcp/src/shared/utf8.c
    /bin/cp "$SYSTEMD_DIR"/src/shared/utf8.h ./src/dhcp-manager/systemd-dhcp/src/shared/utf8.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/util.c ./src/dhcp-manager/systemd-dhcp/src/shared/util.c
    /bin/cp "$SYSTEMD_DIR"/src/shared/util.h ./src/dhcp-manager/systemd-dhcp/src/shared/util.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/unaligned.h ./src/dhcp-manager/systemd-dhcp/src/shared/unaligned.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/in-addr-util.c ./src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c
    /bin/cp "$SYSTEMD_DIR"/src/shared/in-addr-util.h ./src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.h
    /bin/cp "$SYSTEMD_DIR"/src/systemd/_sd-common.h ./src/dhcp-manager/systemd-dhcp/src/systemd/_sd-common.h
    /bin/cp "$SYSTEMD_DIR"/src/systemd/sd-dhcp-client.h ./src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-client.h
    /bin/cp "$SYSTEMD_DIR"/src/systemd/sd-dhcp-lease.h ./src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-lease.h
    /bin/cp "$SYSTEMD_DIR"/src/systemd/sd-dhcp6-client.h ./src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-client.h
    /bin/cp "$SYSTEMD_DIR"/src/systemd/sd-dhcp6-lease.h ./src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-lease.h
    /bin/cp "$SYSTEMD_DIR"/src/systemd/sd-event.h ./src/dhcp-manager/systemd-dhcp/src/systemd/sd-event.h
    /bin/cp "$SYSTEMD_DIR"/src/systemd/sd-id128.h ./src/dhcp-manager/systemd-dhcp/src/systemd/sd-id128.h
parent 20462b50
......@@ -35,7 +35,7 @@
struct sd_dhcp_route {
struct in_addr dst_addr;
struct in_addr gw_addr;
uint8_t dst_prefixlen;
unsigned char dst_prefixlen;
};
struct sd_dhcp_lease {
......@@ -70,16 +70,18 @@ struct sd_dhcp_lease {
char *domainname;
char *hostname;
char *root_path;
uint8_t *client_id;
size_t client_id_len;
};
int dhcp_lease_new(sd_dhcp_lease **ret);
int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
void *user_data);
int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file);
int dhcp_lease_load(const char *lease_file, sd_dhcp_lease **ret);
int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease);
int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const uint8_t *client_id,
size_t client_id_len);
DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_lease*, sd_dhcp_lease_unref);
#define _cleanup_dhcp_lease_unref_ _cleanup_(sd_dhcp_lease_unrefp)
......@@ -24,31 +24,37 @@
#include <string.h>
#include "sparse-endian.h"
#include "unaligned.h"
#include "util.h"
#include "dhcp6-internal.h"
#include "dhcp6-protocol.h"
#define DHCP6_OPTION_HDR_LEN 4
#define DHCP6_OPTION_IA_NA_LEN 12
#define DHCP6_OPTION_IA_TA_LEN 4
typedef struct DHCP6Option {
be16_t code;
be16_t len;
uint8_t data[];
} _packed_ DHCP6Option;
static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode,
size_t optlen) {
DHCP6Option *option = (DHCP6Option*) *buf;
assert_return(buf, -EINVAL);
assert_return(*buf, -EINVAL);
assert_return(buflen, -EINVAL);
if (optlen > 0xffff || *buflen < optlen + DHCP6_OPTION_HDR_LEN)
if (optlen > 0xffff || *buflen < optlen + sizeof(DHCP6Option))
return -ENOBUFS;
(*buf)[0] = optcode >> 8;
(*buf)[1] = optcode & 0xff;
(*buf)[2] = optlen >> 8;
(*buf)[3] = optlen & 0xff;
option->code = htobe16(optcode);
option->len = htobe16(optlen);
*buf += DHCP6_OPTION_HDR_LEN;
*buflen -= DHCP6_OPTION_HDR_LEN;
*buf += sizeof(DHCP6Option);
*buflen -= sizeof(DHCP6Option);
return 0;
}
......@@ -100,8 +106,8 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
ia_hdr = *buf;
ia_buflen = *buflen;
*buf += DHCP6_OPTION_HDR_LEN;
*buflen -= DHCP6_OPTION_HDR_LEN;
*buf += sizeof(DHCP6Option);
*buflen -= sizeof(DHCP6Option);
memcpy(*buf, &ia->id, len);
......@@ -119,7 +125,7 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
*buf += sizeof(addr->iaaddr);
*buflen -= sizeof(addr->iaaddr);
ia_addrlen += DHCP6_OPTION_HDR_LEN + sizeof(addr->iaaddr);
ia_addrlen += sizeof(DHCP6Option) + sizeof(addr->iaaddr);
}
r = option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len + ia_addrlen);
......@@ -130,23 +136,23 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
}
static int option_parse_hdr(uint8_t **buf, size_t *buflen, uint16_t *opt,
size_t *optlen) {
static int option_parse_hdr(uint8_t **buf, size_t *buflen, uint16_t *optcode, size_t *optlen) {
DHCP6Option *option = (DHCP6Option*) *buf;
uint16_t len;
assert_return(buf, -EINVAL);
assert_return(opt, -EINVAL);
assert_return(optcode, -EINVAL);
assert_return(optlen, -EINVAL);
if (*buflen < 4)
if (*buflen < sizeof(DHCP6Option))
return -ENOMSG;
len = (*buf)[2] << 8 | (*buf)[3];
len = be16toh(option->len);
if (len > *buflen)
return -ENOMSG;
*opt = (*buf)[0] << 8 | (*buf)[1];
*optcode = be16toh(option->code);
*optlen = len;
*buf += 4;
......@@ -190,7 +196,7 @@ int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
switch (iatype) {
case DHCP6_OPTION_IA_NA:
if (*buflen < DHCP6_OPTION_IA_NA_LEN + DHCP6_OPTION_HDR_LEN +
if (*buflen < DHCP6_OPTION_IA_NA_LEN + sizeof(DHCP6Option) +
sizeof(addr->iaaddr)) {
r = -ENOBUFS;
goto error;
......@@ -212,7 +218,7 @@ int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
break;
case DHCP6_OPTION_IA_TA:
if (*buflen < DHCP6_OPTION_IA_TA_LEN + DHCP6_OPTION_HDR_LEN +
if (*buflen < DHCP6_OPTION_IA_TA_LEN + sizeof(DHCP6Option) +
sizeof(addr->iaaddr)) {
r = -ENOBUFS;
goto error;
......
......@@ -98,16 +98,16 @@ bool net_match_config(const struct ether_addr *match_mac,
const char *dev_type,
const char *dev_name) {
if (match_host && !condition_test_host(match_host))
if (match_host && !condition_test(match_host))
return 0;
if (match_virt && !condition_test_virtualization(match_virt))
if (match_virt && !condition_test(match_virt))
return 0;
if (match_kernel && !condition_test_kernel_command_line(match_kernel))
if (match_kernel && !condition_test(match_kernel))
return 0;
if (match_arch && !condition_test_architecture(match_arch))
if (match_arch && !condition_test(match_arch))
return 0;
if (match_mac && (!dev_mac || memcmp(match_mac, dev_mac, ETH_ALEN)))
......
......@@ -26,7 +26,7 @@
#include <stdbool.h>
#include "udev.h"
#include "condition-util.h"
#include "condition.h"
bool net_match_config(const struct ether_addr *match_mac,
const char *match_path,
......
......@@ -38,6 +38,7 @@
#include "dhcp-lease-internal.h"
#include "sd-dhcp-client.h"
#define MAX_CLIENT_ID_LEN 64 /* Arbitrary limit */
#define MAX_MAC_ADDR_LEN INFINIBAND_ALEN
struct sd_dhcp_client {
......@@ -56,19 +57,38 @@ struct sd_dhcp_client {
size_t req_opts_allocated;
size_t req_opts_size;
be32_t last_addr;
struct {
uint8_t type;
struct ether_addr mac_addr;
} _packed_ client_id;
uint8_t mac_addr[MAX_MAC_ADDR_LEN];
size_t mac_addr_len;
uint16_t arp_type;
union {
struct {
uint8_t type; /* 0: Generic (non-LL) (RFC 2132) */
uint8_t data[MAX_CLIENT_ID_LEN];
} _packed_ gen;
struct {
uint8_t type; /* 1: Ethernet Link-Layer (RFC 2132) */
uint8_t haddr[ETH_ALEN];
} _packed_ eth;
struct {
uint8_t type; /* 2 - 254: ARP/Link-Layer (RFC 2132) */
uint8_t haddr[0];
} _packed_ ll;
struct {
uint8_t type; /* 255: Node-specific (RFC 4361) */
uint8_t iaid[4];
uint8_t duid[MAX_CLIENT_ID_LEN - 4];
} _packed_ ns;
struct {
uint8_t type;
uint8_t data[MAX_CLIENT_ID_LEN];
} _packed_ raw;
} client_id;
size_t client_id_len;
char *hostname;
char *vendor_class_identifier;
uint32_t mtu;
uint32_t xid;
usec_t start_time;
uint16_t secs;
unsigned int attempt;
usec_t request_sent;
sd_event_source *timeout_t1;
......@@ -201,8 +221,70 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr,
client->mac_addr_len = addr_len;
client->arp_type = arp_type;
memcpy(&client->client_id.mac_addr, addr, ETH_ALEN);
client->client_id.type = 0x01;
if (need_restart && client->state != DHCP_STATE_STOPPED)
sd_dhcp_client_start(client);
return 0;
}
int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type,
const uint8_t **data, size_t *data_len) {
assert_return(client, -EINVAL);
assert_return(type, -EINVAL);
assert_return(data, -EINVAL);
assert_return(data_len, -EINVAL);
*type = 0;
*data = NULL;
*data_len = 0;
if (client->client_id_len) {
*type = client->client_id.raw.type;
*data = client->client_id.raw.data;
*data_len = client->client_id_len -
sizeof (client->client_id.raw.type);
}
return 0;
}
int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
const uint8_t *data, size_t data_len) {
DHCP_CLIENT_DONT_DESTROY(client);
bool need_restart = false;
assert_return(client, -EINVAL);
assert_return(data, -EINVAL);
assert_return(data_len > 0 && data_len <= MAX_CLIENT_ID_LEN, -EINVAL);
switch (type) {
case ARPHRD_ETHER:
if (data_len != ETH_ALEN)
return -EINVAL;
break;
case ARPHRD_INFINIBAND:
if (data_len != INFINIBAND_ALEN)
return -EINVAL;
break;
default:
break;
}
if (client->client_id_len == data_len + sizeof (client->client_id.raw.type) &&
client->client_id.raw.type == type &&
memcmp(&client->client_id.raw.data, data, data_len) == 0)
return 0;
if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
log_dhcp_client(client, "Changing client ID on running DHCP "
"client, restarting");
need_restart = true;
client_stop(client, DHCP_EVENT_STOP);
}
client->client_id.raw.type = type;
memcpy(&client->client_id.raw.data, data, data_len);
client->client_id_len = data_len + sizeof (client->client_id.raw.type);
if (need_restart && client->state != DHCP_STATE_STOPPED)
sd_dhcp_client_start(client);
......@@ -321,10 +403,12 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
_cleanup_free_ DHCPPacket *packet;
size_t optlen, optoffset, size;
be16_t max_size;
usec_t time_now;
uint16_t secs;
int r;
assert(client);
assert(client->secs);
assert(client->start_time);
assert(ret);
assert(_optlen);
assert(_optoffset);
......@@ -344,7 +428,15 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
/* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
refuse to issue an DHCP lease if 'secs' is set to zero */
packet->dhcp.secs = htobe16(client->secs);
r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
if (r < 0)
return r;
assert(time_now >= client->start_time);
/* seconds between sending first and last DISCOVER
* must always be strictly positive to deal with broken servers */
secs = ((time_now - client->start_time) / USEC_PER_SEC) ? : 1;
packet->dhcp.secs = htobe16(secs);
/* RFC2132 section 4.1
A client that cannot receive unicast IP datagrams until its protocol
......@@ -369,14 +461,24 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
if (client->arp_type == ARPHRD_ETHER)
memcpy(&packet->dhcp.chaddr, &client->mac_addr, ETH_ALEN);
/* If no client identifier exists, construct one from an ethernet
address if present */
if (client->client_id_len == 0 && client->arp_type == ARPHRD_ETHER) {
client->client_id.eth.type = ARPHRD_ETHER;
memcpy(&client->client_id.eth.haddr, &client->mac_addr, ETH_ALEN);
client->client_id_len = sizeof (client->client_id.eth);
}
/* Some DHCP servers will refuse to issue an DHCP lease if the Client
Identifier option is not set */
r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
DHCP_OPTION_CLIENT_IDENTIFIER,
sizeof(client->client_id), &client->client_id);
if (r < 0)
return r;
if (client->client_id_len) {
r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
DHCP_OPTION_CLIENT_IDENTIFIER,
client->client_id_len,
&client->client_id.raw);
if (r < 0)
return r;
}
/* RFC2131 section 3.5:
in its initial DHCPDISCOVER or DHCPREQUEST message, a
......@@ -441,24 +543,12 @@ static int dhcp_client_send_raw(sd_dhcp_client *client, DHCPPacket *packet,
static int client_send_discover(sd_dhcp_client *client) {
_cleanup_free_ DHCPPacket *discover = NULL;
size_t optoffset, optlen;
usec_t time_now;
int r;
assert(client);
assert(client->state == DHCP_STATE_INIT ||
client->state == DHCP_STATE_SELECTING);
/* See RFC2131 section 4.4.1 */
r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
if (r < 0)
return r;
assert(time_now >= client->start_time);
/* seconds between sending first and last DISCOVER
* must always be strictly positive to deal with broken servers */
client->secs = ((time_now - client->start_time) / USEC_PER_SEC) ? : 1;
r = client_message_init(client, &discover, DHCP_DISCOVER,
&optlen, &optoffset);
if (r < 0)
......@@ -723,8 +813,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec,
if (r < 0)
goto error;
r = sd_event_source_set_name(client->timeout_resend,
"dhcp4-resend-timer");
r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
if (r < 0)
goto error;
......@@ -801,8 +890,7 @@ static int client_initialize_io_events(sd_dhcp_client *client,
if (r < 0)
goto error;
r = sd_event_source_set_name(client->receive_message,
"dhcp4-receive-message");
r = sd_event_source_set_description(client->receive_message, "dhcp4-receive-message");
if (r < 0)
goto error;
......@@ -832,8 +920,7 @@ static int client_initialize_time_events(sd_dhcp_client *client) {
r = sd_event_source_set_priority(client->timeout_resend,
client->event_priority);
r = sd_event_source_set_name(client->timeout_resend,
"dhcp4-resend-timer");
r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
if (r < 0)
goto error;
......@@ -875,10 +962,8 @@ static int client_start(sd_dhcp_client *client) {
}
client->fd = r;
if (client->state == DHCP_STATE_INIT) {
if (client->state == DHCP_STATE_INIT || client->state == DHCP_STATE_INIT_REBOOT)
client->start_time = now(clock_boottime_or_monotonic());
client->secs = 0;
}
return client_initialize_events(client, client_receive_message_raw);
}
......@@ -944,6 +1029,14 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
if (r < 0)
return r;
if (client->client_id_len) {
r = dhcp_lease_set_client_id(lease,
(uint8_t *) &client->client_id.raw,
client->client_id_len);
if (r < 0)
return r;
}
r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease);
if (r != DHCP_OFFER) {
log_dhcp_client(client, "received message was not an OFFER, ignoring");
......@@ -1003,6 +1096,14 @@ static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack,
if (r < 0)
return r;
if (client->client_id_len) {
r = dhcp_lease_set_client_id(lease,
(uint8_t *) &client->client_id.raw,
client->client_id_len);
if (r < 0)
return r;
}
r = dhcp_option_parse(ack, len, dhcp_lease_parse_options, lease);
if (r == DHCP_NAK) {
log_dhcp_client(client, "NAK");
......@@ -1149,8 +1250,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
if (r < 0)
return r;
r = sd_event_source_set_name(client->timeout_expire,
"dhcp4-lifetime");
r = sd_event_source_set_description(client->timeout_expire, "dhcp4-lifetime");
if (r < 0)
return r;
......@@ -1177,8 +1277,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
if (r < 0)
return r;
r = sd_event_source_set_name(client->timeout_t2,
"dhcp4-t2-timeout");
r = sd_event_source_set_description(client->timeout_t2, "dhcp4-t2-timeout");
if (r < 0)
return r;
......@@ -1204,8 +1303,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
if (r < 0)
return r;
r = sd_event_source_set_name(client->timeout_t1,
"dhcp4-t1-timer");
r = sd_event_source_set_description(client->timeout_t1, "dhcp4-t1-timer");
if (r < 0)
return r;
......@@ -1250,8 +1348,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
if (r < 0)
goto error;
r = sd_event_source_set_name(client->timeout_resend,
"dhcp4-resend-timer");
r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
if (r < 0)
goto error;
} else if (r == -ENOMSG)
......@@ -1269,6 +1366,9 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
if (r >= 0) {
client->timeout_resend =
sd_event_source_unref(client->timeout_resend);
client->receive_message =
sd_event_source_unref(client->receive_message);
client->fd = asynchronous_close(client->fd);
if (IN_SET(client->state, DHCP_STATE_REQUESTING,
DHCP_STATE_REBOOTING))
......
......@@ -30,6 +30,7 @@
#include "list.h"
#include "mkdir.h"
#include "fileio.h"
#include "unaligned.h"
#include "in-addr-util.h"
#include "dhcp-protocol.h"
......@@ -198,6 +199,7 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) {
free(lease->dns);
free(lease->ntp);
free(lease->static_route);
free(lease->client_id);
free(lease);
}
......@@ -205,14 +207,11 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) {
}
static void lease_parse_u32(const uint8_t *option, size_t len, uint32_t *ret, uint32_t min) {
be32_t val;
assert(option);
assert(ret);
if (len == 4) {
memcpy(&val, option, 4);
*ret = be32toh(val);
*ret = unaligned_read_be32((be32_t*) option);
if (*ret < min)
*ret = min;
......@@ -224,14 +223,11 @@ static void lease_parse_s32(const uint8_t *option, size_t len, int32_t *ret) {
}
static void lease_parse_u16(const uint8_t *option, size_t len, uint16_t *ret, uint16_t min) {
be16_t val;
assert(option);
assert(ret);
if (len == 2) {
memcpy(&val, option, 2);
*ret = be16toh(val);
*ret = unaligned_read_be16((be16_t*) option);
if (*ret < min)
*ret = min;
......@@ -315,23 +311,6 @@ static int lease_parse_in_addrs_pairs(const uint8_t *option, size_t len, struct
return lease_parse_in_addrs_aux(option, len, ret, ret_size, 2);
}
static int class_prefixlen(uint8_t msb_octet, uint8_t *ret) {
if (msb_octet < 128)
/* Class A */
*ret = 8;
else if (msb_octet < 192)
/* Class B */
*ret = 16;
else if (msb_octet < 224)
/* Class C */
*ret = 24;
else
/* Class D or E -- no subnet mask */
return -ERANGE;
return 0;
}
static int lease_parse_routes(const uint8_t *option, size_t len, struct sd_dhcp_route **routes,
size_t *routes_size, size_t *routes_allocated) {
......@@ -353,8 +332,10 @@ static int lease_parse_routes(const uint8_t *option, size_t len, struct sd_dhcp_
while (len >= 8) {