devices.c 79.7 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* nmcli - command-line tool to control NetworkManager
 *
 * 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 - 2012 Red Hat, Inc.
18
19
 */

20
21
#include "config.h"

22
23
24
25
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
26
#include <netinet/ether.h>
27
28
29
30
31
32
33

#include <glib.h>
#include <glib/gi18n.h>

#include <nm-client.h>
#include <nm-device.h>
#include <nm-device-ethernet.h>
34
#include <nm-device-adsl.h>
35
#include <nm-device-wifi.h>
36
#include <nm-device-modem.h>
37
#include <nm-device-bt.h>
38
#include <nm-device-olpc-mesh.h>
39
#if WITH_WIMAX
40
#include <nm-device-wimax.h>
41
#endif
Dan Winship's avatar
Dan Winship committed
42
#include <nm-device-infiniband.h>
Jiří Klimeš's avatar
Jiří Klimeš committed
43
#include <nm-device-bond.h>
Thomas Graf's avatar
Thomas Graf committed
44
#include <nm-device-bridge.h>
Dan Williams's avatar
Dan Williams committed
45
#include <nm-device-vlan.h>
46
47
#include <nm-utils.h>
#include <nm-setting-ip4-config.h>
48
#include <nm-setting-ip6-config.h>
49
50
51
#include <nm-vpn-connection.h>
#include <nm-setting-connection.h>
#include <nm-setting-wired.h>
52
#include <nm-setting-adsl.h>
53
54
55
56
57
58
#include <nm-setting-pppoe.h>
#include <nm-setting-wireless.h>
#include <nm-setting-gsm.h>
#include <nm-setting-cdma.h>
#include <nm-setting-bluetooth.h>
#include <nm-setting-olpc-mesh.h>
59
#if WITH_WIMAX
60
#include <nm-setting-wimax.h>
61
#endif
Dan Winship's avatar
Dan Winship committed
62
#include <nm-setting-infiniband.h>
63
64

#include "utils.h"
65
#include "common.h"
66
67
68
#include "devices.h"


69
/* Available fields for 'device status' */
70
static NmcOutputField nmc_fields_dev_status[] = {
71
72
73
74
75
	{"DEVICE",    N_("DEVICE"),      10, NULL, 0},  /* 0 */
	{"TYPE",      N_("TYPE"),        17, NULL, 0},  /* 1 */
	{"STATE",     N_("STATE"),       13, NULL, 0},  /* 2 */
	{"DBUS-PATH", N_("DBUS-PATH"),   43, NULL, 0},  /* 3 */
	{NULL,        NULL,               0, NULL, 0}
76
};
77
#define NMC_FIELDS_DEV_STATUS_ALL     "DEVICE,TYPE,STATE,DBUS-PATH"
78
79
#define NMC_FIELDS_DEV_STATUS_COMMON  "DEVICE,TYPE,STATE"

Jiří Klimeš's avatar
Jiří Klimeš committed
80

81
82
/* Available sections for 'device show' */
static NmcOutputField nmc_fields_dev_show_sections[] = {
Jiří Klimeš's avatar
Jiří Klimeš committed
83
84
85
86
87
	{"GENERAL",           N_("GENERAL"),           0, NULL, 0},  /* 0 */
	{"CAPABILITIES",      N_("CAPABILITIES"),      0, NULL, 0},  /* 1 */
	{"WIFI-PROPERTIES",   N_("WIFI-PROPERTIES"),   0, NULL, 0},  /* 2 */
	{"AP",                N_("AP"),                0, NULL, 0},  /* 3 */
	{"WIRED-PROPERTIES",  N_("WIRED-PROPERTIES"),  0, NULL, 0},  /* 4 */
88
89
	{"WIMAX-PROPERTIES",  N_("WIMAX-PROPERTIES"),  0, NULL, 0},  /* 5 */
	{"NSP",               N_("NSP"),               0, NULL, 0},  /* 6 */
90
91
92
93
	{"IP4",               N_("IP4"),               0, NULL, 0},  /* 7 */
	{"DHCP4",             N_("DHCP4"),             0, NULL, 0},  /* 8 */
	{"IP6",               N_("IP6"),               0, NULL, 0},  /* 9 */
	{"DHCP6",             N_("DHCP6"),             0, NULL, 0},  /* 10 */
94
	{"BOND",              N_("BOND"),              0, NULL, 0},  /* 11 */
95
	{"VLAN",              N_("VLAN"),              0, NULL, 0},  /* 12 */
96
	{"CONNECTIONS",       N_("CONNECTIONS"),       0, NULL, 0},  /* 13 */
Jiří Klimeš's avatar
Jiří Klimeš committed
97
98
	{NULL,                NULL,                    0, NULL, 0}
};
99
#if WITH_WIMAX
100
101
#define NMC_FIELDS_DEV_SHOW_SECTIONS_ALL     "GENERAL,CAPABILITIES,BOND,VLAN,CONNECTIONS,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,WIMAX-PROPERTIES,NSP,IP4,DHCP4,IP6,DHCP6"
#define NMC_FIELDS_DEV_SHOW_SECTIONS_COMMON  "GENERAL,CAPABILITIES,BOND,VLAN,CONNECTIONS,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,WIMAX-PROPERTIES,NSP,IP4,DHCP4,IP6,DHCP6"
102
#else
103
104
#define NMC_FIELDS_DEV_SHOW_SECTIONS_ALL     "GENERAL,CAPABILITIES,BOND,VLAN,CONNECTIONS,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,IP4,DHCP4,IP6,DHCP6"
#define NMC_FIELDS_DEV_SHOW_SECTIONS_COMMON  "GENERAL,CAPABILITIES,BOND,VLAN,CONNECTIONS,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,IP4,DHCP4,IP6,DHCP6"
105
#endif
Jiří Klimeš's avatar
Jiří Klimeš committed
106

107
108
/* Available fields for 'device show' - GENERAL part */
static NmcOutputField nmc_fields_dev_show_general[] = {
109
110
111
112
113
114
	{"NAME",              N_("NAME"),              10, NULL, 0},  /* 0 */
	{"DEVICE",            N_("DEVICE"),            10, NULL, 0},  /* 1 */
	{"TYPE",              N_("TYPE"),              17, NULL, 0},  /* 2 */
	{"VENDOR",            N_("VENDOR"),            20, NULL, 0},  /* 3 */
	{"PRODUCT",           N_("PRODUCT"),           50, NULL, 0},  /* 4 */
	{"DRIVER",            N_("DRIVER"),             9, NULL, 0},  /* 5 */
115
116
117
118
119
120
121
122
123
124
125
	{"DRIVER-VERSION",    N_("DRIVER-VERSION"),    18, NULL, 0},  /* 6 */
	{"FIRMWARE-VERSION",  N_("FIRMWARE-VERSION"),  18, NULL, 0},  /* 7 */
	{"HWADDR",            N_("HWADDR"),            19, NULL, 0},  /* 8 */
	{"STATE",             N_("STATE"),             14, NULL, 0},  /* 9 */
	{"REASON",            N_("REASON"),            25, NULL, 0},  /* 10 */
	{"UDI",               N_("UDI"),               64, NULL, 0},  /* 11 */
	{"IP-IFACE",          N_("IP-IFACE"),          10, NULL, 0},  /* 12 */
	{"NM-MANAGED",        N_("NM-MANAGED"),        15, NULL, 0},  /* 13 */
	{"AUTOCONNECT",       N_("AUTOCONNECT"),       15, NULL, 0},  /* 14 */
	{"FIRMWARE-MISSING",  N_("FIRMWARE-MISSING"),  18, NULL, 0},  /* 15 */
	{"CONNECTION",        N_("CONNECTION"),        51, NULL, 0},  /* 16 */
126
	{NULL, NULL, 0, NULL, 0}
127
};
128
#define NMC_FIELDS_DEV_SHOW_GENERAL_ALL     "NAME,DEVICE,TYPE,VENDOR,PRODUCT,DRIVER,DRIVER-VERSION,FIRMWARE-VERSION,HWADDR,STATE,REASON,UDI,IP-IFACE,"\
129
                                            "NM-MANAGED,AUTOCONNECT,FIRMWARE-MISSING,CONNECTION"
130
#define NMC_FIELDS_DEV_SHOW_GENERAL_COMMON  "NAME,DEVICE,TYPE,VENDOR,PRODUCT,DRIVER,HWADDR,STATE"
131

132
133
/* Available fields for 'device show' - CONNECTIONS part */
static NmcOutputField nmc_fields_dev_show_connections[] = {
134
135
136
137
138
	{"NAME",                       N_("NAME"),                       10, NULL, 0},  /* 0 */
	{"AVAILABLE-CONNECTION-PATHS", N_("AVAILABLE-CONNECTION-PATHS"), 80, NULL, 0},  /* 1 */
	{"AVAILABLE-CONNECTIONS",      N_("AVAILABLE-CONNECTIONS"),      80, NULL, 0},  /* 2 */
	{NULL, NULL, 0, NULL, 0}
};
139
140
#define NMC_FIELDS_DEV_SHOW_CONNECTIONS_ALL     "AVAILABLE-CONNECTION-PATHS,AVAILABLE-CONNECTIONS"
#define NMC_FIELDS_DEV_SHOW_CONNECTIONS_COMMON  "AVAILABLE-CONNECTION-PATHS,AVAILABLE-CONNECTIONS"
141

142
143
/* Available fields for 'device show' - CAPABILITIES part */
static NmcOutputField nmc_fields_dev_show_cap[] = {
144
145
146
147
148
	{"NAME",            N_("NAME"),            13, NULL, 0},  /* 0 */
	{"CARRIER-DETECT",  N_("CARRIER-DETECT"),  16, NULL, 0},  /* 1 */
	{"SPEED",           N_("SPEED"),           10, NULL, 0},  /* 2 */
	{NULL,              NULL,                   0, NULL, 0}
};
149
150
#define NMC_FIELDS_DEV_SHOW_CAP_ALL     "NAME,CARRIER-DETECT,SPEED"
#define NMC_FIELDS_DEV_SHOW_CAP_COMMON  "NAME,CARRIER-DETECT,SPEED"
151

152
153
/* Available fields for 'device show' - wired properties part */
static NmcOutputField nmc_fields_dev_show_wired_prop[] = {
154
155
156
157
	{"NAME",            N_("NAME"),     18, NULL, 0},  /* 0 */
	{"CARRIER",         N_("CARRIER"),  10, NULL, 0},  /* 1 */
	{NULL,              NULL,            0, NULL, 0}
};
158
159
#define NMC_FIELDS_DEV_SHOW_WIRED_PROP_ALL     "NAME,CARRIER"
#define NMC_FIELDS_DEV_SHOW_WIRED_PROP_COMMON  "NAME,CARRIER"
160
161


162
163
/* Available fields for 'device show' - wireless properties part */
static NmcOutputField nmc_fields_dev_show_wifi_prop[] = {
164
165
166
167
168
169
	{"NAME",       N_("NAME"),        18, NULL, 0},  /* 0 */
	{"WEP",        N_("WEP"),          5, NULL, 0},  /* 1 */
	{"WPA",        N_("WPA"),          5, NULL, 0},  /* 2 */
	{"WPA2",       N_("WPA2"),         6, NULL, 0},  /* 3 */
	{"TKIP",       N_("TKIP"),         6, NULL, 0},  /* 4 */
	{"CCMP",       N_("CCMP"),         6, NULL, 0},  /* 5 */
170
171
	{"AP",         N_("AP"),           6, NULL, 0},  /* 6 */
	{"ADHOC",      N_("ADHOC"),        6, NULL, 0},  /* 7 */
172
173
	{NULL,         NULL,               0, NULL, 0}
};
174
175
#define NMC_FIELDS_DEV_SHOW_WIFI_PROP_ALL     "NAME,WEP,WPA,WPA2,TKIP,CCMP,AP,ADHOC"
#define NMC_FIELDS_DEV_SHOW_WIFI_PROP_COMMON  "NAME,WEP,WPA,WPA2,TKIP,CCMP,AP,ADHOC"
176

177
#if WITH_WIMAX
178
179
/* Available fields for 'device show' - wimax properties part */
static NmcOutputField nmc_fields_dev_show_wimax_prop[] = {
180
181
182
183
184
185
186
187
	{"NAME",       N_("NAME"),        18, NULL, 0},  /* 0 */
	{"CTR-FREQ",   N_("CTR-FREQ"),     7, NULL, 0},  /* 1 */
	{"RSSI",       N_("RSSI"),         5, NULL, 0},  /* 2 */
	{"CINR",       N_("CINR"),         5, NULL, 0},  /* 3 */
	{"TX-POW",     N_("TX-POW"),       5, NULL, 0},  /* 4 */
	{"BSID",       N_("BSID"),        18, NULL, 0},  /* 5 */
	{NULL,         NULL,               0, NULL, 0}
};
188
189
#define NMC_FIELDS_DEV_SHOW_WIMAX_PROP_ALL     "NAME,CTR-FREQ,RSSI,CINR,TX-POW,BSID"
#define NMC_FIELDS_DEV_SHOW_WIMAX_PROP_COMMON  "NAME,CTR-FREQ,RSSI,CINR,TX-POW,BSID"
190
#endif
191

