assert_return(client, -EINVAL);
assert_return(client->state == DHCP_STATE_INIT, -EBUSY);
+ 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]);
+
memcpy(&client->mac_addr, addr, ETH_ALEN);
return 0;
sd_event_source_unref(client->receive_message);
if (client->fd >= 0)
- close(client->fd);
+ close_nointr_nofail(client->fd);
client->fd = -1;
client->timeout_resend = sd_event_source_unref(client->timeout_resend);
return 0;
}
+static int dhcp_client_send_raw(sd_dhcp_client *client, DHCPPacket *packet,
+ size_t len) {
+ dhcp_packet_append_ip_headers(packet, INADDR_ANY, DHCP_PORT_CLIENT,
+ INADDR_BROADCAST, DHCP_PORT_SERVER, len);
+
+ return dhcp_network_send_raw_socket(client->fd, &client->link,
+ packet, len);
+}
+
static int client_send_discover(sd_dhcp_client *client, uint16_t secs) {
int err = 0;
_cleanup_free_ DHCPPacket *discover;
if (err < 0)
return err;
- dhcp_packet_append_ip_headers(discover, len);
-
- err = dhcp_network_send_raw_socket(client->fd, &client->link,
- discover, len);
+ err = dhcp_client_send_raw(client, discover, len);
+ if (err < 0)
+ return err;
log_dhcp_client(client, "DISCOVER");
- return err;
+ return 0;
}
static int client_send_request(sd_dhcp_client *client, uint16_t secs) {
&request->dhcp,
len - DHCP_IP_UDP_SIZE);
} else {
- dhcp_packet_append_ip_headers(request, len);
-
- err = dhcp_network_send_raw_socket(client->fd, &client->link,
- request, len);
+ err = dhcp_client_send_raw(client, request, len);
}
+ if (err < 0)
+ return err;
log_dhcp_client(client, "REQUEST");
- return err;
+ return 0;
}
static uint16_t client_update_secs(sd_dhcp_client *client, usec_t time_now)
void *userdata) {
sd_dhcp_client *client = userdata;
usec_t next_timeout = 0;
+ uint64_t time_now;
uint32_t time_left;
- int r = 0;
+ int r;
assert(s);
assert(client);
assert(client->event);
+ r = sd_event_get_now_monotonic(client->event, &time_now);
+ if (r < 0)
+ goto error;
+
switch (client->state) {
case DHCP_STATE_RENEWING:
if (time_left < 60)
time_left = 60;
- next_timeout = usec + time_left * USEC_PER_SEC;
+ next_timeout = time_now + time_left * USEC_PER_SEC;
break;
if (time_left < 60)
time_left = 60;
- next_timeout = usec + time_left * USEC_PER_SEC;
+ next_timeout = time_now + time_left * USEC_PER_SEC;
break;
case DHCP_STATE_INIT:
if (client->attempt < 64)
client->attempt *= 2;
- next_timeout = usec + (client->attempt - 1) * USEC_PER_SEC;
+ next_timeout = time_now + (client->attempt - 1) * USEC_PER_SEC;
break;
}
switch (client->state) {
case DHCP_STATE_INIT:
- client_update_secs(client, usec);
+ client_update_secs(client, time_now);
r = client_send_discover(client, client->secs);
if (r >= 0) {
break;
case DHCP_STATE_SELECTING:
- client_update_secs(client, usec);
+ client_update_secs(client, time_now);
r = client_send_discover(client, client->secs);
if (r < 0 && client->attempt >= 64)
if (r < 0 && client->attempt >= 64)
goto error;
- client->request_sent = usec;
+ client->request_sent = time_now;
break;
}
static int client_initialize_events(sd_dhcp_client *client,
- sd_event_io_handler_t io_callback,
- usec_t usec) {
+ sd_event_io_handler_t io_callback) {
int r;
assert(client);
client->timeout_resend = sd_event_source_unref(client->timeout_resend);
r = sd_event_add_monotonic(client->event,
- &client->timeout_resend,
- usec, 0,
+ &client->timeout_resend, 0, 0,
client_timeout_resend, client);
if (r < 0)
goto error;
if (client->fd >= 0) {
client->receive_message =
sd_event_source_unref(client->receive_message);
- close(client->fd);
+ close_nointr_nofail(client->fd);
client->fd = -1;
}
log_dhcp_client(client, "TIMEOUT T2");
- return client_initialize_events(client, client_receive_message_raw,
- usec);
+ return client_initialize_events(client, client_receive_message_raw);
}
static int client_timeout_t1(sd_event_source *s, uint64_t usec,
log_dhcp_client(client, "TIMEOUT T1");
- return client_initialize_events(client, client_receive_message_udp, usec);
+ return client_initialize_events(client, client_receive_message_udp);
}
static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
return -EINVAL;
r = sd_event_add_monotonic(client->event,
- &client->timeout_t1,
- next_timeout,
- 10 * USEC_PER_MSEC,
- client_timeout_t1, client);
+ &client->timeout_t1,
+ next_timeout,
+ 10 * USEC_PER_MSEC,
+ client_timeout_t1, client);
if (r < 0)
return r;
return -EINVAL;
r = sd_event_add_monotonic(client->event,
- &client->timeout_t2,
- next_timeout,
- 10 * USEC_PER_MSEC,
- client_timeout_t2, client);
+ &client->timeout_t2,
+ next_timeout,
+ 10 * USEC_PER_MSEC,
+ client_timeout_t2, client);
if (r < 0)
return r;
return -EINVAL;
r = sd_event_add_monotonic(client->event,
- &client->timeout_expire, next_timeout,
- 10 * USEC_PER_MSEC,
- client_timeout_expire, client);
+ &client->timeout_expire, next_timeout,
+ 10 * USEC_PER_MSEC,
+ client_timeout_expire, client);
if (r < 0)
return r;
client->attempt = 1;
r = sd_event_add_monotonic(client->event,
- &client->timeout_resend,
- time_now, 0,
- client_timeout_resend,
+ &client->timeout_resend, 0,
+ 0, client_timeout_resend,
client);
if (r < 0)
goto error;
client->receive_message =
sd_event_source_unref(client->receive_message);
- close(client->fd);
+ close_nointr_nofail(client->fd);
client->fd = -1;
}
log_dhcp_client(client, "STARTED");
- return client_initialize_events(client, client_receive_message_raw,
- client->start_time);
+ return client_initialize_events(client, client_receive_message_raw);
}
int sd_dhcp_client_stop(sd_dhcp_client *client) {