get-active-connections-dbus-glib.c 7.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
17
 * (C) Copyright 2010 -2014 Red Hat, Inc.
18 19 20 21 22
 */

/*
 * The example shows how to call the D-Bus properties interface to get the
 * list of currently active connections known to NetworkManager.  It uses
Dan Winship's avatar
Dan Winship committed
23
 * dbus-glib and libnm libraries.
24 25
 *
 * Compile with:
Dan Winship's avatar
Dan Winship committed
26
 *   gcc -Wall `pkg-config --libs --cflags glib-2.0 dbus-glib-1 libnm` get-active-connections-dbus-glib.c -o get-active-connections-dbus-glib
27 28
 */

29
#include <stdio.h>
30 31 32
#include <glib.h>
#include <dbus/dbus-glib.h>

33
#include <NetworkManager.h>
34 35 36 37 38 39

#define DBUS_TYPE_G_MAP_OF_VARIANT          (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
#define DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT   (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT))
#define DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH    (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH))

static void
40
print_connection (DBusGConnection *bus, const char *path)
41 42 43 44 45 46
{
	DBusGProxy *proxy;
	GError *error = NULL;
	GHashTable *hash = NULL;
	NMConnection *connection = NULL;

47
	/* This function asks NetworkManager for the details of the connection */
Dan Williams's avatar
Dan Williams committed
48

49
	/* Create the D-Bus proxy so we can ask it for the connection configuration details. */
50
	proxy = dbus_g_proxy_new_for_name (bus,
51
	                                   NM_DBUS_SERVICE,
52
	                                   path,
53
	                                   NM_DBUS_INTERFACE_SETTINGS_CONNECTION);
54 55
	g_assert (proxy);

Dan Williams's avatar
Dan Williams committed
56
	/* Request the all the configuration of the Connection */
57 58 59 60 61 62 63 64 65 66
	if (!dbus_g_proxy_call (proxy, "GetSettings", &error,
	                        G_TYPE_INVALID,
	                        DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &hash,
	                        G_TYPE_INVALID)) {
		g_warning ("Failed to get active connection Connection property: %s",
		           error->message);
		g_error_free (error);
		goto out;
	}

67 68
	/* Using the raw configuration, create an NMConnection object for it. This
	 * step also verifies that the data we got from NetworkManager are valid. */
69 70 71 72 73 74 75
	connection = nm_connection_new_from_hash (hash, &error);
	if (!connection) {
		g_warning ("Received invalid connection data: %s", error->message);
		g_error_free (error);
		goto out;
	}

Dan Williams's avatar
Dan Williams committed
76
	/* And finally dump all the configuration to stdout */
77
	printf ("%s <=> %s\n", nm_connection_get_id (connection), path);
78 79 80 81 82 83 84 85 86 87 88 89 90 91
	nm_connection_dump (connection);

out:
	if (connection)
		g_object_unref (connection);
	if (hash)
		g_hash_table_destroy (hash);
	g_object_unref (proxy);
}

static void
get_active_connection_details (DBusGConnection *bus, const char *obj_path)
{
	DBusGProxy *props_proxy;
92
	GValue path_value = G_VALUE_INIT;
93
	GError *error = NULL;
94
	const char *path = NULL;
95

Dan Williams's avatar
Dan Williams committed
96 97 98 99 100 101 102
	/* This function gets the backing Connection object that describes the
	 * network configuration that the ActiveConnection object is actually using.
	 * The ActiveConnection object contains the mapping between the configuration
	 * and the actual network interfaces that are using that configuration.
	 */

	/* Create a D-Bus object proxy for the active connection object's properties */
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
	props_proxy = dbus_g_proxy_new_for_name (bus,
	                                         NM_DBUS_SERVICE,
	                                         obj_path,
	                                         DBUS_INTERFACE_PROPERTIES);
	g_assert (props_proxy);
	
	/* Get the object path of the Connection details */
	if (!dbus_g_proxy_call (props_proxy, "Get", &error,
	                        G_TYPE_STRING, NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
	                        G_TYPE_STRING, "Connection",
	                        G_TYPE_INVALID,
	                        G_TYPE_VALUE, &path_value,
	                        G_TYPE_INVALID)) {
		g_warning ("Failed to get active connection Connection property: %s",
		           error->message);
		g_error_free (error);
		goto out;
	}

	if (!G_VALUE_HOLDS (&path_value, DBUS_TYPE_G_OBJECT_PATH)) {
		g_warning ("Unexpected type returned getting Connection property: %s",
		           G_VALUE_TYPE_NAME (&path_value));
		goto out;
	}

	path = g_value_get_boxed (&path_value);
	if (!path) {
		g_warning ("Missing connection path!");
		goto out;
	}

Dan Williams's avatar
Dan Williams committed
134
	/* Print out the actual connection details */
135
	print_connection (bus, path);
136 137 138 139 140 141 142 143 144 145

out:
	g_value_unset (&path_value);
	g_object_unref (props_proxy);
}

