mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-28 00:30:09 +01:00
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.
818 lines
22 KiB
C
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;
|
|
}
|