192
/* Available fields for 'device wifi list' */
193
static NmcOutputField nmc_fields_dev_wifi_list[] = {
Jiří Klimeš's avatar
Jiří Klimeš committed
194
195
196
197
198
199
200
201
202
203
204
205
	{"NAME",       N_("NAME"),        15, NULL, 0},  /* 0 */
	{"SSID",       N_("SSID"),        33, NULL, 0},  /* 1 */
	{"BSSID",      N_("BSSID"),       19, NULL, 0},  /* 2 */
	{"MODE",       N_("MODE"),        16, NULL, 0},  /* 3 */
	{"FREQ",       N_("FREQ"),        10, NULL, 0},  /* 4 */
	{"RATE",       N_("RATE"),        10, NULL, 0},  /* 5 */
	{"SIGNAL",     N_("SIGNAL"),       8, NULL, 0},  /* 6 */
	{"SECURITY",   N_("SECURITY"),    10, NULL, 0},  /* 7 */
	{"WPA-FLAGS",  N_("WPA-FLAGS"),   25, NULL, 0},  /* 8 */
	{"RSN-FLAGS",  N_("RSN-FLAGS"),   25, NULL, 0},  /* 9 */
	{"DEVICE",     N_("DEVICE"),      10, NULL, 0},  /* 10 */
	{"ACTIVE",     N_("ACTIVE"),       8, NULL, 0},  /* 11 */
206
	{"DBUS-PATH",  N_("DBUS-PATH"),   46, NULL, 0},  /* 12 */
207
208
	{NULL,         NULL,               0, NULL, 0}
};
209
#define NMC_FIELDS_DEV_WIFI_LIST_ALL           "SSID,BSSID,MODE,FREQ,RATE,SIGNAL,SECURITY,WPA-FLAGS,RSN-FLAGS,DEVICE,ACTIVE,DBUS-PATH"
Jiří Klimeš's avatar
Jiří Klimeš committed
210
#define NMC_FIELDS_DEV_WIFI_LIST_COMMON        "SSID,BSSID,MODE,FREQ,RATE,SIGNAL,SECURITY,ACTIVE"
211
#define NMC_FIELDS_DEV_WIFI_LIST_FOR_DEV_LIST  "NAME,"NMC_FIELDS_DEV_WIFI_LIST_COMMON
212

213
#if WITH_WIMAX
214
/* Available fields for 'device wimax list' */
215
216
217
218
219
220
221
222
223
224
225
226
227
static NmcOutputField nmc_fields_dev_wimax_list[] = {
	{"NAME",       N_("NAME"),        15, NULL, 0},  /* 0 */
	{"NSP",        N_("NSP"),         33, NULL, 0},  /* 1 */
	{"SIGNAL",     N_("SIGNAL"),       8, NULL, 0},  /* 2 */
	{"TYPE",       N_("TYPE"),        16, NULL, 0},  /* 3 */
	{"DEVICE",     N_("DEVICE"),      10, NULL, 0},  /* 4 */
	{"ACTIVE",     N_("ACTIVE"),       8, NULL, 0},  /* 5 */
	{"DBUS-PATH",  N_("DBUS-PATH"),   46, NULL, 0},  /* 6 */
	{NULL,         NULL,               0, NULL, 0}
};
#define NMC_FIELDS_DEV_WIMAX_LIST_ALL           "NSP,SIGNAL,TYPE,DEVICE,ACTIVE,DBUS-PATH"
#define NMC_FIELDS_DEV_WIMAX_LIST_COMMON        "NSP,SIGNAL,TYPE,DEVICE,ACTIVE"
#define NMC_FIELDS_DEV_WIMAX_LIST_FOR_DEV_LIST  "NAME,"NMC_FIELDS_DEV_WIMAX_LIST_COMMON
228
#endif
229

230
231
/* Available fields for 'device show' - BOND part */
static NmcOutputField nmc_fields_dev_show_bond_prop[] = {
232
233
234
235
	{"NAME",            N_("NAME"),     18, NULL, 0},  /* 0 */
	{"SLAVES",          N_("SLAVES"),   20, NULL, 0},  /* 1 */
	{NULL,              NULL,            0, NULL, 0}
};
236
237
#define NMC_FIELDS_DEV_SHOW_BOND_PROP_ALL     "NAME,SLAVES"
#define NMC_FIELDS_DEV_SHOW_BOND_PROP_COMMON  "NAME,SLAVES"
238

239
240
/* Available fields for 'device show' - VLAN part */
static NmcOutputField nmc_fields_dev_show_vlan_prop[] = {
241
242
243
244
	{"NAME",            N_("NAME"),     18, NULL, 0},  /* 0 */
	{"ID",              N_("ID"),        5, NULL, 0},  /* 1 */
	{NULL,              NULL,            0, NULL, 0}
};
245
246
#define NMC_FIELDS_DEV_SHOW_VLAN_PROP_ALL     "NAME,ID"
#define NMC_FIELDS_DEV_SHOW_VLAN_PROP_COMMON  "NAME,ID"
247

248

249
250
/* glib main loop variable - defined in nmcli.c */
extern GMainLoop *loop;
251

252
253
static guint progress_id = 0;  /* ID of event source for displaying progress */

254
255
256
257
static void
usage (void)
{
	fprintf (stderr,
258
	         _("Usage: nmcli device { COMMAND | help }\n\n"
259
#if WITH_WIMAX
260
	         "  COMMAND := { status | show | disconnect | wifi | wimax }\n\n"
261
#else
262
	         "  COMMAND := { status | show | disconnect | wifi }\n\n"
263
#endif
264
	         "  status\n\n"
265
266
267
268
	         "  show [<ifname>]\n\n"
	         "  disconnect <ifname> [--nowait] [--timeout <timeout>]\n\n"
	         "  wifi [list [ifname <ifname>] [bssid <BSSID>]]\n\n"
	         "  wifi connect <(B)SSID> [password <password>] [wep-key-type key|phrase] [ifname <ifname>] [bssid <BSSID>] [name <name>]\n\n"
269
	         "               [--private] [--nowait] [--timeout <timeout>]\n\n"
270
	         "  wifi rescan [[ifname] <ifname>]\n\n"
271
#if WITH_WIMAX
272
	         "  wimax [list [ifname <ifname>] [nsp <name>]]\n\n"
273
274
#endif
	         ));
275
276
277
278
279
280
}

