mirror of
https://github.com/systemd/systemd
synced 2024-10-15 04:24:19 +00:00
ndisc: parse RFC8910 captive portal ipv6ra option
This commit is contained in:
parent
fde788601b
commit
9747955d2d
|
@ -715,3 +715,45 @@ int sd_ndisc_router_dnssl_get_lifetime(sd_ndisc_router *rt, uint32_t *ret_sec) {
|
||||||
*ret_sec = be32toh(*(uint32_t*) (ri + 4));
|
*ret_sec = be32toh(*(uint32_t*) (ri + 4));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sd_ndisc_router_captive_portal_get_uri(sd_ndisc_router *rt, const char **ret_uri, size_t *ret_size) {
|
||||||
|
int r;
|
||||||
|
const char *nd_opt_captive_portal;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
assert_return(rt, -EINVAL);
|
||||||
|
assert_return(ret_uri, -EINVAL);
|
||||||
|
|
||||||
|
r = sd_ndisc_router_option_is_type(rt, SD_NDISC_OPTION_CAPTIVE_PORTAL);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
if (r == 0)
|
||||||
|
return -EMEDIUMTYPE;
|
||||||
|
|
||||||
|
r = sd_ndisc_router_option_get_raw(rt, (void *)&nd_opt_captive_portal, &length);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
/* The length field has units of 8 octets */
|
||||||
|
assert(length % 8 == 0);
|
||||||
|
if (length == 0)
|
||||||
|
return -EBADMSG;
|
||||||
|
|
||||||
|
/* Check that the message is not truncated by an embedded NUL.
|
||||||
|
* NUL padding to a multiple of 8 is expected. */
|
||||||
|
size_t size = strnlen(nd_opt_captive_portal + 2, length - 2);
|
||||||
|
if (DIV_ROUND_UP(size + 2, 8) != length / 8)
|
||||||
|
return -EBADMSG;
|
||||||
|
|
||||||
|
/* Let's not return an empty buffer */
|
||||||
|
if (size == 0) {
|
||||||
|
*ret_uri = NULL;
|
||||||
|
*ret_size = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret_uri = nd_opt_captive_portal + 2;
|
||||||
|
*ret_size = size;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -196,6 +196,7 @@ static Link *link_free(Link *link) {
|
||||||
free(link->ssid);
|
free(link->ssid);
|
||||||
free(link->previous_ssid);
|
free(link->previous_ssid);
|
||||||
free(link->driver);
|
free(link->driver);
|
||||||
|
free(link->ndisc_captive_portal);
|
||||||
|
|
||||||
unlink_and_free(link->lease_file);
|
unlink_and_free(link->lease_file);
|
||||||
unlink_and_free(link->lldp_file);
|
unlink_and_free(link->lldp_file);
|
||||||
|
|
|
@ -154,6 +154,7 @@ typedef struct Link {
|
||||||
sd_event_source *ndisc_expire;
|
sd_event_source *ndisc_expire;
|
||||||
Set *ndisc_rdnss;
|
Set *ndisc_rdnss;
|
||||||
Set *ndisc_dnssl;
|
Set *ndisc_dnssl;
|
||||||
|
char *ndisc_captive_portal;
|
||||||
unsigned ndisc_messages;
|
unsigned ndisc_messages;
|
||||||
bool ndisc_configured:1;
|
bool ndisc_configured:1;
|
||||||
|
|
||||||
|
|
|
@ -716,6 +716,43 @@ DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
|
||||||
ndisc_dnssl_compare_func,
|
ndisc_dnssl_compare_func,
|
||||||
free);
|
free);
|
||||||
|
|
||||||
|
static int ndisc_router_process_captive_portal(Link *link, sd_ndisc_router *rt) {
|
||||||
|
const char *uri;
|
||||||
|
_cleanup_free_ char *captive_portal = NULL;
|
||||||
|
size_t len;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(link->network);
|
||||||
|
assert(rt);
|
||||||
|
|
||||||
|
if (!link->network->ipv6_accept_ra_use_captive_portal)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = sd_ndisc_router_captive_portal_get_uri(rt, &uri, &len);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
mfree(link->ndisc_captive_portal);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = make_cstring(uri, len, MAKE_CSTRING_REFUSE_TRAILING_NUL, &captive_portal);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (!in_charset(captive_portal, URI_VALID))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!streq_ptr(link->ndisc_captive_portal, captive_portal)) {
|
||||||
|
free_and_replace(link->ndisc_captive_portal, captive_portal);
|
||||||
|
link_dirty(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) {
|
static int ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) {
|
||||||
_cleanup_strv_free_ char **l = NULL;
|
_cleanup_strv_free_ char **l = NULL;
|
||||||
usec_t lifetime_usec, timestamp_usec;
|
usec_t lifetime_usec, timestamp_usec;
|
||||||
|
@ -832,6 +869,9 @@ static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) {
|
||||||
case SD_NDISC_OPTION_DNSSL:
|
case SD_NDISC_OPTION_DNSSL:
|
||||||
r = ndisc_router_process_dnssl(link, rt);
|
r = ndisc_router_process_dnssl(link, rt);
|
||||||
break;
|
break;
|
||||||
|
case SD_NDISC_OPTION_CAPTIVE_PORTAL:
|
||||||
|
r = ndisc_router_process_captive_portal(link, rt);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (r < 0 && r != -EBADMSG)
|
if (r < 0 && r != -EBADMSG)
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -476,6 +476,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
||||||
.ipv6_accept_ra = -1,
|
.ipv6_accept_ra = -1,
|
||||||
.ipv6_accept_ra_use_dns = true,
|
.ipv6_accept_ra_use_dns = true,
|
||||||
.ipv6_accept_ra_use_gateway = true,
|
.ipv6_accept_ra_use_gateway = true,
|
||||||
|
.ipv6_accept_ra_use_captive_portal = true,
|
||||||
.ipv6_accept_ra_use_route_prefix = true,
|
.ipv6_accept_ra_use_route_prefix = true,
|
||||||
.ipv6_accept_ra_use_autonomous_prefix = true,
|
.ipv6_accept_ra_use_autonomous_prefix = true,
|
||||||
.ipv6_accept_ra_use_onlink_prefix = true,
|
.ipv6_accept_ra_use_onlink_prefix = true,
|
||||||
|
|
|
@ -315,6 +315,7 @@ struct Network {
|
||||||
bool ipv6_accept_ra_use_onlink_prefix;
|
bool ipv6_accept_ra_use_onlink_prefix;
|
||||||
bool ipv6_accept_ra_use_mtu;
|
bool ipv6_accept_ra_use_mtu;
|
||||||
bool ipv6_accept_ra_quickack;
|
bool ipv6_accept_ra_quickack;
|
||||||
|
bool ipv6_accept_ra_use_captive_portal;
|
||||||
bool active_slave;
|
bool active_slave;
|
||||||
bool primary_slave;
|
bool primary_slave;
|
||||||
DHCPUseDomains ipv6_accept_ra_use_domains;
|
DHCPUseDomains ipv6_accept_ra_use_domains;
|
||||||
|
|
|
@ -123,6 +123,9 @@ int sd_ndisc_router_rdnss_get_lifetime(sd_ndisc_router *rt, uint32_t *ret);
|
||||||
int sd_ndisc_router_dnssl_get_domains(sd_ndisc_router *rt, char ***ret);
|
int sd_ndisc_router_dnssl_get_domains(sd_ndisc_router *rt, char ***ret);
|
||||||
int sd_ndisc_router_dnssl_get_lifetime(sd_ndisc_router *rt, uint32_t *ret);
|
int sd_ndisc_router_dnssl_get_lifetime(sd_ndisc_router *rt, uint32_t *ret);
|
||||||
|
|
||||||
|
/* Specific option access: SD_NDISC_OPTION_CAPTIVE_PORTAL */
|
||||||
|
int sd_ndisc_router_captive_portal_get_uri(sd_ndisc_router *rt, const char **uri, size_t *size);
|
||||||
|
|
||||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_ndisc, sd_ndisc_unref);
|
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_ndisc, sd_ndisc_unref);
|
||||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_ndisc_router, sd_ndisc_router_unref);
|
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_ndisc_router, sd_ndisc_router_unref);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue