Пример #1
0
static gpointer
hostname_thread_worker (gpointer data)
{
	HostnameThread *ht = (HostnameThread *) data;
	int i;

	nm_log_dbg (LOGD_DNS, "(%p) starting address reverse-lookup", ht);

	g_mutex_lock (ht->lock);
	if (ht->dead) {
		g_mutex_unlock (ht->lock);
		return (gpointer) NULL;
	}
	g_mutex_unlock (ht->lock);

	ht->ret = getnameinfo (ht->addr, ht->addr_size, ht->hostname, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
	if (ht->ret == 0) {
		nm_log_dbg (LOGD_DNS, "(%p) address reverse-lookup returned hostname '%s'",
		            ht, ht->hostname);
		for (i = 0; i < strlen (ht->hostname); i++)
			ht->hostname[i] = tolower (ht->hostname[i]);
	} else {
		nm_log_dbg (LOGD_DNS, "(%p) address reverse-lookup failed: (%d) %s",
		            ht, ht->ret, gai_strerror (ht->ret));
	}

	/* Don't track the idle handler ID because by the time the g_idle_add()
	 * returns the ID, the handler may already have run and freed the
	 * HostnameThread.
	 */
	nm_log_dbg (LOGD_DNS, "(%p) scheduling address reverse-lookup result handler", ht);
	g_idle_add (hostname_thread_run_cb, ht);
	return (gpointer) TRUE;
}
Пример #2
0
static GObject*
constructor (GType type,
			 guint n_construct_params,
			 GObjectConstructParam *construct_params)
{
	GObject *object;
	NMDeviceAdslPrivate *priv;
	GError *error = NULL;

	object = G_OBJECT_CLASS (nm_device_adsl_parent_class)->constructor (type,
	                                                                    n_construct_params,
	                                                                    construct_params);
	if (!object)
		return NULL;

	priv = NM_DEVICE_ADSL_GET_PRIVATE (object);

	priv->atm_index = get_atm_index (nm_device_get_iface (NM_DEVICE (object)), &error);
	if (priv->atm_index < 0) {
		nm_log_dbg (LOGD_ADSL, "error reading ATM device index: (%d) %s",
		            error ? error->code : -1,
		            error && error->message ? error->message : "(unknown)");
		g_clear_error (&error);
		g_object_unref (object);
		return NULL;
	} else {
		nm_log_dbg (LOGD_ADSL, "(%s): ATM device index %d",
				    nm_device_get_iface (NM_DEVICE (object)), priv->atm_index);
	}

	/* Poll the carrier */
	priv->carrier_poll_id = g_timeout_add_seconds (5, carrier_update_cb, object);

	return object;
}
Пример #3
0
gpointer
nm_firewall_manager_add_or_change_zone (NMFirewallManager *self,
                                        const char *iface,
                                        const char *zone,
                                        gboolean add, /* TRUE == add, FALSE == change */
                                        FwAddToZoneFunc callback,
                                        gpointer user_data)
{
	NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self);
	CBInfo *info;

	if (priv->running == FALSE) {
		nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone add/change skipped (not running)", iface);
		callback (NULL, user_data);
		return NULL;
	}

	info = g_malloc0 (sizeof (*info));
	info->iface = g_strdup (iface);
	info->callback = callback;
	info->user_data = user_data;

	nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone %s -> %s", iface, add ? "add" : "change", zone);
	return dbus_g_proxy_begin_call_with_timeout (priv->proxy,
	                                             add ? "addInterface" : "changeZone",
	                                             add_or_change_cb,
	                                             info,
	                                             (GDestroyNotify) cb_info_free,
	                                             10000,      /* timeout */
	                                             G_TYPE_STRING, zone ? zone : "",
	                                             G_TYPE_STRING, iface,
	                                             G_TYPE_INVALID);
}
Пример #4
0
static void
init_auditd (NMAuditManager *self)
{
	NMAuditManagerPrivate *priv = NM_AUDIT_MANAGER_GET_PRIVATE (self);
	NMConfigData *data = nm_config_get_data (priv->config);

	if (nm_config_data_get_value_boolean (data, NM_CONFIG_KEYFILE_GROUP_LOGGING,
	                                      NM_CONFIG_KEYFILE_KEY_AUDIT,
	                                      NM_CONFIG_DEFAULT_LOGGING_AUDIT)) {
		if (priv->auditd_fd < 0) {
			priv->auditd_fd = audit_open ();
			if (priv->auditd_fd < 0) {
				nm_log_err (LOGD_CORE, "failed to open auditd socket: %s",
				            strerror (errno));
			} else
				nm_log_dbg (LOGD_CORE, "audit socket created");
		}
	} else {
		if (priv->auditd_fd >= 0) {
			audit_close (priv->auditd_fd);
			priv->auditd_fd = -1;
			nm_log_dbg (LOGD_CORE, "audit socket closed");
		}
	}
}
Пример #5
0
gpointer
nm_firewall_manager_remove_from_zone (NMFirewallManager *self,
                                      const char *iface,
                                      const char *zone)
{
	NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self);
	CBInfo *info;

	if (priv->running == FALSE) {
		nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove skipped (not running)", iface);
		return NULL;
	}

	info = g_malloc0 (sizeof (*info));
	info->iface = g_strdup (iface);

	nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove -> %s", iface, zone );
	return dbus_g_proxy_begin_call_with_timeout (priv->proxy,
	                                             "removeInterface",
	                                             remove_cb,
	                                             info,
	                                             (GDestroyNotify) cb_info_free,
	                                             10000,      /* timeout */
	                                             G_TYPE_STRING, zone ? zone : "",
	                                             G_TYPE_STRING, iface,
	                                             G_TYPE_INVALID);
}
static void
remove_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
	CBInfo *info = user_data;
	GError *error = NULL;
	char * zone = NULL;

	if (!dbus_g_proxy_end_call (proxy, call_id, &error,
	                            G_TYPE_STRING, &zone,
	                            G_TYPE_INVALID)) {
		g_assert (error);
		/* ignore UNKNOWN_INTERFACE errors */
		if (error->message && !strstr (error->message, "UNKNOWN_INTERFACE")) {
			nm_log_warn (LOGD_FIREWALL, "(%s) firewall zone remove failed [%u]: (%d) %s",
			             info->iface, info->id, error->code, error->message);
		} else {
			nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove failed [%u]: (%d) %s",
			            info->iface, info->id, error->code, error->message);
		}
	} else {
		nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove succeeded [%u]",
		            info->iface, info->id);
	}

	info->completed = TRUE;
	g_free (zone);
	g_clear_error (&error);
}
NMSupplicantInterface *
nm_supplicant_manager_iface_get (NMSupplicantManager * self,
                                 const char *ifname,
                                 gboolean is_wireless)
{
	NMSupplicantManagerPrivate *priv;
	NMSupplicantInterface *iface = NULL;
	gboolean start_now;

	g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), NULL);
	g_return_val_if_fail (ifname != NULL, NULL);

	priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);

	iface = g_hash_table_lookup (priv->ifaces, ifname);
	if (!iface) {
		/* If we're making the supplicant take a time out for a bit, don't
		 * let the supplicant interface start immediately, just let it hang
		 * around in INIT state until we're ready to talk to the supplicant
		 * again.
		 */
		start_now = !die_count_exceeded (priv->die_count);

		nm_log_dbg (LOGD_SUPPLICANT, "(%s): creating new supplicant interface", ifname);
		iface = nm_supplicant_interface_new (self, ifname, is_wireless, start_now);
		if (iface)
			g_hash_table_insert (priv->ifaces, g_strdup (ifname), iface);
	} else {
		nm_log_dbg (LOGD_SUPPLICANT, "(%s): returning existing supplicant interface", ifname);
	}

	return iface;
}
Пример #8
0
static void
wmx_new_sdk_cb (struct wmxsdk *sdk, void *user_data)
{
	NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
	NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);

	/* We only track one wmxsdk at a time because the WiMAX SDK is pretty stupid */
	if (priv->sdk) {
		nm_log_dbg (LOGD_WIMAX, "(%s): WiMAX interface already known", sdk->ifname);
		return;
	}

	nm_log_dbg (LOGD_WIMAX, "(%s): new WiMAX interface (%s)", sdk->ifname, sdk->name);

	/* Now that we have an SDK, schedule an idle handler to start the device up */
	priv->sdk = wmxsdk_ref (sdk);
	iwmx_sdk_set_callbacks(priv->sdk,
	                       wmx_state_change_cb,
	                       wmx_media_status_cb,
	                       wmx_connect_result_cb,
	                       wmx_scan_result_cb,
	                       wmx_removed_cb,
	                       self);
	iwmx_sdk_set_fast_reconnect_enabled (priv->sdk, 0);

	if (!priv->sdk_action_defer_id)
		priv->sdk_action_defer_id = g_idle_add (sdk_action_defer_cb, self);
}
Пример #9
0
static gboolean
is_available (NMDevice *device)
{
	NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device);
	const char *iface = nm_device_get_iface (device);

	if (!priv->enabled) {
		nm_log_dbg (LOGD_WIMAX, "(%s): not available because not enabled", iface);
		return FALSE;
	}

	if (!priv->wimaxd_enabled) {
		nm_log_dbg (LOGD_WIMAX, "(%s): not available because not enabled in wimaxd", iface);
		return FALSE;
	}

	if (!nm_wimax_util_sdk_is_initialized ()) {
		nm_log_dbg (LOGD_WIMAX, "(%s): not available because WiMAX SDK not initialized", iface);
		return FALSE;
	}

	if (!priv->sdk) {
		nm_log_dbg (LOGD_WIMAX, "(%s): not available because not known to WiMAX SDK", iface);
		return FALSE;
	}

	return iwmxsdk_status_get (priv->sdk) >= WIMAX_API_DEVICE_STATUS_Ready;
}
Пример #10
0
static NMIP6Device *
process_nduseropt (NMIP6Manager *manager, struct nl_msg *msg)
{
	NMIP6Device *device;
	struct nduseroptmsg *ndmsg;
	struct nd_opt_hdr *opt;
	guint opts_len;
	gboolean changed = FALSE;

	nm_log_dbg (LOGD_IP6, "processing netlink nduseropt message");

	ndmsg = (struct nduseroptmsg *) NLMSG_DATA (nlmsg_hdr (msg));

	if (!nlmsg_valid_hdr (nlmsg_hdr (msg), sizeof (*ndmsg)) ||
	    nlmsg_datalen (nlmsg_hdr (msg)) <
		(ndmsg->nduseropt_opts_len + sizeof (*ndmsg))) {
		nm_log_dbg (LOGD_IP6, "ignoring invalid nduseropt message");
		return NULL;
	}

	if (ndmsg->nduseropt_family != AF_INET6 ||
		ndmsg->nduseropt_icmp_type != ND_ROUTER_ADVERT ||
		ndmsg->nduseropt_icmp_code != 0) {
		nm_log_dbg (LOGD_IP6, "ignoring non-Router Advertisement message");
		return NULL;
	}

	device = nm_ip6_manager_get_device (manager, ndmsg->nduseropt_ifindex);
	if (!device) {
		nm_log_dbg (LOGD_IP6, "ignoring message for unknown device");
		return NULL;
	}

	opt = (struct nd_opt_hdr *) (ndmsg + 1);
	opts_len = ndmsg->nduseropt_opts_len;

	while (opts_len >= sizeof (struct nd_opt_hdr)) {
		size_t nd_opt_len = opt->nd_opt_len;

		if (nd_opt_len == 0 || opts_len < (nd_opt_len << 3))
			break;

		switch (opt->nd_opt_type) {
		case ND_OPT_RDNSS:
			changed = process_nduseropt_rdnss (device, opt);
			break;
		case ND_OPT_DNSSL:
			changed = process_nduseropt_dnssl (device, opt);
			break;
		}

		opts_len -= opt->nd_opt_len << 3;
		opt = (struct nd_opt_hdr *) ((uint8_t *) opt + (opt->nd_opt_len << 3));
	}

	if (changed)
		return device;
	else
		return NULL;
}
Пример #11
0
static NMIP6Device *
process_prefix (NMIP6Manager *manager, struct nl_msg *msg)
{
	struct prefixmsg *pmsg;
	NMIP6Device *device;

	/* We don't care about the prefix itself, but if we receive a
	 * router advertisement telling us to use DHCP, we might not
	 * get any RTM_NEWADDRs or RTM_NEWROUTEs, so this is our only
	 * way to notice immediately that an RA was received.
	 */

	nm_log_dbg (LOGD_IP6, "processing netlink new prefix message");

	if (!nlmsg_valid_hdr (nlmsg_hdr (msg), sizeof(*pmsg))) {
		nm_log_dbg (LOGD_IP6, "ignoring invalid prefix message");
		return NULL;
	}

	pmsg = (struct prefixmsg *) NLMSG_DATA (nlmsg_hdr (msg));
	device = nm_ip6_manager_get_device (manager, pmsg->prefix_ifindex);

	if (!device || device->addrconf_complete) {
		nm_log_dbg (LOGD_IP6, "(%s): ignoring unknown or completed device",
		            device ? device->iface : "(none)");
		return NULL;
	}

	return device;
}
static NMIP6Device *
process_address_change (NMIP6Manager *manager, struct nl_msg *msg)
{
	NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
	NMIP6Device *device;
	struct nlmsghdr *hdr;
	struct rtnl_addr *rtnladdr;
	int old_size;

	hdr = nlmsg_hdr (msg);
	rtnladdr = NULL;
	nl_msg_parse (msg, ref_object, &rtnladdr);
	if (!rtnladdr) {
		nm_log_dbg (LOGD_IP6, "error processing netlink new/del address message");
		return NULL;
	}

	device = nm_ip6_manager_get_device (manager, rtnl_addr_get_ifindex (rtnladdr));

	old_size = nl_cache_nitems (priv->addr_cache);
	nl_cache_include (priv->addr_cache, (struct nl_object *)rtnladdr, NULL, NULL);

	/* The kernel will re-notify us of automatically-added addresses
	 * every time it gets another router advertisement. We only want
	 * to notify higher levels if we actually changed something.
	 */
	nm_log_dbg (LOGD_IP6, "(%s): address cache size: %d -> %d:",
		    device_get_iface (device), old_size, nl_cache_nitems (priv->addr_cache));
	dump_address_change (device, hdr, rtnladdr);
	rtnl_addr_put (rtnladdr);
	if (nl_cache_nitems (priv->addr_cache) == old_size)
		return NULL;

	return device;
}
NMFirewallPendingCall
nm_firewall_manager_remove_from_zone (NMFirewallManager *self,
                                      const char *iface,
                                      const char *zone)
{
	NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self);
	CBInfo *info;

	if (priv->running == FALSE) {
		nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove skipped (not running)", iface);
		return PENDING_CALL_DUMMY;
	}

	info = _cb_info_create (self, iface, NULL, NULL);

	nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove -> %s%s%s [%u]", iface,
	                           zone?"\"":"", zone ? zone : "*", zone?"\"":"", info->id);
	info->dbus_call = dbus_g_proxy_begin_call_with_timeout (priv->proxy,
	                                                        "removeInterface",
	                                                        remove_cb,
	                                                        info,
	                                                        (GDestroyNotify) _cb_info_free,
	                                                        10000,      /* timeout */
	                                                        G_TYPE_STRING, zone ? zone : "",
	                                                        G_TYPE_STRING, iface,
	                                                        G_TYPE_INVALID);
	return PENDING_CALL_FROM_INFO (info);
}
static void
add_or_change_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
	CBInfo *info = user_data;
	GError *error = NULL;
	char *zone = NULL;

	if (!dbus_g_proxy_end_call (proxy, call_id, &error,
	                            G_TYPE_STRING, &zone,
	                            G_TYPE_INVALID)) {
		g_assert (error);
		if (g_strcmp0 (error->message, "ZONE_ALREADY_SET") != 0) {
			nm_log_warn (LOGD_FIREWALL, "(%s) firewall zone add/change failed [%u]: (%d) %s",
			             info->iface, info->id, error->code, error->message);
		} else {
			nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone add/change failed [%u]: (%d) %s",
			            info->iface, info->id, error->code, error->message);
		}
	} else {
		nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone add/change succeeded [%u]",
		            info->iface, info->id);
	}

	if (info->callback)
		info->callback (error, info->user_data);

	info->completed = TRUE;
	g_free (zone);
	g_clear_error (&error);
}
Пример #15
0
static void
set_enabled (NMDevice *device, gboolean enabled)
{
	NMDeviceWimax *self = NM_DEVICE_WIMAX (device);
	NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
	gboolean old_available;
	int ret;
	const char *iface;

	iface = nm_device_get_iface (NM_DEVICE (self));

	nm_log_dbg (LOGD_WIMAX, "(%s): setting radio enabled %d -> %d",
	            iface, priv->enabled, enabled);
	if (priv->enabled == enabled)
		return;

	old_available = nm_device_is_available (NM_DEVICE (device));
	priv->enabled = enabled;

	nm_log_dbg (LOGD_WIMAX, "(%s): radio now %s",
	            iface, priv->enabled ? "enabled" : "disabled");

	/* Set the WiMAX device RF state to the current user-specified enabled state */
	if (priv->sdk) {
		ret = iwmx_sdk_rf_state_set (priv->sdk,
		                             enabled ? WIMAX_API_RF_ON : WIMAX_API_RF_OFF);
		if (ret < 0 && ret != -EINPROGRESS) {
			nm_log_warn (LOGD_WIMAX, "(%s): failed to %s radio",
			             iface, priv->enabled ? "enable" : "disable");
		}
	}

	update_availability (self, old_available);
}
Пример #16
0
static void
vpn_dir_changed (GFileMonitor *monitor,
                 GFile *file,
                 GFile *other_file,
                 GFileMonitorEvent event_type,
                 gpointer user_data)
{
	NMVpnManager *self = NM_VPN_MANAGER (user_data);
	NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self);
	NMVpnPluginInfo *plugin_info;
	gs_free char *path = NULL;
	GError *error = NULL;

	path = g_file_get_path (file);
	if (!nm_vpn_plugin_info_validate_filename (path))
		return;

	switch (event_type) {
	case G_FILE_MONITOR_EVENT_DELETED:
		plugin_info = nm_vpn_plugin_info_list_find_by_filename (priv->plugins, path);
		if (!plugin_info)
			break;

		nm_log_dbg (LOGD_VPN, "vpn: service file %s deleted", path);
		nm_vpn_plugin_info_list_remove (&priv->plugins, plugin_info);
		break;
	case G_FILE_MONITOR_EVENT_CREATED:
	case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
		plugin_info = nm_vpn_plugin_info_list_find_by_filename (priv->plugins, path);
		if (plugin_info) {
			/* we don't support reloading an existing plugin. You can only remove the file
			 * and re-add it. By reloading we want to support the use case of installing
			 * a VPN plugin after NM started. No need to burden ourself with a complete
			 * reload. */
			break;
		}

		if (!_nm_vpn_plugin_info_check_file (path, TRUE, TRUE, 0,
		                                     NULL, NULL, &error)) {
			nm_log_dbg (LOGD_VPN, "vpn: ignore changed service file %s (%s)", path, error->message);
			g_clear_error (&error);
			break;
		}
		plugin_info = nm_vpn_plugin_info_new_from_file (path, &error);
		if (!plugin_info) {
			nm_log_dbg (LOGD_VPN, "vpn: ignore changed service file %s due to invalid content (%s)", path, error->message);
			g_clear_error (&error);
			break;
		}

		nm_log_dbg (LOGD_VPN, "vpn: service file %s created or modified", path);
		try_add_plugin (self, plugin_info);
		g_object_unref (plugin_info);
		break;
	default:
		nm_log_dbg (LOGD_VPN, "vpn: service file %s change event %d", path, event_type);
		break;
	}
}
Пример #17
0
static void
bluez_property_changed (DBusGProxy *proxy,
                        const char *property,
                        GValue *value,
                        gpointer user_data)
{
	NMDevice *device = NM_DEVICE (user_data);
	NMDeviceBt *self = NM_DEVICE_BT (user_data);
	NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self);
	gboolean connected;
	NMDeviceState state;
	const char *prop_str = "(unknown)";

	if (G_VALUE_HOLDS_STRING (value))
		prop_str = g_value_get_string (value);
	else if (G_VALUE_HOLDS_BOOLEAN (value))
		prop_str = g_value_get_boolean (value) ? "true" : "false";

	nm_log_dbg (LOGD_BT, "(%s): bluez property '%s' changed to '%s'",
	            nm_device_get_iface (device),
	            property,
	            prop_str);

	if (strcmp (property, "Connected"))
		return;

	state = nm_device_get_state (device);
	connected = g_value_get_boolean (value);
	if (connected) {
		if (state == NM_DEVICE_STATE_CONFIG) {
			nm_log_dbg (LOGD_BT, "(%s): connected to the device",
			            nm_device_get_iface (device));

			priv->connected = TRUE;
			check_connect_continue (self);
		}
	} else {
		gboolean fail = FALSE;

		/* Bluez says we're disconnected from the device.  Suck. */

		if (nm_device_is_activating (device)) {
			nm_log_info (LOGD_BT,
			             "Activation (%s/bluetooth): bluetooth link disconnected.",
			             nm_device_get_iface (device));
			fail = TRUE;
		} else if (state == NM_DEVICE_STATE_ACTIVATED) {
			nm_log_info (LOGD_BT, "(%s): bluetooth link disconnected.",
			             nm_device_get_iface (device));
			fail = TRUE;
		}

		if (fail) {
			nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CARRIER);
			priv->connected = FALSE;
		}
	}
}
Пример #18
0
static void iwmx_sdk_addremove_cb(WIMAX_API_DEVICE_ID *devid,
				  BOOL presence)
{
	unsigned int cnt;
	WIMAX_API_RET r;
	WIMAX_API_HW_DEVICE_ID device_id_list[5];
	UINT32 device_id_list_size = ARRAY_SIZE(device_id_list);
	char errstr[512];
	UINT32 errstr_size = sizeof(errstr);

	g_mutex_lock(&add_remove_mutex);

	nm_log_dbg(LOGD_WIMAX, "cb: handle %u index #%u is %d", devid->sdkHandle,
	           devid->deviceIndex, presence);

	r = GetListDevice(devid, device_id_list, &device_id_list_size);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(devid, r, errstr, &errstr_size);
		nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot obtain list of devices: %d (%s)", r, errstr);
		goto out;
	}

	if (device_id_list_size == 0) {
		nm_log_dbg(LOGD_WIMAX, "No WiMAX devices reported");
	} else {
		for (cnt = 0; cnt < device_id_list_size; cnt++) {
			WIMAX_API_HW_DEVICE_ID *dev =
				device_id_list + cnt;
			nm_log_dbg(LOGD_WIMAX, "#%u index #%u device %s", cnt,
			           dev->deviceIndex, dev->deviceName);
		}
	}

	if (presence) {
		WIMAX_API_HW_DEVICE_ID *dev;

		/* Make sure the wimax NS isn't lying to us */
		if (device_id_list_size < devid->deviceIndex) {
			nm_log_err(LOGD_WIMAX, "wmxsdk: changed device (%u) not in the list? (%u items)",
			           devid->deviceIndex, device_id_list_size);
			goto out;
		}

		/* Add the device to our internal list */
		dev = device_id_list + devid->deviceIndex;
		iwmx_sdk_dev_add(devid->deviceIndex, dev->deviceIndex, dev->deviceName);
	} else {
		/* Remove the device from our internal list */
		int idx = deviceid_to_index(devid);

		if (idx >= 0)
			iwmx_sdk_dev_rm(idx);
	}

