Beispiel #1
0
static void add_adapter(DBusConnection *conn, const char *path)
{
	DBusMessage *message;
	DBusPendingCall *call;

	DBG("path %s", path);

	message = dbus_message_new_method_call(BLUEZ_SERVICE, path,
				BLUEZ_ADAPTER_INTERFACE, GET_PROPERTIES);
	if (message == NULL)
		return;

	dbus_message_set_auto_start(message, FALSE);

	if (dbus_connection_send_with_reply(conn, message,
						&call, TIMEOUT) == FALSE) {
		connman_error("Failed to get adapter properties for %s", path);
		goto done;
	}

	if (call == NULL) {
		connman_error("D-Bus connection not available");
		goto done;
	}

	dbus_pending_call_set_notify(call, adapter_properties_reply,
						g_strdup(path), g_free);

done:
	dbus_message_unref(message);
}
Beispiel #2
0
static int read_command_complete(int fd, unsigned short opcode)
{
	struct cmd_complete resp;
	int err;

	DBG("");

	err = read_hci_event(fd, (unsigned char *)&resp, sizeof(resp));
	if (err < 0)
		return err;

	DBG("HCI event %d bytes", err);

	if (resp.uart_prefix != HCI_EVENT_PKT) {
		connman_error("Not an event packet");
		return -EIO;
	}

	if (resp.evt != EVT_CMD_COMPLETE) {
	        connman_error("Not a cmd complete event");
		return -EIO;
	}

	if (resp.plen < 4) {
		connman_error("HCI header length %d", resp.plen);
		return -EIO;
	}

	if (resp.opcode != (unsigned short) opcode) {
		connman_error("opcode 0x%04x 0x%04x", resp.opcode, opcode);
		return -EIO;
	}

	return 0;
}
Beispiel #3
0
static void pan_create(GDBusProxy *network_proxy)
{
	const char *path = g_dbus_proxy_get_path(network_proxy);
	struct bluetooth_pan *pan;

	pan = g_try_new0(struct bluetooth_pan, 1);

	if (!pan) {
		connman_error("Out of memory creating PAN NAP");
		return;
	}

	g_hash_table_replace(networks, g_strdup(path), pan);

	pan->btnetwork_proxy = g_dbus_proxy_ref(network_proxy);
	pan->btdevice_proxy = g_dbus_proxy_new(client, path,
			"org.bluez.Device1");

	if (!pan->btdevice_proxy) {
		connman_error("Cannot create BT PAN watcher %s", path);
		g_hash_table_remove(networks, path);
		return;
	}

	g_dbus_proxy_set_property_watch(pan->btnetwork_proxy,
			btnetwork_property_change, NULL);

	g_dbus_proxy_set_property_watch(pan->btdevice_proxy,
			btdevice_property_change, NULL);

	DBG("pan %p %s role %s", pan, path, proxy_get_role(pan->btdevice_proxy));

	pan_create_nap(pan);
}
Beispiel #4
0
static int nmcompat_init(void)
{
	DBG("");

	connection = connman_dbus_get_connection();
	if (connection == NULL)
		return -1;

	if (g_dbus_request_name(connection, NM_SERVICE, NULL) == FALSE) {
		connman_error("nmcompat: failed register service\n");
		return -1;
	}

	if (connman_notifier_register(&notifier) < 0) {
		connman_error("nmcompat: failed to register notifier");
		return -1;
	}

	if (g_dbus_register_interface(connection, NM_PATH,
				DBUS_PROPERTIES_INTERFACE,
				methods, signals, NULL, NULL, NULL) == FALSE) {
		connman_error("nmcompat: failed to register "
						DBUS_PROPERTIES_INTERFACE);
		return -1;
	}

	return 0;
}
static void add_network(const char *path)
{
	DBusMessage *message;
	DBusPendingCall *call;

	DBG("path %s", path);

	message = dbus_message_new_method_call(BLUEZ_SERVICE, path,
				BLUEZ_DEVICE_INTERFACE, GET_PROPERTIES);
	if (!message)
		return;

	dbus_message_set_auto_start(message, FALSE);

	if (!dbus_connection_send_with_reply(connection, message,
						&call, TIMEOUT)) {
		connman_error("Failed to get network properties for %s", path);
		goto done;
	}

	if (!call) {
		connman_error("D-Bus connection not available");
		goto done;
	}

	dbus_pending_call_set_notify(call, network_properties_reply,
						g_strdup(path), g_free);

done:
	dbus_message_unref(message);
}
static int run_connect(struct vpn_provider *provider,
			struct connman_task *task, const char *if_name,
			vpn_provider_connect_cb_t cb, void *user_data)
{
	const char *vpnhost, *vpncookie, *servercert, *mtu;
	int fd, err = 0, len;

	vpnhost = vpn_provider_get_string(provider, "OpenConnect.VPNHost");
	if (vpnhost == NULL)
		vpnhost = vpn_provider_get_string(provider, "Host");
	vpncookie = vpn_provider_get_string(provider, "OpenConnect.Cookie");
	servercert = vpn_provider_get_string(provider,
			"OpenConnect.ServerCert");

	if (vpncookie == NULL || servercert == NULL) {
		err = -EINVAL;
		goto done;
	}

	task_append_config_data(provider, task);

	connman_task_add_argument(task, "--servercert", servercert);

	mtu = vpn_provider_get_string(provider, "VPN.MTU");

	if (mtu != NULL)
		connman_task_add_argument(task, "--mtu", (char *)mtu);

	connman_task_add_argument(task, "--syslog", NULL);
	connman_task_add_argument(task, "--cookie-on-stdin", NULL);

	connman_task_add_argument(task, "--script",
				  SCRIPTDIR "/openconnect-script");

	connman_task_add_argument(task, "--interface", if_name);

	connman_task_add_argument(task, (char *)vpnhost, NULL);

	err = connman_task_run(task, vpn_died, provider,
			       &fd, NULL, NULL);
	if (err < 0) {
		connman_error("openconnect failed to start");
		err = -EIO;
		goto done;
	}

	len = strlen(vpncookie);
	if (write(fd, vpncookie, len) != (ssize_t)len ||
			write(fd, "\n", 1) != 1) {
		connman_error("openconnect failed to take cookie on stdin");
		err = -EIO;
		goto done;
	}

done:
	if (cb != NULL)
		cb(provider, user_data, err);

	return err;
}
Beispiel #7
0
static int disconnect_network(struct supplicant_task *task)
{
	DBusMessage *message, *reply;
	DBusError error;

	_DBG_SUPPLICANT("task %p", task);

	message = dbus_message_new_method_call(SUPPLICANT_NAME, task->path,
				SUPPLICANT_INTF ".Interface", "disconnect");
	if (message == NULL)
		return -ENOMEM;

	dbus_message_set_auto_start(message, FALSE);

	dbus_error_init(&error);

	reply = dbus_connection_send_with_reply_and_block(connection,
							message, -1, &error);
	if (reply == NULL) {
		if (dbus_error_is_set(&error) == TRUE) {
			connman_error("%s", error.message);
			dbus_error_free(&error);
		} else
			connman_error("Failed to disconnect network");
		dbus_message_unref(message);
		return -EIO;
	}

	dbus_message_unref(message);

	dbus_message_unref(reply);

	return 0;
}
Beispiel #8
0
static int
mk3_init(void) {

	int err;

	DBG("");


	err = connman_network_driver_register(&network_driver);
	if(err < 0) {

		connman_error("Register network driver");
		return err;
	}

	err = connman_device_driver_register(&mk3_driver);
	if(err < 0) {

		connman_error("Register device driver");
		connman_network_driver_unregister(&network_driver);
		return err;
	}

	err = connman_technology_driver_register(&tech_driver);
	if(err < 0) {

		connman_error("Register technology driver");
		connman_network_driver_unregister(&network_driver);
		connman_device_driver_unregister(&mk3_driver);

		return err;
	}

	return 0;
}
Beispiel #9
0
static int mk3_enable(struct connman_device *device) {

	int err = 0;
	struct mk3_data *mk3 = NULL;

	DBG("device %p", device);

	g_return_val_if_fail(device, -ENODEV);

	mk3 = connman_device_get_data(device);
	if(!mk3) {

		connman_error("No device data available");
		return -ENODEV;
	}

	DBG("device %p data %p", device, mk3);

	err = connman_inet_ifup(mk3->index);
	if(err < 0) {

		connman_error("QMI device could not getting up with ifup");
		return err;
	}

	add_network(mk3);

	return 0;
}
Beispiel #10
0
static int mk3_disable(struct connman_device *device) {

	int err = 0;
	struct mk3_data *mk3 = NULL;

	DBG("device %p", device);

	g_return_val_if_fail(device, -ENODEV);

	mk3 = connman_device_get_data(device);
	if(!mk3) {

		connman_error("Could not get device data");
		return -ENODEV;
	}

	DBG("device %p data %p", device, mk3);
	err = connman_inet_ifdown(mk3->index);
	if(err < 0) {

		connman_error("QMI device could not getting down with ifdown");
		return err;
	}

	delete_network(mk3);

	return 0;
}
Beispiel #11
0
static void signal_handler(int signo)
{
	void *frames[64];
	char **symbols;
	size_t n_ptrs;
	unsigned int i;

	n_ptrs = backtrace(frames, G_N_ELEMENTS(frames));
	symbols = backtrace_symbols(frames, n_ptrs);
	if (symbols == NULL) {
		connman_error("No backtrace symbols");
		exit(1);
	}

	connman_error("Aborting (signal %d)", signo);
	connman_error("++++++++ backtrace ++++++++");

	for (i = 1; i < n_ptrs; i++)
		connman_error("[%d]: %s", i - 1, symbols[i]);

	connman_error("+++++++++++++++++++++++++++");

	g_free(symbols);
	exit(1);
}
static void connect_reply(DBusPendingCall *call, void *user_data)
{
	char *path = user_data;
	struct connman_network *network;
	DBusMessage *reply;
	DBusError error;
	const char *interface = NULL;
	int index;

	network = g_hash_table_lookup(bluetooth_networks, path);
	if (!network)
		return;

	DBG("network %p", network);

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply)) {
		connman_error("%s", error.message);
		dbus_error_free(&error);

		goto err;
	}

	if (!dbus_message_get_args(reply, &error, DBUS_TYPE_STRING,
					&interface, DBUS_TYPE_INVALID)) {
		if (dbus_error_is_set(&error)) {
			connman_error("%s", error.message);
			dbus_error_free(&error);
		} else
			connman_error("Wrong arguments for connect");
		goto err;
	}

	if (!interface)
		goto err;

	DBG("interface %s", interface);

	index = connman_inet_ifindex(interface);

	connman_network_set_index(network, index);

	connman_network_set_connected(network, true);

	dbus_message_unref(reply);

	dbus_pending_call_unref(call);

	return;
