summaryrefslogtreecommitdiff
path: root/src/libsystemd-network/sd-dhcp6-client.c
diff options
context:
space:
mode:
authorSusant Sahani <ssahani@vmware.com>2020-04-20 09:04:58 +0200
committerSusant Sahani <ssahani@vmware.com>2020-05-20 07:52:19 +0200
commit73c8ced784c467a27732cd45e24d06b8a33c457d (patch)
treeac90455ec750e23230cbfeaab5af6e97479df919 /src/libsystemd-network/sd-dhcp6-client.c
parentd08a6ec39c2cb786bbf8ba2a8d480ada2973ad59 (diff)
downloadsystemd-73c8ced784c467a27732cd45e24d06b8a33c457d.tar.gz
sd-network: DHCPv6 - Add support to send vendor class data
``` 21.16. Vendor Class Option This option is used by a client to identify the vendor that manufactured the hardware on which the client is running. The information contained in the data area of this option is contained in one or more opaque fields that identify details of the hardware configuration. The format of the Vendor Class option is: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | OPTION_VENDOR_CLASS | option-len | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | enterprise-number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ . . . vendor-class-data . . . . . . +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Figure 28: Vendor Class Option Format option-code OPTION_VENDOR_CLASS (16). option-len 4 + length of vendor-class-data field. enterprise-number The vendor's registered Enterprise Number as maintained by IANA [IANA-PEN]. A 4-octet field containing an unsigned integer. vendor-class-data The hardware configuration of the node on which the client is running. A variable-length field (4 octets less than the value in the option-len field). The vendor-class-data field is composed of a series of separate items, each of which describes some characteristic of the client's hardware configuration. Examples of vendor-class-data instances might include the version of the operating system the client is running or the amount of memory installed on the client. Each instance of vendor-class-data is formatted as follows: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...-+-+-+-+-+-+-+ | vendor-class-len | opaque-data | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...-+-+-+-+-+-+-+ Figure 29: Format of vendor-class-data Field The vendor-class-len field is 2 octets long and specifies the length of the opaque vendor-class-data in network byte order. Servers and clients MUST NOT include more than one instance of OPTION_VENDOR_CLASS with the same Enterprise Number. Each instance of OPTION_VENDOR_CLASS can carry multiple vendor-class-data instances. ```
Diffstat (limited to 'src/libsystemd-network/sd-dhcp6-client.c')
-rw-r--r--src/libsystemd-network/sd-dhcp6-client.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index 0240f1b7c7..ce9e6cae7e 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -68,6 +68,7 @@ struct sd_dhcp6_client {
char *fqdn;
char *mudurl;
char **user_class;
+ char **vendor_class;
sd_event_source *receive_message;
usec_t retransmit_time;
uint8_t retransmit_count;
@@ -380,7 +381,7 @@ int sd_dhcp6_client_set_request_mud_url(sd_dhcp6_client *client, const char *mud
assert_return(client, -EINVAL);
assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
assert_return(mudurl, -EINVAL);
- assert_return(strlen(mudurl) <= 255, -EINVAL);
+ assert_return(strlen(mudurl) <= UINT8_MAX, -EINVAL);
assert_return(http_url_is_valid(mudurl), -EINVAL);
return free_and_strdup(&client->mudurl, mudurl);
@@ -392,6 +393,7 @@ int sd_dhcp6_client_set_request_user_class(sd_dhcp6_client *client, char **user_
assert_return(client, -EINVAL);
assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
+
assert_return(user_class, -EINVAL);
STRV_FOREACH(p, user_class)
@@ -407,6 +409,27 @@ int sd_dhcp6_client_set_request_user_class(sd_dhcp6_client *client, char **user_
return 0;
}
+int sd_dhcp6_client_set_request_vendor_class(sd_dhcp6_client *client, char **vendor_class) {
+ _cleanup_strv_free_ char **s = NULL;
+ char **p;
+
+ assert_return(client, -EINVAL);
+ assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
+ assert_return(vendor_class, -EINVAL);
+
+ STRV_FOREACH(p, vendor_class)
+ if (strlen(*p) > UINT8_MAX)
+ return -ENAMETOOLONG;
+
+ s = strv_copy(vendor_class);
+ if (!s)
+ return -ENOMEM;
+
+ client->vendor_class = TAKE_PTR(s);
+
+ return 0;
+}
+
int sd_dhcp6_client_get_prefix_delegation(sd_dhcp6_client *client, int *delegation) {
assert_return(client, -EINVAL);
assert_return(delegation, -EINVAL);
@@ -593,6 +616,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
return r;
}
+ if (client->vendor_class) {
+ r = dhcp6_option_append_vendor_class(&opt, &optlen, client->vendor_class);
+ if (r < 0)
+ return r;
+ }
+
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
r = dhcp6_option_append_pd(opt, optlen, &client->ia_pd, &client->hint_pd_prefix);
if (r < 0)
@@ -645,6 +674,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
return r;
}
+ if (client->vendor_class) {
+ r = dhcp6_option_append_vendor_class(&opt, &optlen, client->vendor_class);
+ if (r < 0)
+ return r;
+ }
+
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL);
if (r < 0)
@@ -685,6 +720,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
return r;
}
+ if (client->vendor_class) {
+ r = dhcp6_option_append_vendor_class(&opt, &optlen, client->vendor_class);
+ if (r < 0)
+ return r;
+ }
+
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL);
if (r < 0)
@@ -1645,6 +1686,7 @@ static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) {
ordered_hashmap_free(client->extra_options);
strv_free(client->user_class);
+ strv_free(client->vendor_class);
return mfree(client);
}