out:
	g_mutex_unlock(&add_remove_mutex);
}
Пример #19
0
static NMActStageReturn
act_stage3_ip4_config_start (NMDevice *device,
                             NMIP4Config **out_config,
                             NMDeviceStateReason *reason)
{
	NMDeviceAdsl *self = NM_DEVICE_ADSL (device);
	NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self);
	NMConnection *connection;
	NMSettingAdsl *s_adsl;
	NMActRequest *req;
	GError *err = NULL;
	NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
	const char *iface = nm_device_get_iface (device);
	const char *ppp_iface;

	req = nm_device_get_act_request (device);
	g_assert (req);

	connection = nm_act_request_get_connection (req);
	g_assert (req);

	s_adsl = nm_connection_get_setting_adsl (connection);
	g_assert (s_adsl);

	/* PPPoE uses the NAS inteface, not the ATM interface */
	if (g_strcmp0 (nm_setting_adsl_get_protocol (s_adsl), NM_SETTING_ADSL_PROTOCOL_PPPOE) == 0) {
		g_assert (priv->nas_ifname);
		ppp_iface = priv->nas_ifname;

		nm_log_dbg (LOGD_ADSL, "(%s): starting PPPoE on NAS interface %s",
			        iface, priv->nas_ifname);
	} else {
		ppp_iface = iface;
		nm_log_dbg (LOGD_ADSL, "(%s): starting PPPoA", iface);
	}

	priv->ppp_manager = nm_ppp_manager_new (ppp_iface);
	if (nm_ppp_manager_start (priv->ppp_manager, req, nm_setting_adsl_get_username (s_adsl), 30, &err)) {
		g_signal_connect (priv->ppp_manager, "state-changed",
		                  G_CALLBACK (ppp_state_changed),
		                  self);
		g_signal_connect (priv->ppp_manager, "ip4-config",
		                  G_CALLBACK (ppp_ip4_config),
		                  self);
		ret = NM_ACT_STAGE_RETURN_POSTPONE;
	} else {
		nm_log_warn (LOGD_ADSL, "(%s): PPP failed to start: %s", iface, err->message);
		g_error_free (err);

		g_object_unref (priv->ppp_manager);
		priv->ppp_manager = NULL;

		*reason = NM_DEVICE_STATE_REASON_PPP_START_FAILED;
	}

	return ret;
}
Пример #20
0
/*
 * Initialize the WiMAX API, register with it, setup callbacks for
 * device coming up / dissapearing
 */