err:

	connman_network_set_connected(network, false);

	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}
Beispiel #13
0
static int setup_hostname(void)
{
	char name[HOST_NAME_MAX + 1];

	memset(system_hostname, 0, sizeof(system_hostname));

	if (gethostname(system_hostname, HOST_NAME_MAX) < 0) {
		connman_error("Failed to get current hostname");
		return -EIO;
	}

	if (strlen(system_hostname) > 0 &&
				strcmp(system_hostname, "(none)") != 0)
		connman_info("System hostname is %s", system_hostname);
	else
		create_hostname();

	memset(name, 0, sizeof(name));

	if (getdomainname(name, HOST_NAME_MAX) < 0) {
		connman_error("Failed to get current domainname");
		return -EIO;
	}

	if (strlen(name) > 0 && strcmp(name, "(none)") != 0)
		connman_info("System domainname is %s", name);

	return 0;
}
Beispiel #14
0
/**
* @brief Enable qmi device and add network if modem opened
*/
static int qmi_enable(struct connman_device *device)
{
	int err = 0;
	struct qmi_data *qmi = NULL;

	DBG("device %p", device);

	g_return_val_if_fail(device, -ENODEV);

	qmi = connman_device_get_data(device);
	if(!qmi) {

		connman_error("No device data available");
		return -ENODEV;
	}

	DBG("device %p data %p", device, qmi);

	/* Add new qmi network interface */
	err = connman_inet_ifup(qmi->index);
	if(err < 0) {

		connman_error("QMI device could not getting up with ifup");
		return err;
	}

	if(qmi->modem_opened == TRUE) {

		add_network(qmi);
	}

	return 0;
}
Beispiel #15
0
static int read_hci_event(int fd, unsigned char *buf, int size)
{
	int prefix_len, param_len;

	if (size <= 0)
		return -EINVAL;

	/* First 3 bytes are prefix, event and param length */
	prefix_len = read(fd, buf, 3);
	if (prefix_len < 0)
		return prefix_len;

	if (prefix_len < 3) {
		connman_error("Truncated HCI prefix %d bytes 0x%x",
						prefix_len, buf[0]);
		return -EIO;
	}

	DBG("type 0x%x event 0x%x param len %d", buf[0], buf[1], buf[2]);

	param_len = buf[2];
	if (param_len > size - 3) {
		connman_error("Buffer is too small %d", size);
		return -EINVAL;
	}

	return read(fd, buf + 3, param_len);
}
Beispiel #16
0
/**
* @brief Disable qmi device and delete the associated network
*/
static int qmi_disable(struct connman_device *device)
{
	int err = 0;
	struct qmi_data *qmi = NULL;

	DBG("device %p", device);

	g_return_val_if_fail(device, -ENODEV);

	qmi = connman_device_get_data(device);
	if(!qmi) {

		connman_error("Could not get device data");
		return -ENODEV;
	}

	DBG("device %p data %p", device, qmi);
	/* Remove qmi network interface */
	err = connman_inet_ifdown(qmi->index);
	if(err < 0) {

		connman_error("QMI device could not getting down with ifdown");
		return err;
	}

	/* Delete associated qmi network */
	delete_network(qmi);

	return 0;
}
Beispiel #17
0
/**
 * connman_network_set_address:
 * @network: network structure
 * @address: binary address value
 * @size: binary address length
 *
 * Set unique address value for network
 */
