diff options
| author | Michael Biebl <biebl@debian.org> | 2019-03-26 23:25:23 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2019-03-26 23:25:23 +0100 |
| commit | 9a6dcbf895f9da01768e64b73cec88c16157d91e (patch) | |
| tree | a359958930d731e9f1b59344642e10754419fe84 /src/nm-core-utils.c | |
| parent | 964ae8cc391520440cf5aa13e2b9cc34850ea6c2 (diff) | |
New upstream version 1.16.0 upstream/1.16.0
Diffstat (limited to 'src/nm-core-utils.c')
| -rw-r--r-- | src/nm-core-utils.c | 389 |
1 files changed, 110 insertions, 279 deletions
diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index a65ac636..6f55e62a 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -23,10 +23,8 @@ #include "nm-core-utils.h" -#include <errno.h> #include <fcntl.h> #include <fnmatch.h> -#include <string.h> #include <unistd.h> #include <stdlib.h> #include <resolv.h> @@ -51,6 +49,10 @@ #include "nm-setting-wireless.h" #include "nm-setting-wireless-security.h" +#ifdef __NM_SD_UTILS_H__ +#error "nm-core-utils.c should stay independent of systemd utils. Are you looking for NetworkMangerUtils.c? " +#endif + G_STATIC_ASSERT (sizeof (NMUtilsTestFlags) <= sizeof (int)); /* we read _nm_utils_testing without memory barrier. This is thread-safe, @@ -242,16 +244,20 @@ nm_ethernet_address_is_valid (gconstpointer addr, gssize len) gconstpointer nm_utils_ipx_address_clear_host_address (int family, gpointer dst, gconstpointer src, guint8 plen) { - g_return_val_if_fail (src, NULL); g_return_val_if_fail (dst, NULL); switch (family) { case AF_INET: g_return_val_if_fail (plen <= 32, NULL); + + if (!src) { + /* allow "self-assignment", by specifying %NULL as source. */ + src = dst; + } + *((guint32 *) dst) = nm_utils_ip4_address_clear_host_address (*((guint32 *) src), plen); break; case AF_INET6: - g_return_val_if_fail (plen <= 128, NULL); nm_utils_ip6_address_clear_host_address (dst, src, plen); break; default: @@ -437,6 +443,7 @@ nm_utils_modprobe (GError **error, gboolean suppress_error_logging, const char * /* construct the argument list */ argv = g_ptr_array_sized_new (4); g_ptr_array_add (argv, "/sbin/modprobe"); + g_ptr_array_add (argv, "--use-blacklist"); g_ptr_array_add (argv, (char *) arg1); va_start (ap, arg1); @@ -571,7 +578,7 @@ _kc_cb_timeout_grace_period (void *user_data) /* ESRCH means, process does not exist or is already a zombie. */ if (errsv != ESRCH) { nm_log_err (LOGD_CORE | data->log_domain, "%s: kill(SIGKILL) returned unexpected return value %d: (%s, %d)", - data->log_name, ret, strerror (errsv), errsv); + data->log_name, ret, nm_strerror_native (errsv), errsv); } } else { nm_log_dbg (data->log_domain, "%s: process not terminated after %ld usec. Sending SIGKILL signal", @@ -657,7 +664,7 @@ nm_utils_kill_child_async (pid_t pid, int sig, NMLogDomain log_domain, /* ECHILD means, the process is not a child/does not exist or it has SIGCHILD blocked. */ if (errsv != ECHILD) { nm_log_err (LOGD_CORE | log_domain, LOG_NAME_FMT ": unexpected error while waitpid: %s (%d)", - LOG_NAME_ARGS, strerror (errsv), errsv); + LOG_NAME_ARGS, nm_strerror_native (errsv), errsv); _kc_invoke_callback (pid, log_domain, log_name, callback, user_data, FALSE, -1); return; } @@ -669,7 +676,7 @@ nm_utils_kill_child_async (pid_t pid, int sig, NMLogDomain log_domain, /* ESRCH means, process does not exist or is already a zombie. */ if (errsv != ESRCH) { nm_log_err (LOGD_CORE | log_domain, LOG_NAME_FMT ": unexpected error sending %s: %s (%d)", - LOG_NAME_ARGS, _kc_signal_to_string (sig), strerror (errsv), errsv); + LOG_NAME_ARGS, _kc_signal_to_string (sig), nm_strerror_native (errsv), errsv); _kc_invoke_callback (pid, log_domain, log_name, callback, user_data, FALSE, -1); return; } @@ -683,7 +690,7 @@ nm_utils_kill_child_async (pid_t pid, int sig, NMLogDomain log_domain, } else { errsv = errno; nm_log_err (LOGD_CORE | log_domain, LOG_NAME_FMT ": failed due to unexpected return value %ld by waitpid (%s, %d) after sending %s", - LOG_NAME_ARGS, (long) ret, strerror (errsv), errsv, _kc_signal_to_string (sig)); + LOG_NAME_ARGS, (long) ret, nm_strerror_native (errsv), errsv, _kc_signal_to_string (sig)); _kc_invoke_callback (pid, log_domain, log_name, callback, user_data, FALSE, -1); } return; @@ -705,7 +712,7 @@ nm_utils_kill_child_async (pid_t pid, int sig, NMLogDomain log_domain, g_child_watch_add (pid, _kc_cb_watch_child, data); } -static inline gulong +static gulong _sleep_duration_convert_ms_to_us (guint32 sleep_duration_msec) { if (sleep_duration_msec > 0) { @@ -723,7 +730,7 @@ _sleep_duration_convert_ms_to_us (guint32 sleep_duration_msec) * @log_domain: log debug information for this domain. Errors and warnings are logged both * as %LOGD_CORE and @log_domain. * @log_name: name of the process to kill for logging. - * @child_status: (out) (allow-none): return the exit status of the child, if no error occured. + * @child_status: (out) (allow-none): return the exit status of the child, if no error occurred. * @wait_before_kill_msec: Waittime in milliseconds before sending %SIGKILL signal. Set this value * to zero, not to send %SIGKILL. If @sig is already %SIGKILL, this parameter has not effect. * @sleep_duration_msec: the synchronous function sleeps repeatedly waiting for the child to terminate. @@ -732,7 +739,7 @@ _sleep_duration_convert_ms_to_us (guint32 sleep_duration_msec) * Kill a child process synchronously and wait. The function first checks if the child already terminated * and if it did, return the exit status. Otherwise send one @sig signal. @sig will always be * sent unless the child already exited. If the child does not exit within @wait_before_kill_msec milliseconds, - * the function will send %SIGKILL and waits for the child indefinitly. If @wait_before_kill_msec is zero, no + * the function will send %SIGKILL and waits for the child indefinitely. If @wait_before_kill_msec is zero, no * %SIGKILL signal will be sent. * * In case of error, errno is preserved to contain the last reason of failure. @@ -765,7 +772,7 @@ nm_utils_kill_child_sync (pid_t pid, int sig, NMLogDomain log_domain, const char /* ECHILD means, the process is not a child/does not exist or it has SIGCHILD blocked. */ if (errsv != ECHILD) { nm_log_err (LOGD_CORE | log_domain, LOG_NAME_FMT ": unexpected error while waitpid: %s (%d)", - LOG_NAME_ARGS, strerror (errsv), errsv); + LOG_NAME_ARGS, nm_strerror_native (errsv), errsv); goto out; } } @@ -776,7 +783,7 @@ nm_utils_kill_child_sync (pid_t pid, int sig, NMLogDomain log_domain, const char /* ESRCH means, process does not exist or is already a zombie. */ if (errsv != ESRCH) { nm_log_err (LOGD_CORE | log_domain, LOG_NAME_FMT ": failed to send %s: %s (%d)", - LOG_NAME_ARGS, _kc_signal_to_string (sig), strerror (errsv), errsv); + LOG_NAME_ARGS, _kc_signal_to_string (sig), nm_strerror_native (errsv), errsv); } else { /* let's try again with waitpid, probably there was a race... */ ret = waitpid (pid, &status, 0); @@ -787,7 +794,7 @@ nm_utils_kill_child_sync (pid_t pid, int sig, NMLogDomain log_domain, const char } else { errsv = errno; nm_log_err (LOGD_CORE | log_domain, LOG_NAME_FMT ": failed due to unexpected return value %ld by waitpid (%s, %d) after sending %s", - LOG_NAME_ARGS, (long) ret, strerror (errsv), errsv, _kc_signal_to_string (sig)); + LOG_NAME_ARGS, (long) ret, nm_strerror_native (errsv), errsv, _kc_signal_to_string (sig)); } } goto out; @@ -818,7 +825,7 @@ nm_utils_kill_child_sync (pid_t pid, int sig, NMLogDomain log_domain, const char /* ECHILD means, the process is not a child/does not exist or it has SIGCHILD blocked. */ if (errsv != ECHILD) { nm_log_err (LOGD_CORE | log_domain, LOG_NAME_FMT ": after sending %s, waitpid failed with %s (%d)%s", - LOG_NAME_ARGS, _kc_signal_to_string (sig), strerror (errsv), errsv, + LOG_NAME_ARGS, _kc_signal_to_string (sig), nm_strerror_native (errsv), errsv, was_waiting ? _kc_waited_to_string (buf_wait, wait_start_us) : ""); goto out; } @@ -857,7 +864,7 @@ nm_utils_kill_child_sync (pid_t pid, int sig, NMLogDomain log_domain, const char /* ESRCH means, process does not exist or is already a zombie. */ if (errsv != ESRCH) { nm_log_err (LOGD_CORE | log_domain, LOG_NAME_FMT ": failed to send SIGKILL (after sending %s), %s (%d)", - LOG_NAME_ARGS, _kc_signal_to_string (sig), strerror (errsv), errsv); + LOG_NAME_ARGS, _kc_signal_to_string (sig), nm_strerror_native (errsv), errsv); goto out; } } @@ -875,7 +882,7 @@ nm_utils_kill_child_sync (pid_t pid, int sig, NMLogDomain log_domain, const char if (errsv != EINTR) { nm_log_err (LOGD_CORE | log_domain, LOG_NAME_FMT ": after sending %s%s, waitpid failed with %s (%d)%s", - LOG_NAME_ARGS, _kc_signal_to_string (sig), send_kill ? " and SIGKILL" : "", strerror (errsv), errsv, + LOG_NAME_ARGS, _kc_signal_to_string (sig), send_kill ? " and SIGKILL" : "", nm_strerror_native (errsv), errsv, _kc_waited_to_string (buf_wait, wait_start_us)); goto out; } @@ -909,7 +916,7 @@ out: * @sleep_duration_msec: the synchronous function sleeps repeatedly waiting for the child to terminate. * Set to zero, to use the default (meaning 20 wakeups per seconds). * @max_wait_msec: if 0, waits indefinitely until the process is gone (or a zombie). Otherwise, this - * is the maxium wait time until returning. If @max_wait_msec is non-zero but smaller then @wait_before_kill_msec, + * is the maximum wait time until returning. If @max_wait_msec is non-zero but smaller then @wait_before_kill_msec, * we will not send a final %SIGKILL. * * Kill a non-child process synchronously and wait. This function will not return before the @@ -963,7 +970,7 @@ nm_utils_kill_process_sync (pid_t pid, guint64 start_time, int sig, NMLogDomain LOG_NAME_ARGS, _kc_signal_to_string (sig)); } else { nm_log_warn (LOGD_CORE | log_domain, LOG_NAME_PROCESS_FMT ": failed to send %s: %s (%d)", - LOG_NAME_ARGS, _kc_signal_to_string (sig), strerror (errsv), errsv); + LOG_NAME_ARGS, _kc_signal_to_string (sig), nm_strerror_native (errsv), errsv); } return; } @@ -1014,7 +1021,7 @@ nm_utils_kill_process_sync (pid_t pid, guint64 start_time, int sig, NMLogDomain was_waiting ? _kc_waited_to_string (buf_wait, wait_start_us) : ""); } else { nm_log_warn (LOGD_CORE | log_domain, LOG_NAME_PROCESS_FMT ": failed to kill(%ld, 0): %s (%d)%s", - LOG_NAME_ARGS, (long int) pid, strerror (errsv), errsv, + LOG_NAME_ARGS, (long int) pid, nm_strerror_native (errsv), errsv, was_waiting ? _kc_waited_to_string (buf_wait, wait_start_us) : ""); } return; @@ -1050,7 +1057,7 @@ nm_utils_kill_process_sync (pid_t pid, guint64 start_time, int sig, NMLogDomain LOG_NAME_ARGS, _kc_waited_to_string (buf_wait, wait_start_us)); } else { nm_log_warn (LOGD_CORE | log_domain, LOG_NAME_PROCESS_FMT ": failed to send SIGKILL (after sending %s), %s (%d)%s", - LOG_NAME_ARGS, _kc_signal_to_string (sig), strerror (errsv), errsv, + LOG_NAME_ARGS, _kc_signal_to_string (sig), nm_strerror_native (errsv), errsv, _kc_waited_to_string (buf_wait, wait_start_us)); } return; @@ -1129,13 +1136,17 @@ nm_utils_read_link_absolute (const char *link_file, GError **error) return ln; dirname = g_path_get_dirname (link_file); - if (!g_path_is_absolute (link_file)) { - gs_free char *dirname_rel = dirname; + if (!g_path_is_absolute (dirname)) { gs_free char *current_dir = g_get_current_dir (); - dirname = g_build_filename (current_dir, dirname_rel, NULL); - } - ln_abs = g_build_filename (dirname, ln, NULL); + /* @link_file argument was not an absolute path in the first place. + * That actually may be a bug, because the CWD is not well defined + * in most cases. Anyway, apparently we were able to load the file + * even from a relative path. So, when making the link absolute, we + * also need to prepend the CWD. */ + ln_abs = g_build_filename (current_dir, dirname, ln, NULL); + } else + ln_abs = g_build_filename (dirname, ln, NULL); g_free (dirname); g_free (ln); return ln_abs; @@ -1939,173 +1950,6 @@ nm_utils_cmp_connection_by_autoconnect_priority (NMConnection *a, NMConnection * /*****************************************************************************/ -static gint64 monotonic_timestamp_offset_sec; -static int monotonic_timestamp_clock_mode = 0; - -static void -monotonic_timestamp_get (struct timespec *tp) -{ - int clock_mode = 0; - int err = 0; - - switch (monotonic_timestamp_clock_mode) { - case 0: - /* the clock is not yet initialized (first run) */ - err = clock_gettime (CLOCK_BOOTTIME, tp); - if (err == -1 && errno == EINVAL) { - clock_mode = 2; - err = clock_gettime (CLOCK_MONOTONIC, tp); - } else - clock_mode = 1; - break; - case 1: - /* default, return CLOCK_BOOTTIME */ - err = clock_gettime (CLOCK_BOOTTIME, tp); - break; - case 2: - /* fallback, return CLOCK_MONOTONIC. Kernels prior to 2.6.39 - * (released on 18 May, 2011) don't support CLOCK_BOOTTIME. */ - err = clock_gettime (CLOCK_MONOTONIC, tp); - break; - } - - g_assert (err == 0); (void)err; - g_assert (tp->tv_nsec >= 0 && tp->tv_nsec < NM_UTILS_NS_PER_SECOND); - - if (G_LIKELY (clock_mode == 0)) - return; - - /* Calculate an offset for the time stamp. - * - * We always want positive values, because then we can initialize - * a timestamp with 0 and be sure, that it will be less then any - * value nm_utils_get_monotonic_timestamp_*() might return. - * For this to be true also for nm_utils_get_monotonic_timestamp_s() at - * early boot, we have to shift the timestamp to start counting at - * least from 1 second onward. - * - * Another advantage of shifting is, that this way we make use of the whole 31 bit - * range of signed int, before the time stamp for nm_utils_get_monotonic_timestamp_s() - * wraps (~68 years). - **/ - monotonic_timestamp_offset_sec = (- ((gint64) tp->tv_sec)) + 1; - monotonic_timestamp_clock_mode = clock_mode; - - if (nm_logging_enabled (LOGL_DEBUG, LOGD_CORE)) { - time_t now = time (NULL); - struct tm tm; - char s[255]; - - strftime (s, sizeof (s), "%Y-%m-%d %H:%M:%S", localtime_r (&now, &tm)); - nm_log_dbg (LOGD_CORE, "monotonic timestamp started counting 1.%09ld seconds ago with " - "an offset of %lld.0 seconds to %s (local time is %s)", - tp->tv_nsec, (long long) -monotonic_timestamp_offset_sec, - clock_mode == 1 ? "CLOCK_BOOTTIME" : "CLOCK_MONOTONIC", s); - } -} - -/** - * nm_utils_get_monotonic_timestamp_ns: - * - * Returns: a monotonically increasing time stamp in nanoseconds, - * starting at an unspecified offset. See clock_gettime(), %CLOCK_BOOTTIME. - * - * The returned value will start counting at an undefined point - * in the past and will always be positive. - * - * All the nm_utils_get_monotonic_timestamp_*s functions return the same - * timestamp but in different scales (nsec, usec, msec, sec). - **/ -gint64 -nm_utils_get_monotonic_timestamp_ns (void) -{ - struct timespec tp = { 0 }; - - monotonic_timestamp_get (&tp); - - /* Although the result will always be positive, we return a signed - * integer, which makes it easier to calculate time differences (when - * you want to subtract signed values). - **/ - return (((gint64) tp.tv_sec) + monotonic_timestamp_offset_sec) * NM_UTILS_NS_PER_SECOND + - tp.tv_nsec; -} - -/** - * nm_utils_get_monotonic_timestamp_us: - * - * Returns: a monotonically increasing time stamp in microseconds, - * starting at an unspecified offset. See clock_gettime(), %CLOCK_BOOTTIME. - * - * The returned value will start counting at an undefined point - * in the past and will always be positive. - * - * All the nm_utils_get_monotonic_timestamp_*s functions return the same - * timestamp but in different scales (nsec, usec, msec, sec). - **/ -gint64 -nm_utils_get_monotonic_timestamp_us (void) -{ - struct timespec tp = { 0 }; - - monotonic_timestamp_get (&tp); - - /* Although the result will always be positive, we return a signed - * integer, which makes it easier to calculate time differences (when - * you want to subtract signed values). - **/ - return (((gint64) tp.tv_sec) + monotonic_timestamp_offset_sec) * ((gint64) G_USEC_PER_SEC) + - (tp.tv_nsec / (NM_UTILS_NS_PER_SECOND/G_USEC_PER_SEC)); -} - -/** - * nm_utils_get_monotonic_timestamp_ms: - * - * Returns: a monotonically increasing time stamp in milliseconds, - * starting at an unspecified offset. See clock_gettime(), %CLOCK_BOOTTIME. - * - * The returned value will start counting at an undefined point - * in the past and will always be positive. - * - * All the nm_utils_get_monotonic_timestamp_*s functions return the same - * timestamp but in different scales (nsec, usec, msec, sec). - **/ -gint64 -nm_utils_get_monotonic_timestamp_ms (void) -{ - struct timespec tp = { 0 }; - - monotonic_timestamp_get (&tp); - - /* Although the result will always be positive, we return a signed - * integer, which makes it easier to calculate time differences (when - * you want to subtract signed values). - **/ - return (((gint64) tp.tv_sec) + monotonic_timestamp_offset_sec) * ((gint64) 1000) + - (tp.tv_nsec / (NM_UTILS_NS_PER_SECOND/1000)); -} - -/** - * nm_utils_get_monotonic_timestamp_s: - * - * Returns: nm_utils_get_monotonic_timestamp_ms() in seconds (throwing - * away sub second parts). The returned value will always be positive. - * - * This value wraps after roughly 68 years which should be fine for any - * practical purpose. - * - * All the nm_utils_get_monotonic_timestamp_*s functions return the same - * timestamp but in different scales (nsec, usec, msec, sec). - **/ -gint32 -nm_utils_get_monotonic_timestamp_s (void) -{ - struct timespec tp = { 0 }; - - monotonic_timestamp_get (&tp); - return (((gint64) tp.tv_sec) + monotonic_timestamp_offset_sec); -} - typedef struct { const char *name; @@ -2192,7 +2036,7 @@ _log_connection_get_property (NMSetting *setting, const char *name) return g_strdup ("****"); if (!_nm_setting_get_property (setting, name, &val)) - g_return_val_if_reached (FALSE); + return g_strdup ("<unknown>"); if (G_VALUE_HOLDS_STRING (&val)) { const char *val_s; @@ -2295,7 +2139,7 @@ nm_utils_log_connection_diff (NMConnection *connection, return; } - /* FIXME: it doesn't nicely show the content of NMSettingVpn, becuase nm_connection_diff() does not + /* FIXME: it doesn't nicely show the content of NMSettingVpn, because nm_connection_diff() does not * expand the hash values. */ sorted_hashes = _log_connection_sort_hashes (connection, diff_base, connection_diff); @@ -2385,49 +2229,6 @@ out: g_array_free (sorted_hashes, TRUE); } -/** - * nm_utils_monotonic_timestamp_as_boottime: - * @timestamp: the monotonic-timestamp that should be converted into CLOCK_BOOTTIME. - * @timestamp_ns_per_tick: How many nano seconds make one unit of @timestamp? E.g. if - * @timestamp is in unit seconds, pass %NM_UTILS_NS_PER_SECOND; @timestamp in nano - * seconds, pass 1; @timestamp in milli seconds, pass %NM_UTILS_NS_PER_SECOND/1000; etc. - * - * Returns: the monotonic-timestamp as CLOCK_BOOTTIME, as returned by clock_gettime(). - * The unit is the same as the passed in @timestamp basd on @timestamp_ns_per_tick. - * E.g. if you passed @timestamp in as seconds, it will return boottime in seconds. - * If @timestamp is a non-positive, it returns -1. Note that a (valid) monotonic-timestamp - * is always positive. - * - * On older kernels that don't support CLOCK_BOOTTIME, the returned time is instead CLOCK_MONOTONIC. - **/ -gint64 -nm_utils_monotonic_timestamp_as_boottime (gint64 timestamp, gint64 timestamp_ns_per_tick) -{ - gint64 offset; - - /* only support ns-per-tick being a multiple of 10. */ - g_return_val_if_fail (timestamp_ns_per_tick == 1 - || (timestamp_ns_per_tick > 0 && - timestamp_ns_per_tick <= NM_UTILS_NS_PER_SECOND && - timestamp_ns_per_tick % 10 == 0), - -1); - - /* Check that the timestamp is in a valid range. */ - g_return_val_if_fail (timestamp >= 0, -1); - - /* if the caller didn't yet ever fetch a monotonic-timestamp, he cannot pass any meaningful - * value (because he has no idea what these timestamps would be). That would be a bug. */ - g_return_val_if_fail (monotonic_timestamp_clock_mode != 0, -1); - - /* calculate the offset of monotonic-timestamp to boottime. offset_s is <= 1. */ - offset = monotonic_timestamp_offset_sec * (NM_UTILS_NS_PER_SECOND / timestamp_ns_per_tick); - - /* check for overflow. */ - g_return_val_if_fail (offset > 0 || timestamp < G_MAXINT64 + offset, G_MAXINT64); - - return timestamp - offset; -} - #define IPV6_PROPERTY_DIR "/proc/sys/net/ipv6/conf/" #define IPV4_PROPERTY_DIR "/proc/sys/net/ipv4/conf/" G_STATIC_ASSERT (sizeof (IPV4_PROPERTY_DIR) == sizeof (IPV6_PROPERTY_DIR)); @@ -2595,11 +2396,11 @@ _uuid_data_init (UuidData *uuid_data, uuid_data->is_fake = is_fake; if (packed) { G_STATIC_ASSERT_EXPR (sizeof (uuid_data->str) >= (sizeof (*uuid) * 2 + 1)); - _nm_utils_bin2hexstr_full (uuid, - sizeof (*uuid), - '\0', - FALSE, - uuid_data->str); + nm_utils_bin2hexstr_full (uuid, + sizeof (*uuid), + '\0', + FALSE, + uuid_data->str); } else { G_STATIC_ASSERT_EXPR (sizeof (uuid_data->str) >= 37); _nm_utils_uuid_unparse (uuid, uuid_data->str); @@ -2632,14 +2433,14 @@ again: if ( nm_utils_file_get_contents (-1, "/etc/machine-id", 100*1024, 0, &content, NULL, NULL) >= 0 || nm_utils_file_get_contents (-1, LOCALSTATEDIR"/lib/dbus/machine-id", 100*1024, 0, &content, NULL, NULL) >= 0) { g_strstrip (content); - if (_nm_utils_hexstr2bin_full (content, - FALSE, - FALSE, - NULL, - 16, - (guint8 *) &uuid, - sizeof (uuid), - NULL)) { + if (nm_utils_hexstr2bin_full (content, + FALSE, + FALSE, + NULL, + 16, + (guint8 *) &uuid, + sizeof (uuid), + NULL)) { if (!nm_utils_uuid_is_null (&uuid)) { /* an all-zero machine-id is not valid. */ is_fake = FALSE; @@ -2661,7 +2462,7 @@ again: if (nm_utils_host_id_get (&seed_bin, &seed_len)) { /* we have no valid machine-id. Generate a fake one by hashing * the secret-key. This key is commonly persisted, so it should be - * stable accross reboots (despite having a broken system without + * stable across reboots (despite having a broken system without * proper machine-id). */ fake_type = "secret-key"; hash_seed = "ab085f06-b629-46d1-a553-84eeba5683b6"; @@ -2758,7 +2559,7 @@ _host_id_read_timestamp (gboolean use_secret_key_file, * the secret_key) if we are unable to access the secret_key file in the first place. * * Pick a random timestamp from the past two years. Yes, this timestamp - * is not stable accross restarts, but apparently neither is the host-id + * is not stable across restarts, but apparently neither is the host-id * nor the secret_key itself. */ #define EPOCH_TWO_YEARS (G_GINT64_CONSTANT (2 * 365 * 24 * 3600) * NM_UTILS_NS_PER_SECOND) @@ -3292,14 +3093,12 @@ nm_utils_ipv6_interface_identifier_get_from_token (NMUtilsIPv6IfaceId *iid, /** * nm_utils_inet6_interface_identifier_to_token: * @iid: %NMUtilsIPv6IfaceId interface identifier - * @buf: the destination buffer or %NULL + * @buf: the destination buffer of at least %NM_UTILS_INET_ADDRSTRLEN + * bytes. * * Converts the interface identifier to a string token. - * If the destination buffer it set, set it is used to store the - * resulting token, otherwise an internal static buffer is used. - * The buffer needs to be %NM_UTILS_INET_ADDRSTRLEN characters long. * - * Returns: a statically allocated array. Do not g_free(). + * Returns: the input buffer filled with the id as string. */ const char * nm_utils_inet6_interface_identifier_to_token (NMUtilsIPv6IfaceId iid, char *buf) @@ -3328,7 +3127,7 @@ nm_utils_stable_id_generated_complete (const char *stable_id_generated) guint8 buf[NM_UTILS_CHECKSUM_LENGTH_SHA1]; char *base64; - /* for NM_UTILS_STABLE_TYPE_GENERATED we genererate a possibly long string + /* for NM_UTILS_STABLE_TYPE_GENERATED we generate a possibly long string * by doing text-substitutions in nm_utils_stable_id_parse(). * * Let's shorten the (possibly) long stable_id to something more compact. */ @@ -3382,7 +3181,7 @@ nm_utils_stable_id_parse (const char *stable_id, * of ${...} patterns. * * At first, it looks a bit like bash parameter substitution. - * In contrast however, the process is unambigious so that the resulting + * In contrast however, the process is unambiguous so that the resulting * effective id differs if: * - the original, untranslated stable-id differs * - or any of the subsitutions differs. @@ -3446,7 +3245,7 @@ nm_utils_stable_id_parse (const char *stable_id, _stable_id_append (str, hwaddr); else if (g_str_has_prefix (&stable_id[i], "${RANDOM}")) { /* RANDOM makes not so much sense for cloned-mac-address - * as the result is simmilar to specyifing "cloned-mac-address=random". + * as the result is similar to specyifing "cloned-mac-address=random". * It makes however sense for RFC 7217 Stable Privacy IPv6 addresses * where this is effectively the only way to generate a different * (random) host identifier for each connect. @@ -3780,12 +3579,55 @@ nm_utils_dhcp_client_id_mac (int arp_type, return g_bytes_new_take (client_id_buf, hwaddr_len + 1); } +#define HASH_KEY ((const guint8[16]) { 0x80, 0x11, 0x8c, 0xc2, 0xfe, 0x4a, 0x03, 0xee, 0x3e, 0xd6, 0x0c, 0x6f, 0x36, 0x39, 0x14, 0x09 }) + +/** + * nm_utils_create_dhcp_iaid: + * @legacy_unstable_byteorder: legacy behavior is to generate a u32 iaid which + * is endianness dependent. This is to preserve backward compatibility. + * For non-legacy behavior, the returned integer is in stable endianness, + * and corresponds to legacy behavior on little endian systems. + * @interface_id: the seed for hashing when generating the ID. Usually, + * this is the interface name. + * @interface_id_len: length of @interface_id + * + * This corresponds to systemd's dhcp_identifier_set_iaid() for generating + * a IAID for the interface. + * + * Returns: the IAID in host byte order. */ +guint32 +nm_utils_create_dhcp_iaid (gboolean legacy_unstable_byteorder, + const guint8 *interface_id, + gsize interface_id_len) +{ + guint64 u64; + guint32 u32; + + u64 = c_siphash_hash (HASH_KEY, interface_id, interface_id_len); + u32 = (u64 & 0xffffffffu) ^ (u64 >> 32); + if (legacy_unstable_byteorder) { + /* legacy systemd code dhcp_identifier_set_iaid() generates the iaid + * dependent on the host endianness. Since this function returns the IAID + * in native-byte order, we need to account for that. + * + * On little endian systems, we want the legacy-behavior is identical to + * the endianness-agnostic behavior. So, we need to swap the bytes on + * big-endian systems. + * + * (https://github.com/systemd/systemd/pull/10614). */ + return htole32 (u32); + } else { + /* we return the value as-is, in native byte order. */ + return u32; + } +} + /** * nm_utils_dhcp_client_id_systemd_node_specific_full: * @legacy_unstable_byteorder: historically, the code would generate a iaid * dependent on host endianness. This is undesirable, if backward compatibility * are not a concern, generate stable endianness. - * @interface_id: a binary identifer that is hashed into the DUID. + * @interface_id: a binary identifier that is hashed into the DUID. * Comonly this is the interface-name, but it may be the MAC address. * @interface_id_len: the length of @interface_id. * @machine_id: the binary identifier for the machine. It is hashed @@ -3805,7 +3647,6 @@ nm_utils_dhcp_client_id_systemd_node_specific_full (gboolean legacy_unstable_byt const guint8 *machine_id, gsize machine_id_len) { - const guint8 HASH_KEY[16] = { 0x80, 0x11, 0x8c, 0xc2, 0xfe, 0x4a, 0x03, 0xee, 0x3e, 0xd6, 0x0c, 0x6f, 0x36, 0x39, 0x14, 0x09 }; const guint16 DUID_TYPE_EN = 2; const guint32 SYSTEMD_PEN = 43793; struct _nm_packed { @@ -3834,20 +3675,10 @@ nm_utils_dhcp_client_id_systemd_node_specific_full (gboolean legacy_unstable_byt client_id->type = 255; - u64 = c_siphash_hash (HASH_KEY, interface_id, interface_id_len); - u32 = (u64 & 0xffffffffu) ^ (u64 >> 32); - if (legacy_unstable_byteorder) { - /* original systemd code dhcp_identifier_set_iaid() generates the iaid - * in native endianness. Do that too, to preserve compatibility - * (https://github.com/systemd/systemd/pull/10614). */ - u32 = bswap_32 (u32); - } else { - /* generate fixed byteorder, in a way that on little endian systems - * the values agree. Meaning: legacy behavior is identical to this - * on little endian. */ - u32 = be32toh (u32); - } - unaligned_write_ne32 (&client_id->iaid, u32); + u32 = nm_utils_create_dhcp_iaid (legacy_unstable_byteorder, + interface_id, + interface_id_len); + unaligned_write_be32 (&client_id->iaid, u32); unaligned_write_be16 (&client_id->duid.type, DUID_TYPE_EN); @@ -4191,7 +4022,7 @@ nm_utils_get_reverse_dns_domains_ip6 (const struct in6_addr *ip, guint8 plen, GP return; memcpy (&addr, ip, sizeof (struct in6_addr)); - nm_utils_ip6_address_clear_host_address (&addr, &addr, plen); + nm_utils_ip6_address_clear_host_address (&addr, NULL, plen); /* Number of nibbles to include in domains */ nibbles = (plen - 1) / 4 + 1; @@ -4315,7 +4146,7 @@ nm_utils_read_plugin_paths (const char *dirname, const char *prefix) errsv = errno; nm_log_warn (LOGD_CORE, "plugin: skip invalid file %s (error during stat: %s)", - data.path, strerror (errsv)); + data.path, nm_strerror_native (errsv)); goto skip; } |