/* quit main loop */
static void
quit (void)
{
281
282
283
284
285
	if (progress_id) {
		g_source_remove (progress_id);
		nmc_terminal_erase_line ();
	}

286
287
288
	g_main_loop_quit (loop);  /* quit main loop */
}

289
290
291
/* Convert device type to string. Use setting names strings to match with
 * connection type names.
 */
292
static const char *
293
device_type_to_string (NMDevice *device)
294
{
295
296
297
	NMDeviceModemCapabilities caps = NM_DEVICE_MODEM_CAPABILITY_NONE;

	switch (nm_device_get_device_type (device)) {
298
	case NM_DEVICE_TYPE_ETHERNET:
299
		return NM_SETTING_WIRED_SETTING_NAME;
300
301
	case NM_DEVICE_TYPE_ADSL:
		return NM_SETTING_ADSL_SETTING_NAME;
302
	case NM_DEVICE_TYPE_WIFI:
303
		return NM_SETTING_WIRELESS_SETTING_NAME;
304
305
306
307
308
309
310
	case NM_DEVICE_TYPE_MODEM:
		caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device));
		if (caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS)
			return NM_SETTING_GSM_SETTING_NAME;
		else if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)
			return NM_SETTING_CDMA_SETTING_NAME;
		return _("Unknown");
311
	case NM_DEVICE_TYPE_BT:
312
		return NM_SETTING_BLUETOOTH_SETTING_NAME;
313
314
	case NM_DEVICE_TYPE_OLPC_MESH:
		return NM_SETTING_OLPC_MESH_SETTING_NAME;
315
#if WITH_WIMAX
316
	case NM_DEVICE_TYPE_WIMAX:
317
		return NM_SETTING_WIMAX_SETTING_NAME;
318
#endif
Dan Winship's avatar
Dan Winship committed
319
320
	case NM_DEVICE_TYPE_INFINIBAND:
		return NM_SETTING_INFINIBAND_SETTING_NAME;
Jiří Klimeš's avatar
Jiří Klimeš committed
321
322
	case NM_DEVICE_TYPE_BOND:
		return NM_SETTING_BOND_SETTING_NAME;
Dan Williams's avatar
Dan Williams committed
323
324
	case NM_DEVICE_TYPE_VLAN:
		return NM_SETTING_VLAN_SETTING_NAME;
Thomas Graf's avatar
Thomas Graf committed
325
326
	case NM_DEVICE_TYPE_BRIDGE:
		return NM_SETTING_BRIDGE_SETTING_NAME;
327
	default:
328
		return _("Unknown");
329
	}
330
331
332
}

