dhcp/nettools: cleanup lease_parse_routes()
This commit is contained in:
@@ -94,9 +94,9 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
in_addr_class(struct in_addr addr)
|
in_addr_class(in_addr_t addr)
|
||||||
{
|
{
|
||||||
switch (ntohl(addr.s_addr) >> 24) {
|
switch (ntohl(addr) >> 24) {
|
||||||
case 0 ... 127:
|
case 0 ... 127:
|
||||||
return NM_IN_ADDR_CLASS_A;
|
return NM_IN_ADDR_CLASS_A;
|
||||||
case 128 ... 191:
|
case 128 ... 191:
|
||||||
@@ -109,7 +109,7 @@ in_addr_class(struct in_addr addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
lease_option_consume(void *out, size_t n_out, uint8_t **datap, size_t *n_datap)
|
lease_option_consume(uint8_t **datap, size_t *n_datap, void *out, size_t n_out)
|
||||||
{
|
{
|
||||||
if (*n_datap < n_out)
|
if (*n_datap < n_out)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -121,27 +121,29 @@ lease_option_consume(void *out, size_t n_out, uint8_t **datap, size_t *n_datap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
lease_option_next_in_addr(struct in_addr *addrp, uint8_t **datap, size_t *n_datap)
|
lease_option_consume_in_addr(uint8_t **datap, size_t *n_datap, in_addr_t *addrp)
|
||||||
{
|
{
|
||||||
return lease_option_consume(addrp, sizeof(struct in_addr), datap, n_datap);
|
return lease_option_consume(datap, n_datap, addrp, sizeof(struct in_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
lease_option_next_route(struct in_addr *destp,
|
lease_option_consume_route(uint8_t ** datap,
|
||||||
uint8_t * plenp,
|
size_t * n_datap,
|
||||||
struct in_addr *gatewayp,
|
gboolean classless,
|
||||||
gboolean classless,
|
in_addr_t *destp,
|
||||||
uint8_t ** datap,
|
uint8_t * plenp,
|
||||||
size_t * n_datap)
|
in_addr_t *gatewayp)
|
||||||
{
|
{
|
||||||
struct in_addr dest = {}, gateway;
|
in_addr_t dest;
|
||||||
uint8_t * data = *datap;
|
in_addr_t gateway;
|
||||||
size_t n_data = *n_datap;
|
uint8_t * data = *datap;
|
||||||
uint8_t plen;
|
size_t n_data = *n_datap;
|
||||||
uint8_t bytes;
|
uint8_t plen;
|
||||||
|
|
||||||
if (classless) {
|
if (classless) {
|
||||||
if (!lease_option_consume(&plen, sizeof(plen), &data, &n_data))
|
uint8_t bytes;
|
||||||
|
|
||||||
|
if (!lease_option_consume(&data, &n_data, &plen, sizeof(plen)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (plen > 32)
|
if (plen > 32)
|
||||||
@@ -149,10 +151,11 @@ lease_option_next_route(struct in_addr *destp,
|
|||||||
|
|
||||||
bytes = plen == 0 ? 0 : ((plen - 1) / 8) + 1;
|
bytes = plen == 0 ? 0 : ((plen - 1) / 8) + 1;
|
||||||
|
|
||||||
if (!lease_option_consume(&dest, bytes, &data, &n_data))
|
dest = 0;
|
||||||
|
if (!lease_option_consume(&data, &n_data, &dest, bytes))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else {
|
} else {
|
||||||
if (!lease_option_next_in_addr(&dest, &data, &n_data))
|
if (!lease_option_consume_in_addr(&data, &n_data, &dest))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
switch (in_addr_class(dest)) {
|
switch (in_addr_class(dest)) {
|
||||||
@@ -170,9 +173,9 @@ lease_option_next_route(struct in_addr *destp,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dest.s_addr = nm_utils_ip4_address_clear_host_address(dest.s_addr, plen);
|
dest = nm_utils_ip4_address_clear_host_address(dest, plen);
|
||||||
|
|
||||||
if (!lease_option_next_in_addr(&gateway, &data, &n_data))
|
if (!lease_option_consume_in_addr(&data, &n_data, &gateway))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
*destp = dest;
|
*destp = dest;
|
||||||
@@ -183,13 +186,15 @@ lease_option_next_route(struct in_addr *destp,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
lease_option_print_label(GString *str, size_t n_label, uint8_t **datap, size_t *n_datap)
|
lease_option_print_label(GString *str, size_t n_label, uint8_t **datap, size_t *n_datap)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < n_label; ++i) {
|
for (size_t i = 0; i < n_label; ++i) {
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
|
|
||||||
if (!lease_option_consume(&c, sizeof(c), datap, n_datap))
|
if (!lease_option_consume(datap, n_datap, &c, sizeof(c)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
@@ -246,7 +251,7 @@ lease_option_print_domain_name(GString * str,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!lease_option_consume(&c, sizeof(c), domainp, n_domainp))
|
if (!lease_option_consume(domainp, n_domainp, &c, sizeof(c)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
switch (c & 0xC0) {
|
switch (c & 0xC0) {
|
||||||
@@ -282,7 +287,7 @@ lease_option_print_domain_name(GString * str,
|
|||||||
* two high bits are masked out.
|
* two high bits are masked out.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!lease_option_consume(&c, sizeof(c), domainp, n_domainp))
|
if (!lease_option_consume(domainp, n_domainp, &c, sizeof(c)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
offset += c;
|
offset += c;
|
||||||
@@ -305,6 +310,8 @@ lease_option_print_domain_name(GString * str,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
lease_parse_address(NDhcp4ClientLease *lease,
|
lease_parse_address(NDhcp4ClientLease *lease,
|
||||||
NMIP4Config * ip4_config,
|
NMIP4Config * ip4_config,
|
||||||
@@ -489,39 +496,37 @@ lease_parse_routes(NDhcp4ClientLease *lease,
|
|||||||
NMIP4Config * ip4_config,
|
NMIP4Config * ip4_config,
|
||||||
GHashTable * options,
|
GHashTable * options,
|
||||||
guint32 route_table,
|
guint32 route_table,
|
||||||
guint32 route_metric)
|
guint32 route_metric,
|
||||||
|
NMStrBuf * sbuf)
|
||||||
{
|
{
|
||||||
nm_auto_free_gstring GString *str = NULL;
|
char dest_str[NM_UTILS_INET_ADDRSTRLEN];
|
||||||
char dest_str[NM_UTILS_INET_ADDRSTRLEN];
|
char gateway_str[NM_UTILS_INET_ADDRSTRLEN];
|
||||||
char gateway_str[NM_UTILS_INET_ADDRSTRLEN];
|
in_addr_t dest;
|
||||||
const char * s;
|
in_addr_t gateway;
|
||||||
struct in_addr dest, gateway;
|
uint8_t plen;
|
||||||
uint8_t plen;
|
guint32 m;
|
||||||
guint32 m;
|
gboolean has_router_from_classless = FALSE;
|
||||||
gboolean has_router_from_classless = FALSE, has_classless = FALSE;
|
gboolean has_classless = FALSE;
|
||||||
guint32 default_route_metric = route_metric;
|
guint32 default_route_metric = route_metric;
|
||||||
uint8_t * data;
|
guint8 * l_data;
|
||||||
size_t n_data;
|
gsize l_data_len;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = n_dhcp4_client_lease_query(lease,
|
r = n_dhcp4_client_lease_query(lease,
|
||||||
NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE,
|
NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE,
|
||||||
&data,
|
&l_data,
|
||||||
&n_data);
|
&l_data_len);
|
||||||
if (!r) {
|
if (r == 0) {
|
||||||
nm_gstring_prepare(&str);
|
nm_str_buf_reset(sbuf);
|
||||||
|
|
||||||
has_classless = TRUE;
|
has_classless = TRUE;
|
||||||
|
|
||||||
while (lease_option_next_route(&dest, &plen, &gateway, TRUE, &data, &n_data)) {
|
while (lease_option_consume_route(&l_data, &l_data_len, TRUE, &dest, &plen, &gateway)) {
|
||||||
_nm_utils_inet4_ntop(dest.s_addr, dest_str);
|
_nm_utils_inet4_ntop(dest, dest_str);
|
||||||
_nm_utils_inet4_ntop(gateway.s_addr, gateway_str);
|
_nm_utils_inet4_ntop(gateway, gateway_str);
|
||||||
|
|
||||||
g_string_append_printf(nm_gstring_add_space_delimiter(str),
|
nm_str_buf_append_required_delimiter(sbuf, ' ');
|
||||||
"%s/%d %s",
|
nm_str_buf_append_printf(sbuf, "%s/%d %s", dest_str, (int) plen, gateway_str);
|
||||||
dest_str,
|
|
||||||
(int) plen,
|
|
||||||
gateway_str);
|
|
||||||
|
|
||||||
if (plen == 0) {
|
if (plen == 0) {
|
||||||
/* if there are multiple default routes, we add them with differing
|
/* if there are multiple default routes, we add them with differing
|
||||||
@@ -538,34 +543,32 @@ lease_parse_routes(NDhcp4ClientLease *lease,
|
|||||||
nm_ip4_config_add_route(
|
nm_ip4_config_add_route(
|
||||||
ip4_config,
|
ip4_config,
|
||||||
&((const NMPlatformIP4Route){
|
&((const NMPlatformIP4Route){
|
||||||
.network = dest.s_addr,
|
.network = dest,
|
||||||
.plen = plen,
|
.plen = plen,
|
||||||
.gateway = gateway.s_addr,
|
.gateway = gateway,
|
||||||
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
||||||
.metric = m,
|
.metric = m,
|
||||||
.table_coerced = nm_platform_route_table_coerce(route_table),
|
.table_coerced = nm_platform_route_table_coerce(route_table),
|
||||||
}),
|
}),
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
nm_dhcp_option_add_option(options,
|
nm_dhcp_option_add_option(options,
|
||||||
_nm_dhcp_option_dhcp4_options,
|
_nm_dhcp_option_dhcp4_options,
|
||||||
NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE,
|
NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE,
|
||||||
str->str);
|
nm_str_buf_get_str(sbuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
r = n_dhcp4_client_lease_query(lease, NM_DHCP_OPTION_DHCP4_STATIC_ROUTE, &data, &n_data);
|
r = n_dhcp4_client_lease_query(lease, NM_DHCP_OPTION_DHCP4_STATIC_ROUTE, &l_data, &l_data_len);
|
||||||
if (!r) {
|
if (r == 0) {
|
||||||
nm_gstring_prepare(&str);
|
nm_str_buf_reset(sbuf);
|
||||||
|
|
||||||
while (lease_option_next_route(&dest, &plen, &gateway, FALSE, &data, &n_data)) {
|
while (lease_option_consume_route(&l_data, &l_data_len, FALSE, &dest, &plen, &gateway)) {
|
||||||
_nm_utils_inet4_ntop(dest.s_addr, dest_str);
|
_nm_utils_inet4_ntop(dest, dest_str);
|
||||||
_nm_utils_inet4_ntop(gateway.s_addr, gateway_str);
|
_nm_utils_inet4_ntop(gateway, gateway_str);
|
||||||
|
|
||||||
g_string_append_printf(nm_gstring_add_space_delimiter(str),
|
nm_str_buf_append_required_delimiter(sbuf, ' ');
|
||||||
"%s/%d %s",
|
nm_str_buf_append_printf(sbuf, "%s/%d %s", dest_str, (int) plen, gateway_str);
|
||||||
dest_str,
|
|
||||||
(int) plen,
|
|
||||||
gateway_str);
|
|
||||||
|
|
||||||
if (has_classless) {
|
if (has_classless) {
|
||||||
/* RFC 3443: if the DHCP server returns both a Classless Static Routes
|
/* RFC 3443: if the DHCP server returns both a Classless Static Routes
|
||||||
@@ -585,30 +588,31 @@ lease_parse_routes(NDhcp4ClientLease *lease,
|
|||||||
nm_ip4_config_add_route(
|
nm_ip4_config_add_route(
|
||||||
ip4_config,
|
ip4_config,
|
||||||
&((const NMPlatformIP4Route){
|
&((const NMPlatformIP4Route){
|
||||||
.network = dest.s_addr,
|
.network = dest,
|
||||||
.plen = plen,
|
.plen = plen,
|
||||||
.gateway = gateway.s_addr,
|
.gateway = gateway,
|
||||||
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
||||||
.metric = route_metric,
|
.metric = route_metric,
|
||||||
.table_coerced = nm_platform_route_table_coerce(route_table),
|
.table_coerced = nm_platform_route_table_coerce(route_table),
|
||||||
}),
|
}),
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
nm_dhcp_option_add_option(options,
|
nm_dhcp_option_add_option(options,
|
||||||
_nm_dhcp_option_dhcp4_options,
|
_nm_dhcp_option_dhcp4_options,
|
||||||
NM_DHCP_OPTION_DHCP4_STATIC_ROUTE,
|
NM_DHCP_OPTION_DHCP4_STATIC_ROUTE,
|
||||||
str->str);
|
nm_str_buf_get_str(sbuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
r = n_dhcp4_client_lease_query(lease, NM_DHCP_OPTION_DHCP4_ROUTER, &data, &n_data);
|
r = n_dhcp4_client_lease_query(lease, NM_DHCP_OPTION_DHCP4_ROUTER, &l_data, &l_data_len);
|
||||||
if (!r) {
|
if (r == 0) {
|
||||||
nm_gstring_prepare(&str);
|
nm_str_buf_reset(sbuf);
|
||||||
|
|
||||||
while (lease_option_next_in_addr(&gateway, &data, &n_data)) {
|
while (lease_option_consume_in_addr(&l_data, &l_data_len, &gateway)) {
|
||||||
s = _nm_utils_inet4_ntop(gateway.s_addr, gateway_str);
|
nm_str_buf_append_required_delimiter(sbuf, ' ');
|
||||||
g_string_append(nm_gstring_add_space_delimiter(str), s);
|
nm_str_buf_append(sbuf, _nm_utils_inet4_ntop(gateway, gateway_str));
|
||||||
|
|
||||||
if (gateway.s_addr == 0) {
|
if (gateway == 0) {
|
||||||
/* silently skip 0.0.0.0 */
|
/* silently skip 0.0.0.0 */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -633,19 +637,22 @@ lease_parse_routes(NDhcp4ClientLease *lease,
|
|||||||
ip4_config,
|
ip4_config,
|
||||||
&((const NMPlatformIP4Route){
|
&((const NMPlatformIP4Route){
|
||||||
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
||||||
.gateway = gateway.s_addr,
|
.gateway = gateway,
|
||||||
.table_coerced = nm_platform_route_table_coerce(route_table),
|
.table_coerced = nm_platform_route_table_coerce(route_table),
|
||||||
.metric = m,
|
.metric = m,
|
||||||
}),
|
}),
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
nm_dhcp_option_add_option(options,
|
nm_dhcp_option_add_option(options,
|
||||||
_nm_dhcp_option_dhcp4_options,
|
_nm_dhcp_option_dhcp4_options,
|
||||||
NM_DHCP_OPTION_DHCP4_ROUTER,
|
NM_DHCP_OPTION_DHCP4_ROUTER,
|
||||||
str->str);
|
nm_str_buf_get_str(sbuf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
char **
|
char **
|
||||||
nm_dhcp_parse_search_list(guint8 *data, size_t n_data)
|
nm_dhcp_parse_search_list(guint8 *data, size_t n_data)
|
||||||
{
|
{
|
||||||
@@ -778,7 +785,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
|
|||||||
v_inaddr);
|
v_inaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
lease_parse_routes(lease, ip4_config, options, route_table, route_metric);
|
lease_parse_routes(lease, ip4_config, options, route_table, route_metric, &sbuf);
|
||||||
|
|
||||||
lease_parse_address_list(lease,
|
lease_parse_address_list(lease,
|
||||||
ip4_config,
|
ip4_config,
|
||||||
|
Reference in New Issue
Block a user