diff options
Diffstat (limited to 'src/dhcp/nm-dhcp-nettools.c')
-rw-r--r-- | src/dhcp/nm-dhcp-nettools.c | 168 |
1 files changed, 103 insertions, 65 deletions
diff --git a/src/dhcp/nm-dhcp-nettools.c b/src/dhcp/nm-dhcp-nettools.c index 1f183f362a..86c3311f40 100644 --- a/src/dhcp/nm-dhcp-nettools.c +++ b/src/dhcp/nm-dhcp-nettools.c @@ -341,24 +341,21 @@ lease_get_u16 (NDhcp4ClientLease *lease, return TRUE; } -#define LOG_LEASE(domain, ...) \ - G_STMT_START { \ - _LOG2I ((domain), (iface), " "__VA_ARGS__); \ - } G_STMT_END - static gboolean lease_parse_address (NDhcp4ClientLease *lease, - const char *iface, NMIP4Config *ip4_config, GHashTable *options, GError **error) { char addr_str[NM_UTILS_INET_ADDRSTRLEN]; const gint64 ts = nm_utils_get_monotonic_timestamp_ns (); + const gint64 ts_clock_boottime = nm_utils_monotonic_timestamp_as_boottime (ts, 1); struct in_addr a_address; struct in_addr a_netmask; guint32 a_plen; - guint64 a_lifetime; + guint64 nettools_lifetime; + gint64 a_lifetime; + gint64 a_expiry; n_dhcp4_client_lease_get_yiaddr (lease, &a_address); if (a_address.s_addr == INADDR_ANY) { @@ -367,7 +364,29 @@ lease_parse_address (NDhcp4ClientLease *lease, } /* n_dhcp4_client_lease_get_lifetime() never fails */ - n_dhcp4_client_lease_get_lifetime (lease, &a_lifetime); + n_dhcp4_client_lease_get_lifetime (lease, &nettools_lifetime); + /* FIXME: n_dhcp4_client_lease_get_lifetime() returns the time in nsec of CLOCK_BOOTTIME. + * We want to retrieve the original lifetime value in seconds, so we approximate it in a_lifetime. + * Use a nettools API to retrieve the original value as passed by the server. + */ + if (nettools_lifetime == G_MAXUINT64) { + a_lifetime = NM_PLATFORM_LIFETIME_PERMANENT; + a_expiry = NM_PLATFORM_LIFETIME_PERMANENT; + } else { + gint64 ts_time = time (NULL); + + a_lifetime = ((gint64) nettools_lifetime - ts_clock_boottime) / NM_UTILS_NS_PER_SECOND; + /* A lease time of 0 is allowed on some dhcp servers, so, let's accept it. */ + if (a_lifetime < 0) + a_lifetime = 0; + else if (a_lifetime > NM_PLATFORM_LIFETIME_PERMANENT) + a_lifetime = NM_PLATFORM_LIFETIME_PERMANENT - 1; + + if (ts_time > NM_PLATFORM_LIFETIME_PERMANENT - a_lifetime) + a_expiry = NM_PLATFORM_LIFETIME_PERMANENT - 1; + else + a_expiry = ts_time + a_lifetime; + } if (!lease_get_in_addr (lease, NM_DHCP_OPTION_DHCP4_SUBNET_MASK, &a_netmask)) { nm_utils_error_set_literal (error, NM_UTILS_ERROR_UNKNOWN, "could not get netmask from lease"); @@ -377,7 +396,6 @@ lease_parse_address (NDhcp4ClientLease *lease, nm_utils_inet4_ntop (a_address.s_addr, addr_str); a_plen = nm_utils_ip4_netmask_to_prefix (a_netmask.s_addr); - LOG_LEASE (LOGD_DHCP4, "address %s/%u", addr_str, a_plen); nm_dhcp_option_add_option (options, _nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS, @@ -387,12 +405,15 @@ lease_parse_address (NDhcp4ClientLease *lease, NM_DHCP_OPTION_DHCP4_SUBNET_MASK, nm_utils_inet4_ntop (a_netmask.s_addr, addr_str)); - LOG_LEASE (LOGD_DHCP4, "expires in %u seconds", - (guint) ((a_lifetime - ts)/1000000000)); nm_dhcp_option_add_option_u64 (options, _nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_IP_ADDRESS_LEASE_TIME, - (guint64) (a_lifetime / 1000000000)); + (guint64) a_lifetime); + + nm_dhcp_option_add_option_u64 (options, + _nm_dhcp_option_dhcp4_options, + NM_DHCP_OPTION_DHCP4_NM_EXPIRY, + (guint64) a_expiry); nm_ip4_config_add_address (ip4_config, &((const NMPlatformIP4Address) { @@ -400,9 +421,9 @@ lease_parse_address (NDhcp4ClientLease *lease, .peer_address = a_address.s_addr, .plen = a_plen, .addr_source = NM_IP_CONFIG_SOURCE_DHCP, - .timestamp = ts / 1000000000, - .lifetime = (a_lifetime - ts) / 1000000000, - .preferred = (a_lifetime - ts) / 1000000000, + .timestamp = ts / NM_UTILS_NS_PER_SECOND, + .lifetime = a_lifetime, + .preferred = a_lifetime, })); return TRUE; @@ -410,7 +431,6 @@ lease_parse_address (NDhcp4ClientLease *lease, static void lease_parse_domain_name_servers (NDhcp4ClientLease *lease, - const char *iface, NMIP4Config *ip4_config, GHashTable *options) { @@ -441,7 +461,6 @@ lease_parse_domain_name_servers (NDhcp4ClientLease *lease, nm_ip4_config_add_nameserver (ip4_config, addr.s_addr); } - LOG_LEASE (LOGD_DHCP4, "nameserver '%s'", str->str); nm_dhcp_option_add_option (options, _nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER, @@ -450,7 +469,6 @@ lease_parse_domain_name_servers (NDhcp4ClientLease *lease, static void lease_parse_routes (NDhcp4ClientLease *lease, - const char *iface, NMIP4Config *ip4_config, GHashTable *options, guint32 route_table, @@ -480,11 +498,6 @@ lease_parse_routes (NDhcp4ClientLease *lease, nm_utils_inet4_ntop (dest.s_addr, dest_str); nm_utils_inet4_ntop (gateway.s_addr, gateway_str); - LOG_LEASE (LOGD_DHCP4, - "classless static route %s/%d gw %s", - dest_str, - (int) plen, - gateway_str); g_string_append_printf (nm_gstring_add_space_delimiter (str), "%s/%d %s", dest_str, @@ -529,11 +542,6 @@ lease_parse_routes (NDhcp4ClientLease *lease, nm_utils_inet4_ntop (dest.s_addr, dest_str); nm_utils_inet4_ntop (gateway.s_addr, gateway_str); - LOG_LEASE (LOGD_DHCP4, - "static route %s/%d gw %s", - dest_str, - (int) plen, - gateway_str); g_string_append_printf (nm_gstring_add_space_delimiter (str), "%s/%d %s", dest_str, @@ -610,7 +618,6 @@ lease_parse_routes (NDhcp4ClientLease *lease, }), NULL); } - LOG_LEASE (LOGD_DHCP4, "router %s", str->str); nm_dhcp_option_add_option (options, _nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_ROUTER, @@ -620,7 +627,6 @@ lease_parse_routes (NDhcp4ClientLease *lease, static void lease_parse_mtu (NDhcp4ClientLease *lease, - const char *iface, NMIP4Config *ip4_config, GHashTable *options) { @@ -632,7 +638,6 @@ lease_parse_mtu (NDhcp4ClientLease *lease, if (mtu < 68) return; - LOG_LEASE (LOGD_DHCP4, "mtu %u", mtu); nm_dhcp_option_add_option_u64 (options, _nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_INTERFACE_MTU, @@ -642,7 +647,6 @@ lease_parse_mtu (NDhcp4ClientLease *lease, static void lease_parse_metered (NDhcp4ClientLease *lease, - const char *iface, NMIP4Config *ip4_config, GHashTable *options) { @@ -658,13 +662,12 @@ lease_parse_metered (NDhcp4ClientLease *lease, metered = !!memmem (data, n_data, "ANDROID_METERED", NM_STRLEN ("ANDROID_METERED")); } - LOG_LEASE (LOGD_DHCP4, "%s", metered ? "metered" : "unmetered"); + /* TODO: expose the vendor specific option when present */ nm_ip4_config_set_metered (ip4_config, metered); } static void lease_parse_ntps (NDhcp4ClientLease *lease, - const char *iface, GHashTable *options) { nm_auto_free_gstring GString *str = NULL; @@ -685,13 +688,14 @@ lease_parse_ntps (NDhcp4ClientLease *lease, g_string_append (nm_gstring_add_space_delimiter (str), addr_str); } - LOG_LEASE (LOGD_DHCP4, "ntp server '%s'", str->str); - nm_dhcp_option_add_option (options, _nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_NTP_SERVER, str->str); + nm_dhcp_option_add_option (options, + _nm_dhcp_option_dhcp4_options, + NM_DHCP_OPTION_DHCP4_NTP_SERVER, + str->str); } static void lease_parse_hostname (NDhcp4ClientLease *lease, - const char *iface, GHashTable *options) { nm_auto_free_gstring GString *str = NULL; @@ -708,13 +712,14 @@ lease_parse_hostname (NDhcp4ClientLease *lease, if (is_localhost(str->str)) return; - LOG_LEASE (LOGD_DHCP4, "hostname '%s'", str->str); - nm_dhcp_option_add_option (options, _nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_HOST_NAME, str->str); + nm_dhcp_option_add_option (options, + _nm_dhcp_option_dhcp4_options, + NM_DHCP_OPTION_DHCP4_HOST_NAME, + str->str); } static void lease_parse_domainname (NDhcp4ClientLease *lease, - const char *iface, NMIP4Config *ip4_config, GHashTable *options) { @@ -741,13 +746,14 @@ lease_parse_domainname (NDhcp4ClientLease *lease, g_string_append (nm_gstring_add_space_delimiter (str), *d); nm_ip4_config_add_domain (ip4_config, *d); } - LOG_LEASE (LOGD_DHCP4, "domain name '%s'", str->str); - nm_dhcp_option_add_option (options, _nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME, str->str); + nm_dhcp_option_add_option (options, + _nm_dhcp_option_dhcp4_options, + NM_DHCP_OPTION_DHCP4_DOMAIN_NAME, + str->str); } static void lease_parse_search_domains (NDhcp4ClientLease *lease, - const char *iface, NMIP4Config *ip4_config, GHashTable *options) { @@ -775,7 +781,6 @@ lease_parse_search_domains (NDhcp4ClientLease *lease, g_string_append (nm_gstring_add_space_delimiter (str), domain->str); nm_ip4_config_add_search (ip4_config, domain->str); } - LOG_LEASE (LOGD_DHCP4, "domain search '%s'", str->str); nm_dhcp_option_add_option (options, _nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST, @@ -784,7 +789,6 @@ lease_parse_search_domains (NDhcp4ClientLease *lease, static void lease_parse_root_path (NDhcp4ClientLease *lease, - const char *iface, GHashTable *options) { nm_auto_free_gstring GString *str = NULL; @@ -797,16 +801,17 @@ lease_parse_root_path (NDhcp4ClientLease *lease, return; str = g_string_new_len ((char *)data, n_data); - LOG_LEASE (LOGD_DHCP4, "root path '%s'", str->str); - nm_dhcp_option_add_option (options, _nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_ROOT_PATH, str->str); + nm_dhcp_option_add_option (options, + _nm_dhcp_option_dhcp4_options, + NM_DHCP_OPTION_DHCP4_ROOT_PATH, + str->str); } static void lease_parse_wpad (NDhcp4ClientLease *lease, - const char *iface, GHashTable *options) { - nm_auto_free_gstring GString *str = NULL; + gs_free char *wpad = NULL; uint8_t *data; size_t n_data; int r; @@ -815,12 +820,44 @@ lease_parse_wpad (NDhcp4ClientLease *lease, if (r) return; - str = g_string_new_len ((char *)data, n_data); - LOG_LEASE (LOGD_DHCP4, "wpad '%s'", str->str); + nm_utils_buf_utf8safe_escape ((char *)data, n_data, 0, &wpad); + if (wpad == NULL) + wpad = g_strndup ((char *)data, n_data); + nm_dhcp_option_add_option (options, _nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY, - str->str); + wpad); +} + +static void +lease_parse_private_options (NDhcp4ClientLease *lease, + GHashTable *options) +{ + int i; + + for (i = NM_DHCP_OPTION_DHCP4_PRIVATE_224; i <= NM_DHCP_OPTION_DHCP4_PRIVATE_254; i++) { + gs_free char *option_string = NULL; + guint8 *data; + gsize n_data; + int r; + + /* We manage private options 249 (private classless static route) and 252 (wpad) in a special + * way, so skip them as we here just manage all (the other) private options as raw data */ + if (NM_IN_SET (i, NM_DHCP_OPTION_DHCP4_PRIVATE_CLASSLESS_STATIC_ROUTE, + NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY)) + continue; + + r = n_dhcp4_client_lease_query (lease, i, &data, &n_data); + if (r) + continue; + + option_string = nm_utils_bin2hexstr_full (data, n_data, ':', FALSE, NULL); + nm_dhcp_option_take_option (options, + _nm_dhcp_option_dhcp4_options, + i, + g_steal_pointer (&option_string)); + } } static NMIP4Config * @@ -839,22 +876,23 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx, g_return_val_if_fail (lease != NULL, NULL); ip4_config = nm_ip4_config_new (multi_idx, ifindex); - options = out_options ? nm_dhcp_option_create_options_dict () : NULL; + options = nm_dhcp_option_create_options_dict (); - if (!lease_parse_address (lease, iface, ip4_config, options, error)) + if (!lease_parse_address (lease, ip4_config, options, error)) return NULL; - lease_parse_routes (lease, iface, ip4_config, options, route_table, route_metric); - lease_parse_domain_name_servers (lease, iface, ip4_config, options); - lease_parse_domainname (lease, iface, ip4_config, options); - lease_parse_search_domains (lease, iface, ip4_config, options); - lease_parse_mtu (lease, iface, ip4_config, options); - lease_parse_metered (lease, iface, ip4_config, options); - - lease_parse_hostname (lease, iface, options); - lease_parse_ntps (lease, iface, options); - lease_parse_root_path (lease, iface, options); - lease_parse_wpad (lease, iface, options); + lease_parse_routes (lease, ip4_config, options, route_table, route_metric); + lease_parse_domain_name_servers (lease, ip4_config, options); + lease_parse_domainname (lease, ip4_config, options); + lease_parse_search_domains (lease, ip4_config, options); + lease_parse_mtu (lease, ip4_config, options); + lease_parse_metered (lease, ip4_config, options); + + lease_parse_hostname (lease, options); + lease_parse_ntps (lease, options); + lease_parse_root_path (lease, options); + lease_parse_wpad (lease, options); + lease_parse_private_options (lease, options); NM_SET_OUT (out_options, g_steal_pointer (&options)); return g_steal_pointer (&ip4_config); |