static char *
333
ap_wpa_rsn_flags_to_string (NM80211ApSecurityFlags flags)
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
{
	char *flags_str[16]; /* Enough space for flags and terminating NULL */
	char *ret_str;
	int i = 0;

	if (flags & NM_802_11_AP_SEC_PAIR_WEP40)
		flags_str[i++] = g_strdup ("pair_wpe40");
	if (flags & NM_802_11_AP_SEC_PAIR_WEP104)
		flags_str[i++] = g_strdup ("pair_wpe104");
	if (flags & NM_802_11_AP_SEC_PAIR_TKIP)
		flags_str[i++] = g_strdup ("pair_tkip");
	if (flags & NM_802_11_AP_SEC_PAIR_CCMP)
		flags_str[i++] = g_strdup ("pair_ccmp");
	if (flags & NM_802_11_AP_SEC_GROUP_WEP40)
		flags_str[i++] = g_strdup ("group_wpe40");
	if (flags & NM_802_11_AP_SEC_GROUP_WEP104)
		flags_str[i++] = g_strdup ("group_wpe104");
	if (flags & NM_802_11_AP_SEC_GROUP_TKIP)
		flags_str[i++] = g_strdup ("group_tkip");
	if (flags & NM_802_11_AP_SEC_GROUP_CCMP)
		flags_str[i++] = g_strdup ("group_ccmp");
	if (flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)
		flags_str[i++] = g_strdup ("psk");
	if (flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
		flags_str[i++] = g_strdup ("802.1X");

	if (i == 0)
		flags_str[i++] = g_strdup (_("(none)"));

	flags_str[i] = NULL;

	ret_str = g_strjoinv (" ", flags_str);

	i = 0;
	while (flags_str[i])
Jiří Klimeš's avatar
Jiří Klimeš committed
369
		g_free (flags_str[i++]);
370
371
372
373

	return ret_str;
}

374
375
typedef struct {
	NmCli *nmc;
Jiří Klimeš's avatar
Jiří Klimeš committed
376
	int index;
377
378
379
380
	const char* active_bssid;
	const char* device;
} APInfo;

381
382
383
384
static void
detail_access_point (gpointer data, gpointer user_data)
{
	NMAccessPoint *ap = NM_ACCESS_POINT (data);
385
	APInfo *info = (APInfo *) user_data;
386
	gboolean active = FALSE;
387
388
389
	NM80211ApFlags flags;
	NM80211ApSecurityFlags wpa_flags, rsn_flags;
	guint32 freq, bitrate;
390
	guint8 strength;
391
392
	const GByteArray *ssid;
	const char *bssid;
393
394
395
	NM80211Mode mode;
	char *freq_str, *ssid_str, *bitrate_str, *strength_str, *wpa_flags_str, *rsn_flags_str;
	GString *security_str;
Jiří Klimeš's avatar
Jiří Klimeš committed
396
	char *ap_name;
397

398
	if (info->active_bssid) {
399
		const char *current_bssid = nm_access_point_get_bssid (ap);
400
		if (current_bssid && !strcmp (current_bssid, info->active_bssid))
401
402
403
			active = TRUE;
	}

404
405
406
407
408
	/* Get AP properties */
	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);
	ssid = nm_access_point_get_ssid (ap);
409
	bssid = nm_access_point_get_bssid (ap);
410
411
412
413
414
415
	freq = nm_access_point_get_frequency (ap);
	mode = nm_access_point_get_mode (ap);
	bitrate = nm_access_point_get_max_bitrate (ap);
	strength = nm_access_point_get_strength (ap);

	/* Convert to strings */
416
	ssid_str = ssid_to_printable ((const char *) ssid->data, ssid->len);
417
418
419
420
421
	freq_str = g_strdup_printf (_("%u MHz"), freq);
	bitrate_str = g_strdup_printf (_("%u MB/s"), bitrate/1000);
	strength_str = g_strdup_printf ("%u", strength);
	wpa_flags_str = ap_wpa_rsn_flags_to_string (wpa_flags);
	rsn_flags_str = ap_wpa_rsn_flags_to_string (rsn_flags);
422

423
	security_str = g_string_new (NULL);
424
425
426
	if (   !(flags & NM_802_11_AP_FLAGS_PRIVACY)
	    &&  (wpa_flags != NM_802_11_AP_SEC_NONE)
	    &&  (rsn_flags != NM_802_11_AP_SEC_NONE))
427
		g_string_append (security_str, _("Encrypted: "));
428
429
430
431

	if (   (flags & NM_802_11_AP_FLAGS_PRIVACY)
	    && (wpa_flags == NM_802_11_AP_SEC_NONE)
	    && (rsn_flags == NM_802_11_AP_SEC_NONE))
432
		g_string_append (security_str, _("WEP "));
433
	if (wpa_flags != NM_802_11_AP_SEC_NONE)
434
		g_string_append (security_str, _("WPA "));
435
	if (rsn_flags != NM_802_11_AP_SEC_NONE)
436
		g_string_append (security_str, _("WPA2 "));
437
438
	if (   (wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
	    || (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X))
439
440
441
442
443
		g_string_append (security_str, _("Enterprise "));

	if (security_str->len > 0)
		g_string_truncate (security_str, security_str->len-1);  /* Chop off last space */

444
	ap_name = g_strdup_printf ("AP[%d]", info->index++); /* AP */
Jiří Klimeš's avatar
Jiří Klimeš committed
445
446
	info->nmc->allowed_fields[0].value = ap_name;
	info->nmc->allowed_fields[1].value = ssid_str;
447
	info->nmc->allowed_fields[2].value = (char *) bssid;
448
449
450
	info->nmc->allowed_fields[3].value = mode == NM_802_11_MODE_ADHOC ? _("Ad-Hoc")
	                                   : mode == NM_802_11_MODE_INFRA ? _("Infrastructure")
	                                   : _("Unknown");
Jiří Klimeš's avatar
Jiří Klimeš committed
451
452
453
454
455
456
	info->nmc->allowed_fields[4].value = freq_str;
	info->nmc->allowed_fields[5].value = bitrate_str;
	info->nmc->allowed_fields[6].value = strength_str;
	info->nmc->allowed_fields[7].value = security_str->str;
	info->nmc->allowed_fields[8].value = wpa_flags_str;
	info->nmc->allowed_fields[9].value = rsn_flags_str;
457
	info->nmc->allowed_fields[10].value = (char *) info->device;
Jiří Klimeš's avatar
Jiří Klimeš committed
458
	info->nmc->allowed_fields[11].value = active ? _("yes") : _("no");
459
	info->nmc->allowed_fields[12].value = (char *) nm_object_get_path (NM_OBJECT (ap));
Jiří Klimeš's avatar
Jiří Klimeš committed
460
461

	info->nmc->print_fields.flags &= ~NMC_PF_FLAG_MAIN_HEADER_ADD & ~NMC_PF_FLAG_MAIN_HEADER_ONLY & ~NMC_PF_FLAG_FIELD_NAMES; /* Clear header flags */
462
	print_fields (info->nmc->print_fields, info->nmc->allowed_fields);
463

Jiří Klimeš's avatar
Jiří Klimeš committed
464
	g_free (ap_name);
465
466
467
468
469
470
471
	g_free (ssid_str);
	g_free (freq_str);
	g_free (bitrate_str);
	g_free (strength_str);
	g_free (wpa_flags_str);
	g_free (rsn_flags_str);
	g_string_free (security_str, TRUE);
472
473
}

474
#if WITH_WIMAX
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
static void
detail_wimax_nsp (NMWimaxNsp *nsp, NmCli *nmc, NMDevice *dev, int idx)
{
	NMDeviceWimax *wimax = NM_DEVICE_WIMAX (dev);
	char *nsp_name, *quality_str;
	const char *ntype;
	gboolean active = FALSE;

	switch (nm_wimax_nsp_get_network_type (nsp)) {
	case NM_WIMAX_NSP_NETWORK_TYPE_HOME:
		ntype = _("Home");
		break;
	case NM_WIMAX_NSP_NETWORK_TYPE_PARTNER:
		ntype = _("Partner");
		break;
	case NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER:
		ntype = _("Roaming");
		break;
	default:
		ntype = _("Unknown");
		break;
	}

	if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) {
		if (nsp == nm_device_wimax_get_active_nsp (wimax))
			active = TRUE;
	}

	quality_str = g_strdup_printf ("%u", nm_wimax_nsp_get_signal_quality (nsp));
504
	nsp_name = g_strdup_printf ("NSP[%d]", idx); /* NSP */
505
506

	nmc->allowed_fields[0].value = nsp_name;
507
	nmc->allowed_fields[1].value = (char *) nm_wimax_nsp_get_name (nsp);
508
	nmc->allowed_fields[2].value = quality_str;
509
510
	nmc->allowed_fields[3].value = (char *) ntype;
	nmc->allowed_fields[4].value = (char *) nm_device_get_iface (dev);
511
	nmc->allowed_fields[5].value = active ? _("yes") : _("no");
512
	nmc->allowed_fields[6].value = (char *) nm_object_get_path (NM_OBJECT (nsp));
513
514
515
516
517
518
519

	nmc->print_fields.flags &= ~NMC_PF_FLAG_MAIN_HEADER_ADD & ~NMC_PF_FLAG_MAIN_HEADER_ONLY & ~NMC_PF_FLAG_FIELD_NAMES; /* Clear header flags */
	print_fields (nmc->print_fields, nmc->allowed_fields);

	g_free (nsp_name);
	g_free (quality_str);
}
520
#endif
521

522
523
524
525
526
527
528
529
530
struct cb_info {
	NMClient *client;
	const GPtrArray *active;
};