int connman_network_set_address(struct connman_network *network,
				const void *address, unsigned int size)
{
	const unsigned char *addr_octet = address;
	char *str;

	_DBG_NETWORK("network %p size %d", network, size);

	if (size != 6) {
		connman_error("%s: bad size %d", __func__, size);
		return -EINVAL;
	}

	str = g_strdup_printf("%02X:%02X:%02X:%02X:%02X:%02X",
				addr_octet[0], addr_octet[1], addr_octet[2],
				addr_octet[3], addr_octet[4], addr_octet[5]);
	if (str == NULL) {
		connman_error("%s: no memory", __func__);
		return -ENOMEM;
	}

	g_free(network->address);
	network->address = str;

	return connman_element_set_string(&network->element,
						"Address", network->address);
}
Beispiel #18
0
static int oc_connect(struct vpn_provider *provider,
			struct connman_task *task, const char *if_name)
{
	const char *vpnhost, *vpncookie, *cafile, *certsha1, *mtu;
	int fd, err;

	vpnhost = vpn_provider_get_string(provider, "Host");
	if (!vpnhost) {
		connman_error("Host not set; cannot enable VPN");
		return -EINVAL;
	}

	vpncookie = vpn_provider_get_string(provider, "OpenConnect.Cookie");
	if (!vpncookie) {
		connman_error("OpenConnect.Cookie not set; cannot enable VPN");
		return -EINVAL;
	}

