-
Notifications
You must be signed in to change notification settings - Fork 10
/
cnetworkmanager
executable file
·372 lines (320 loc) · 12.3 KB
/
cnetworkmanager
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
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
369
370
371
372
#!/usr/bin/python
VERSION = "0.21.1"
# must be set before we ask for signals
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
import sys
import os
import time
import dbus
from networkmanager import NetworkManager
from networkmanager.monitor import Monitor
from networkmanager.applet import NetworkManagerSettings, SYSTEM_SERVICE, USER_SERVICE
from networkmanager.applet.service import NetworkManagerUserSettings
import networkmanager.applet.settings as settings
from networkmanager.util import Table
import networkmanager.base
# for calling quit
import gobject
loop = gobject.MainLoop()
LOOP = False
from optparse import OptionParser
op = OptionParser(version="%prog " + VERSION)
op.add_option("-t", "--terse",
action="store_true", default=False,
help="No table headings and padding, suitable for parsing")
# TODO http://docs.python.org/lib/optparse-adding-new-types.html
op.add_option("-w", "--wifi",
choices=["0","1","off","on","no","yes","false","true"],
metavar="BOOL",
help="Enable or disable wireless")
op.add_option("-o", "--online",
choices=["0","1","off","on","no","yes","false","true"],
metavar="BOOL",
help="Enable or disable network at all")
op.add_option("--state",
action="store_true", default=False,
help="Print the NM state")
op.add_option("--we", "--wireless-enabled",
action="store_true", default=False,
help="Print whether the WiFi is enabled")
op.add_option("--whe", "--wireless-hardware-enabled",
action="store_true", default=False,
help="Print whether the WiFi hardware is enabled")
op.add_option("-d", "--device-list", "--dev",
action="store_true", default=False,
help="List devices")
op.add_option("--device-info", "--di",
help="Info about device DEV (by interface or UDI(TODO))",
metavar="DEV")
op.add_option("-a", "--ap-list", "--ap", "-n", "--nets",# -n is a stopgap
action="store_true", default=False,
help="List access points")
op.add_option("--ap-info", "--ai",
help="Info about access point AP (by hw address or UDI(TODO))",
metavar="AP")
op.add_option("-u", "--usrcon",
action="store_true", default=False,
help="List user connection settings")
op.add_option("-s", "--syscon",
action="store_true", default=False,
help="List system connection settings")
op.add_option("--con-info", "--ci",
help="Info about connection settings ID (of the *user*/system KIND)",
metavar="[KIND,]ID")
op.add_option("-c", "--actcon",
action="store_true", default=False,
help="List active connections")
op.add_option("--demo",
action="store_true", default=False,
help="Run a random demonstration of the API")
op.add_option("--activate-connection",
help="activate the KIND(user/system) connection ID on device DEV using APMAC.",
metavar="[KIND],ID,[DEV],[APMAC]")
op.add_option("-m", "--monitor",
action="store_true", default=False,
help="loop to show dbus signals")
op.add_option("-C", "--connect",
help="Connect to a wireless network SSID (creating the configuration using the key options below)",
metavar="SSID")
op.add_option("--unprotected",
action="store_true", default=False,
help="network does not require a key")
op.add_option("--wep-hex",
metavar="KEY",
help="use this WEP key of 26 hex digits")
op.add_option("--wep-pass",
metavar="KEY",
help="use this WEP passphrase")
op.add_option("--wpa-psk-hex",
metavar="KEY",
help="use this WPA key of 64 hex digits")
op.add_option("--wpa-pass",
metavar="KEY",
help="use this WPA passphrase")
op.add_option("--session",
action="store_true", default=False,
help="Connect to the session bus for testing")
(options, args) = op.parse_args()
Table.terse = options.terse
# TODO: CNM_OPTS, like nmcli
if options.session or os.getenv("CNETWORKMANAGER_TEST") != None:
networkmanager.base.NM_BUS = dbus.SessionBus()
nm = NetworkManager()
true_choices = ["1", "on", "yes", "true"]
if options.wifi != None:
nm["WirelessEnabled"] = options.wifi in true_choices
if options.we:
print nm["WirelessEnabled"]
if options.online != None:
try:
nm.Sleep(not options.online in true_choices)
except dbus.exceptions.DBusException, e:
if e.get_dbus_name() != "org.freedesktop.NetworkManager.AlreadyAsleepOrAwake":
raise
if options.state:
print nm["State"]
if options.whe:
print nm["WirelessHardwareEnabled"]
# style option: pretend that properties are methods (er, python properties)
# nm["WirelessEnabled"] -> nm.WirelessEnabled() (er, nm.WirelessEnabled )
if options.device_list:
devs = nm.GetDevices()
t = Table("Interface", "Type", "State")
for dev in devs:
t.row(dev["Interface"], dev["DeviceType"], dev["State"])
print t
# --device-info, TODO clean up
def get_device(dev_spec, hint):
candidates = []
# print "Hint:", hint
devs = NetworkManager().GetDevices()
for dev in devs:
# print dev
if dev._settings_type() == hint:
candidates.append(dev)
# print "Candidates:", candidates
if len(candidates) == 1:
return candidates[0]
for dev in devs:
if dev["Interface"] == dev_spec:
return dev
print "Device '%s' not found" % dev_spec
return None
if options.device_info != None:
d = get_device(options.device_info, "no hint")
if d == None:
print "not found"
else:
props = ["Udi", "Interface", "Driver", "Capabilities",
# "Ip4Address", # bogus, remembers last addr even after disused
"State",
# "Ip4Config", "Dhcp4Config", # only __repr__
"Managed", "DeviceType"]
if d._settings_type() == "802-11-wireless":
props.extend(["Mode", "WirelessCapabilities"])
elif d._settings_type() == "802-3-ethernet":
props.extend(["Carrier"])
print Table.from_items(d, *props)
if options.ap_list:
devs = nm.GetDevices()
# nm.get_wifi_devices()
# nm.get_devices_by_type(Device.Type.WIRELESS)
for dev in filter(lambda d: d._settings_type() == "802-11-wireless", devs):
aap = dev["ActiveAccessPoint"]
t = Table("Active", "HwAddress", "Ssid")
for ap in dev.GetAccessPoints():
active = "*" if ap.object_path == aap.object_path else ""
t.row(active, ap["HwAddress"], ap["Ssid"])
print t
if options.ap_info != None:
devs = nm.GetDevices()
for dev in filter(lambda d: d._settings_type() == "802-11-wireless", devs):
aap = dev["ActiveAccessPoint"]
for ap in dev.GetAccessPoints():
if ap["HwAddress"] == options.ap_info:
t = Table.from_items(ap, "Flags", "WpaFlags", "RsnFlags",
"Ssid", "Frequency", "HwAddress",
"Mode", "MaxBitrate", "Strength")
t.row("Active", ap.object_path == aap.object_path)
print t
#def is_opath(x):
# return is_instance(x, str) and x[0] == "/"
def get_service_name(svc):
if svc == "" or svc == "user":
svc = USER_SERVICE
elif svc == "system":
svc = SYSTEM_SERVICE
return svc
# move this to networkmanagersettings
def get_connection(svc, conn_spec):
# if is_opath(conn_spec):
# return conn_spec
applet = NetworkManagerSettings(get_service_name(svc))
for conn in applet.ListConnections():
cs = conn.GetSettings()
if cs["connection"]["id"] == conn_spec:
return conn
print "Connection '%s' not found" % conn_spec
return None
def get_connection_devtype(conn):
cs = conn.GetSettings()
return cs["connection"]["type"]
def list_connections(svc):
acs = nm["ActiveConnections"]
acos = map(lambda a: a["Connection"].object_path, acs)
try:
applet = NetworkManagerSettings(svc)
except dbus.exceptions.DBusException, e:
print e
return
t = Table("Active", "Name", "Type")
for conn in applet.ListConnections():
cs = conn.GetSettings()
active = "*" if conn.object_path in acos else ""
t.row(active, cs["connection"]["id"], cs["connection"]["type"])
print t
if options.usrcon:
list_connections(USER_SERVICE)
if options.syscon:
list_connections(SYSTEM_SERVICE)
if options.con_info != None:
(svc, con) = ("", options.con_info)
if "," in con:
(svc, con) = con.split(",")
c = get_connection(svc, con)
cs = c.GetSettings()
print Table.from_nested_dict(cs)
type = cs["connection"]["type"]
secu = cs[type]["security"]
cse = c.GetSecrets(secu, [], False)
print Table.from_nested_dict(cse)
# this shows we do need to add __str__ to the objects
if options.actcon:
acs = nm["ActiveConnections"]
t = Table("State", "Name", "AP", "Devices", "Default route")
for ac in acs:
cid = ac["Connection"].GetSettings()["connection"]["id"]
try:
apmac = ac["SpecificObject"]["HwAddress"]
except: # no AP for wired. TODO figure out "/" object
apmac = ""
devs = ", ".join(map(lambda d: d["Interface"], ac["Devices"]))
hdr = "*" if ac["Default"] else ""
t.row(ac["State"], cid, apmac, devs, hdr)
print t
if options.monitor:
m = Monitor()
LOOP = True
def print_state_changed(*args):
print time.strftime("(%X)"),
print "State:", ", ".join(map(str,args))
if options.connect != None:
ssid = options.connect
try:
us = NetworkManagerUserSettings([]) # request_name may fail
except dbus.exceptions.NameExistsException, e:
print "Another applet is running:", e
sys.exit(1)
c = None
if options.unprotected:
c = settings.WiFi(ssid)
if options.wep_hex != None:
c = settings.Wep(ssid, "", options.wep_hex)
if options.wep_pass != None:
c = settings.Wep(ssid, options.wep_pass)
if options.wpa_psk_hex != None:
c = settings.WpaPsk(ssid, "", options.wpa_psk_hex)
if options.wpa_pass != None:
c = settings.WpaPsk(ssid, options.wpa_pass)
if c == None:
print "Error, connection settings not specified"
sys.exit(1)
svc = USER_SERVICE
svc_conn = us.addCon(c.conmap)
hint = svc_conn.settings["connection"]["type"]
dev = get_device("", hint)
appath = "/"
nm._connect_to_signal("StateChanged", print_state_changed)
# must be async because ourselves are providing the service
dummy_handler = lambda *args: None
nm.ActivateConnection(svc, svc_conn, dev, appath,
reply_handler=dummy_handler,
error_handler=dummy_handler)
LOOP = True
if options.activate_connection != None:
(svc, conpath, devpath, appath) = options.activate_connection.split(',')
svc = get_service_name(svc)
conn = get_connection(svc, conpath)
hint = get_connection_devtype(conn)
dev = get_device(devpath, hint)
if appath == "":
appath = "/"
nm._connect_to_signal("StateChanged", print_state_changed)
# TODO make it accept both objects and opaths
nm.ActivateConnection(svc, conn, dev, appath)
# TODO (optionally) block only until a stable state is reached
LOOP = True
######## demo ##########
if options.demo:
from dbusclient import DBusMio
mio = DBusMio(networkmanager.base.Bus(), "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager")
i = mio.Introspect()
d = mio.GetDevices()
nm = NetworkManager()
# TODO: generic signal (adapt cnm monitor), print name and args
nm["WirelessEnabled"] = "yes"
devs = nm.GetDevices()
for d in devs:
print "\n DEVICE"
# TODO: find API for any object
d._connect_to_signal("StateChanged", print_state_changed)
LOOP = True
######## demo end ##########
# TODO wrap this
if LOOP:
try:
print "Entering mainloop"
loop.run()
except KeyboardInterrupt:
print "Loop exited"