int sd_dhcp_client_set_mac(sd_dhcp_client *client,
const struct ether_addr *addr) {
+ bool need_restart = false;
+
assert_return(client, -EINVAL);
- assert_return(client->state == DHCP_STATE_INIT, -EBUSY);
+ assert_return(addr, -EINVAL);
- log_dhcp_client(client, "set MAC address to "
- "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
- addr->ether_addr_octet[0],
- addr->ether_addr_octet[1],
- addr->ether_addr_octet[2],
- addr->ether_addr_octet[3],
- addr->ether_addr_octet[4],
- addr->ether_addr_octet[5]);
+ if (memcmp(&client->client_id.mac_addr, addr, ETH_ALEN) == 0)
+ return 0;
+
+ if (client->state != DHCP_STATE_INIT) {
+ log_dhcp_client(client, "Changing MAC address on running DHCP "
+ "client, restarting");
+ sd_dhcp_client_stop(client);
+ need_restart = true;
+ }
memcpy(&client->client_id.mac_addr, addr, ETH_ALEN);
client->client_id.type = 0x01;
+ if (need_restart)
+ sd_dhcp_client_start(client);
+
return 0;
}
}
static int client_send_discover(sd_dhcp_client *client) {
- _cleanup_free_ DHCPPacket *discover;
+ _cleanup_free_ DHCPPacket *discover = NULL;
size_t optlen, len;
uint8_t *opt;
usec_t time_now;
assert(client);
- r = sd_event_get_now_monotonic(client->event, &time_now);
+ r = sd_event_now(client->event, CLOCK_MONOTONIC, &time_now);
if (r < 0)
return r;
assert(time_now >= client->start_time);
assert(client);
assert(client->event);
- r = sd_event_get_now_monotonic(client->event, &time_now);
+ r = sd_event_now(client->event, CLOCK_MONOTONIC, &time_now);
if (r < 0)
goto error;
client->timeout_resend = sd_event_source_unref(client->timeout_resend);
- r = sd_event_add_monotonic(client->event,
- &client->timeout_resend,
- next_timeout,
- 10 * USEC_PER_MSEC,
- client_timeout_resend, client);
+ r = sd_event_add_time(client->event,
+ &client->timeout_resend,
+ CLOCK_MONOTONIC,
+ next_timeout, 10 * USEC_PER_MSEC,
+ client_timeout_resend, client);
if (r < 0)
goto error;
client->timeout_resend = sd_event_source_unref(client->timeout_resend);
- r = sd_event_add_monotonic(client->event,
- &client->timeout_resend, 0, 0,
- client_timeout_resend, client);
+ r = sd_event_add_time(client->event,
+ &client->timeout_resend,
+ CLOCK_MONOTONIC,
+ 0, 0,
+ client_timeout_resend, client);
if (r < 0)
goto error;
return r;
r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease);
- if (r != DHCP_OFFER)
+ if (r != DHCP_OFFER) {
+ log_dhcp_client(client, "receieved message was not an OFFER, ignoring");
return -ENOMSG;
+ }
lease->next_server = offer->siaddr;
if (lease->address == INADDR_ANY ||
lease->server_address == INADDR_ANY ||
- lease->subnet_mask == INADDR_ANY ||
- lease->lifetime == 0)
+ lease->lifetime == 0) {
+ log_dhcp_client(client, "receieved lease lacks address, server "
+ "address or lease lifetime, ignoring");
return -ENOMSG;
+ }
+
+ if (lease->subnet_mask == INADDR_ANY) {
+ r = dhcp_lease_set_default_subnet_mask(lease);
+ if (r < 0) {
+ log_dhcp_client(client, "receieved lease lacks subnet "
+ "mask, and a fallback one can not be "
+ "generated, ignoring");
+ return -ENOMSG;
+ }
+ }
client->lease = lease;
lease = NULL;
return DHCP_EVENT_NO_LEASE;
}
- if (r != DHCP_ACK)
+ if (r != DHCP_ACK) {
+ log_dhcp_client(client, "receieved message was not an ACK, ignoring");
return -ENOMSG;
+ }
lease->next_server = ack->siaddr;
if (lease->address == INADDR_ANY ||
lease->server_address == INADDR_ANY ||
- lease->subnet_mask == INADDR_ANY || lease->lifetime == 0)
+ lease->lifetime == 0) {
+ log_dhcp_client(client, "receieved lease lacks address, server "
+ "address or lease lifetime, ignoring");
return -ENOMSG;
+ }
+
+ if (lease->subnet_mask == INADDR_ANY) {
+ r = dhcp_lease_set_default_subnet_mask(lease);
+ if (r < 0) {
+ log_dhcp_client(client, "receieved lease lacks subnet "
+ "mask, and a fallback one can not be "
+ "generated, ignoring");
+ return -ENOMSG;
+ }
+ }
r = DHCP_EVENT_IP_ACQUIRE;
if (client->lease) {
if (client->lease->lifetime == 0xffffffff)
return 0;
- r = sd_event_get_now_monotonic(client->event, &time_now);
+ r = sd_event_now(client->event, CLOCK_MONOTONIC, &time_now);
if (r < 0)
return r;
assert(client->request_sent <= time_now);
}
/* arm lifetime timeout */
- r = sd_event_add_monotonic(client->event,
- &client->timeout_expire, lifetime_timeout,
- 10 * USEC_PER_MSEC,
- client_timeout_expire, client);
+ r = sd_event_add_time(client->event, &client->timeout_expire,
+ CLOCK_MONOTONIC,
+ lifetime_timeout, 10 * USEC_PER_MSEC,
+ client_timeout_expire, client);
if (r < 0)
return r;
return 0;
/* arm T2 timeout */
- r = sd_event_add_monotonic(client->event,
- &client->timeout_t2,
- t2_timeout,
- 10 * USEC_PER_MSEC,
- client_timeout_t2, client);
+ r = sd_event_add_time(client->event,
+ &client->timeout_t2,
+ CLOCK_MONOTONIC,
+ t2_timeout,
+ 10 * USEC_PER_MSEC,
+ client_timeout_t2, client);
if (r < 0)
return r;
return 0;
/* arm T1 timeout */
- r = sd_event_add_monotonic(client->event,
- &client->timeout_t1,
- t1_timeout,
- 10 * USEC_PER_MSEC,
- client_timeout_t1, client);
+ r = sd_event_add_time(client->event,
+ &client->timeout_t1,
+ CLOCK_MONOTONIC,
+ t1_timeout, 10 * USEC_PER_MSEC,
+ client_timeout_t1, client);
if (r < 0)
return r;
client->state = DHCP_STATE_REQUESTING;
client->attempt = 1;
- r = sd_event_add_monotonic(client->event,
- &client->timeout_resend, 0,
- 0, client_timeout_resend,
- client);
+ r = sd_event_add_time(client->event,
+ &client->timeout_resend,
+ CLOCK_MONOTONIC,
+ 0, 0,
+ client_timeout_resend, client);
if (r < 0)
goto error;
client->event_priority);
if (r < 0)
goto error;
- }
+ } else if (r == -ENOMSG)
+ /* invalid message, let's ignore it */
+ return 0;
break;
case DHCP_STATE_REBINDING:
r = client_handle_ack(client, message, len);
-
if (r == DHCP_EVENT_NO_LEASE) {
client->timeout_resend =
}
goto error;
- }
-
- if (r >= 0) {
+ } else 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 = safe_close(client->fd);
- }
-
- r = 0;
+ } else if (r == -ENOMSG)
+ /* invalid message, let's ignore it */
+ return 0;
break;