	certsha1 = vpn_provider_get_string(provider,
						"OpenConnect.ServerCert");
	if (certsha1)
		connman_task_add_argument(task, "--servercert",
							(char *)certsha1);

	cafile = vpn_provider_get_string(provider, "OpenConnect.CACert");
	mtu = vpn_provider_get_string(provider, "VPN.MTU");

	if (cafile)
		connman_task_add_argument(task, "--cafile",
							(char *)cafile);
	if (mtu)
		connman_task_add_argument(task, "--mtu", (char *)mtu);

	connman_task_add_argument(task, "--syslog", NULL);
	connman_task_add_argument(task, "--cookie-on-stdin", NULL);

	connman_task_add_argument(task, "--script",
				  SCRIPTDIR "/openconnect-script");

	connman_task_add_argument(task, "--interface", if_name);

	connman_task_add_argument(task, (char *)vpnhost, NULL);

	err = connman_task_run(task, vpn_died, provider,
			       &fd, NULL, NULL);
	if (err < 0) {
		connman_error("openconnect failed to start");
		return -EIO;
	}

	if (write(fd, vpncookie, strlen(vpncookie)) !=
			(ssize_t)strlen(vpncookie) ||
			write(fd, "\n", 1) != 1) {
		connman_error("openconnect failed to take cookie on stdin");
		return -EIO;
	}