int iwmx_sdk_api_init(void)
{
	int result;
	unsigned int cnt;
	WIMAX_API_RET r;
	char errstr[512];
	UINT32 errstr_size = sizeof(errstr);

	WIMAX_API_HW_DEVICE_ID device_id_list[5];
	UINT32 device_id_list_size = ARRAY_SIZE(device_id_list);

	memset(&g_api, 0, sizeof(g_api));
	g_api.privilege = WIMAX_API_PRIVILEGE_READ_WRITE;

	result = -EIO;
	r = WiMaxAPIOpen(&g_api);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&g_api, r, errstr, &errstr_size);
		nm_log_err(LOGD_WIMAX, "wmxsdk: WiMaxAPIOpen failed with %d (%s)", r, errstr);
		goto error_wimaxapiopen;
	}

	r = SubscribeDeviceInsertRemove(&g_api, iwmx_sdk_addremove_cb);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&g_api, r, errstr, &errstr_size);
		nm_log_err(LOGD_WIMAX, "wmxsdk: insert/remove subscribe failed with %d (%s)", r, errstr);
		goto error_close;
	}

	r = GetListDevice(&g_api, device_id_list, &device_id_list_size);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&g_api, r, errstr, &errstr_size);
		nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot obtain list of devices: %d (%s)", r, errstr);
		goto error_close;
	}
	if (device_id_list_size < g_api.deviceIndex) {
		nm_log_err(LOGD_WIMAX, "wmxsdk: changed device (%u) not in the list? (%u items)",
		           g_api.deviceIndex, device_id_list_size);
	}

	if (device_id_list_size == 0) {
		nm_log_dbg(LOGD_WIMAX, "No WiMAX devices reported");
	} else {
		for (cnt = 0; cnt < device_id_list_size; cnt++) {
			WIMAX_API_HW_DEVICE_ID *dev = device_id_list + cnt;
			nm_log_dbg(LOGD_WIMAX, "#%u index #%u device %s", cnt, dev->deviceIndex, dev->deviceName);
			iwmx_sdk_dev_add(cnt, dev->deviceIndex, dev->deviceName);
		}
	}
	return 0;

