Ejemplo n.º 1
0
static void
dhcp6_event_cb (sd_dhcp6_client *client, int event, gpointer user_data)
{
	NMDhcpSystemd *self = NM_DHCP_SYSTEMD (user_data);
	NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self);
	const char *iface = nm_dhcp_client_get_iface (NM_DHCP_CLIENT (self));

	g_assert (priv->client6 == client);

	nm_log_dbg (LOGD_DHCP6, "(%s): DHCPv6 client event %d", iface, event);

	switch (event) {
	case SD_DHCP6_CLIENT_EVENT_RETRANS_MAX:
		nm_dhcp_client_set_state (NM_DHCP_CLIENT (user_data), NM_DHCP_STATE_TIMEOUT, NULL, NULL);
		break;
	case SD_DHCP6_CLIENT_EVENT_RESEND_EXPIRE:
	case SD_DHCP6_CLIENT_EVENT_STOP:
		nm_dhcp_client_set_state (NM_DHCP_CLIENT (user_data), NM_DHCP_STATE_FAIL, NULL, NULL);
		break;
	case SD_DHCP6_CLIENT_EVENT_IP_ACQUIRE:
		bound6_handle (self);
		break;
	default:
		nm_log_warn (LOGD_DHCP6, "(%s): unhandled DHCPv6 event %d", iface, event);
		break;
	}
}
Ejemplo n.º 2
0
static void
dhcp6_event_cb (sd_dhcp6_client *client, int event, gpointer user_data)
{
	NMDhcpSystemd *self = NM_DHCP_SYSTEMD (user_data);
	NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self);

	g_assert (priv->client6 == client);

	_LOGD ("client event %d", event);

	switch (event) {
	case SD_DHCP6_CLIENT_EVENT_RETRANS_MAX:
		nm_dhcp_client_set_state (NM_DHCP_CLIENT (user_data), NM_DHCP_STATE_TIMEOUT, NULL, NULL);
		break;
	case SD_DHCP6_CLIENT_EVENT_RESEND_EXPIRE:
	case SD_DHCP6_CLIENT_EVENT_STOP:
		nm_dhcp_client_set_state (NM_DHCP_CLIENT (user_data), NM_DHCP_STATE_FAIL, NULL, NULL);
		break;
	case SD_DHCP6_CLIENT_EVENT_IP_ACQUIRE:
	case SD_DHCP6_CLIENT_EVENT_INFORMATION_REQUEST:
		bound6_handle (self);
		break;
	default:
		_LOGW ("unhandled event %d", event);
		break;
	}
}
Ejemplo n.º 3
0
static void
dhcp_event_cb (sd_dhcp_client *client, int event, gpointer user_data)
{
	NMDhcpSystemd *self = NM_DHCP_SYSTEMD (user_data);
	NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self);

	g_assert (priv->client4 == client);

	_LOGD ("client event %d", event);

	switch (event) {
	case SD_DHCP_CLIENT_EVENT_EXPIRED:
		nm_dhcp_client_set_state (NM_DHCP_CLIENT (user_data), NM_DHCP_STATE_EXPIRE, NULL, NULL);
		break;
	case SD_DHCP_CLIENT_EVENT_STOP:
		nm_dhcp_client_set_state (NM_DHCP_CLIENT (user_data), NM_DHCP_STATE_FAIL, NULL, NULL);
		break;
	case SD_DHCP_CLIENT_EVENT_RENEW:
	case SD_DHCP_CLIENT_EVENT_IP_CHANGE:
	case SD_DHCP_CLIENT_EVENT_IP_ACQUIRE:
		bound4_handle (self);
		break;
	default:
		_LOGW ("unhandled DHCP event %d", event);
		break;
	}
}
Ejemplo n.º 4
0
static void
bound6_handle (NMDhcpSystemd *self)
{
	/* not yet supported... */
	nm_log_warn (LOGD_DHCP6, "(%s): internal DHCP does not yet support DHCPv6",
	             nm_dhcp_client_get_iface (NM_DHCP_CLIENT (self)));
	nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), NM_DHCP_STATE_FAIL, NULL, NULL);
}
static void
daemon_watch_cb (GPid pid, gint status, gpointer user_data)
{
	NMDHCPClient *self = NM_DHCP_CLIENT (user_data);
	NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self);
	NMDHCPState new_state;

	if (priv->ipv6) {
		nm_log_info (LOGD_DHCP6, "(%s): DHCPv6 client pid %d exited with status %d",
		             priv->iface, pid,
		             WIFEXITED (status) ? WEXITSTATUS (status) : -1);
	} else {
		nm_log_info (LOGD_DHCP4, "(%s): DHCPv4 client pid %d exited with status %d",
		             priv->iface, pid,
		             WIFEXITED (status) ? WEXITSTATUS (status) : -1);
	}

	if (!WIFEXITED (status)) {
		new_state = DHC_ABEND;
		nm_log_warn (LOGD_DHCP, "DHCP client died abnormally");
	} else
		new_state = DHC_END;

	watch_cleanup (self);
	timeout_cleanup (self);
	priv->dead = TRUE;

	dhcp_client_set_state (self, new_state, TRUE, FALSE);
}
Ejemplo n.º 6
0
static NMDHCPClient *
get_client_for_iface (NMDHCPManager *manager,
                      const char *iface,
                      gboolean ip6)
{
	NMDHCPManagerPrivate *priv;
	GHashTableIter iter;
	gpointer value;

	g_return_val_if_fail (manager != NULL, NULL);
	g_return_val_if_fail (NM_IS_DHCP_MANAGER (manager), NULL);
	g_return_val_if_fail (iface, NULL);

	priv = NM_DHCP_MANAGER_GET_PRIVATE (manager);

	g_hash_table_iter_init (&iter, priv->clients);
	while (g_hash_table_iter_next (&iter, NULL, &value)) {
		NMDHCPClient *candidate = NM_DHCP_CLIENT (value);

		if (   !strcmp (iface, nm_dhcp_client_get_iface (candidate))
		    && (nm_dhcp_client_get_ipv6 (candidate) == ip6))
			return candidate;
	}

	return NULL;
}
static gboolean
signal_remove (gpointer user_data)
{
	NMDHCPClient *self = NM_DHCP_CLIENT (user_data);

	NM_DHCP_CLIENT_GET_PRIVATE (self)->remove_id = 0;
	g_signal_emit (G_OBJECT (self), signals[REMOVE], 0);
	return FALSE;
}
Ejemplo n.º 8
0
static void
_save_client_id (NMDhcpSystemd *self,
                 uint8_t type,
                 const uint8_t *client_id,
                 size_t len)
{
	gs_unref_bytes GBytes *b = NULL;
	gs_free char *buf = NULL;

	g_return_if_fail (self != NULL);
	g_return_if_fail (client_id != NULL);
	g_return_if_fail (len > 0);

	if (!nm_dhcp_client_get_client_id (NM_DHCP_CLIENT (self))) {
		buf = g_malloc (len + 1);
		buf[0] = type;
		memcpy (buf + 1, client_id, len);
		b = g_bytes_new (buf, len + 1);
		nm_dhcp_client_set_client_id (NM_DHCP_CLIENT (self), b);
	}
}
static gboolean
daemon_timeout (gpointer user_data)
{
	NMDHCPClient *self = NM_DHCP_CLIENT (user_data);
	NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self);

	if (priv->ipv6) {
		nm_log_warn (LOGD_DHCP6, "(%s): DHCPv6 request timed out.", priv->iface);
	} else {
		nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 request timed out.", priv->iface);
	}
	g_signal_emit (G_OBJECT (self), signals[TIMEOUT], 0);
	return FALSE;
}
Ejemplo n.º 10
0
static void
dispose (GObject *object)
{
	NMDhcpManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (object);
	GList *values, *iter;

	if (priv->clients) {
		values = g_hash_table_get_values (priv->clients);
		for (iter = values; iter; iter = g_list_next (iter))
			remove_client (NM_DHCP_MANAGER (object), NM_DHCP_CLIENT (iter->data));
		g_list_free (values);
	}

	G_OBJECT_CLASS (nm_dhcp_manager_parent_class)->dispose (object);
}
Ejemplo n.º 11
0
static void
bound4_handle (NMDhcpSystemd *self)
{
	NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self);
	const char *iface = nm_dhcp_client_get_iface (NM_DHCP_CLIENT (self));
	sd_dhcp_lease *lease;
	NMIP4Config *ip4_config;
	GHashTable *options;
	GError *error = NULL;
	int r;

	r = sd_dhcp_client_get_lease (priv->client4, &lease);
	if (r < 0 || !lease) {
		_LOGW ("no lease!");
		nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), NM_DHCP_STATE_FAIL, NULL, NULL);
		return;
	}

	_LOGD ("lease available");

	options = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
	ip4_config = lease_to_ip4_config (iface,
	                                  nm_dhcp_client_get_ifindex (NM_DHCP_CLIENT (self)),
	                                  lease,
	                                  options,
	                                  nm_dhcp_client_get_priority (NM_DHCP_CLIENT (self)),
	                                  TRUE,
	                                  &error);
	if (ip4_config) {
		const uint8_t *client_id = NULL;
		size_t client_id_len = 0;
		uint8_t type = 0;

		add_requests_to_options (options, dhcp4_requests);
		dhcp_lease_save (lease, priv->lease_file);

		sd_dhcp_client_get_client_id(priv->client4, &type, &client_id, &client_id_len);
		if (client_id)
			_save_client_id (self, type, client_id, client_id_len);

		nm_dhcp_client_set_state (NM_DHCP_CLIENT (self),
		                          NM_DHCP_STATE_BOUND,
		                          G_OBJECT (ip4_config),
		                          options);
	} else {
		_LOGW ("%s", error->message);
		nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), NM_DHCP_STATE_FAIL, NULL, NULL);
		g_clear_error (&error);
	}

	g_hash_table_destroy (options);
	g_clear_object (&ip4_config);
}
static void
dispose (GObject *object)
{
	NMDHCPClient *self = NM_DHCP_CLIENT (object);
	NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self);

	/* Stopping the client is left up to the controlling device
	 * explicitly since we may want to quit NetworkManager but not terminate
	 * the DHCP client.
	 */

	if (priv->remove_id)
		g_source_remove (priv->remove_id);

	g_hash_table_destroy (priv->options);
	g_free (priv->iface);

	G_OBJECT_CLASS (nm_dhcp_client_parent_class)->dispose (object);
}
Ejemplo n.º 13
0
static NMDHCPClient *
get_client_for_pid (NMDHCPManager *manager, GPid pid)
{
	NMDHCPManagerPrivate *priv;
	GHashTableIter iter;
	gpointer value;

	g_return_val_if_fail (manager != NULL, NULL);
	g_return_val_if_fail (NM_IS_DHCP_MANAGER (manager), NULL);

	priv = NM_DHCP_MANAGER_GET_PRIVATE (manager);

	g_hash_table_iter_init (&iter, priv->clients);
	while (g_hash_table_iter_next (&iter, NULL, &value)) {
		NMDHCPClient *candidate = NM_DHCP_CLIENT (value);

		if (nm_dhcp_client_get_pid (candidate) == pid)
			return candidate;
	}

	return NULL;
}
Ejemplo n.º 14
0
static NMDhcpClient *
get_client_for_ifindex (NMDhcpManager *manager, int ifindex, gboolean ip6)
{
	NMDhcpManagerPrivate *priv;
	GHashTableIter iter;
	gpointer value;

	g_return_val_if_fail (NM_IS_DHCP_MANAGER (manager), NULL);
	g_return_val_if_fail (ifindex > 0, NULL);

	priv = NM_DHCP_MANAGER_GET_PRIVATE (manager);

	g_hash_table_iter_init (&iter, priv->clients);
	while (g_hash_table_iter_next (&iter, NULL, &value)) {
		NMDhcpClient *candidate = NM_DHCP_CLIENT (value);

		if (   nm_dhcp_client_get_ifindex (candidate) == ifindex
		    && nm_dhcp_client_get_ipv6 (candidate) == ip6)
			return candidate;
	}

	return NULL;
}
Ejemplo n.º 15
0
static NMIP6Config *
lease_to_ip6_config (const char *iface,
                     int ifindex,
                     sd_dhcp6_lease *lease,
                     GHashTable *options,
                     gboolean log_lease,
                     gboolean info_only,
                     GError **error)
{
	struct in6_addr tmp_addr, *dns;
	uint32_t lft_pref, lft_valid;
	NMIP6Config *ip6_config;
	const char *addr_str;
	char **domains;
	GString *str;
	int num, i;
	gint32 ts;

	g_return_val_if_fail (lease, NULL);
	ip6_config = nm_ip6_config_new (ifindex);
	ts = nm_utils_get_monotonic_timestamp_s ();
	str = g_string_sized_new (30);

	/* Addresses */
	sd_dhcp6_lease_reset_address_iter (lease);
	while (sd_dhcp6_lease_get_address (lease, &tmp_addr, &lft_pref, &lft_valid) >= 0) {
		NMPlatformIP6Address address = {
			.plen = 128,
			.address = tmp_addr,
			.timestamp = ts,
			.lifetime = lft_valid,
			.preferred = lft_pref,
			.addr_source = NM_IP_CONFIG_SOURCE_DHCP,
		};

		nm_ip6_config_add_address (ip6_config, &address);

		addr_str = nm_utils_inet6_ntop (&tmp_addr, NULL);
		g_string_append_printf (str, "%s%s", str->len ? " " : "", addr_str);

		LOG_LEASE (LOGD_DHCP6,
		           "  address %s",
		           nm_platform_ip6_address_to_string (&address, NULL, 0));
	};

	if (str->len) {
		add_option (options, dhcp6_requests, DHCP6_OPTION_IP_ADDRESS, str->str);
		g_string_set_size (str , 0);
	}

	if (!info_only && nm_ip6_config_get_num_addresses (ip6_config) == 0) {
		g_string_free (str, TRUE);
		g_object_unref (ip6_config);
		g_set_error_literal (error,
		                     NM_MANAGER_ERROR,
		                     NM_MANAGER_ERROR_FAILED,
		                     "no address received in managed mode");
		return NULL;
	}

	/* DNS servers */
	num = sd_dhcp6_lease_get_dns (lease, &dns);
	if (num > 0) {
		for (i = 0; i < num; i++) {
			nm_ip6_config_add_nameserver (ip6_config, &dns[i]);
			addr_str = nm_utils_inet6_ntop (&dns[i], NULL);
			g_string_append_printf (str, "%s%s", str->len ? " " : "", addr_str);
			LOG_LEASE (LOGD_DHCP6, "  nameserver %s", addr_str);
		}
		add_option (options, dhcp6_requests, SD_DHCP6_OPTION_DNS_SERVERS, str->str);
		g_string_set_size (str, 0);
	}

	/* Search domains */
	num = sd_dhcp6_lease_get_domains (lease, &domains);
	if (num > 0) {
		for (i = 0; i < num; i++) {
			nm_ip6_config_add_search (ip6_config, domains[i]);
			g_string_append_printf (str, "%s%s", str->len ? " " : "", domains[i]);
			LOG_LEASE (LOGD_DHCP6, "  domain name '%s'", domains[i]);
		}
		add_option (options, dhcp6_requests, SD_DHCP6_OPTION_DOMAIN_LIST, str->str);
		g_string_set_size (str, 0);
	}

	g_string_free (str, TRUE);

	return ip6_config;
}