	return 0;
}
Beispiel #19
0
/**
* @brief Create a new qmi device, set default values and insert it in the hash table.
*/
static int qmi_probe(struct connman_device *device)
{
	struct qmi_data *qmi;

	DBG("device %p", device);

	g_return_val_if_fail(device, -ENODEV);

	qmi = g_try_new0(struct qmi_data, 1);
	if(qmi == NULL) {

		connman_error("Allocation error, no memory available.");
		return -ENOMEM;
	}

	DBG("device %p data %p", device, qmi);

	connman_device_set_data(device, qmi);

	qmi->device = connman_device_ref(device);
	qmi->network = NULL;
	qmi->qmi_proxy_device = NULL;
	qmi->modem_opening = FALSE;
	qmi->modem_connected = FALSE;
	qmi->modem_opened = FALSE;

	qmi->imsi = NULL;
	qmi->apn = NULL;
	/* Group has to be "IMSI_qmi" */
	qmi->group = NULL;

	qmi->strength = 0;
	/* Name of the provider e.g "o2" */
	qmi->provider = NULL;
	/* Name of the specific QMI-Device e.g. wwan0 */
	qmi->devname = g_strdup(connman_device_get_string(device, "Interface"));
	/* Index of the specific QMI-Device */
	qmi->index = connman_device_get_index(device);

	qmi->devpath = get_device_path_from_name(qmi->devname);
	qmi->object_path = NULL;
	qmi->qmi_proxy_device = NULL;
	DBG("device name %s path %s", qmi->devname, qmi->devpath);
	if(qmi->devpath == NULL) {

		connman_error("No device path available");
		return -ENODEV;
	}

	connman_device_set_string(device, "Path", qmi->devpath);

	g_hash_table_insert(qmi_hash, qmi->devpath, qmi);

	/* Signal to init thread a new connected modem is available. */
	sem_post(&new_device_sem);

	return 0;
}
Beispiel #20
0
static int l2tp_connect(struct connman_provider *provider,
		struct connman_task *task, const char *if_name)
{
	const char *host;
	char *l2tp_name, *pppd_name;
	int l2tp_fd, pppd_fd;
	int err;

	if (connman_task_set_notify(task, "getsec",
					l2tp_get_sec, provider))
		return -ENOMEM;

	host = connman_provider_get_string(provider, "Host");
	if (host == NULL) {
		connman_error("Host not set; cannot enable VPN");
		return -EINVAL;
	}

	l2tp_name = g_strdup_printf("/var/run/connman/connman-xl2tpd.conf");

