Skip to content

Commit

Permalink
Merge pull request #13 from lwindg/develop
Browse files Browse the repository at this point in the history
Use netifaces to speedup query time.
  • Loading branch information
lwindg committed Jun 2, 2015
2 parents fbee600 + bcb2dbb commit 780b4ef
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 72 deletions.
2 changes: 1 addition & 1 deletion bundle.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "route",
"version": "0.9.3",
"version": "0.9.4",
"author": "Aeluin Chen",
"email": "[email protected]",
"description": "Handle the routing table",
Expand Down
53 changes: 16 additions & 37 deletions ip/addr.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import os
import sh
import netifaces
import ipcalc
import logging

Expand All @@ -18,7 +18,7 @@
# https://pypi.python.org/pypi/sh


_logger = logging.getLogger("sanji.route.ip.addr")
_logger = logging.getLogger("sanji.ethernet.ip.addr")


def interfaces():
Expand All @@ -35,7 +35,7 @@ def interfaces():
# ifaces=$(ip a show | grep -Eo "[0-9]: wlan[0-9]" | sed "s/.*wlan//g")
# ifaces=$(ip a show | grep -Eo '[0-9]: eth[0-9]' | awk '{print $2}')
try:
ifaces = os.listdir("/sys/class/net")
ifaces = netifaces.interfaces()
ifaces = [x for x in ifaces if not
(x.startswith("lo") or x.startswith("mon."))]
return ifaces
Expand All @@ -62,14 +62,12 @@ def ifaddresses(iface):
"broadcast": ""}]}
Raises:
ValueError
ValueError: You must specify a valid interface name.
"""
info = dict()
try:
info["mac"] = open("/sys/class/net/%s/address" % iface).read()
info["mac"] = info["mac"][:-1] # remove '\n'
except:
info["mac"] = None
full = netifaces.ifaddresses(iface)

info = {}
info["mac"] = full[netifaces.AF_LINK][0]['addr']

try:
info["link"] = open("/sys/class/net/%s/operstate" % iface).read()
Expand All @@ -81,33 +79,14 @@ def ifaddresses(iface):
except:
info["link"] = 0

# "ip addr show %s | grep inet | grep -v inet6 | awk '{print $2}'"
info["inet"] = list()
try:
'''
output = sh.awk(sh.grep(
sh.ip("addr", "show", iface), "inet"),
"{print $2}")
'''
output = sh.ip("addr", "show", iface)
try:
output = sh.awk(sh.grep(output, "inet"), "{print $2}")
except:
return info
except sh.ErrorReturnCode_1:
raise ValueError("Device \"%s\" does not exist." % iface)
except:
raise ValueError("Unknown error for \"%s\"." % iface)

# info["inet"] = list()
for ip in output.split():
net = ipcalc.Network(ip)
item = dict()
item["ip"] = str(ip.split("/")[0])
item["netmask"] = str(net.netmask())
if 4 == net.version():
item["subnet"] = str(net.network())
item["broadcast"] = str(net.broadcast())
info["inet"] = []
for ip in full[netifaces.AF_INET]:
item = {}
item["ip"] = ip['addr']
item["netmask"] = ip['netmask']
item["broadcast"] = ip["broadcast"]
net = ipcalc.Network("%s/%s" % (ip['addr'], ip['netmask']))
item["subnet"] = str(net.network())
info["inet"].append(item)

return info
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
paho-mqtt==1.1
sh
ipcalc
netifaces
sanji
28 changes: 10 additions & 18 deletions route.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# -*- coding: UTF-8 -*-

import os
import netifaces
import logging
from sanji.core import Sanji
from sanji.core import Route
Expand Down Expand Up @@ -76,7 +77,7 @@ def cellular_connected(self, name, up=True):
Args:
name: cellular's interface name
"""
default = dict()
default = {}
if up:
self.cellular = name
default["interface"] = self.cellular
Expand Down Expand Up @@ -118,16 +119,15 @@ def list_default(self):
Return:
default: dict format with "interface" and/or "gateway"
"""
rules = ip.route.show()
default = dict()
for rule in rules:
if "default" in rule:
break
gws = netifaces.gateways()
default = {}
if gws['default'] != {}:
gw = gws['default'][netifaces.AF_INET]
else:
return default

default["interface"] = rule["dev"]
default["gateway"] = rule["default"]
default["gateway"] = gw[0]
default["interface"] = gw[1]
return default

def update_default(self, default):
Expand Down Expand Up @@ -196,7 +196,7 @@ def update_interface_router(self, interface):
iface["gateway"] = interface["gateway"]
break
else:
iface = dict()
iface = {}
iface["interface"] = interface["name"]
if "gateway" in interface:
iface["gateway"] = interface["gateway"]
Expand Down Expand Up @@ -246,22 +246,14 @@ def _put_default(self, message, response, schema=put_default_schema):
data={"message": "Invalid input: %s." % e})

# retrieve the default gateway
rules = ip.route.show()
default = None
for rule in rules:
if "default" in rule:
default = rule
break

default = self.list_default()
try:
self.update_default(message.data)
return response(data=self.model.db)
except Exception as e:
# recover the previous default gateway if any
try:
if default:
default["interface"] = default["dev"]
default["gateway"] = default["default"]
self.update_default(default)
except:
_logger.info("Failed to recover the default gateway.")
Expand Down
24 changes: 8 additions & 16 deletions tests/test_route.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,29 +173,21 @@ def mock_ip_addr_ifaddresses_ppp0_failed(iface):
self.assertEqual(1, len(ifaces))
self.assertIn("eth0", ifaces)

@patch("route.ip.route.show")
def test__list_default(self, mock_route_show):
@patch("route.netifaces.gateways")
def test__list_default(self, mock_gateways):
# case: get current default gateway
mock_route_show.return_value = [
{"default": "192.168.3.254", "dev": "eth0"},
{"src": "192.168.4.127",
"dev": "eth1",
"dest": "192.168.4.0/24"}]
mock_gateways.return_value = {
'default': {2: ('192.168.3.254', 'eth0')},
2: [('192.168.3.254', 'eth0', True)]}

default = self.bundle.list_default()
self.assertEqual("eth0", default["interface"])
self.assertEqual("192.168.3.254", default["gateway"])

@patch("route.ip.route.show")
def test__list_default__no_default(self, mock_route_show):
@patch("route.netifaces.gateways")
def test__list_default__no_default(self, mock_gateways):
# case: no current default gateway
mock_route_show.return_value = [
{"src": "192.168.3.127",
"dev": "eth0",
"dest": "192.168.3.0/24"},
{"src": "192.168.4.127",
"dev": "eth1",
"dest": "192.168.4.0/24"}]
mock_gateways.return_value = {'default': {}}

default = self.bundle.list_default()
self.assertEqual({}, default)
Expand Down

0 comments on commit 780b4ef

Please sign in to comment.