Skip to content

Commit

Permalink
Add providers for macos
Browse files Browse the repository at this point in the history
  • Loading branch information
gmacon committed Oct 12, 2018
1 parent 87483c4 commit e2d5d3f
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 0 deletions.
9 changes: 9 additions & 0 deletions vpn_slice/generic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from .provider import FirewallProvider


class NoFirewallProvider(FirewallProvider):
def configure_firewall(self, device):
pass

def deconfigure_firewall(self, device):
pass
95 changes: 95 additions & 0 deletions vpn_slice/mac.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import re
import subprocess

from .provider import ProcessProvider, RouteProvider
from .util import get_executable


class PsProvider(ProcessProvider):
def __init__(self):
self.lsof = get_executable('/usr/sbin/lsof')
self.ps = get_executable('/bin/ps')

def pid2exe(self, pid):
info = subprocess.check_output([self.lsof, '-p', str(pid)]).decode()
for line in info.splitlines():
parts = line.split()
if parts[3] == 'txt':
return parts[8]

def ppid_of(self, pid):
try:
return int(subprocess.check_output([self.ps, '-p', str(pid), '-o', 'ppid=']).decode().strip())
except ValueError:
return None


class BSDRouteProvider(RouteProvider):
def __init__(self):
self.route = get_executable('/sbin/route')
self.ifconfig = get_executable('/sbin/ifconfig')

def _route(self, *args):
return subprocess.check_output([self.route, '-n'] + list(map(str, args))).decode()

def _ifconfig(self, *args):
return subprocess.check_output([self.ifconfig] + list(map(str, args))).decode()

def add_route(self, destination, *, via=None, dev=None, src=None, mtu=None):
args = ['add']
if mtu is not None:
args.extend(('-mtu', str(mtu)))
if via is not None:
args.extend((destination, via))
elif dev is not None:
args.extend(('-interface', destination, dev))
self._route(*args)

def remove_route(self, destination):
self._route('delete', destination)

def get_route(self, destination):
info = self._route('get', destination)
lines = iter(info.splitlines())
info_d = {}
for line in lines:
if ':' not in line:
break
key, _, val = line.partition(':')
info_d[key.strip()] = val.strip()
keys = line.split()
vals = next(lines).split()
info_d.update(zip(keys, vals))
return {
'via': info_d['gateway'],
'dev': info_d['interface'],
'mtu': info_d['mtu'],
}

def flush_cache(self):
pass

_LINK_INFO_RE = re.compile(r'flags=\d<(.*?)>\smtu\s(\d+)$')

def get_link_info(self, device):
info = self._ifconfig(device)
match = self._LINK_INFO_RE.search(info)
if match:
flags = match.group(1).split(',')
mtu = int(match.group(2))
return {
'state': 'up' if 'UP' in flags else 'down',
'mtu': mtu,
}
return None

def set_link_info(self, device, state, mtu=None):
args = [device]
if state is not None:
args.append(state)
if mtu is not None:
args.extend(('mtu', str(mtu)))
self._ifconfig(*args)

def add_address(self, device, address):
self._ifconfig(device, address, address)
11 changes: 11 additions & 0 deletions vpn_slice/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ def get_default_providers():
'dns': DigProvider(),
'hosts': PosixHostsFileProvider(),
}
elif platform.startswith('darwin'):
from .mac import PsProvider, BSDRouteProvider
from .generic import NoFirewallProvider
from .posix import DigProvider, PosixHostsFileProvider
return {
'process': PsProvider(),
'route': BSDRouteProvider(),
'firewall': NoFirewallProvider(),
'dns': DigProvider(),
'hosts': PosixHostsFileProvider(),
}
else:
raise OSError('Your platform, {}, is unsupported'.format(platform))

Expand Down

0 comments on commit e2d5d3f

Please sign in to comment.