	l2tp_fd = open(l2tp_name, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
	if (l2tp_fd < 0) {
		g_free(l2tp_name);
		connman_error("Error writing l2tp config");
		return -EIO;
	}

	pppd_name = g_strdup_printf("/var/run/connman/connman-ppp-option.conf");

	pppd_fd = open(pppd_name, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
	if (pppd_fd < 0) {
		connman_error("Error writing pppd config");
		g_free(l2tp_name);
		g_free(pppd_name);
		close(l2tp_fd);
		return -EIO;
	}

	l2tp_write_config(provider, pppd_name, l2tp_fd);

	write_pppd_option(provider, pppd_fd);

	connman_task_add_argument(task, "-D", NULL);
	connman_task_add_argument(task, "-c", l2tp_name);

	g_free(l2tp_name);
	g_free(pppd_name);

	err = connman_task_run(task, l2tp_died, provider,
				NULL, NULL, NULL);
	if (err < 0) {
		connman_error("l2tp failed to start");
		return -EIO;
	}

	return 0;
}
Beispiel #21
0
/**
* @brief Callback getting available properties (IMSI, IMEI, ...) from qmi-dbus and
* finally add connman network
*/
static void
open_modem_get_properties_callback(DBusMessage *message, void *user_data) {

	DBusMessageIter iter;
	struct qmi_data *qmi = (struct qmi_data *)user_data;

	DBG("QMI data %p D-Bus message %p", qmi, message);

	if(dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR) {

		const char *dbus_error = dbus_message_get_error_name(message);
		qmi->modem_opening = FALSE;
		connman_error("%s", dbus_error);
		return;

	}

	if(dbus_message_iter_init(message, &iter) == FALSE) {

		connman_error("Failure init ITER");
		qmi->modem_opening = FALSE;
		return;
	}

	if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_INVALID) {

		connman_error("Invalid D-Bus type");
		qmi->modem_opening = FALSE;
		return;
	}

	/* Set new D-Bus reply properties */
	if(set_reply_to_qmi_data(&iter, qmi) == FALSE) {

		connman_error("Failure parse D-Bus message");

		return;
	}


	DBG("Modem opened %d", qmi->modem_opened);

	DBG("IMSI %s", qmi->imsi);

	/* Set a new connman network group of the newly replied IMSI */
	if(qmi->group)
		g_free(qmi->group);
	qmi->group = g_strdup_printf("%s_none", qmi->imsi);

	/* Modem was opened successfully, add the new device to connman */
	qmi->modem_opened = TRUE;
	qmi->modem_opening = FALSE;

	add_network(qmi);

}
Beispiel #22
0
static void send_packet(int fd, const char *server)
{
	struct ntp_msg msg;
	struct sockaddr_in addr;
	struct timeval transmit_timeval;
	ssize_t len;

	/*
	 * At some point, we could specify the actual system precision with:
	 *
	 *   clock_getres(CLOCK_REALTIME, &ts);
	 *   msg.precision = (int)log2(ts.tv_sec + (ts.tv_nsec * 1.0e-9));
	 */
	memset(&msg, 0, sizeof(msg));
	msg.flags = NTP_FLAGS_ENCODE(NTP_FLAG_LI_NOTINSYNC, NTP_FLAG_VN_VER4,
	    NTP_FLAG_MD_CLIENT);
	msg.poll = 4;	// min
	msg.poll = 10;	// max
	msg.precision = NTP_PRECISION_S;

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(123);
	addr.sin_addr.s_addr = inet_addr(server);

	gettimeofday(&transmit_timeval, NULL);
	clock_gettime(CLOCK_MONOTONIC, &mtx_time);

	msg.xmttime.seconds = htonl(transmit_timeval.tv_sec + OFFSET_1900_1970);
	msg.xmttime.fraction = htonl(transmit_timeval.tv_usec * 1000);

	len = sendto(fd, &msg, sizeof(msg), MSG_DONTWAIT,
						&addr, sizeof(addr));
	if (len < 0) {
		connman_error("Time request for server %s failed (%d/%s)",
			server, errno, strerror(errno));

		if (errno == ENETUNREACH)
			__connman_timeserver_sync_next();

		return;
	}

	if (len != sizeof(msg)) {
		connman_error("Broken time request for server %s", server);
		return;
	}

	/*
	 * Add a retry timeout of two seconds to retry the existing
	 * request. After a set number of retries, we'll fallback to
	 * trying another server.
	 */

	timeout_id = g_timeout_add_seconds(NTP_SEND_TIMEOUT, send_timeout, NULL);
}
Beispiel #23
0
static void connect_reply(DBusPendingCall *call, void *user_data)
{
	struct connman_network *network = user_data;
	DBusMessage *reply;
	DBusError error;
	const char *interface = NULL;
	int index;

	DBG("network %p", network);

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply) == TRUE) {
		connman_error("%s", error.message);
		dbus_error_free(&error);

		goto err;
	}

	if (dbus_message_get_args(reply, &error,
					DBUS_TYPE_STRING, &interface,
						DBUS_TYPE_INVALID) == FALSE) {
		if (dbus_error_is_set(&error) == TRUE) {
			connman_error("%s", error.message);
			dbus_error_free(&error);
		} else
			connman_error("Wrong arguments for connect");
		goto err;
	}

	if (interface == NULL)
		goto err;

	DBG("interface %s", interface);

	index = connman_inet_ifindex(interface);

	connman_network_set_index(network, index);

	connman_network_set_connected(network, TRUE);

	dbus_message_unref(reply);

	dbus_pending_call_unref(call);

	return;
err:

	connman_network_set_connected(network, FALSE);

	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}