error_close:
	WiMaxAPIClose(&g_api);
error_wimaxapiopen:
	return result;
}
static void
update_capabilities (NMSupplicantManager *self)
{
	NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
	NMSupplicantInterface *iface;
	GHashTableIter hash_iter;
	const char **array;
	GVariant *value;

	/* The supplicant only advertises global capabilities if the following
	 * commit has been applied:
	 *
	 * commit 1634ac0654eba8d458640a115efc0a6cde3bac4d
	 * Author: Dan Williams <*****@*****.**>
	 * Date:   Sat Sep 29 19:06:30 2012 +0300
	 *
	 * dbus: Add global capabilities property
	 */
	priv->ap_support = AP_SUPPORT_UNKNOWN;

	value = g_dbus_proxy_get_cached_property (priv->proxy, "Capabilities");
	if (value) {
		if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING_ARRAY)) {
			array = g_variant_get_strv (value, NULL);
			priv->ap_support = AP_SUPPORT_NO;
			if (_nm_utils_string_in_list ("ap", array))
				priv->ap_support = AP_SUPPORT_YES;
			g_free (array);
		}
		g_variant_unref (value);
	}

	/* Tell all interfaces about results of the AP check */
	g_hash_table_iter_init (&hash_iter, priv->ifaces);
	while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &iface))
		nm_supplicant_interface_set_ap_support (iface, priv->ap_support);

	nm_log_dbg (LOGD_SUPPLICANT, "AP mode is %ssupported",
	            (priv->ap_support == AP_SUPPORT_YES) ? "" :
	                (priv->ap_support == AP_SUPPORT_NO) ? "not " : "possibly ");

	/* EAP-FAST */
	priv->fast_supported = FALSE;
	value = g_dbus_proxy_get_cached_property (priv->proxy, "EapMethods");
	if (value) {
		if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING_ARRAY)) {
			array = g_variant_get_strv (value, NULL);
			if (_nm_utils_string_in_list ("fast", array))
				priv->fast_supported = TRUE;
			g_free (array);
		}
		g_variant_unref (value);
	}

	nm_log_dbg (LOGD_SUPPLICANT, "EAP-FAST is %ssupported", priv->fast_supported ? "" : "not ");
}
static void
check_addresses (NMIP6Device *device)
{
	NMIP6Manager *manager = device->manager;
	NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
	struct rtnl_addr *rtnladdr;
	struct nl_addr *nladdr;
	struct in6_addr *addr;

	/* Reset address information */
	device->has_linklocal = FALSE;
	device->has_nonlinklocal = FALSE;

	/* Look for any IPv6 addresses the kernel may have set for the device */
	for (rtnladdr = (struct rtnl_addr *) nl_cache_get_first (priv->addr_cache);
		 rtnladdr;
		 rtnladdr = (struct rtnl_addr *) nl_cache_get_next ((struct nl_object *) rtnladdr)) {
		char buf[INET6_ADDRSTRLEN];

		if (rtnl_addr_get_ifindex (rtnladdr) != device->ifindex)
			continue;

		nladdr = rtnl_addr_get_local (rtnladdr);
		if (!nladdr || nl_addr_get_family (nladdr) != AF_INET6)
			continue;

		addr = nl_addr_get_binary_addr (nladdr);

		if (inet_ntop (AF_INET6, addr, buf, INET6_ADDRSTRLEN) > 0) {
			nm_log_dbg (LOGD_IP6, "(%s): netlink address: %s/%d",
			            device->iface, buf,
			            rtnl_addr_get_prefixlen (rtnladdr));
		}

		if (IN6_IS_ADDR_LINKLOCAL (addr)) {
			if (device->state == NM_IP6_DEVICE_UNCONFIGURED)
				device_set_state (device, NM_IP6_DEVICE_GOT_LINK_LOCAL);
			device->has_linklocal = TRUE;
		} else {
			if (device->state == NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT)
				device_set_state (device, NM_IP6_DEVICE_GOT_ADDRESS);
			device->has_nonlinklocal = TRUE;
		}
	}

	/* There might be a LL address hanging around on the interface from
	 * before in the initial run, but if it goes away later, make sure we
	 * regress from GOT_LINK_LOCAL back to UNCONFIGURED.
	 */
	if ((device->state == NM_IP6_DEVICE_GOT_LINK_LOCAL) && !device->has_linklocal)
		device_set_state (device, NM_IP6_DEVICE_UNCONFIGURED);

	nm_log_dbg (LOGD_IP6, "(%s): addresses checked (state %s)",
		    device->iface, state_to_string (device->state));
}
static void
check_addrconf_complete (NMIP6Device *device)
{
	CallbackInfo *info;

	if (!device->addrconf_complete) {
		/* Managed mode (ie DHCP only) short-circuits automatic addrconf, so
		 * we don't bother waiting for the device's target state to be reached
		 * when the RA requests managed mode.
		 */
		if (   (device->state >= device->target_state)
		    || (device->dhcp_opts == IP6_DHCP_OPT_MANAGED)) {
			/* device->finish_addrconf_id may currently be a timeout
			 * rather than an idle, so we remove the existing source.
			 */
			if (device->finish_addrconf_id)
				g_source_remove (device->finish_addrconf_id);

			nm_log_dbg (LOGD_IP6, "(%s): reached target state or Managed-mode requested (state '%s') (dhcp opts 0x%X)",
			            device->iface, state_to_string (device->state),
			            device->dhcp_opts);

			info = callback_info_new (device, TRUE);
			device->finish_addrconf_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
			                                              finish_addrconf,
			                                              info,
			                                              (GDestroyNotify) g_free);
		}
	} else {
		if (!device->config_changed_id) {
			gboolean success = TRUE;

			/* If for some reason an RA-provided address disappeared, we need
			 * to make sure we fail the connection as it's no longer valid.
			 */
			if (   (device->state == NM_IP6_DEVICE_GOT_ADDRESS)
			    && (device->target_state == NM_IP6_DEVICE_GOT_ADDRESS)
			    && !device->has_nonlinklocal) {
				nm_log_dbg (LOGD_IP6, "(%s): RA-provided address no longer found",
				            device->iface);
				success = FALSE;
			}

			info = callback_info_new (device, success);
			device->config_changed_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
			                                             emit_config_changed,
			                                             info,
			                                             (GDestroyNotify) g_free);
		}
	}

	nm_log_dbg (LOGD_IP6, "(%s): dhcp_opts checked (state %s)",
		    device->iface, state_to_string (device->state));
}
Пример #24
0
static NMActStageReturn
act_stage2_config (NMDevice *device, NMDeviceStateReason *out_reason)
{
	NMDeviceAdsl *self = NM_DEVICE_ADSL (device);
	NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self);
	NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
	NMSettingAdsl *s_adsl;
	const char *protocol;

	g_assert (out_reason);

	s_adsl = nm_connection_get_setting_adsl (nm_device_get_connection (device));
	g_assert (s_adsl);

	protocol = nm_setting_adsl_get_protocol (s_adsl);
	nm_log_dbg (LOGD_ADSL, "(%s): using ADSL protocol '%s'",
	             nm_device_get_iface (device), protocol);

	if (g_strcmp0 (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE) == 0) {

		/* PPPoE needs RFC2684 bridging before we can do PPP over it */
		if (!br2684_create_iface (self, s_adsl)) {
			*out_reason = NM_DEVICE_STATE_REASON_BR2684_FAILED;
			goto done;
		}

		/* Set up the VCC */
		if (!br2684_assign_vcc (self, s_adsl)) {
			*out_reason = NM_DEVICE_STATE_REASON_BR2684_FAILED;
			goto done;
		}

		/* Watch for the 'nas' interface going away */
		priv->lost_link_id = g_signal_connect (nm_platform_get (), "link-removed",
		                                       G_CALLBACK (lost_link),
		                                       self);

		nm_log_dbg (LOGD_ADSL, "(%s): ATM setup successful", nm_device_get_iface (device));

		/* otherwise we're good for stage3 */
		nm_platform_link_set_up (priv->nas_ifindex);
		ret = NM_ACT_STAGE_RETURN_SUCCESS;

	} else if (g_strcmp0 (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOA) == 0) {
		/* PPPoA doesn't need anything special */
		ret = NM_ACT_STAGE_RETURN_SUCCESS;
	} else {
		nm_log_warn (LOGD_ADSL, "(%s): unhandled ADSL protocol '%s'",
		             nm_device_get_iface (device), protocol);
	}

