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; }
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; }
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); }
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"); } } }
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; }
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); }
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; }
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; }
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); }
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); }
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; } }
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; } } }
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); }
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; }
/* * 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)); }
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; }
/* * 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; }
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); } }
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; }
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); }
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; } }
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; }