static void
bound6_handle (NMDhcpSystemd *self)
{
	NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self);
	const char *iface = nm_dhcp_client_get_iface (NM_DHCP_CLIENT (self));
	gs_unref_object NMIP6Config *ip6_config = NULL;
	gs_unref_hashtable GHashTable *options = NULL;
	gs_free_error GError *error = NULL;
	sd_dhcp6_lease *lease;
	int r;

	r = sd_dhcp6_client_get_lease (priv->client6, &lease);
	if (r < 0 || !lease) {
		_LOGW (" no lease!");
		nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), NM_DHCP_STATE_FAIL, NULL, NULL);
		return;
	}

	_LOGD ("lease available");

	options = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
	ip6_config = lease_to_ip6_config (iface,
	                                  nm_dhcp_client_get_ifindex (NM_DHCP_CLIENT (self)),
	                                  lease,
	                                  options,
	                                  TRUE,
	                                  priv->info_only,
	                                  &error);

	if (ip6_config) {
		nm_dhcp_client_set_state (NM_DHCP_CLIENT (self),
		                          NM_DHCP_STATE_BOUND,
		                          G_OBJECT (ip6_config),
		                          options);
	} else {
		_LOGW ("%s", error->message);
		nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), NM_DHCP_STATE_FAIL, NULL, NULL);
	}
}