static void
show_device_info (gpointer data, gpointer user_data)
{
	NMDevice *device = NM_DEVICE (data);
531
	NmCli *nmc = (NmCli *) user_data;
Jiří Klimeš's avatar
Jiří Klimeš committed
532
	GError *error = NULL;
533
	APInfo *info;
534
	const char *hwaddr = NULL;
535
	NMDeviceState state = NM_DEVICE_STATE_UNKNOWN;
536
	NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
537
	NMDeviceCapabilities caps;
538
	NMActiveConnection *acon;
539
	guint32 speed;
540
	char *speed_str = NULL;
541
542
	char *state_str = NULL;
	char *reason_str = NULL;
Jiří Klimeš's avatar
Jiří Klimeš committed
543
544
545
	GArray *sections_array;
	int k;
	char *fields_str;
546
547
	char *fields_all =    NMC_FIELDS_DEV_SHOW_SECTIONS_ALL;
	char *fields_common = NMC_FIELDS_DEV_SHOW_SECTIONS_COMMON;
548
549
550
	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
Jiří Klimeš's avatar
Jiří Klimeš committed
551
552
553
554
555
556
557
558
559
	gboolean was_output = FALSE;

	if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0)
		fields_str = fields_common;
	else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0)
		fields_str = fields_all;
	else
		fields_str = nmc->required_fields;

560
	sections_array = parse_output_fields (fields_str, nmc_fields_dev_show_sections, &error);
Jiří Klimeš's avatar
Jiří Klimeš committed
561
562
	if (error) {
		if (error->code == 0)
563
			g_string_printf (nmc->return_text, _("Error: 'device show': %s"), error->message);
Jiří Klimeš's avatar
Jiří Klimeš committed
564
		else
565
			g_string_printf (nmc->return_text, _("Error: 'device show': %s; allowed fields: %s"), error->message, NMC_FIELDS_DEV_SHOW_SECTIONS_ALL);
Jiří Klimeš's avatar
Jiří Klimeš committed
566
567
568
569
		g_error_free (error);
		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
		return;
	}
570

Jiří Klimeš's avatar
Jiří Klimeš committed
571
	/* Main header */
572
	nmc->allowed_fields = nmc_fields_dev_show_general;
Jiří Klimeš's avatar
Jiří Klimeš committed
573
	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ONLY;
574
	nmc->print_fields.header_name = _("Device details");
575
	nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_SHOW_GENERAL_ALL, nmc->allowed_fields, NULL);
576
	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
577

Jiří Klimeš's avatar
Jiří Klimeš committed
578
579
580
	/* Loop through the required sections and print them. */
	for (k = 0; k < sections_array->len; k++) {
		int section_idx = g_array_index (sections_array, int, k);
581

Jiří Klimeš's avatar
Jiří Klimeš committed
582
583
		if (nmc->print_output != NMC_PRINT_TERSE && !nmc->multiline_output && was_output)
			printf ("\n"); /* Empty line */
584

Jiří Klimeš's avatar
Jiří Klimeš committed
585
		was_output = FALSE;
586

587
		state = nm_device_get_state_reason (device, &reason);
588

Jiří Klimeš's avatar
Jiří Klimeš committed
589
		/* section GENERAL */
590
591
		if (!strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[0].name)) {
			nmc->allowed_fields = nmc_fields_dev_show_general;
Jiří Klimeš's avatar
Jiří Klimeš committed
592
			nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
593
			nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_SHOW_GENERAL_ALL, nmc->allowed_fields, NULL);
Jiří Klimeš's avatar
Jiří Klimeš committed
594
			print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
595

Jiří Klimeš's avatar
Jiří Klimeš committed
596
597
598
599
			if (NM_IS_DEVICE_ETHERNET (device))
				hwaddr = nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (device));
			else if (NM_IS_DEVICE_WIFI (device))
				hwaddr = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (device));
600
#if WITH_WIMAX
601
602
			else if (NM_IS_DEVICE_WIMAX (device))
				hwaddr = nm_device_wimax_get_hw_address (NM_DEVICE_WIMAX (device));
603
#endif
Dan Winship's avatar
Dan Winship committed
604
605
			else if (NM_IS_DEVICE_INFINIBAND (device))
				hwaddr = nm_device_infiniband_get_hw_address (NM_DEVICE_INFINIBAND (device));
Jiří Klimeš's avatar
Jiří Klimeš committed
606
607
			else if (NM_IS_DEVICE_BOND (device))
				hwaddr = nm_device_bond_get_hw_address (NM_DEVICE_BOND (device));
Dan Williams's avatar
Dan Williams committed
608
609
			else if (NM_IS_DEVICE_VLAN (device))
				hwaddr = nm_device_vlan_get_hw_address (NM_DEVICE_VLAN (device));
Thomas Graf's avatar
Thomas Graf committed
610
611
			else if (NM_IS_DEVICE_BRIDGE (device))
				hwaddr = nm_device_bridge_get_hw_address (NM_DEVICE_BRIDGE (device));
612

613
614
			state_str = g_strdup_printf ("%d (%s)", state, nmc_device_state_to_string (state));
			reason_str = g_strdup_printf ("%d (%s)", reason, nmc_device_reason_to_string (reason));
615

616
			nmc->allowed_fields[0].value = (char *) nmc_fields_dev_show_sections[0].name;  /* "GENERAL"*/
617
618
619
620
621
622
623
624
625
626
627
628
			nmc->allowed_fields[1].value = (char *) nm_device_get_iface (device);
			nmc->allowed_fields[2].value = (char *) device_type_to_string (device);
			nmc->allowed_fields[3].value = (char *) nm_device_get_vendor (device);
			nmc->allowed_fields[4].value = (char *) nm_device_get_product (device);
			nmc->allowed_fields[5].value = (char *) (nm_device_get_driver (device) ? nm_device_get_driver (device) : _("(unknown)"));
			nmc->allowed_fields[6].value = (char *) nm_device_get_driver_version (device);
			nmc->allowed_fields[7].value = (char *) nm_device_get_firmware_version (device);
			nmc->allowed_fields[8].value = (char *) (hwaddr ? hwaddr : _("(unknown)"));
			nmc->allowed_fields[9].value = (char *) state_str;
			nmc->allowed_fields[10].value = (char *) reason_str;
			nmc->allowed_fields[11].value = (char *) nm_device_get_udi (device);
			nmc->allowed_fields[12].value = (char *) nm_device_get_ip_iface (device);
629
630
631
			nmc->allowed_fields[13].value = nm_device_get_managed (device) ? _("yes") : _("no");
			nmc->allowed_fields[14].value = nm_device_get_autoconnect (device) ? _("yes") : _("no");
			nmc->allowed_fields[15].value = nm_device_get_firmware_missing (device) ? _("yes") : _("no");
