summaryrefslogtreecommitdiff
path: root/src/libsystemd-network/sd-dhcp-client.c
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2014-03-19 16:05:44 +0100
committerTom Gundersen <teg@jklm.no>2014-03-21 17:52:42 +0100
commit9e64dd72765ddc2583554ebed24eb2c824564838 (patch)
tree85f7e9394a093269adfa6ca917b203221b38bba8 /src/libsystemd-network/sd-dhcp-client.c
parent022446adf99b84c59a88c2e614033ccde13c395c (diff)
sd-dhcp-client: add fallback subnet masks
The DHCP RFC does not require the DHCP server to send a subnet mask, so if it is missing, let's try to use the default subnet masks based on address class. In case the class the address belongs to does not have a default subnet mask, we fail as before. Also improve logging when handling invalid dhcp messages, and simply ignore them rather than stop the whole dhcp client.
Diffstat (limited to 'src/libsystemd-network/sd-dhcp-client.c')
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c54
1 files changed, 41 insertions, 13 deletions
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index aff4c21e95..59cd30c606 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -673,8 +673,10 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
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;
@@ -682,9 +684,21 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
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;
@@ -709,8 +723,10 @@ static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack,
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;
@@ -718,8 +734,21 @@ static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack,
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) {
@@ -940,7 +969,9 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
client->event_priority);
if (r < 0)
goto error;
- }
+ } else if (r == -ENOMSG)
+ /* invalid message, let's ignore it */
+ return 0;
break;
@@ -950,7 +981,6 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
case DHCP_STATE_REBINDING:
r = client_handle_ack(client, message, len);
-
if (r == DHCP_EVENT_NO_LEASE) {
client->timeout_resend =
@@ -967,9 +997,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
}
goto error;
- }
-
- if (r >= 0) {
+ } else if (r >= 0) {
client->timeout_resend =
sd_event_source_unref(client->timeout_resend);
@@ -994,9 +1022,9 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
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;