diff options
author | Tom Gundersen <teg@jklm.no> | 2014-03-19 16:05:44 +0100 |
---|---|---|
committer | Tom Gundersen <teg@jklm.no> | 2014-03-21 17:52:42 +0100 |
commit | 9e64dd72765ddc2583554ebed24eb2c824564838 (patch) | |
tree | 85f7e9394a093269adfa6ca917b203221b38bba8 /src/libsystemd-network/sd-dhcp-lease.c | |
parent | 022446adf99b84c59a88c2e614033ccde13c395c (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-lease.c')
-rw-r--r-- | src/libsystemd-network/sd-dhcp-lease.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index e6d80d4c66..159bb502c8 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -481,3 +481,29 @@ int dhcp_lease_load(const char *lease_file, sd_dhcp_lease **ret) { return 0; } + +int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease) { + uint32_t address; + + assert(lease); + assert(lease->address != INADDR_ANY); + + address = be32toh(lease->address); + + /* fall back to the default subnet masks based on address class */ + + if ((address >> 31) == 0x0) + /* class A, leading bits: 0 */ + lease->subnet_mask = htobe32(0xff000000); + else if ((address >> 30) == 0x2) + /* class B, leading bits 10 */ + lease->subnet_mask = htobe32(0xffff0000); + else if ((address >> 29) == 0x6) + /* class C, leading bits 110 */ + lease->subnet_mask = htobe32(0xffffff00); + else + /* class D or E, no default mask. give up */ + return -ERANGE; + + return 0; +} |