summaryrefslogtreecommitdiff
path: root/src/libsystemd-network
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2014-11-18 17:13:12 -0600
committerTom Gundersen <teg@jklm.no>2014-11-19 00:58:51 +0100
commite37f74a6d5cc3c0a3d214c3a7f5de234b0696b4c (patch)
tree1ab3077929b5ec5bbe654a26ac36ad2a86ba73c9 /src/libsystemd-network
parentba6c0fd6303c63576983c7be892d80d954c1e4c5 (diff)
sd-dhcp-lease: load/save client ID
The lease is usually tied to the client ID, so users of the lease may want to know what client ID it was acquired with.
Diffstat (limited to 'src/libsystemd-network')
-rw-r--r--src/libsystemd-network/dhcp-lease-internal.h5
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c16
-rw-r--r--src/libsystemd-network/sd-dhcp-lease.c58
3 files changed, 78 insertions, 1 deletions
diff --git a/src/libsystemd-network/dhcp-lease-internal.h b/src/libsystemd-network/dhcp-lease-internal.h
index 8806351eb2..9e184ac4b5 100644
--- a/src/libsystemd-network/dhcp-lease-internal.h
+++ b/src/libsystemd-network/dhcp-lease-internal.h
@@ -70,6 +70,8 @@ struct sd_dhcp_lease {
char *domainname;
char *hostname;
char *root_path;
+ uint8_t *client_id;
+ size_t client_id_len;
};
int dhcp_lease_new(sd_dhcp_lease **ret);
@@ -78,5 +80,8 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease);
+int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const uint8_t *client_id,
+ size_t client_id_len);
+
DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_lease*, sd_dhcp_lease_unref);
#define _cleanup_dhcp_lease_unref_ _cleanup_(sd_dhcp_lease_unrefp)
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 8503f19c27..b2b72befbf 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -1029,6 +1029,14 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
if (r < 0)
return r;
+ if (client->client_id_len) {
+ r = dhcp_lease_set_client_id(lease,
+ (uint8_t *) &client->client_id.raw,
+ client->client_id_len);
+ if (r < 0)
+ return r;
+ }
+
r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease);
if (r != DHCP_OFFER) {
log_dhcp_client(client, "received message was not an OFFER, ignoring");
@@ -1088,6 +1096,14 @@ static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack,
if (r < 0)
return r;
+ if (client->client_id_len) {
+ r = dhcp_lease_set_client_id(lease,
+ (uint8_t *) &client->client_id.raw,
+ client->client_id_len);
+ if (r < 0)
+ return r;
+ }
+
r = dhcp_option_parse(ack, len, dhcp_lease_parse_options, lease);
if (r == DHCP_NAK) {
log_dhcp_client(client, "NAK");
diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c
index 1a6add0fa3..f046ac5672 100644
--- a/src/libsystemd-network/sd-dhcp-lease.c
+++ b/src/libsystemd-network/sd-dhcp-lease.c
@@ -199,6 +199,7 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) {
free(lease->dns);
free(lease->ntp);
free(lease->static_route);
+ free(lease->client_id);
free(lease);
}
@@ -585,6 +586,8 @@ int sd_dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
_cleanup_fclose_ FILE *f = NULL;
struct in_addr address;
const struct in_addr *addresses;
+ const uint8_t *client_id;
+ size_t client_id_len;
const char *string;
uint16_t mtu;
struct sd_dhcp_route *routes;
@@ -658,6 +661,18 @@ 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_client_id(lease, &client_id, &client_id_len);
+ if (r >= 0) {
+ _cleanup_free_ char *client_id_hex;
+
+ client_id_hex = hexmem (client_id, client_id_len);
+ if (!client_id_hex) {
+ r = -ENOMEM;
+ goto finish;
+ }
+ fprintf(f, "CLIENTID=%s\n", client_id_hex);
+ }
+
r = 0;
fflush(f);
@@ -679,7 +694,8 @@ int sd_dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
_cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL;
_cleanup_free_ char *address = NULL, *router = NULL, *netmask = NULL,
*server_address = NULL, *next_server = NULL,
- *dns = NULL, *ntp = NULL, *mtu = NULL, *routes = NULL;
+ *dns = NULL, *ntp = NULL, *mtu = NULL,
+ *routes = NULL, *client_id_hex = NULL;
struct in_addr addr;
int r;
@@ -703,6 +719,7 @@ int sd_dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
"HOSTNAME", &lease->hostname,
"ROOT_PATH", &lease->root_path,
"ROUTES", &routes,
+ "CLIENTID", &client_id_hex,
NULL);
if (r < 0) {
if (r == -ENOENT)
@@ -777,6 +794,16 @@ int sd_dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
return r;
}
+ if (client_id_hex) {
+ if (strlen (client_id_hex) % 2)
+ return -EINVAL;
+
+ lease->client_id = unhexmem (client_id_hex, strlen (client_id_hex));
+ if (!lease->client_id)
+ return -ENOMEM;
+ lease->client_id_len = strlen (client_id_hex) / 2;
+ }
+
*ret = lease;
lease = NULL;
@@ -801,3 +828,32 @@ int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease) {
return 0;
}
+
+int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const uint8_t **client_id,
+ size_t *client_id_len) {
+ assert_return(lease, -EINVAL);
+ assert_return(client_id, -EINVAL);
+ assert_return(client_id_len, -EINVAL);
+
+ *client_id = lease->client_id;
+ *client_id_len = lease->client_id_len;
+ return 0;
+}
+
+int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const uint8_t *client_id,
+ size_t client_id_len) {
+ assert_return(lease, -EINVAL);
+ assert_return((!client_id && !client_id_len) ||
+ (client_id && client_id_len), -EINVAL);
+
+ free (lease->client_id);
+ lease->client_id = NULL;
+ lease->client_id_len = 0;
+
+ if (client_id) {
+ lease->client_id = memdup (client_id, client_id_len);
+ lease->client_id_len = client_id_len;
+ }
+
+ return 0;
+}