Beispiel #24
0
static int add_network(struct supplicant_task *task)
{
	DBusMessage *message, *reply;
	DBusError error;
	const char *path;

	_DBG_SUPPLICANT("task %p", task);

	if (task->netpath != NULL)
		return -EALREADY;

	message = dbus_message_new_method_call(SUPPLICANT_NAME, task->path,
				SUPPLICANT_INTF ".Interface", "addNetwork");
	if (message == NULL)
		return -ENOMEM;

	dbus_message_set_auto_start(message, FALSE);

	dbus_error_init(&error);

	reply = dbus_connection_send_with_reply_and_block(connection,
							message, -1, &error);
	if (reply == NULL) {
		if (dbus_error_is_set(&error) == TRUE) {
			connman_error("%s", error.message);
			dbus_error_free(&error);
		} else
			connman_error("Failed to add network");
		dbus_message_unref(message);
		return -EIO;
	}

	dbus_message_unref(message);

	dbus_error_init(&error);

	if (dbus_message_get_args(reply, &error, DBUS_TYPE_OBJECT_PATH, &path,
						DBUS_TYPE_INVALID) == FALSE) {
		if (dbus_error_is_set(&error) == TRUE) {
			connman_error("%s", error.message);
			dbus_error_free(&error);
		} else
			connman_error("Wrong arguments for network");
		dbus_message_unref(reply);
		return -EIO;
	}

	_DBG_SUPPLICANT("path %s", path);

	task->netpath = g_strdup(path);

	dbus_message_unref(reply);

	return 0;
}
Beispiel #25
0
static int stats_file_remap(struct stats_file *file, size_t size)
{
	size_t page_size, new_size;
	void *addr;
	int err;

	DBG("file %p size %zu addr %p len %zu", file, size, file->addr,
		file->len);

	page_size = sysconf(_SC_PAGESIZE);
	new_size = (size + page_size - 1) & ~(page_size - 1);

	err = ftruncate(file->fd, new_size);
	if (err < 0) {
		connman_error("ftrunctate error %s for %s",
				strerror(errno), file->name);
		return -errno;
	}

	if (!file->addr) {
		/*
		 * Though the buffer is not shared between processes, we still
		 * have to take MAP_SHARED because MAP_PRIVATE does not
		 * guarantee that writes will hit the file without an explicit
		 * call to munmap or msync. For more details please read the
		 * mmap man pages.
		 */
		addr = mmap(NULL, new_size, PROT_READ | PROT_WRITE,
				MAP_SHARED, file->fd, 0);
	} else {
		addr = mremap(file->addr, file->len, new_size, MREMAP_MAYMOVE);
	}

	if (addr == MAP_FAILED) {
		connman_error("mmap error %s for %s",
				strerror(errno), file->name);
		if (errno == EINVAL) {
			connman_error("%s might be on a file system, such as "
					"JFFS2, that does not allow shared "
					"writable mappings.", file->name);
		}
		return -errno;
	}

	file->addr = addr;
	file->len = new_size;

	if (get_hdr(file)->magic == MAGIC32)
		stats_file_update_cache32(file);
	else
		stats_file_update_cache(file);

	return 0;
}
Beispiel #26
0
static int vc_connect(struct vpn_provider *provider,
			struct connman_task *task, const char *if_name,
			vpn_provider_connect_cb_t cb, const char *dbus_sender,
			void *user_data)
{
	const char *option;
	int err = 0, fd;

	option = vpn_provider_get_string(provider, "Host");
	if (!option) {
		connman_error("Host not set; cannot enable VPN");
		err = -EINVAL;
		goto done;
	}
	option = vpn_provider_get_string(provider, "VPNC.IPSec.ID");
	if (!option) {
		connman_error("Group not set; cannot enable VPN");
		err = -EINVAL;
		goto done;
	}

	connman_task_add_argument(task, "--non-inter", NULL);
	connman_task_add_argument(task, "--no-detach", NULL);

	connman_task_add_argument(task, "--ifname", if_name);
	connman_task_add_argument(task, "--ifmode", "tun");

	connman_task_add_argument(task, "--script",
				SCRIPTDIR "/openconnect-script");

	option = vpn_provider_get_string(provider, "VPNC.Debug");
	if (option)
		connman_task_add_argument(task, "--debug", option);

	connman_task_add_argument(task, "-", NULL);

	err = connman_task_run(task, vpn_died, provider,
				&fd, NULL, NULL);
	if (err < 0) {
		connman_error("vpnc failed to start");
		err = -EIO;
		goto done;
	}

	err = vc_write_config_data(provider, fd);

	close(fd);

done:
	if (cb)
		cb(provider, user_data, err);

	return err;
}
Beispiel #27
0
static int stop_vpn(struct connman_provider *provider)
{
    struct vpn_data *data = connman_provider_get_data(provider);
    struct vpn_driver_data *vpn_driver_data;
    const char *name;
    struct ifreq ifr;
    int fd, err;

    if (data == NULL)
        return -EINVAL;

    name = connman_provider_get_driver_name(provider);
    if (name == NULL)
        return -EINVAL;

    vpn_driver_data = g_hash_table_lookup(driver_hash, name);

    if (vpn_driver_data != NULL && vpn_driver_data->vpn_driver != NULL &&
            vpn_driver_data->vpn_driver->flags == VPN_FLAG_NO_TUN)
        return 0;

    memset(&ifr, 0, sizeof(ifr));
    ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
    sprintf(ifr.ifr_name, "%s", data->if_name);

    fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
    if (fd < 0) {
        err = -errno;
        connman_error("Failed to open /dev/net/tun to device %s: %s",
                      data->if_name, strerror(errno));
        return err;
    }

    if (ioctl(fd, TUNSETIFF, (void *)&ifr)) {
        err = -errno;
        connman_error("Failed to TUNSETIFF for device %s to it: %s",
                      data->if_name, strerror(errno));
        close(fd);
        return err;
    }

    if (ioctl(fd, TUNSETPERSIST, 0)) {
        err = -errno;
        connman_error("Failed to set tun device %s nonpersistent: %s",
                      data->if_name, strerror(errno));
        close(fd);
        return err;
    }
    close(fd);
    DBG("Killed tun device %s", data->if_name);
    return 0;
}
Beispiel #28
0
static int add_interface(struct supplicant_task *task)
{
	const char *driver = connman_option_get_string("wifi");
	DBusMessage *message;
	DBusMessageIter array, dict;
	DBusPendingCall *call;

	_DBG_SUPPLICANT("task %p", task);

	message = dbus_message_new_method_call(SUPPLICANT_NAME, SUPPLICANT_PATH,
					SUPPLICANT_INTF, "addInterface");
	if (message == NULL)
		return -ENOMEM;

	dbus_message_set_auto_start(message, FALSE);

	dbus_message_iter_init_append(message, &array);

	dbus_message_iter_append_basic(&array,
					DBUS_TYPE_STRING, &task->ifname);

	dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);

	connman_dbus_dict_append_variant(&dict, "driver",
						DBUS_TYPE_STRING, &driver);

	dbus_message_iter_close_container(&array, &dict);

	if (dbus_connection_send_with_reply(connection, message,
						&call, TIMEOUT) == FALSE) {
		connman_error("Failed to add interface");
		dbus_message_unref(message);
		return -EIO;
	}

	if (call == NULL) {
		connman_error("D-Bus connection not available");
		dbus_message_unref(message);
		return -EIO;
	}

	dbus_pending_call_set_notify(call, add_interface_reply, task, NULL);

	dbus_message_unref(message);

	return -EINPROGRESS;
}
Beispiel #29
0
static void dhcp_server_error(GDHCPServerError error)
{
	switch (error) {
	case G_DHCP_SERVER_ERROR_NONE:
		connman_error("OK");
		break;
	case G_DHCP_SERVER_ERROR_INTERFACE_UNAVAILABLE:
		connman_error("Interface unavailable");
		break;
	case G_DHCP_SERVER_ERROR_INTERFACE_IN_USE:
		connman_error("Interface in use");
		break;
	case G_DHCP_SERVER_ERROR_INTERFACE_DOWN:
		connman_error("Interface down");
		break;
	case G_DHCP_SERVER_ERROR_NOMEM:
		connman_error("No memory");
		break;
	case G_DHCP_SERVER_ERROR_INVALID_INDEX:
		connman_error("Invalid index");
		break;
	case G_DHCP_SERVER_ERROR_INVALID_OPTION:
		connman_error("Invalid option");
		break;
	case G_DHCP_SERVER_ERROR_IP_ADDRESS_INVALID:
		connman_error("Invalid address");
		break;
	}
}
Beispiel #30
0
static void get_properties(struct supplicant_task *task)
{
	DBusMessage *message;
	char *path;

	path = g_slist_nth_data(task->scan_results, 0);
	if (path == NULL)
		goto noscan;

	message = dbus_message_new_method_call(SUPPLICANT_NAME, path,
						SUPPLICANT_INTF ".BSSID",
								"properties");

	task->scan_results = g_slist_remove(task->scan_results, path);
	g_free(path);

	if (message == NULL)
		goto noscan;

	dbus_message_set_auto_start(message, FALSE);

	if (dbus_connection_send_with_reply(connection, message,
				&task->result_call, TIMEOUT) == FALSE) {
		connman_error("Failed to get network properties");
		dbus_message_unref(message);
		goto noscan;
	}

	if (task->result_call == NULL) {
		connman_error("D-Bus connection not available");
		dbus_message_unref(message);
		goto noscan;
	}

	dbus_pending_call_set_notify(task->result_call,
					properties_reply, task, NULL);

	dbus_message_unref(message);

	return;

noscan:
	task->result_call = NULL;

	if (task->scanning == TRUE) {
		connman_device_set_scanning(task->device, FALSE);
		task->scanning = FALSE;
	}
}