NetworkManager/test/nm-tool.c
Dan Williams 2140dad5e0 core: consolidate mobile broadband device types
These days more and more devices are showing up that support a
number of different access technology families in the same hardware,
like Qualcomm Gobi (CDMA and GSM), Pantech UM190 (CDMA and GSM),
Pantech UML290 (CDMA and LTE), LG VL600 (CDMA and LTE), Sierra
320U (GSM and LTE), etc.  The previous scheme of having device
classes based on access technology family simply cannot handle
this hardware and attempting to add LTE to both the CDMA and GSM
device classes would result in a bunch of code duplication that
we don't want.  There's a better way...

Instead, combine both CDMA and GSM device classes into a generic
"Modem" device class that provides capabilities indicating what
access technology families a modem supports, and what families
it supports immediately without a firmware reload.  (Gobi devices
for example require a firmware reload before they can switch
between GSM and CDMA).  This provides the necessary flexibility
to the client and allows us to keep the API stable when the
same consolidation change is made in ModemManager.

The current code doesn't yet allow multi-mode operation internally,
but the API is now what we want it to be and won't need to be
changed.
2011-02-25 10:16:17 -06:00

818 lines
22 KiB
C

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* nm-tool - information tool for NetworkManager
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*
* (C) Copyright 2005 - 2011 Red Hat, Inc.
* (C) Copyright 2007 Novell, Inc.
*/
#include <config.h>
#include <glib.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <nm-client.h>
#include <nm-device.h>
#include <nm-device-ethernet.h>
#include <nm-device-wifi.h>
#include <nm-device-modem.h>
#include <nm-device-bt.h>
#if WITH_WIMAX
#include <nm-device-wimax.h>
#endif
#include <nm-utils.h>
#include <nm-setting-ip4-config.h>
#include <nm-setting-ip6-config.h>
#include <nm-vpn-connection.h>
#include <nm-setting-connection.h>
/* Don't use nm-dbus-glib-types.h so that we can keep nm-tool
* building standalone outside of the NM tree.
*/
#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 GHashTable *connections = NULL;
static gboolean
get_nm_state (NMClient *client)
{
NMState state;
char *state_string;
gboolean success = TRUE;
state = nm_client_get_state (client);
switch (state) {
case NM_STATE_ASLEEP:
state_string = "asleep";
break;
case NM_STATE_CONNECTING:
state_string = "connecting";
break;
case NM_STATE_CONNECTED_LOCAL:
state_string = "connected (local only)";
break;
case NM_STATE_CONNECTED_SITE:
state_string = "connected (site only)";
break;
case NM_STATE_CONNECTED_GLOBAL:
state_string = "connected (global)";
break;
case NM_STATE_DISCONNECTED:
state_string = "disconnected";
break;
case NM_STATE_UNKNOWN:
default:
state_string = "unknown";
success = FALSE;
break;
}
printf ("State: %s\n\n", state_string);
return success;
}
static void
print_header (const char *label, const char *iface, const char *connection)
{
GString *string;
string = g_string_sized_new (79);
g_string_append_printf (string, "- %s: ", label);
if (iface)
g_string_append_printf (string, "%s ", iface);
if (connection)
g_string_append_printf (string, " [%s] ", connection);
while (string->len < 80)
g_string_append_c (string, '-');
printf ("%s\n", string->str);
g_string_free (string, TRUE);
}
static void
print_string (const char *label, const char *data)
{
#define SPACING 18
int label_len = 0;
char spaces[50];
int i;
g_return_if_fail (label != NULL);
g_return_if_fail (data != NULL);
label_len = strlen (label);
if (label_len > SPACING)
label_len = SPACING - 1;
for (i = 0; i < (SPACING - label_len); i++)
spaces[i] = 0x20;
spaces[i] = 0x00;
printf (" %s:%s%s\n", label, &spaces[0], data);
}
static void
detail_access_point (gpointer data, gpointer user_data)
{
NMAccessPoint *ap = NM_ACCESS_POINT (data);
const char *active_bssid = (const char *) user_data;
GString *str;
gboolean active = FALSE;
guint32 flags, wpa_flags, rsn_flags;
const GByteArray * ssid;
char *tmp;
flags = nm_access_point_get_flags (ap);
wpa_flags = nm_access_point_get_wpa_flags (ap);
rsn_flags = nm_access_point_get_rsn_flags (ap);
if (active_bssid) {
const char *current_bssid = nm_access_point_get_hw_address (ap);
if (current_bssid && !strcmp (current_bssid, active_bssid))
active = TRUE;
}
str = g_string_new (NULL);
g_string_append_printf (str,
"%s, %s, Freq %d MHz, Rate %d Mb/s, Strength %d",
(nm_access_point_get_mode (ap) == NM_802_11_MODE_INFRA) ? "Infra" : "Ad-Hoc",
nm_access_point_get_hw_address (ap),
nm_access_point_get_frequency (ap),
nm_access_point_get_max_bitrate (ap) / 1000,
nm_access_point_get_strength (ap));
if ( !(flags & NM_802_11_AP_FLAGS_PRIVACY)
&& (wpa_flags != NM_802_11_AP_SEC_NONE)
&& (rsn_flags != NM_802_11_AP_SEC_NONE))
g_string_append (str, ", Encrypted: ");
if ( (flags & NM_802_11_AP_FLAGS_PRIVACY)
&& (wpa_flags == NM_802_11_AP_SEC_NONE)
&& (rsn_flags == NM_802_11_AP_SEC_NONE))
g_string_append (str, " WEP");
if (wpa_flags != NM_802_11_AP_SEC_NONE)
g_string_append (str, " WPA");
if (rsn_flags != NM_802_11_AP_SEC_NONE)
g_string_append (str, " WPA2");
if ( (wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
|| (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X))
g_string_append (str, " Enterprise");
/* FIXME: broadcast/hidden */
ssid = nm_access_point_get_ssid (ap);
tmp = g_strdup_printf (" %s%s", active ? "*" : "",
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)");
print_string (tmp, str->str);
g_string_free (str, TRUE);
g_free (tmp);
}
#if WITH_WIMAX
static const char *
wimax_network_type_to_str (NMWimaxNspNetworkType type)
{
switch (type) {
case NM_WIMAX_NSP_NETWORK_TYPE_HOME:
return "Home";
case NM_WIMAX_NSP_NETWORK_TYPE_PARTNER:
return "Partner";
case NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER:
return "Roaming";
default:
return "Unknown";
}
}
static void
detail_nsp (gpointer data, gpointer user_data)
{
NMWimaxNsp *nsp = NM_WIMAX_NSP (data);
const char *active_name = (const char *) user_data;
const char *name;
char *label;
char *data_str;
gboolean active = FALSE;
name = nm_wimax_nsp_get_name (nsp);
if (active_name)
active = g_strcmp0 (active_name, name) == 0;
label = g_strdup_printf (" %s%s", active ? "*" : "", name);
data_str = g_strdup_printf ("%d%% (%s)",
nm_wimax_nsp_get_signal_quality (nsp),
wimax_network_type_to_str (nm_wimax_nsp_get_network_type (nsp)));
print_string (label, data_str);
g_free (label);
g_free (data_str);
}
#endif
static gchar *
ip4_address_as_string (guint32 ip)
{
struct in_addr tmp_addr;
char buf[INET_ADDRSTRLEN+1];
memset (&buf, '\0', sizeof (buf));
tmp_addr.s_addr = ip;
if (inet_ntop (AF_INET, &tmp_addr, buf, INET_ADDRSTRLEN)) {
return g_strdup (buf);
} else {
g_warning ("%s: error converting IP4 address 0x%X",
__func__, ntohl (tmp_addr.s_addr));
return NULL;
}
}
static gchar *
ip6_address_as_string (const struct in6_addr *ip)
{
char buf[INET6_ADDRSTRLEN];
memset (&buf, '\0', sizeof (buf));
if (inet_ntop (AF_INET6, ip, buf, INET6_ADDRSTRLEN)) {
return g_strdup (buf);
} else {
int j;
GString *ip6_str = g_string_new (NULL);
g_string_append_printf (ip6_str, "%02X", ip->s6_addr[0]);
for (j = 1; j < 16; j++)
g_string_append_printf (ip6_str, " %02X", ip->s6_addr[j]);
g_warning ("%s: error converting IP6 address %s",
__func__, ip6_str->str);
g_string_free (ip6_str, TRUE);
return NULL;
}
}
static const char *
get_dev_state_string (NMDeviceState state)
{
if (state == NM_DEVICE_STATE_UNMANAGED)
return "unmanaged";
else if (state == NM_DEVICE_STATE_UNAVAILABLE)
return "unavailable";
else if (state == NM_DEVICE_STATE_DISCONNECTED)
return "disconnected";
else if (state == NM_DEVICE_STATE_PREPARE)
return "connecting (prepare)";
else if (state == NM_DEVICE_STATE_CONFIG)
return "connecting (configuring)";
else if (state == NM_DEVICE_STATE_NEED_AUTH)
return "connecting (need authentication)";
else if (state == NM_DEVICE_STATE_IP_CONFIG)
return "connecting (getting IP configuration)";
else if (state == NM_DEVICE_STATE_ACTIVATED)
return "connected";
else if (state == NM_DEVICE_STATE_FAILED)
return "connection failed";
return "unknown";
}
static NMConnection *
get_connection_for_active (NMActiveConnection *active)
{
const char *path;
g_return_val_if_fail (active != NULL, NULL);
path = nm_active_connection_get_connection (active);
g_return_val_if_fail (path != NULL, NULL);
return (NMConnection *) g_hash_table_lookup (connections, path);
}
struct cb_info {
NMClient *client;
const GPtrArray *active;
};
static void
detail_device (gpointer data, gpointer user_data)
{
NMDevice *device = NM_DEVICE (data);
struct cb_info *info = user_data;
char *tmp;
NMDeviceState state;
guint32 caps;
guint32 speed;
const GArray *array;
int j;
gboolean is_default = FALSE;
const char *id = NULL;
state = nm_device_get_state (device);
for (j = 0; info->active && (j < info->active->len); j++) {
NMActiveConnection *candidate = g_ptr_array_index (info->active, j);
const GPtrArray *devices = nm_active_connection_get_devices (candidate);
NMDevice *candidate_dev;
NMConnection *connection;
NMSettingConnection *s_con;
if (!devices || !devices->len)
continue;
candidate_dev = g_ptr_array_index (devices, 0);
if (candidate_dev == device) {
if (nm_active_connection_get_default (candidate))
is_default = TRUE;
connection = get_connection_for_active (candidate);
if (!connection)
break;
s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
if (s_con)
id = nm_setting_connection_get_id (s_con);
break;
}
}
print_header ("Device", nm_device_get_iface (device), id);
/* General information */
if (NM_IS_DEVICE_ETHERNET (device))
print_string ("Type", "Wired");
else if (NM_IS_DEVICE_WIFI (device))
print_string ("Type", "802.11 WiFi");
else if (NM_IS_DEVICE_MODEM (device)) {
NMDeviceModemCapabilities modem_caps;
modem_caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device));
if (modem_caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS)
print_string ("Type", "Mobile Broadband (GSM)");
else if (modem_caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)
print_string ("Type", "Mobile Broadband (CDMA)");
else
print_string ("Type", "Mobile Broadband (unknown)");
} else if (NM_IS_DEVICE_BT (device))
print_string ("Type", "Bluetooth");
#if WITH_WIMAX
else if (NM_IS_DEVICE_WIMAX (device))
print_string ("Type", "WiMAX");
#endif
print_string ("Driver", nm_device_get_driver (device) ? nm_device_get_driver (device) : "(unknown)");
print_string ("State", get_dev_state_string (state));
if (is_default)
print_string ("Default", "yes");
else
print_string ("Default", "no");
tmp = NULL;
if (NM_IS_DEVICE_ETHERNET (device))
tmp = g_strdup (nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (device)));
else if (NM_IS_DEVICE_WIFI (device))
tmp = g_strdup (nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (device)));
#if WITH_WIMAX
else if (NM_IS_DEVICE_WIMAX (device))
tmp = g_strdup (nm_device_wimax_get_hw_address (NM_DEVICE_WIMAX (device)));
#endif
if (tmp) {
print_string ("HW Address", tmp);
g_free (tmp);
}
/* Capabilities */
caps = nm_device_get_capabilities (device);
printf ("\n Capabilities:\n");
if (caps & NM_DEVICE_CAP_CARRIER_DETECT)
print_string (" Carrier Detect", "yes");
speed = 0;
if (NM_IS_DEVICE_ETHERNET (device)) {
/* Speed in Mb/s */
speed = nm_device_ethernet_get_speed (NM_DEVICE_ETHERNET (device));
} else if (NM_IS_DEVICE_WIFI (device)) {
/* Speed in b/s */
speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (device));
speed /= 1000;
}
if (speed) {
char *speed_string;
speed_string = g_strdup_printf ("%u Mb/s", speed);
print_string (" Speed", speed_string);
g_free (speed_string);
}
/* Wireless specific information */
if ((NM_IS_DEVICE_WIFI (device))) {
guint32 wcaps;
NMAccessPoint *active_ap = NULL;
const char *active_bssid = NULL;
const GPtrArray *aps;
printf ("\n Wireless Properties\n");
wcaps = nm_device_wifi_get_capabilities (NM_DEVICE_WIFI (device));
if (wcaps & (NM_WIFI_DEVICE_CAP_CIPHER_WEP40 | NM_WIFI_DEVICE_CAP_CIPHER_WEP104))
print_string (" WEP Encryption", "yes");
if (wcaps & NM_WIFI_DEVICE_CAP_WPA)
print_string (" WPA Encryption", "yes");
if (wcaps & NM_WIFI_DEVICE_CAP_RSN)
print_string (" WPA2 Encryption", "yes");
if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) {
active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (device));
active_bssid = active_ap ? nm_access_point_get_hw_address (active_ap) : NULL;
}
printf ("\n Wireless Access Points %s\n", active_ap ? "(* = current AP)" : "");
aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (device));
if (aps && aps->len)
g_ptr_array_foreach ((GPtrArray *) aps, detail_access_point, (gpointer) active_bssid);
} else if (NM_IS_DEVICE_ETHERNET (device)) {
printf ("\n Wired Properties\n");
if (nm_device_ethernet_get_carrier (NM_DEVICE_ETHERNET (device)))
print_string (" Carrier", "on");
else
print_string (" Carrier", "off");
#if WITH_WIMAX
} else if (NM_IS_DEVICE_WIMAX (device)) {
NMDeviceWimax *wimax = NM_DEVICE_WIMAX (device);
NMWimaxNsp *active_nsp = NULL;
const char *active_name = NULL;
const GPtrArray *nsps;
if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) {
guint tmp_uint;
gint tmp_int;
const char *tmp_str;
active_nsp = nm_device_wimax_get_active_nsp (wimax);
active_name = active_nsp ? nm_wimax_nsp_get_name (active_nsp) : NULL;
printf ("\n Link Status\n");
tmp_uint = nm_device_wimax_get_center_frequency (wimax);
if (tmp_uint)
tmp = g_strdup_printf ("%'.1f MHz", (double) tmp_uint / 1000.0);
else
tmp = g_strdup ("(unknown)");
print_string (" Center Freq.", tmp);
g_free (tmp);
tmp_int = nm_device_wimax_get_rssi (wimax);
if (tmp_int)
tmp = g_strdup_printf ("%d dBm", tmp_int);
else
tmp = g_strdup ("(unknown)");
print_string (" RSSI", tmp);
g_free (tmp);
tmp_int = nm_device_wimax_get_cinr (wimax);
if (tmp_int)
tmp = g_strdup_printf ("%d dB", tmp_int);
else
tmp = g_strdup ("(unknown)");
print_string (" CINR", tmp);
g_free (tmp);
tmp_int = nm_device_wimax_get_tx_power (wimax);
if (tmp_int)
tmp = g_strdup_printf ("%'.2f dBm", (float) tmp_int / 2.0);
else
tmp = g_strdup ("(unknown)");
print_string (" TX Power", tmp);
g_free (tmp);
tmp_str = nm_device_wimax_get_bsid (wimax);
if (tmp_str)
print_string (" BSID", tmp_str);
else
print_string (" BSID", "(unknown)");
}
printf ("\n WiMAX NSPs %s\n", active_nsp ? "(* current NSP)" : "");
nsps = nm_device_wimax_get_nsps (NM_DEVICE_WIMAX (device));
if (nsps && nsps->len)
g_ptr_array_foreach ((GPtrArray *) nsps, detail_nsp, (gpointer) active_name);
#endif
}
/* IP Setup info */
if (state == NM_DEVICE_STATE_ACTIVATED) {
NMIP4Config *cfg4 = nm_device_get_ip4_config (device);
NMIP6Config *cfg6 = nm_device_get_ip6_config (device);
GSList *iter;
if (cfg4) {
printf ("\n IPv4 Settings:\n");
for (iter = (GSList *) nm_ip4_config_get_addresses (cfg4); iter; iter = g_slist_next (iter)) {
NMIP4Address *addr = (NMIP4Address *) iter->data;
guint32 prefix = nm_ip4_address_get_prefix (addr);
char *tmp2;
tmp = ip4_address_as_string (nm_ip4_address_get_address (addr));
print_string (" Address", tmp);
g_free (tmp);
tmp2 = ip4_address_as_string (nm_utils_ip4_prefix_to_netmask (prefix));
tmp = g_strdup_printf ("%d (%s)", prefix, tmp2);
g_free (tmp2);
print_string (" Prefix", tmp);
g_free (tmp);
tmp = ip4_address_as_string (nm_ip4_address_get_gateway (addr));
print_string (" Gateway", tmp);
g_free (tmp);
printf ("\n");
}
array = nm_ip4_config_get_nameservers (cfg4);
if (array) {
int i;
for (i = 0; i < array->len; i++) {
tmp = ip4_address_as_string (g_array_index (array, guint32, i));
print_string (" DNS", tmp);
g_free (tmp);
}
}
}
if (cfg6) {
printf ("\n IPv6 Settings:\n");
for (iter = (GSList *) nm_ip6_config_get_addresses (cfg6); iter; iter = g_slist_next (iter)) {
NMIP6Address *addr = (NMIP6Address *) iter->data;
guint32 prefix = nm_ip6_address_get_prefix (addr);
tmp = ip6_address_as_string (nm_ip6_address_get_address (addr));
print_string (" Address", tmp);
g_free (tmp);
tmp = g_strdup_printf ("%d", prefix);
print_string (" Prefix", tmp);
g_free (tmp);
tmp = ip6_address_as_string (nm_ip6_address_get_gateway (addr));
print_string (" Gateway", tmp);
g_free (tmp);
printf ("\n");
}
for (iter = (GSList *) nm_ip6_config_get_nameservers (cfg6); iter; iter = g_slist_next (iter)) {
tmp = ip6_address_as_string (iter->data);
print_string (" DNS", tmp);
g_free (tmp);
}
}
}
printf ("\n\n");
}
static const char *
get_vpn_state_string (NMVPNConnectionState state)
{
switch (state) {
case NM_VPN_CONNECTION_STATE_PREPARE:
return "connecting (prepare)";
case NM_VPN_CONNECTION_STATE_NEED_AUTH:
return "connecting (need authentication)";
case NM_VPN_CONNECTION_STATE_CONNECT:
return "connecting";
case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET:
return "connecting (getting IP configuration)";
case NM_VPN_CONNECTION_STATE_ACTIVATED:
return "connected";
case NM_VPN_CONNECTION_STATE_FAILED:
return "connection failed";
case NM_VPN_CONNECTION_STATE_DISCONNECTED:
return "disconnected";
default:
break;
}
return "unknown";
}
static void
detail_vpn (gpointer data, gpointer user_data)
{
NMActiveConnection *active = NM_ACTIVE_CONNECTION (data);
NMConnection *connection;
NMSettingConnection *s_con;
NMVPNConnectionState state;
const char *banner;
if (!NM_IS_VPN_CONNECTION (active))
return;
connection = get_connection_for_active (active);
g_return_if_fail (connection != NULL);
s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
g_return_if_fail (s_con != NULL);
print_header ("VPN", NULL, nm_setting_connection_get_id (s_con));
state = nm_vpn_connection_get_vpn_state (NM_VPN_CONNECTION (active));
print_string ("State", get_vpn_state_string (state));
if (nm_active_connection_get_default (active))
print_string ("Default", "yes");
else
print_string ("Default", "no");
banner = nm_vpn_connection_get_banner (NM_VPN_CONNECTION (active));
if (banner) {
char **lines, **iter;
printf ("\n Message:\n");
lines = g_strsplit_set (banner, "\n\r", -1);
for (iter = lines; *iter; iter++) {
if (*iter && strlen (*iter))
printf (" %s\n", *iter);
}
g_strfreev (lines);
}
printf ("\n\n");
}
static void
get_one_connection (DBusGConnection *bus,
const char *path,
GHashTable *table)
{
DBusGProxy *proxy;
NMConnection *connection = NULL;
GError *error = NULL;
GHashTable *settings = NULL;
g_return_if_fail (bus != NULL);
g_return_if_fail (path != NULL);
g_return_if_fail (table != NULL);
proxy = dbus_g_proxy_new_for_name (bus, NM_DBUS_SERVICE,
path, NM_DBUS_IFACE_SETTINGS_CONNECTION);
if (!proxy)
return;
if (!dbus_g_proxy_call (proxy, "GetSettings", &error,
G_TYPE_INVALID,
DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &settings,
G_TYPE_INVALID)) {
g_warning ("error: cannot retrieve connection: %s", error ? error->message : "(unknown)");
goto out;
}
connection = nm_connection_new_from_hash (settings, &error);
g_hash_table_destroy (settings);
if (!connection) {
g_warning ("error: invalid connection: '%s' / '%s' invalid: %d",
error ? g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)) : "(unknown)",
error ? error->message : "(unknown)",
error ? error->code : -1);
goto out;
}
nm_connection_set_path (connection, path);
g_hash_table_insert (table, g_strdup (path), g_object_ref (connection));
out:
g_clear_error (&error);
if (connection)
g_object_unref (connection);
g_object_unref (proxy);
}
static gboolean
get_all_connections (void)
{
GError *error = NULL;
DBusGConnection *bus;
DBusGProxy *proxy = NULL;
GPtrArray *paths = NULL;
int i;
gboolean sucess = FALSE;
bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
if (error || !bus) {
g_warning ("error: could not connect to dbus");
goto out;
}
proxy = dbus_g_proxy_new_for_name (bus,
NM_DBUS_SERVICE,
NM_DBUS_PATH_SETTINGS,
NM_DBUS_IFACE_SETTINGS);
if (!proxy) {
g_warning ("error: failed to create DBus proxy for settings service");
goto out;
}
if (!dbus_g_proxy_call (proxy, "ListConnections", &error,
G_TYPE_INVALID,
DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &paths,
G_TYPE_INVALID)) {
/* No connections or settings service may not be running */
g_clear_error (&error);
goto out;
}
connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
for (i = 0; paths && (i < paths->len); i++)
get_one_connection (bus, g_ptr_array_index (paths, i), connections);
sucess = TRUE;
out:
if (bus)
dbus_g_connection_unref (bus);
if (proxy)
g_object_unref (proxy);
return sucess;
}
int
main (int argc, char *argv[])
{
NMClient *client;
const GPtrArray *devices;
struct cb_info info;
g_type_init ();
client = nm_client_new ();
if (!client) {
exit (1);
}
printf ("\nNetworkManager Tool\n\n");
if (!get_nm_state (client)) {
g_warning ("error: could not connect to NetworkManager");
exit (1);
}
if (!get_all_connections ())
exit (1);
info.client = client;
info.active = nm_client_get_active_connections (client);
devices = nm_client_get_devices (client);
if (devices)
g_ptr_array_foreach ((GPtrArray *) devices, detail_device, &info);
if (info.active)
g_ptr_array_foreach ((GPtrArray *) info.active, detail_vpn, &info);
g_object_unref (client);
g_hash_table_unref (connections);
return 0;
}