Guest User

Untitled

a guest
Oct 12th, 2018
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.04 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  3. #
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation; either version 2 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details:
  13. #
  14. # Copyright (C) 2008 Novell, Inc.
  15. # Copyright (C) 2009 Red Hat, Inc.
  16. # Copyright (C) 2011 Markus Rothe <markus@unixforces.net>
  17. #
  18. # based on mm-test.py from ModemManager
  19. #
  20.  
  21. import argparse
  22. import sys
  23. import dbus
  24. import time
  25. import os
  26. import string
  27. import subprocess
  28. import socket
  29.  
  30. DEFAULT_APN='internet.eplus.de'
  31. DEFAULT_USER='blau'
  32. DEFAULT_PASS='blau'
  33.  
  34. DBUS_INTERFACE_PROPERTIES='org.freedesktop.DBus.Properties'
  35. MM_DBUS_SERVICE='org.freedesktop.ModemManager'
  36. MM_DBUS_PATH='/org/freedesktop/ModemManager'
  37. MM_DBUS_INTERFACE='org.freedesktop.ModemManager'
  38. MM_DBUS_INTERFACE_MODEM='org.freedesktop.ModemManager.Modem'
  39. MM_DBUS_INTERFACE_MODEM_CDMA='org.freedesktop.ModemManager.Modem.Cdma'
  40. MM_DBUS_INTERFACE_MODEM_GSM_CARD='org.freedesktop.ModemManager.Modem.Gsm.Card'
  41. MM_DBUS_INTERFACE_MODEM_GSM_NETWORK='org.freedesktop.ModemManager.Modem.Gsm.Network'
  42. MM_DBUS_INTERFACE_MODEM_SIMPLE='org.freedesktop.ModemManager.Modem.Simple'
  43.  
  44. def get_cdma_band_class(band_class):
  45. if band_class == 1:
  46. return "800MHz"
  47. elif band_class == 2:
  48. return "1900MHz"
  49. else:
  50. return "Unknown"
  51.  
  52. def get_reg_state(state):
  53. if state == 1:
  54. return "registered (roaming unknown)"
  55. elif state == 2:
  56. return "registered on home network"
  57. elif state == 3:
  58. return "registered on roaming network"
  59. else:
  60. return "unknown"
  61.  
  62. def cdma_inspect(proxy, show_private):
  63. cdma = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM_CDMA)
  64.  
  65. esn = "<private>"
  66. if show_private:
  67. try:
  68. esn = cdma.GetEsn()
  69. except dbus.exceptions.DBusException:
  70. esn = "<unavailable>"
  71.  
  72. print ""
  73. print "ESN: %s" % esn
  74.  
  75. try:
  76. (cdma_1x_state, evdo_state) = cdma.GetRegistrationState()
  77. print "1x State: %s" % get_reg_state (cdma_1x_state)
  78. print "EVDO State: %s" % get_reg_state (evdo_state)
  79. except dbus.exceptions.DBusException, e:
  80. print "Error reading registration state: %s" % e
  81.  
  82. try:
  83. quality = cdma.GetSignalQuality()
  84. print "Signal quality: %d" % quality
  85. except dbus.exceptions.DBusException, e:
  86. print "Error reading signal quality: %s" % e
  87.  
  88. try:
  89. info = cdma.GetServingSystem()
  90. print "Class: %s" % get_cdma_band_class(info[0])
  91. print "Band: %s" % info[1]
  92. print "SID: %d" % info[2]
  93. except dbus.exceptions.DBusException, e:
  94. print "Error reading serving system: %s" % e
  95.  
  96. def cdma_connect(proxy, user, password):
  97. # Modem.Simple interface
  98. simple = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM_SIMPLE)
  99. try:
  100. simple.Connect({'number':"#777"}, timeout=92)
  101. print "\nConnected!"
  102. return True
  103. except Exception, e:
  104. print "Error connecting: %s" % e
  105. return False
  106.  
  107. def get_gsm_network_mode(modem):
  108. mode = modem.GetNetworkMode()
  109. if mode == 0x0:
  110. mode = "Unknown"
  111. elif mode == 0x1:
  112. mode = "Any"
  113. elif mode == 0x2:
  114. mode = "GPRS"
  115. elif mode == 0x4:
  116. mode = "EDGE"
  117. elif mode == 0x8:
  118. mode = "UMTS"
  119. elif mode == 0x10:
  120. mode = "HSDPA"
  121. elif mode == 0x20:
  122. mode = "2G Preferred"
  123. elif mode == 0x40:
  124. mode = "3G Preferred"
  125. elif mode == 0x80:
  126. mode = "2G Only"
  127. elif mode == 0x100:
  128. mode = "3G Only"
  129. elif mode == 0x200:
  130. mode = "HSUPA"
  131. elif mode == 0x400:
  132. mode = "HSPA"
  133. else:
  134. mode = "(Unknown)"
  135.  
  136. print "Mode: %s" % mode
  137.  
  138. def get_gsm_band(modem):
  139. band = modem.GetBand()
  140. if band == 0x0:
  141. band = "Unknown"
  142. elif band == 0x1:
  143. band = "Any"
  144. elif band == 0x2:
  145. band = "EGSM (900 MHz)"
  146. elif band == 0x4:
  147. band = "DCS (1800 MHz)"
  148. elif band == 0x8:
  149. band = "PCS (1900 MHz)"
  150. elif band == 0x10:
  151. band = "G850 (850 MHz)"
  152. elif band == 0x20:
  153. band = "U2100 (WCSMA 2100 MHZ, Class I)"
  154. elif band == 0x40:
  155. band = "U1700 (WCDMA 3GPP UMTS1800 MHz, Class III)"
  156. elif band == 0x80:
  157. band = "17IV (WCDMA 3GPP AWS 1700/2100 MHz, Class IV)"
  158. elif band == 0x100:
  159. band = "U800 (WCDMA 3GPP UMTS800 MHz, Class VI)"
  160. elif band == 0x200:
  161. band = "U850 (WCDMA 3GPP UMT850 MHz, Class V)"
  162. elif band == 0x400:
  163. band = "U900 (WCDMA 3GPP UMTS900 MHz, Class VIII)"
  164. elif band == 0x800:
  165. band = "U17IX (WCDMA 3GPP UMTS MHz, Class IX)"
  166. else:
  167. band = "(invalid)"
  168.  
  169. print "Band: %s" % band
  170.  
  171. def gsm_inspect(proxy, show_private, do_scan):
  172. # Gsm.Card interface
  173. card = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM_GSM_CARD)
  174.  
  175. imei = "<private>"
  176. imsi = "<private>"
  177. if show_private:
  178. try:
  179. imei = card.GetImei()
  180. except dbus.exceptions.DBusException:
  181. imei = "<unavailable>"
  182. try:
  183. imsi = card.GetImsi()
  184. except dbus.exceptions.DBusException:
  185. imsi = "<unavailable>"
  186.  
  187. print "IMEI: %s" % imei
  188. print "IMSI: %s" % imsi
  189.  
  190. # Gsm.Network interface
  191. net = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM_GSM_NETWORK)
  192. try:
  193. quality = net.GetSignalQuality()
  194. print "Signal quality: %d" % quality
  195. except dbus.exceptions.DBusException, e:
  196. print "Error reading signal quality: %s" % e
  197.  
  198. if not do_scan:
  199. return
  200.  
  201. print "Scanning..."
  202. try:
  203. results = net.Scan(timeout=120)
  204. except dbus.exceptions.DBusException, e:
  205. print "Error scanning: %s" % e
  206. results = {}
  207.  
  208. for r in results:
  209. status = r['status']
  210. if status == "1":
  211. status = "available"
  212. elif status == "2":
  213. status = "current"
  214. elif status == "3":
  215. status = "forbidden"
  216. else:
  217. status = "(Unknown)"
  218.  
  219. access_tech = ""
  220. try:
  221. access_tech_num = r['access-tech']
  222. if access_tech_num == "0":
  223. access_tech = "(GSM)"
  224. elif access_tech_num == "1":
  225. access_tech = "(Compact GSM)"
  226. elif access_tech_num == "2":
  227. access_tech = "(UMTS)"
  228. elif access_tech_num == "3":
  229. access_tech = "(EDGE)"
  230. elif access_tech_num == "4":
  231. access_tech = "(HSDPA)"
  232. elif access_tech_num == "5":
  233. access_tech = "(HSUPA)"
  234. elif access_tech_num == "6":
  235. access_tech = "(HSPA)"
  236. except KeyError:
  237. pass
  238.  
  239. if r.has_key('operator-long') and len(r['operator-long']):
  240. print "%s: %s %s" % (r['operator-long'], status, access_tech)
  241. elif r.has_key('operator-short') and len(r['operator-short']):
  242. print "%s: %s %s" % (r['operator-short'], status, access_tech)
  243. else:
  244. print "%s: %s %s" % (r['operator-num'], status, access_tech)
  245.  
  246. def gsm_connect(proxy, apn, user, password):
  247. # Modem.Simple interface
  248. simple = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM_SIMPLE)
  249. try:
  250. opts = {'number':"*99#"}
  251. if apn is not None:
  252. opts['apn'] = apn
  253. if user is not None:
  254. opts['username'] = user
  255. if password is not None:
  256. opts['password'] = password
  257. simple.Connect(opts, timeout=120)
  258. print "\nConnected!"
  259. return True
  260. except Exception, e:
  261. print "Error connecting: %s" % e
  262. return False
  263.  
  264. def pppd_find():
  265. paths = ["/usr/local/sbin/pppd", "/usr/sbin/pppd", "/sbin/pppd"]
  266. for p in paths:
  267. if os.path.exists(p):
  268. return p
  269. return None
  270.  
  271. def ppp_start(device, user, password, tmpfile):
  272. path = pppd_find()
  273. if not path:
  274. return None
  275.  
  276. args = [path]
  277. args += ["defaultroute"]
  278. args += ["nodetach"]
  279. args += ["lock"]
  280. if user:
  281. args += ["user"]
  282. args += [user]
  283. args += ["noipdefault"]
  284. args += ["115200"]
  285. args += ["noauth"]
  286. args += ["crtscts"]
  287. args += ["usepeerdns"]
  288. args += ["ipparam"]
  289.  
  290. ipparam = ""
  291. if user:
  292. ipparam += user
  293. ipparam += "+"
  294. if password:
  295. ipparam += password
  296. ipparam += "+"
  297. ipparam += tmpfile
  298. args += [ipparam]
  299.  
  300. # args += ["plugin"]
  301. # args += ["mm-test-pppd-plugin.so"]
  302.  
  303. args += [device]
  304.  
  305. return subprocess.Popen(args, close_fds=True, cwd="/", env={})
  306.  
  307. def ppp_wait(p, tmpfile):
  308. i = 0
  309. while p.poll() == None and i < 30:
  310. time.sleep(1)
  311. if os.path.exists(tmpfile):
  312. f = open(tmpfile, 'r')
  313. stuff = f.read(500)
  314. idx = string.find(stuff, "DONE")
  315. f.close()
  316. if idx >= 0:
  317. return True
  318. i += 1
  319. return False
  320.  
  321. def ppp_stop(p):
  322. import signal
  323. p.send_signal(signal.SIGTERM)
  324. p.wait()
  325.  
  326. def ntop_helper(ip):
  327. ip = socket.ntohl(ip)
  328. n1 = ip >> 24 & 0xFF
  329. n2 = ip >> 16 & 0xFF
  330. n3 = ip >> 8 & 0xFF
  331. n4 = ip & 0xFF
  332. a = "%c%c%c%c" % (n1, n2, n3, n4)
  333. return socket.inet_ntop(socket.AF_INET, a)
  334.  
  335. def static_start(iface, modem):
  336. (addr_num, dns1_num, dns2_num, dns3_num) = modem.GetIP4Config()
  337. addr = ntop_helper(addr_num)
  338. dns1 = ntop_helper(dns1_num)
  339. dns2 = ntop_helper(dns2_num)
  340. configure_iface(iface, addr, 0, dns1, dns2)
  341.  
  342. def down_iface(iface):
  343. ip = ["ip", "addr", "flush", "dev", iface]
  344. print " ".join(ip)
  345. subprocess.call(ip)
  346. ip = ["ip", "link", "set", iface, "down"]
  347. print " ".join(ip)
  348. subprocess.call(ip)
  349.  
  350. def configure_iface(iface, addr, gw, dns1, dns2):
  351. print "\n\n******************************"
  352. print "iface: %s" % iface
  353. print "addr: %s" % addr
  354. print "gw: %s" % gw
  355. print "dns1: %s" % dns1
  356. print "dns2: %s" % dns2
  357.  
  358. ifconfig = ["ifconfig", iface, "%s/32" % addr]
  359. if gw != 0:
  360. ifconfig += ["pointopoint", gw]
  361. print " ".join(ifconfig)
  362. print "\n******************************\n"
  363.  
  364. subprocess.call(ifconfig)
  365.  
  366. def file_configure_iface(tmpfile):
  367. addr = None
  368. gw = None
  369. iface = None
  370. dns1 = None
  371. dns2 = None
  372.  
  373. f = open(tmpfile, 'r')
  374. lines = f.readlines()
  375. for l in lines:
  376. if l.startswith("addr"):
  377. addr = l[len("addr"):].strip()
  378. if l.startswith("gateway"):
  379. gw = l[len("gateway"):].strip()
  380. if l.startswith("iface"):
  381. iface = l[len("iface"):].strip()
  382. if l.startswith("dns1"):
  383. dns1 = l[len("dns1"):].strip()
  384. if l.startswith("dns2"):
  385. dns2 = l[len("dns2"):].strip()
  386. f.close()
  387.  
  388. configure_iface(iface, addr, gw, dns1, dns2)
  389. return iface
  390.  
  391. def try_ping(iface):
  392. cmd = ["ping", "-I", iface, "-c", "4", "-i", "3", "-w", "20", "4.2.2.1"]
  393. print " ".join(cmd)
  394. retcode = subprocess.call(cmd)
  395. if retcode != 0:
  396. print "PING: failed"
  397. else:
  398. print "PING: success"
  399.  
  400. def connect(args):
  401. bus = dbus.SystemBus()
  402.  
  403. # Get available modems:
  404. manager_proxy = bus.get_object('org.freedesktop.ModemManager', '/org/freedesktop/ModemManager')
  405. manager_iface = dbus.Interface(manager_proxy, dbus_interface='org.freedesktop.ModemManager')
  406. modems = manager_iface.EnumerateDevices()
  407.  
  408. if not modems:
  409. print "No modems found"
  410. sys.exit(1)
  411.  
  412. for m in modems:
  413. connect_success = False
  414. data_device = None
  415.  
  416. proxy = bus.get_object(MM_DBUS_SERVICE, m)
  417.  
  418. # Properties
  419. props_iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.DBus.Properties')
  420.  
  421. type = props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'Type')
  422. if type == 1:
  423. print "GSM modem"
  424. elif type == 2:
  425. print "CDMA modem"
  426. else:
  427. print "Invalid modem type: %d" % type
  428.  
  429. print "Driver: '%s'" % (props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'Driver'))
  430. print "Modem device: '%s'" % (props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'MasterDevice'))
  431. data_device = props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'Device')
  432. print "Data device: '%s'" % data_device
  433.  
  434. # Modem interface
  435. modem = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM)
  436.  
  437. try:
  438. modem.Enable(True)
  439. except dbus.exceptions.DBusException, e:
  440. print "Error enabling modem: %s" % e
  441. sys.exit(1)
  442.  
  443. info = modem.GetInfo()
  444. print "Vendor: %s" % info[0]
  445. print "Model: %s" % info[1]
  446. print "Version: %s" % info[2]
  447.  
  448. if type == 1:
  449. gsm_inspect(proxy, args.show_private, False)
  450. connect_success = gsm_connect(proxy, args.apn, args.username, args.password)
  451. elif type == 2:
  452. cdma_inspect(proxy, args.show_private)
  453. connect_success = cdma_connect(proxy, args.username, args.password)
  454. print
  455.  
  456. if connect_success:
  457. tmpfile = "/tmp/mm-test-%d.tmp" % os.getpid()
  458. success = False
  459. try:
  460. ip_method = props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'IpMethod')
  461. if ip_method == 0:
  462. # ppp
  463. p = ppp_start(data_device, args.username, args.password, tmpfile)
  464. if ppp_wait(p, tmpfile):
  465. data_device = file_configure_iface(tmpfile)
  466. success = True
  467. elif ip_method == 1:
  468. # static
  469. if os.geteuid() != 0:
  470. print "You probably want to be root"
  471. sys.exit(1)
  472.  
  473. static_start(data_device, modem)
  474. success = True
  475. elif ip_method == 2:
  476. # dhcp
  477. pass
  478. except Exception, e:
  479. print "Error setting up IP: %s" % e
  480.  
  481. def scan(args):
  482. print "Connecting..."
  483. bus = dbus.SystemBus()
  484.  
  485. # Get available modems:
  486. manager_proxy = bus.get_object('org.freedesktop.ModemManager', '/org/freedesktop/ModemManager')
  487. manager_iface = dbus.Interface(manager_proxy, dbus_interface='org.freedesktop.ModemManager')
  488. modems = manager_iface.EnumerateDevices()
  489.  
  490. if not modems:
  491. print "No modems found"
  492. sys.exit(1)
  493.  
  494. for m in modems:
  495. connect_success = False
  496. data_device = None
  497.  
  498. proxy = bus.get_object(MM_DBUS_SERVICE, m)
  499.  
  500. # Properties
  501. props_iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.DBus.Properties')
  502.  
  503. type = props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'Type')
  504. if type == 1:
  505. print "GSM modem"
  506. elif type == 2:
  507. print "CDMA modem"
  508. else:
  509. print "Invalid modem type: %d" % type
  510.  
  511. print "Driver: '%s'" % (props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'Driver'))
  512. print "Modem device: '%s'" % (props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'MasterDevice'))
  513. data_device = props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'Device')
  514. print "Data device: '%s'" % data_device
  515.  
  516. # Modem interface
  517. modem = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM)
  518.  
  519. try:
  520. modem.Enable(True)
  521. except dbus.exceptions.DBusException, e:
  522. print "Error enabling modem: %s" % e
  523. sys.exit(1)
  524.  
  525. info = modem.GetInfo()
  526. print "Vendor: %s" % info[0]
  527. print "Model: %s" % info[1]
  528. print "Version: %s" % info[2]
  529.  
  530. if type == 1:
  531. gsm_inspect(proxy, args.show_private, True)
  532. elif type == 2:
  533. cdma_inspect(proxy, args.show_private)
  534. print "Sorry, no scanning available with CDMA"
  535. print
  536.  
  537. def disconnect(args):
  538. print "Disconnecting..."
  539.  
  540. bus = dbus.SystemBus()
  541.  
  542. # Get available modems:
  543. manager_proxy = bus.get_object('org.freedesktop.ModemManager', '/org/freedesktop/ModemManager')
  544. manager_iface = dbus.Interface(manager_proxy, dbus_interface='org.freedesktop.ModemManager')
  545. modems = manager_iface.EnumerateDevices()
  546.  
  547. if not modems:
  548. print "No modems found"
  549. sys.exit(1)
  550.  
  551. for m in modems:
  552. connect_success = False
  553. data_device = None
  554.  
  555. proxy = bus.get_object(MM_DBUS_SERVICE, m)
  556.  
  557. # Properties
  558. props_iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.DBus.Properties')
  559.  
  560. type = props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'Type')
  561. if type == 1:
  562. print "GSM modem"
  563. elif type == 2:
  564. print "CDMA modem"
  565. else:
  566. print "Invalid modem type: %d" % type
  567.  
  568. print "Driver: '%s'" % (props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'Driver'))
  569. print "Modem device: '%s'" % (props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'MasterDevice'))
  570. data_device = props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'Device')
  571. print "Data device: '%s'" % data_device
  572.  
  573. # Modem interface
  574. modem = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM)
  575. # try:
  576. # if ip_method == 0:
  577. # ppp_stop(p)
  578. # try:
  579. # os.remove(tmpfile)
  580. # except:
  581. # pass
  582. # elif ip_method == 1:
  583. # # static
  584. # down_iface(data_device)
  585. # elif ip_method == 2:
  586. # # dhcp
  587. # down_iface(data_device)
  588. #
  589. # modem.Disconnect()
  590. # except Exception, e:
  591. # print "Error tearing down IP: %s" % e
  592. #
  593. #
  594. modem.Disconnect()
  595.  
  596. time.sleep(5)
  597. modem.Enable(False)
  598.  
  599. def main():
  600. #
  601. # option parsing
  602. #
  603. parser = argparse.ArgumentParser(description='Set up a connection using ModemManager.')
  604. subparsers = parser.add_subparsers()
  605.  
  606. common_parser = argparse.ArgumentParser(add_help=False)
  607. common_parser.add_argument('--show-private', '-s', action='store_true', help='Show private data (e.g. IMSI)')
  608.  
  609. # create the parser for the "connect" command
  610. parser_connect = subparsers.add_parser('connect', parents=[common_parser], help='Open the connection')
  611. parser_connect.add_argument('--apn', '-a', type=str, default=DEFAULT_APN, help='Access Point Name')
  612. parser_connect.add_argument('--username', '--user', '-u', type=str, default=DEFAULT_USER, help='Username for APN')
  613. parser_connect.add_argument('--password', '--pass', '-p', type=str, default=DEFAULT_PASS, help='Password for APN')
  614. parser_connect.set_defaults(func=connect)
  615.  
  616. # create the parser for the "disconnect" command
  617. parser_disconnect = subparsers.add_parser('disconnect', help='Close the connection')
  618. parser_disconnect.set_defaults(func=disconnect)
  619.  
  620. # create the parser for the "scan" command
  621. parser_scan = subparsers.add_parser('scan', parents=[common_parser], help='Do a network scan')
  622. parser_scan.set_defaults(func=scan)
  623.  
  624. args = parser.parse_args()
  625. args.func(args)
  626.  
  627. if __name__ == '__main__':
  628. main()
Add Comment
Please, Sign In to add comment