632
633
			nmc->allowed_fields[16].value = (char *) ((acon = nm_device_get_active_connection (device)) ?
			                                   nm_object_get_path (NM_OBJECT (acon)) : _("not connected"));
634

Jiří Klimeš's avatar
Jiří Klimeš committed
635
636
			nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
			print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
637
638
			g_free (state_str);
			g_free (reason_str);
Jiří Klimeš's avatar
Jiří Klimeš committed
639
640
			was_output = TRUE;
		}
641

Jiří Klimeš's avatar
Jiří Klimeš committed
642
		/* section CAPABILITIES */
643
644
		if (!strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[1].name)) {
			nmc->allowed_fields = nmc_fields_dev_show_cap;
Jiří Klimeš's avatar
Jiří Klimeš committed
645
			nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
646
			nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_SHOW_CAP_ALL, nmc->allowed_fields, NULL);
Jiří Klimeš's avatar
Jiří Klimeš committed
647
			print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
648

Jiří Klimeš's avatar
Jiří Klimeš committed
649
650
651
652
653
654
655
656
657
658
659
660
			caps = nm_device_get_capabilities (device);
			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)
				speed_str = g_strdup_printf (_("%u Mb/s"), speed);
661

662
			nmc->allowed_fields[0].value = (char *) nmc_fields_dev_show_sections[1].name;  /* "CAPABILITIES" */
Jiří Klimeš's avatar
Jiří Klimeš committed
663
664
			nmc->allowed_fields[1].value = (caps & NM_DEVICE_CAP_CARRIER_DETECT) ? _("yes") : _("no");
			nmc->allowed_fields[2].value = speed_str ? speed_str : _("unknown");
665

Jiří Klimeš's avatar
Jiří Klimeš committed
666
667
668
669
			nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
			print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
			g_free (speed_str);
			was_output = TRUE;
670
671
		}

672

Jiří Klimeš's avatar
Jiří Klimeš committed
673
674
		/* Wireless specific information */
		if ((NM_IS_DEVICE_WIFI (device))) {
675
			NMDeviceWifiCapabilities wcaps;
Jiří Klimeš's avatar
Jiří Klimeš committed
676
677
678
			NMAccessPoint *active_ap = NULL;
			const char *active_bssid = NULL;
			const GPtrArray *aps;
679

Jiří Klimeš's avatar
Jiří Klimeš committed
680
			/* section WIFI-PROPERTIES */
681
			if (!strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[2].name)) {
Jiří Klimeš's avatar
Jiří Klimeš committed
682
				wcaps = nm_device_wifi_get_capabilities (NM_DEVICE_WIFI (device));
683

684
				nmc->allowed_fields = nmc_fields_dev_show_wifi_prop;
Jiří Klimeš's avatar
Jiří Klimeš committed
685
				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
686
				nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_SHOW_WIFI_PROP_ALL, nmc->allowed_fields, NULL);
Jiří Klimeš's avatar
Jiří Klimeš committed
687
				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
688

689
				nmc->allowed_fields[0].value = (char *) nmc_fields_dev_show_sections[2].name;  /* "WIFI-PROPERTIES" */
Jiří Klimeš's avatar
Jiří Klimeš committed
690
691
692
693
694
				nmc->allowed_fields[1].value = (wcaps & (NM_WIFI_DEVICE_CAP_CIPHER_WEP40 | NM_WIFI_DEVICE_CAP_CIPHER_WEP104)) ? _("yes") : _("no");
				nmc->allowed_fields[2].value = (wcaps & NM_WIFI_DEVICE_CAP_WPA) ? _("yes") : _("no");
				nmc->allowed_fields[3].value = (wcaps & NM_WIFI_DEVICE_CAP_RSN) ? _("yes") : _("no");
				nmc->allowed_fields[4].value = (wcaps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP) ? _("yes") : _("no");
				nmc->allowed_fields[5].value = (wcaps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP) ? _("yes") : _("no");
695
696
				nmc->allowed_fields[6].value = (wcaps & NM_WIFI_DEVICE_CAP_AP) ? _("yes") : _("no");
				nmc->allowed_fields[7].value = (wcaps & NM_WIFI_DEVICE_CAP_ADHOC) ? _("yes") : _("no");
697

Jiří Klimeš's avatar
Jiří Klimeš committed
698
699
700
701
				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
				was_output = TRUE;
			}
702

Jiří Klimeš's avatar
Jiří Klimeš committed
703
			/* section AP */
704
			if (!strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[3].name)) {
705
				if (state == NM_DEVICE_STATE_ACTIVATED) {
Jiří Klimeš's avatar
Jiří Klimeš committed
706
					active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (device));
707
					active_bssid = active_ap ? nm_access_point_get_bssid (active_ap) : NULL;
Jiří Klimeš's avatar
Jiří Klimeš committed
708
				}
709

Jiří Klimeš's avatar
Jiří Klimeš committed
710
711
712
713
				nmc->allowed_fields = nmc_fields_dev_wifi_list;
				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
				nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_WIFI_LIST_FOR_DEV_LIST, nmc->allowed_fields, NULL);
				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
714

Jiří Klimeš's avatar
Jiří Klimeš committed
715
716
717
718
719
720
721
722
723
724
725
726
727
728
				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
				info = g_malloc0 (sizeof (APInfo));
				info->nmc = nmc;
				info->index = 1;
				info->active_bssid = active_bssid;
				info->device = nm_device_get_iface (device);
				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) info);
				g_free (info);
				was_output = TRUE;
			}
		} else if (NM_IS_DEVICE_ETHERNET (device)) {
			/* WIRED-PROPERTIES */
729
730
			if (!strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[4].name)) {
				nmc->allowed_fields = nmc_fields_dev_show_wired_prop;
Jiří Klimeš's avatar
Jiří Klimeš committed
731
				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
732
				nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_SHOW_WIRED_PROP_ALL, nmc->allowed_fields, NULL);
Jiří Klimeš's avatar
Jiří Klimeš committed
733
				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
734

735
				nmc->allowed_fields[0].value = (char *) nmc_fields_dev_show_sections[4].name;  /* "WIRED-PROPERTIES" */
Jiří Klimeš's avatar
Jiří Klimeš committed
736
				nmc->allowed_fields[1].value = (nm_device_ethernet_get_carrier (NM_DEVICE_ETHERNET (device))) ? _("on") : _("off");