static void
get_active_connections (DBusGConnection *bus, DBusGProxy *proxy)
{
	GError *error = NULL;
146
	GValue value = G_VALUE_INIT;
147
	GPtrArray *paths = NULL;
148
	const char *a_path;
149 150
	int i;

Dan Williams's avatar
Dan Williams committed
151
	/* Get the ActiveConnections property from the NM Manager object */
152 153 154 155 156 157 158 159 160 161 162
	if (!dbus_g_proxy_call (proxy, "Get", &error,
	                        G_TYPE_STRING, NM_DBUS_INTERFACE,
	                        G_TYPE_STRING, "ActiveConnections",
	                        G_TYPE_INVALID,
	                        G_TYPE_VALUE, &value,
	                        G_TYPE_INVALID)) {
		g_warning ("Failed to get ActiveConnections property: %s", error->message);
		g_error_free (error);
		return;
	}

Dan Williams's avatar
Dan Williams committed
163
	/* Make sure the ActiveConnections property is the type we expect it to be */
164 165 166 167 168 169
	if (!G_VALUE_HOLDS (&value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH)) {
		g_warning ("Unexpected type returned getting ActiveConnections: %s",
		           G_VALUE_TYPE_NAME (&value));
		goto out;
	}

Dan Williams's avatar
Dan Williams committed
170
	/* Extract the active connections array from the GValue */
171 172 173 174 175 176
	paths = g_value_get_boxed (&value);
	if (!paths) {
		g_warning ("Could not retrieve active connections property");
		goto out;
	}

177 178 179 180 181 182
	/* And print out the details for each active connection */
	for (i = 0; i < paths->len; i++) {
		a_path = g_ptr_array_index (paths, i);
		printf ("Active connection path: %s\n", a_path);
		get_active_connection_details (bus, a_path);
	}
183 184 185 186 187 188 189 190 191 192 193

out:
	g_value_unset (&value);
}


int main (int argc, char *argv[])
{
	DBusGConnection *bus;
	DBusGProxy *props_proxy;

194
#if !GLIB_CHECK_VERSION (2, 35, 0)
195 196
	/* Initialize GType system */
	g_type_init ();
197
#endif
198 199 200 201

	/* Get system bus */
	bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);

Dan Williams's avatar
Dan Williams committed
202
	/* Create a D-Bus proxy to get the object properties from the NM Manager
203
	 * object.  NM_DBUS_* defines are from nm-dbus-interface.h.
Dan Williams's avatar
Dan Williams committed
204
	 */
205 206 207 208 209 210
	props_proxy = dbus_g_proxy_new_for_name (bus,
	                                         NM_DBUS_SERVICE,
	                                         NM_DBUS_PATH,
	                                         DBUS_INTERFACE_PROPERTIES);
	g_assert (props_proxy);

Jiří Klimeš's avatar
Jiří Klimeš committed
211
	/* Get active connections */
212 213 214 215 216 217 218
	get_active_connections (bus, props_proxy);

	g_object_unref (props_proxy);
	dbus_g_connection_unref (bus);

	return 0;
}