summaryrefslogtreecommitdiff
path: root/src/libsystemd-network
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-08-26 19:19:32 +0200
committerLennart Poettering <lennart@poettering.net>2015-08-26 20:44:20 +0200
commit8eb9058dc1f99a5eb9b8726a978fcc0720837a10 (patch)
tree9e2670f8a77d6fd01d763c7097908f6824694571 /src/libsystemd-network
parent43f447b121b38c01a7c5626a51cc571a822250b8 (diff)
dhcp,network: implement RFC 4833 (DHCP Timezone option)
This one is simply to add: encode the tzdata timezone in the DHCP options and optionally make use of it.
Diffstat (limited to 'src/libsystemd-network')
-rw-r--r--src/libsystemd-network/dhcp-lease-internal.h1
-rw-r--r--src/libsystemd-network/dhcp-protocol.h2
-rw-r--r--src/libsystemd-network/dhcp-server-internal.h2
-rw-r--r--src/libsystemd-network/sd-dhcp-lease.c32
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c27
5 files changed, 64 insertions, 0 deletions
diff --git a/src/libsystemd-network/dhcp-lease-internal.h b/src/libsystemd-network/dhcp-lease-internal.h
index 5a3fcddb1b..6e247e9865 100644
--- a/src/libsystemd-network/dhcp-lease-internal.h
+++ b/src/libsystemd-network/dhcp-lease-internal.h
@@ -83,6 +83,7 @@ struct sd_dhcp_lease {
size_t client_id_len;
uint8_t *vendor_specific;
size_t vendor_specific_len;
+ char *timezone;
LIST_HEAD(struct sd_dhcp_raw_option, private_options);
};
diff --git a/src/libsystemd-network/dhcp-protocol.h b/src/libsystemd-network/dhcp-protocol.h
index 4308723f91..88a81d2866 100644
--- a/src/libsystemd-network/dhcp-protocol.h
+++ b/src/libsystemd-network/dhcp-protocol.h
@@ -137,6 +137,8 @@ enum {
DHCP_OPTION_REBINDING_T2_TIME = 59,
DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60,
DHCP_OPTION_CLIENT_IDENTIFIER = 61,
+ DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
+ DHCP_OPTION_NEW_TZDB_TIMEZONE = 101,
DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
DHCP_OPTION_PRIVATE_BASE = 224,
DHCP_OPTION_PRIVATE_LAST = 254,
diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h
index 58750c4418..24f99f801d 100644
--- a/src/libsystemd-network/dhcp-server-internal.h
+++ b/src/libsystemd-network/dhcp-server-internal.h
@@ -62,6 +62,8 @@ struct sd_dhcp_server {
size_t pool_size;
size_t next_offer;
+ char *timezone;
+
Hashmap *leases_by_client_id;
DHCPLease **bound_leases;
};
diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c
index 57369a353d..c312c7cad0 100644
--- a/src/libsystemd-network/sd-dhcp-lease.c
+++ b/src/libsystemd-network/sd-dhcp-lease.c
@@ -608,6 +608,22 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
break;
+ case DHCP_OPTION_NEW_TZDB_TIMEZONE: {
+ _cleanup_free_ char *tz = NULL;
+
+ r = lease_parse_string(option, len, &tz);
+ if (r < 0)
+ return r;
+
+ if (!timezone_is_valid(tz))
+ return -EINVAL;
+
+ free(lease->timezone);
+ lease->timezone = tz;
+ tz = NULL;
+ break;
+ }
+
case DHCP_OPTION_VENDOR_SPECIFIC:
if (len >= 1) {
free(lease->vendor_specific);
@@ -757,6 +773,10 @@ int sd_dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
if (r >= 0)
serialize_dhcp_routes(f, "ROUTES", routes, r);
+ r = sd_dhcp_lease_get_timezone(lease, &string);
+ if (r >= 0)
+ fprintf(f, "TIMEZONE=%s\n", string);
+
r = sd_dhcp_lease_get_client_id(lease, &client_id, &client_id_len);
if (r >= 0) {
_cleanup_free_ char *client_id_hex;
@@ -840,6 +860,7 @@ int sd_dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
"ROOT_PATH", &lease->root_path,
"ROUTES", &routes,
"CLIENTID", &client_id_hex,
+ "TIMEZONE", &lease->timezone,
"VENDOR_SPECIFIC", &vendor_specific_hex,
"OPTION_224", &options[0],
"OPTION_225", &options[1],
@@ -1026,3 +1047,14 @@ int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const uint8_t *client_id,
return 0;
}
+
+int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **timezone) {
+ assert_return(lease, -EINVAL);
+ assert_return(timezone, -EINVAL);
+
+ if (!lease->timezone)
+ return -ENXIO;
+
+ *timezone = lease->timezone;
+ return 0;
+}
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index faeab0fd30..730d95e2c0 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -136,6 +136,8 @@ sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server) {
sd_event_unref(server->event);
+ free(server->timezone);
+
while ((lease = hashmap_steal_first(server->leases_by_client_id)))
dhcp_lease_free(lease);
hashmap_free(server->leases_by_client_id);
@@ -474,6 +476,15 @@ static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req,
if (r < 0)
return r;
+ if (server->timezone) {
+ r = dhcp_option_append(
+ &packet->dhcp, req->max_optlen, &offset, 0,
+ DHCP_OPTION_NEW_TZDB_TIMEZONE,
+ strlen(server->timezone), server->timezone);
+ if (r < 0)
+ return r;
+ }
+
r = dhcp_server_send_packet(server, req, packet, DHCP_ACK, offset);
if (r < 0)
return r;
@@ -993,3 +1004,19 @@ int sd_dhcp_server_forcerenew(sd_dhcp_server *server) {
return r;
}
+
+int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone) {
+ int r;
+
+ assert_return(server, -EINVAL);
+ assert_return(timezone_is_valid(timezone), -EINVAL);
+
+ if (streq_ptr(timezone, server->timezone))
+ return 0;
+
+ r = free_and_strdup(&server->timezone, timezone);
+ if (r < 0)
+ return r;
+
+ return 1;
+}