737

Jiří Klimeš's avatar
Jiří Klimeš committed
738
739
740
741
				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
				was_output = TRUE;
			}
742
743
744
		}
#if WITH_WIMAX
		else if (NM_IS_DEVICE_WIMAX (device)) {
745
			/* WIMAX-PROPERTIES */
746
			if (!strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[5].name)) {
747
748
749
				char *cfreq = NULL, *rssi = NULL, *cinr = NULL, *txpow = NULL;
				guint tmp_uint;
				gint tmp_int;
750
				char *bsid;
751

752
				nmc->allowed_fields = nmc_fields_dev_show_wimax_prop;
753
				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
754
				nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_SHOW_WIMAX_PROP_ALL, nmc->allowed_fields, NULL);
755
756
				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */

757
				nmc->allowed_fields[0].value = (char *) nmc_fields_dev_show_sections[5].name;  /* "WIMAX-PROPERTIES" */
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783

				/* Center frequency */
				tmp_uint = nm_device_wimax_get_center_frequency (NM_DEVICE_WIMAX (device));
				if (tmp_uint)
					cfreq = g_strdup_printf ("%'.1f MHz", (double) tmp_uint / 1000.0);
				nmc->allowed_fields[1].value = cfreq ? cfreq : "";

				/* RSSI */
				tmp_int = nm_device_wimax_get_rssi (NM_DEVICE_WIMAX (device));
				if (tmp_int)
					rssi = g_strdup_printf ("%d dBm", tmp_int);
				nmc->allowed_fields[2].value = rssi ? rssi : "";

				/* CINR */
				tmp_int = nm_device_wimax_get_cinr (NM_DEVICE_WIMAX (device));
				if (tmp_int)
					cinr = g_strdup_printf ("%d dB", tmp_int);
				nmc->allowed_fields[3].value = cinr ? cinr : "";

				/* TX Power */
				tmp_int = nm_device_wimax_get_tx_power (NM_DEVICE_WIMAX (device));
				if (tmp_int)
					txpow = g_strdup_printf ("%'.2f dBm", (float) tmp_int / 2.0);
				nmc->allowed_fields[4].value = txpow ? txpow : "";

				/* BSID */
784
				bsid = (char *) nm_device_wimax_get_bsid (NM_DEVICE_WIMAX (device));
785
786
787
788
789
790
791
792
				nmc->allowed_fields[5].value = bsid ? bsid : "";

				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
				was_output = TRUE;
			}

			/* section NSP */
793
			if (!strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[6].name)) {
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
				const GPtrArray *nsps;
				int g, idx = 1;

				nmc->allowed_fields = nmc_fields_dev_wimax_list;
				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
				nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_WIMAX_LIST_FOR_DEV_LIST, nmc->allowed_fields, NULL);
				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */

				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;

				nsps = nm_device_wimax_get_nsps (NM_DEVICE_WIMAX (device));
				for (g = 0; nsps && g < nsps->len; g++) {
					NMWimaxNsp *nsp = g_ptr_array_index (nsps, g);

					detail_wimax_nsp (nsp, nmc, device, idx++);
				}
				was_output = TRUE;
			}
Jiří Klimeš's avatar
Jiří Klimeš committed
812
		}
813
#endif
814

815
		/* IP configuration info */
Jiří Klimeš's avatar
Jiří Klimeš committed
816
		if (state == NM_DEVICE_STATE_ACTIVATED) {
817
818
			NMIP4Config *cfg4 = nm_device_get_ip4_config (device);
			NMIP6Config *cfg6 = nm_device_get_ip6_config (device);
819
820
			NMDHCP4Config *dhcp4 = nm_device_get_dhcp4_config (device);
			NMDHCP6Config *dhcp6 = nm_device_get_dhcp6_config (device);
821

822
			/* IP4 */
823
824
			if (cfg4 && !strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[7].name))
				was_output = print_ip4_config (cfg4, nmc, nmc_fields_dev_show_sections[7].name);
Jiří Klimeš's avatar
Jiří Klimeš committed
825

826
			/* DHCP4 */
827
828
			if (dhcp4 && !strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[8].name))
				was_output = print_dhcp4_config (dhcp4, nmc, nmc_fields_dev_show_sections[8].name);
829

830
			/* IP6 */
831
832
			if (cfg6 && !strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[9].name))
				was_output = print_ip6_config (cfg6, nmc, nmc_fields_dev_show_sections[9].name);
833

834
			/* DHCP6 */
835
836
			if (dhcp6 && !strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[10].name))
				was_output = print_dhcp6_config (dhcp6, nmc, nmc_fields_dev_show_sections[10].name);
837
		}
838
839
840

		/* Bond-specific information */
		if ((NM_IS_DEVICE_BOND (device))) {
841
			if (!strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[11].name)) {
842
843
844
845
846
847
848
849
850
851
				const GPtrArray *slaves;
				GString *bond_slaves_str;
				int idx;

				bond_slaves_str = g_string_new (NULL);
				slaves = nm_device_bond_get_slaves (NM_DEVICE_BOND (device));
				for (idx = 0; slaves && idx < slaves->len; idx++) {
					NMDevice *slave = g_ptr_array_index (slaves, idx);
					const char *iface = nm_device_get_iface (slave);

852
853
854
855
					if (iface) {
						g_string_append (bond_slaves_str, iface);
						g_string_append_c (bond_slaves_str, ' ');
					}
856
857
858
859
				}
				if (bond_slaves_str->len > 0)
					g_string_truncate (bond_slaves_str, bond_slaves_str->len-1);  /* Chop off last space */

860
				nmc->allowed_fields = nmc_fields_dev_show_bond_prop;
861
				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES;
862
				nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_SHOW_BOND_PROP_ALL, nmc->allowed_fields, NULL);
863
864
				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */

865
				nmc->allowed_fields[0].value = (char *) nmc_fields_dev_show_sections[11].name;  /* "BOND" */
866
867
868
869
870
871
872
873
874
875
				nmc->allowed_fields[1].value = bond_slaves_str->str;

				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */

				g_string_free (bond_slaves_str, TRUE);
				was_output = TRUE;
			}
		}

876
877
		/* VLAN-specific information */
		if ((NM_IS_DEVICE_VLAN (device))) {
878
			if (!strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[12].name)) {
879
880
				char * vlan_id_str = g_strdup_printf ("%u", nm_device_vlan_get_vlan_id (NM_DEVICE_VLAN (device)));