done:
	return ret;
}
Пример #25
0
/*
 * Disconnect from a network
 *
 * This function tells the device to disconnect; the state change
 * callback will take care of inform NetworkManager's internals.
 */
int iwmx_sdk_disconnect(struct wmxsdk *wmxsdk)
{
	int result;

	WIMAX_API_RET r;
	char errstr[512];
	UINT32 errstr_size = sizeof(errstr);
	WIMAX_API_DEVICE_STATUS dev_status;

	g_mutex_lock(&wmxsdk->connect_mutex);
	/* Guess what the current radio state is; if it is ON
	 * already, don't redo it. */
	dev_status = iwmx_sdk_get_device_status(wmxsdk);
	if ((int) dev_status < 0) {
		result = dev_status;
		goto error_get_status;
	}
	switch (dev_status) {
	case WIMAX_API_DEVICE_STATUS_UnInitialized:
		nm_log_err(LOGD_WIMAX, "wmxsdk: SW BUG? HW is uninitialized");
		result = -EINVAL;
		goto error_cant_do;
	case WIMAX_API_DEVICE_STATUS_RF_OFF_HW_SW:
	case WIMAX_API_DEVICE_STATUS_RF_OFF_HW:
	case WIMAX_API_DEVICE_STATUS_RF_OFF_SW:
		nm_log_dbg(LOGD_WIMAX, "Cannot disconnect, radio is off; ignoring");
		result = 0;
		goto error_cant_do;
	case WIMAX_API_DEVICE_STATUS_Ready:
	case WIMAX_API_DEVICE_STATUS_Scanning:
		nm_log_dbg(LOGD_WIMAX, "Cannot disconnect, already disconnected; ignoring");
		result = 0;
		goto error_cant_do;
	case WIMAX_API_DEVICE_STATUS_Connecting:
	case WIMAX_API_DEVICE_STATUS_Data_Connected:
		break;
	default:
		g_assert(1);
	}
	/* Ok, flip the radio */
	r = CmdDisconnectFromNetwork(&wmxsdk->device_id);
	if (r != WIMAX_API_RET_SUCCESS) {
		GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
		nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot disconnect from network: %d (%s)", r, errstr);
		result = -EIO;
	} else
		result = -EINPROGRESS;
error_cant_do:
error_get_status:
	g_mutex_unlock(&wmxsdk->connect_mutex);
	return result;
}
Пример #26
0
static void
service_kill (int pid)
{
	if (kill (pid, SIGTERM) == 0)
		g_timeout_add_seconds (2, ensure_killed, GINT_TO_POINTER (pid));
	else {
		kill (pid, SIGKILL);

		/* ensure the child is reaped */
		nm_log_dbg (LOGD_TEAM, "waiting for teamd pid %d to exit", pid);
		waitpid (pid, NULL, 0);
		nm_log_dbg (LOGD_TEAM, "teamd pid %d cleaned up", pid);
	}
}
Пример #27
0
static gboolean
ensure_killed (gpointer data)
{
	int pid = GPOINTER_TO_INT (data);

	if (kill (pid, 0) == 0)
		kill (pid, SIGKILL);

	/* ensure the child is reaped */
	nm_log_dbg (LOGD_VPN, "waiting for VPN service pid %d to exit", pid);
	waitpid (pid, NULL, 0);
	nm_log_dbg (LOGD_VPN, "VPN service pid %d cleaned up", pid);

	return FALSE;
}
Пример #28
0
static void
nm_connectivity_check_cb (SoupSession *session, SoupMessage *msg, gpointer user_data)
{
	GSimpleAsyncResult *simple = user_data;
	NMConnectivity *self;
	NMConnectivityPrivate *priv;
	NMConnectivityState new_state;
	const char *nm_header;

	self = NM_CONNECTIVITY (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
	g_object_unref (self);
	priv = NM_CONNECTIVITY_GET_PRIVATE (self);

	if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) {
		nm_log_info (LOGD_CONCHECK, "Connectivity check for uri '%s' failed with '%s'.",
		             priv->uri, msg->reason_phrase);
		new_state = NM_CONNECTIVITY_LIMITED;
		goto done;
	}

	/* Check headers; if we find the NM-specific one we're done */
	nm_header = soup_message_headers_get_one (msg->response_headers, "X-NetworkManager-Status");
	if (g_strcmp0 (nm_header, "online") == 0) {
		nm_log_dbg (LOGD_CONCHECK, "Connectivity check for uri '%s' with Status header successful.", priv->uri);
		new_state = NM_CONNECTIVITY_FULL;
	} else if (msg->status_code == SOUP_STATUS_OK) {
		/* check response */
		if (msg->response_body->data &&	(g_str_has_prefix (msg->response_body->data, priv->response))) {
			nm_log_dbg (LOGD_CONCHECK, "Connectivity check for uri '%s' successful.",
			            priv->uri);
			new_state = NM_CONNECTIVITY_FULL;
		} else {
			nm_log_info (LOGD_CONCHECK, "Connectivity check for uri '%s' did not match expected response '%s'; assuming captive portal.",
			             priv->uri, priv->response);
			new_state = NM_CONNECTIVITY_PORTAL;
		}
	} else {
		nm_log_info (LOGD_CONCHECK, "Connectivity check for uri '%s' returned status '%d %s'; assuming captive portal.",
		             priv->uri, msg->status_code, msg->reason_phrase);
		new_state = NM_CONNECTIVITY_PORTAL;
	}

 done:
	g_simple_async_result_set_op_res_gssize (simple, new_state);
	g_simple_async_result_complete (simple);

	update_state (self, new_state);
}
Пример #29
0
static void
_ppp_cleanup (NMPPPManager *manager)
{
	NMPPPManagerPrivate *priv;

	g_return_if_fail (NM_IS_PPP_MANAGER (manager));

	priv = NM_PPP_MANAGER_GET_PRIVATE (manager);

	cancel_get_secrets (manager);

	if (priv->monitor_id) {
		g_source_remove (priv->monitor_id);
		priv->monitor_id = 0;
	}

	if (priv->monitor_fd) {
		/* Get the stats one last time */
		monitor_cb (manager);
		close (priv->monitor_fd);
		priv->monitor_fd = 0;
	}

	if (priv->ppp_timeout_handler) {
		g_source_remove (priv->ppp_timeout_handler);
		priv->ppp_timeout_handler = 0;
	}

	if (priv->ppp_watch_id) {
		g_source_remove (priv->ppp_watch_id);
		priv->ppp_watch_id = 0;
	}

	if (priv->pid) {
		if (kill (priv->pid, SIGTERM) == 0)
			g_timeout_add_seconds (2, ensure_killed, GINT_TO_POINTER (priv->pid));
		else {
			kill (priv->pid, SIGKILL);

			/* ensure the child is reaped */
			nm_log_dbg (LOGD_PPP, "waiting for pppd pid %d to exit", priv->pid);
			waitpid (priv->pid, NULL, 0);
			nm_log_dbg (LOGD_PPP, "pppd pid %d cleaned up", priv->pid);
		}

		priv->pid = 0;
	}
}
Пример #30
0
static gboolean
carrier_update_cb (gpointer user_data)
{
	NMDeviceAdsl *self = NM_DEVICE_ADSL (user_data);
	GError *error = NULL;
	gboolean carrier = FALSE;
	char *path, *contents;
	const char *iface;
	gboolean success;

	iface = nm_device_get_iface (NM_DEVICE (self));

	path  = g_strdup_printf ("/sys/class/atm/%s/carrier", iface);
	success = g_file_get_contents (path, &contents, NULL, &error);
	g_free (path);

	if (!success) {
		nm_log_dbg (LOGD_ADSL, "error reading %s: (%d) %s",
		            path,
		            error ? error->code : -1,
		            error && error->message ? error->message : "(unknown)");
		g_clear_error (&error);
		return TRUE;
	}

	carrier = (gboolean) atoi (contents);
	g_free (contents);
	nm_device_set_carrier (NM_DEVICE (self), carrier);
	return TRUE;
}