1 from os import system, popen, path as os_path, listdir
2 from re import compile as re_compile, search as re_search
4 from enigma import eConsoleAppContainer
5 from Components.Console import Console
6 from Components.PluginComponent import plugins
7 from Plugins.Plugin import PluginDescriptor
12 self.configuredInterfaces = []
13 self.configuredNetworkAdapters = []
17 self.ethtool_bin = "ethtool"
18 self.container = eConsoleAppContainer()
19 self.Console = Console()
20 self.LinkConsole = Console()
21 self.restartConsole = Console()
22 self.deactivateConsole = Console()
23 self.deactivateInterfaceConsole = Console()
24 self.activateConsole = Console()
25 self.resetNetworkConsole = Console()
26 self.DnsConsole = Console()
27 self.PingConsole = Console()
28 self.config_ready = None
29 self.friendlyNames = {}
30 self.lan_interfaces = []
31 self.wlan_interfaces = []
34 def onRemoteRootFS(self):
35 fp = file('/proc/mounts', 'r')
36 mounts = fp.readlines()
39 parts = line.strip().split(' ')
40 if parts[1] == '/' and (parts[2] == 'nfs' or parts[2] == 'smbfs'):
44 def getInterfaces(self, callback = None):
45 devicesPattern = re_compile('[a-z]+[0-9]+')
46 self.configuredInterfaces = []
47 fp = file('/proc/net/dev', 'r')
48 result = fp.readlines()
52 device = devicesPattern.search(line).group()
53 if device in ('wifi0', 'wmaster0'):
55 self.getDataForInterface(device, callback)
56 except AttributeError:
58 #print "self.ifaces:", self.ifaces
59 #self.writeNetworkConfig()
65 def regExpMatch(self, pattern, string):
69 return pattern.search(string).group()
70 except AttributeError:
73 # helper function to convert ips from a sring to a list of ints
74 def convertIP(self, ip):
81 def getDataForInterface(self, iface,callback):
82 #get ip out of ip addr, as avahi sometimes overrides it in ifconfig.
84 self.Console = Console()
86 self.Console.ePopen(cmd, self.IPaddrFinished, [iface,callback])
88 def IPaddrFinished(self, result, retval, extra_args):
89 (iface, callback ) = extra_args
90 data = { 'up': False, 'dhcp': False, 'preup' : False, 'postdown' : False }
91 globalIPpattern = re_compile("scope global")
92 ipRegexp = '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
93 netRegexp = '[0-9]{1,2}'
94 macRegexp = '[0-9]{2}\:[0-9]{2}\:[0-9]{2}\:[a-z0-9]{2}\:[a-z0-9]{2}\:[a-z0-9]{2}'
95 ipLinePattern = re_compile('inet ' + ipRegexp + '/')
96 ipPattern = re_compile(ipRegexp)
97 netmaskLinePattern = re_compile('/' + netRegexp)
98 netmaskPattern = re_compile(netRegexp)
99 bcastLinePattern = re_compile(' brd ' + ipRegexp)
100 upPattern = re_compile('UP')
101 macPattern = re_compile('[0-9]{2}\:[0-9]{2}\:[0-9]{2}\:[a-z0-9]{2}\:[a-z0-9]{2}\:[a-z0-9]{2}')
102 macLinePattern = re_compile('link/ether ' + macRegexp)
104 for line in result.splitlines():
105 split = line.strip().split(' ',2)
106 if (split[1][:-1] == iface):
107 up = self.regExpMatch(upPattern, split[2])
108 mac = self.regExpMatch(macPattern, self.regExpMatch(macLinePattern, split[2]))
111 if iface is not 'lo':
112 self.configuredInterfaces.append(iface)
115 if (split[1] == iface):
116 if re_search(globalIPpattern, split[2]):
117 ip = self.regExpMatch(ipPattern, self.regExpMatch(ipLinePattern, split[2]))
118 netmask = self.calc_netmask(self.regExpMatch(netmaskPattern, self.regExpMatch(netmaskLinePattern, split[2])))
119 bcast = self.regExpMatch(ipPattern, self.regExpMatch(bcastLinePattern, split[2]))
121 data['ip'] = self.convertIP(ip)
122 if netmask is not None:
123 data['netmask'] = self.convertIP(netmask)
124 if bcast is not None:
125 data['bcast'] = self.convertIP(bcast)
127 if not data.has_key('ip'):
129 data['ip'] = [0, 0, 0, 0]
130 data['netmask'] = [0, 0, 0, 0]
131 data['gateway'] = [0, 0, 0, 0]
133 cmd = "route -n | grep " + iface
134 self.Console.ePopen(cmd,self.routeFinished, [iface, data, callback])
136 def routeFinished(self, result, retval, extra_args):
137 (iface, data, callback) = extra_args
138 ipRegexp = '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
139 ipPattern = re_compile(ipRegexp)
140 ipLinePattern = re_compile(ipRegexp)
142 for line in result.splitlines():
144 if line[0:7] == "0.0.0.0":
145 gateway = self.regExpMatch(ipPattern, line[16:31])
146 if gateway is not None:
147 data['gateway'] = self.convertIP(gateway)
149 self.ifaces[iface] = data
150 self.loadNetworkConfig(iface,callback)
152 def writeNetworkConfig(self):
153 self.configuredInterfaces = []
154 fp = file('/etc/network/interfaces', 'w')
155 fp.write("# automatically generated by enigma 2\n# do NOT change manually!\n\n")
156 fp.write("auto lo\n")
157 fp.write("iface lo inet loopback\n\n")
158 for ifacename, iface in self.ifaces.items():
159 if iface['up'] == True:
160 fp.write("auto " + ifacename + "\n")
161 self.configuredInterfaces.append(ifacename)
162 if iface['dhcp'] == True:
163 fp.write("iface "+ ifacename +" inet dhcp\n")
164 if iface['dhcp'] == False:
165 fp.write("iface "+ ifacename +" inet static\n")
166 if iface.has_key('ip'):
167 print tuple(iface['ip'])
168 fp.write(" address %d.%d.%d.%d\n" % tuple(iface['ip']))
169 fp.write(" netmask %d.%d.%d.%d\n" % tuple(iface['netmask']))
170 if iface.has_key('gateway'):
171 fp.write(" gateway %d.%d.%d.%d\n" % tuple(iface['gateway']))
172 if iface.has_key("configStrings"):
173 fp.write("\n" + iface["configStrings"] + "\n")
174 if iface["preup"] is not False and not iface.has_key("configStrings"):
175 fp.write(iface["preup"])
176 fp.write(iface["postdown"])
179 self.writeNameserverConfig()
181 def writeNameserverConfig(self):
182 fp = file('/etc/resolv.conf', 'w')
183 for nameserver in self.nameservers:
184 fp.write("nameserver %d.%d.%d.%d\n" % tuple(nameserver))
187 def loadNetworkConfig(self,iface,callback = None):
189 # parse the interfaces-file
191 fp = file('/etc/network/interfaces', 'r')
192 interfaces = fp.readlines()
195 print "[Network.py] interfaces - opening failed"
200 split = i.strip().split(' ')
201 if (split[0] == "iface"):
204 if (len(split) == 4 and split[3] == "dhcp"):
205 ifaces[currif]["dhcp"] = True
207 ifaces[currif]["dhcp"] = False
208 if (currif == iface): #read information only for available interfaces
209 if (split[0] == "address"):
210 ifaces[currif]["address"] = map(int, split[1].split('.'))
211 if self.ifaces[currif].has_key("ip"):
212 if self.ifaces[currif]["ip"] != ifaces[currif]["address"] and ifaces[currif]["dhcp"] == False:
213 self.ifaces[currif]["ip"] = map(int, split[1].split('.'))
214 if (split[0] == "netmask"):
215 ifaces[currif]["netmask"] = map(int, split[1].split('.'))
216 if self.ifaces[currif].has_key("netmask"):
217 if self.ifaces[currif]["netmask"] != ifaces[currif]["netmask"] and ifaces[currif]["dhcp"] == False:
218 self.ifaces[currif]["netmask"] = map(int, split[1].split('.'))
219 if (split[0] == "gateway"):
220 ifaces[currif]["gateway"] = map(int, split[1].split('.'))
221 if self.ifaces[currif].has_key("gateway"):
222 if self.ifaces[currif]["gateway"] != ifaces[currif]["gateway"] and ifaces[currif]["dhcp"] == False:
223 self.ifaces[currif]["gateway"] = map(int, split[1].split('.'))
224 if (split[0] == "pre-up"):
225 if self.ifaces[currif].has_key("preup"):
226 self.ifaces[currif]["preup"] = i
227 if (split[0] == "post-down"):
228 if self.ifaces[currif].has_key("postdown"):
229 self.ifaces[currif]["postdown"] = i
231 for ifacename, iface in ifaces.items():
232 if self.ifaces.has_key(ifacename):
233 self.ifaces[ifacename]["dhcp"] = iface["dhcp"]
235 if len(self.Console.appContainers) == 0:
236 # save configured interfacelist
237 self.configuredNetworkAdapters = self.configuredInterfaces
239 self.loadNameserverConfig()
240 print "read configured interface:", ifaces
241 print "self.ifaces after loading:", self.ifaces
242 self.config_ready = True
244 if callback is not None:
247 def loadNameserverConfig(self):
248 ipRegexp = "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
249 nameserverPattern = re_compile("nameserver +" + ipRegexp)
250 ipPattern = re_compile(ipRegexp)
254 fp = file('/etc/resolv.conf', 'r')
255 resolv = fp.readlines()
257 self.nameservers = []
259 print "[Network.py] resolv.conf - opening failed"
262 if self.regExpMatch(nameserverPattern, line) is not None:
263 ip = self.regExpMatch(ipPattern, line)
265 self.nameservers.append(self.convertIP(ip))
267 print "nameservers:", self.nameservers
269 def deactivateNetworkConfig(self, callback = None):
270 if self.onRemoteRootFS():
271 if callback is not None:
274 self.deactivateConsole = Console()
276 self.commands.append("/etc/init.d/avahi-daemon stop")
277 for iface in self.ifaces.keys():
278 cmd = "ip addr flush " + iface
279 self.commands.append(cmd)
280 self.commands.append("/etc/init.d/networking stop")
281 self.commands.append("killall -9 udhcpc")
282 self.commands.append("rm /var/run/udhcpc*")
283 self.deactivateConsole.eBatch(self.commands, self.deactivateNetworkFinished, callback, debug=True)
285 def deactivateNetworkFinished(self,extra_args):
286 callback = extra_args
287 if len(self.deactivateConsole.appContainers) == 0:
288 if callback is not None:
291 def activateNetworkConfig(self, callback = None):
292 if self.onRemoteRootFS():
293 if callback is not None:
296 self.activateConsole = Console()
298 self.commands.append("/etc/init.d/networking start")
299 self.commands.append("/etc/init.d/avahi-daemon start")
300 self.activateConsole.eBatch(self.commands, self.activateNetworkFinished, callback, debug=True)
302 def activateNetworkFinished(self,extra_args):
303 callback = extra_args
304 if len(self.activateConsole.appContainers) == 0:
305 if callback is not None:
308 def getConfiguredAdapters(self):
309 return self.configuredNetworkAdapters
311 def getNumberOfAdapters(self):
312 return len(self.ifaces)
314 def getFriendlyAdapterName(self, x):
315 if x in self.friendlyNames.keys():
316 return self.friendlyNames.get(x, x)
318 self.friendlyNames[x] = self.getFriendlyAdapterNaming(x)
319 return self.friendlyNames.get(x, x) # when we have no friendly name, use adapter name
321 def getFriendlyAdapterNaming(self, iface):
322 if iface.startswith('eth'):
323 if iface not in self.lan_interfaces and len(self.lan_interfaces) == 0:
324 self.lan_interfaces.append(iface)
325 return _("LAN connection")
326 elif iface not in self.lan_interfaces and len(self.lan_interfaces) >= 1:
327 self.lan_interfaces.append(iface)
328 return _("LAN connection") + " " + str(len(self.lan_interfaces))
330 if iface not in self.wlan_interfaces and len(self.wlan_interfaces) == 0:
331 self.wlan_interfaces.append(iface)
332 return _("WLAN connection")
333 elif iface not in self.wlan_interfaces and len(self.wlan_interfaces) >= 1:
334 self.wlan_interfaces.append(iface)
335 return _("WLAN connection") + " " + str(len(self.wlan_interfaces))
337 def getFriendlyAdapterDescription(self, iface):
339 return _("Internal LAN adapter.")
341 classdir = "/sys/class/net/" + iface + "/device/"
342 driverdir = "/sys/class/net/" + iface + "/device/driver/"
343 if os_path.exists(classdir):
344 files = listdir(classdir)
345 if 'driver' in files:
346 if os_path.realpath(driverdir).endswith('ath_pci'):
347 return _("Atheros")+ " " + str(os_path.basename(os_path.realpath(driverdir))) + " " + _("WLAN adapter.")
348 elif os_path.realpath(driverdir).endswith('zd1211b'):
349 return _("Zydas")+ " " + str(os_path.basename(os_path.realpath(driverdir))) + " " + _("WLAN adapter.")
350 elif os_path.realpath(driverdir).endswith('rt73'):
351 return _("Ralink")+ " " + str(os_path.basename(os_path.realpath(driverdir))) + " " + _("WLAN adapter.")
353 return _("Unknown network adapter.")
355 return _("Unknown network adapter.")
357 def getAdapterName(self, iface):
360 def getAdapterList(self):
361 return self.ifaces.keys()
363 def getAdapterAttribute(self, iface, attribute):
364 if self.ifaces.has_key(iface):
365 if self.ifaces[iface].has_key(attribute):
366 return self.ifaces[iface][attribute]
369 def setAdapterAttribute(self, iface, attribute, value):
370 print "setting for adapter", iface, "attribute", attribute, " to value", value
371 if self.ifaces.has_key(iface):
372 self.ifaces[iface][attribute] = value
374 def removeAdapterAttribute(self, iface, attribute):
375 if self.ifaces.has_key(iface):
376 if self.ifaces[iface].has_key(attribute):
377 del self.ifaces[iface][attribute]
379 def getNameserverList(self):
380 if len(self.nameservers) == 0:
381 return [[0, 0, 0, 0], [0, 0, 0, 0]]
383 return self.nameservers
385 def clearNameservers(self):
386 self.nameservers = []
388 def addNameserver(self, nameserver):
389 if nameserver not in self.nameservers:
390 self.nameservers.append(nameserver)
392 def removeNameserver(self, nameserver):
393 if nameserver in self.nameservers:
394 self.nameservers.remove(nameserver)
396 def changeNameserver(self, oldnameserver, newnameserver):
397 if oldnameserver in self.nameservers:
398 for i in range(len(self.nameservers)):
399 if self.nameservers[i] == oldnameserver:
400 self.nameservers[i] = newnameserver
402 def resetNetworkConfig(self, mode='lan', callback = None):
403 if self.onRemoteRootFS():
404 if callback is not None:
407 self.resetNetworkConsole = Console()
409 self.commands.append("/etc/init.d/avahi-daemon stop")
410 for iface in self.ifaces.keys():
411 cmd = "ip addr flush " + iface
412 self.commands.append(cmd)
413 self.commands.append("/etc/init.d/networking stop")
414 self.commands.append("killall -9 udhcpc")
415 self.commands.append("rm /var/run/udhcpc*")
416 self.resetNetworkConsole.eBatch(self.commands, self.resetNetworkFinishedCB, [mode, callback], debug=True)
418 def resetNetworkFinishedCB(self, extra_args):
419 (mode, callback) = extra_args
420 if len(self.resetNetworkConsole.appContainers) == 0:
421 self.writeDefaultNetworkConfig(mode, callback)
423 def writeDefaultNetworkConfig(self,mode='lan', callback = None):
424 fp = file('/etc/network/interfaces', 'w')
425 fp.write("# automatically generated by enigma 2\n# do NOT change manually!\n\n")
426 fp.write("auto lo\n")
427 fp.write("iface lo inet loopback\n\n")
429 fp.write("auto wlan0\n")
430 fp.write("iface wlan0 inet dhcp\n")
431 if mode == 'wlan-mpci':
432 fp.write("auto ath0\n")
433 fp.write("iface ath0 inet dhcp\n")
435 fp.write("auto eth0\n")
436 fp.write("iface eth0 inet dhcp\n")
440 self.resetNetworkConsole = Console()
443 self.commands.append("ifconfig eth0 down")
444 self.commands.append("ifconfig ath0 down")
445 self.commands.append("ifconfig wlan0 up")
446 if mode == 'wlan-mpci':
447 self.commands.append("ifconfig eth0 down")
448 self.commands.append("ifconfig wlan0 down")
449 self.commands.append("ifconfig ath0 up")
451 self.commands.append("ifconfig eth0 up")
452 self.commands.append("ifconfig wlan0 down")
453 self.commands.append("ifconfig ath0 down")
454 self.commands.append("/etc/init.d/avahi-daemon start")
455 self.resetNetworkConsole.eBatch(self.commands, self.resetNetworkFinished, [mode,callback], debug=True)
457 def resetNetworkFinished(self,extra_args):
458 (mode, callback) = extra_args
459 if len(self.resetNetworkConsole.appContainers) == 0:
460 if callback is not None:
463 def checkNetworkState(self,statecallback):
464 # www.dream-multimedia-tv.de, www.heise.de, www.google.de
465 self.NetworkState = 0
466 cmd1 = "ping -c 1 82.149.226.170"
467 cmd2 = "ping -c 1 193.99.144.85"
468 cmd3 = "ping -c 1 209.85.135.103"
469 self.PingConsole = Console()
470 self.PingConsole.ePopen(cmd1, self.checkNetworkStateFinished,statecallback)
471 self.PingConsole.ePopen(cmd2, self.checkNetworkStateFinished,statecallback)
472 self.PingConsole.ePopen(cmd3, self.checkNetworkStateFinished,statecallback)
474 def checkNetworkStateFinished(self, result, retval,extra_args):
475 (statecallback) = extra_args
476 if self.PingConsole is not None:
478 self.PingConsole = None
479 statecallback(self.NetworkState)
481 self.NetworkState += 1
482 if len(self.PingConsole.appContainers) == 0:
483 statecallback(self.NetworkState)
485 def restartNetwork(self,callback = None):
486 if self.onRemoteRootFS():
487 if callback is not None:
490 self.restartConsole = Console()
491 self.config_ready = False
494 self.commands.append("/etc/init.d/avahi-daemon stop")
495 for iface in self.ifaces.keys():
496 cmd = "ip addr flush " + iface
497 self.commands.append(cmd)
498 self.commands.append("/etc/init.d/networking stop")
499 self.commands.append("killall -9 udhcpc")
500 self.commands.append("rm /var/run/udhcpc*")
501 self.commands.append("/etc/init.d/networking start")
502 self.commands.append("/etc/init.d/avahi-daemon start")
503 self.restartConsole.eBatch(self.commands, self.restartNetworkFinished, callback, debug=True)
505 def restartNetworkFinished(self,extra_args):
506 ( callback ) = extra_args
507 if callback is not None:
510 def getLinkState(self,iface,callback):
511 cmd = self.ethtool_bin + " " + iface
512 self.LinkConsole = Console()
513 self.LinkConsole.ePopen(cmd, self.getLinkStateFinished,callback)
515 def getLinkStateFinished(self, result, retval,extra_args):
516 (callback) = extra_args
518 if self.LinkConsole is not None:
519 if len(self.LinkConsole.appContainers) == 0:
522 def stopPingConsole(self):
523 if self.PingConsole is not None:
524 if len(self.PingConsole.appContainers):
525 for name in self.PingConsole.appContainers.keys():
526 self.PingConsole.kill(name)
528 def stopLinkStateConsole(self):
529 if self.LinkConsole is not None:
530 if len(self.LinkConsole.appContainers):
531 for name in self.LinkConsole.appContainers.keys():
532 self.LinkConsole.kill(name)
534 def stopDNSConsole(self):
535 if self.DnsConsole is not None:
536 if len(self.DnsConsole.appContainers):
537 for name in self.DnsConsole.appContainers.keys():
538 self.DnsConsole.kill(name)
540 def stopRestartConsole(self):
541 if self.restartConsole is not None:
542 if len(self.restartConsole.appContainers):
543 for name in self.restartConsole.appContainers.keys():
544 self.restartConsole.kill(name)
546 def stopGetInterfacesConsole(self):
547 if self.Console is not None:
548 if len(self.Console.appContainers):
549 for name in self.Console.appContainers.keys():
550 self.Console.kill(name)
552 def stopDeactivateInterfaceConsole(self):
553 if self.deactivateInterfaceConsole is not None:
554 if len(self.deactivateInterfaceConsole.appContainers):
555 for name in self.deactivateInterfaceConsole.appContainers.keys():
556 self.deactivateInterfaceConsole.kill(name)
558 def checkforInterface(self,iface):
559 if self.getAdapterAttribute(iface, 'up') is True:
562 ret=system("ifconfig " + iface + " up")
563 system("ifconfig " + iface + " down")
569 def checkDNSLookup(self,statecallback):
570 cmd1 = "nslookup www.dream-multimedia-tv.de"
571 cmd2 = "nslookup www.heise.de"
572 cmd3 = "nslookup www.google.de"
573 self.DnsConsole = Console()
574 self.DnsConsole.ePopen(cmd1, self.checkDNSLookupFinished,statecallback)
575 self.DnsConsole.ePopen(cmd2, self.checkDNSLookupFinished,statecallback)
576 self.DnsConsole.ePopen(cmd3, self.checkDNSLookupFinished,statecallback)
578 def checkDNSLookupFinished(self, result, retval,extra_args):
579 (statecallback) = extra_args
580 if self.DnsConsole is not None:
582 self.DnsConsole = None
583 statecallback(self.DnsState)
586 if len(self.DnsConsole.appContainers) == 0:
587 statecallback(self.DnsState)
589 def deactivateInterface(self,iface,callback = None):
590 if self.onRemoteRootFS():
591 if callback is not None:
594 self.deactivateInterfaceConsole = Console()
596 cmd1 = "ip addr flush " + iface
597 cmd2 = "ifconfig " + iface + " down"
598 self.commands.append(cmd1)
599 self.commands.append(cmd2)
600 self.deactivateInterfaceConsole.eBatch(self.commands, self.deactivateInterfaceFinished, callback, debug=True)
602 def deactivateInterfaceFinished(self,extra_args):
603 callback = extra_args
604 if self.deactivateInterfaceConsole:
605 if len(self.deactivateInterfaceConsole.appContainers) == 0:
606 if callback is not None:
609 def detectWlanModule(self):
610 self.wlanmodule = None
611 rt73_dir = "/sys/bus/usb/drivers/rt73/"
612 zd1211b_dir = "/sys/bus/usb/drivers/zd1211b/"
613 madwifi_dir = "/sys/bus/pci/drivers/ath_pci/"
614 if os_path.exists(madwifi_dir):
615 files = listdir(madwifi_dir)
617 self.wlanmodule = 'madwifi'
618 if os_path.exists(rt73_dir):
619 rtfiles = listdir(rt73_dir)
620 if len(rtfiles) == 2 or len(rtfiles) == 5:
621 self.wlanmodule = 'ralink'
622 if os_path.exists(zd1211b_dir):
623 zdfiles = listdir(zd1211b_dir)
624 if len(zdfiles) == 1 or len(zdfiles) == 5:
625 self.wlanmodule = 'zydas'
626 return self.wlanmodule
628 def calc_netmask(self,nmask):
629 from struct import pack, unpack
630 from socket import inet_ntoa, inet_aton
633 cidr_range = range(0, 32)
635 if cidr not in cidr_range:
636 print 'cidr invalid: %d' % cidr
639 nm = ((1L<<cidr)-1)<<(32-cidr)
640 netmask = str(inet_ntoa(pack('>L', nm)))
643 def msgPlugins(self):
644 if self.config_ready is not None:
645 for p in plugins.getPlugins(PluginDescriptor.WHERE_NETWORKCONFIG_READ):
646 p(reason=self.config_ready)