X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd-network%2Fsd-dhcp-lease.c;h=159bb502c87cac8975b510cc963313f55ae0e8ed;hb=7429b07f822348dc5a87208ce107f5f6bf02656d;hp=722dd0a419bae0c0f715ba2e0ecca36caad736d0;hpb=ce78df79b88d02d36cbf9e39e70ecb871750e16d;p=elogind.git diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 722dd0a41..159bb502c 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -126,6 +126,24 @@ int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr) { return 0; } +int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr) { + assert_return(lease, -EINVAL); + assert_return(addr, -EINVAL); + + addr->s_addr = lease->server_address; + + return 0; +} + +int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr) { + assert_return(lease, -EINVAL); + assert_return(addr, -EINVAL); + + addr->s_addr = lease->next_server; + + return 0; +} + sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease) { if (lease) assert_se(REFCNT_INC(lease->n_ref) >= 2); @@ -279,10 +297,6 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) { assert(lease); assert(lease_file); - r = mkdir_safe_label("/run/systemd/network/leases", 0755, 0, 0); - if (r < 0) - goto finish; - r = fopen_temporary(lease_file, &f, &temp_path); if (r < 0) goto finish; @@ -329,6 +343,30 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) { fprintf(f, "NETMASK=%s\n", string); + r = sd_dhcp_lease_get_server_identifier(lease, &address); + if (r >= 0) { + string = inet_ntop(AF_INET, &address, buf, INET_ADDRSTRLEN); + if (!string) { + r = -errno; + goto finish; + } + + fprintf(f, + "SERVER_ADDRESS=%s\n", string); + } + + r = sd_dhcp_lease_get_next_server(lease, &address); + if (r >= 0) { + string = inet_ntop(AF_INET, &address, buf, INET_ADDRSTRLEN); + if (!string) { + r = -errno; + goto finish; + } + + fprintf(f, + "NEXT_SERVER=%s\n", string); + } + r = sd_dhcp_lease_get_mtu(lease, &mtu); if (r >= 0) fprintf(f, "MTU=%" PRIu16 "\n", mtu); @@ -367,6 +405,7 @@ finish: int dhcp_lease_load(const char *lease_file, sd_dhcp_lease **ret) { _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL; _cleanup_free_ char *address = NULL, *router = NULL, *netmask = NULL, + *server_address = NULL, *next_server = NULL, *mtu = NULL; struct in_addr addr; int r; @@ -382,6 +421,8 @@ int dhcp_lease_load(const char *lease_file, sd_dhcp_lease **ret) { "ADDRESS", &address, "ROUTER", &router, "NETMASK", &netmask, + "SERVER_IDENTIFIER", &server_address, + "NEXT_SERVER", &next_server, "MTU", &mtu, "DOMAINNAME", &lease->domainname, "HOSTNAME", &lease->hostname, @@ -413,6 +454,22 @@ int dhcp_lease_load(const char *lease_file, sd_dhcp_lease **ret) { lease->subnet_mask = addr.s_addr; + if (server_address) { + r = inet_pton(AF_INET, server_address, &addr); + if (r < 0) + return r; + + lease->server_address = addr.s_addr; + } + + if (next_server) { + r = inet_pton(AF_INET, next_server, &addr); + if (r < 0) + return r; + + lease->next_server = addr.s_addr; + } + if (mtu) { uint16_t u; if (sscanf(mtu, "%" SCNu16, &u) > 0) @@ -424,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; +}