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
|
# -*- coding: utf-8 -*-
import logging
import platform
import socket
import netifaces
import ping
import requests
from leap.base import constants
from leap.base import exceptions
logger = logging.getLogger(name=__name__)
class LeapNetworkChecker(object):
"""
all network related checks
"""
def __init__(self, *args, **kwargs):
provider_gw = kwargs.pop('provider_gw', None)
self.provider_gateway = provider_gw
def run_all(self, checker=None):
if not checker:
checker = self
#self.error = None # ?
# for MVS
checker.check_tunnel_default_interface()
checker.check_internet_connection()
checker.is_internet_up()
if self.provider_gateway:
checker.ping_gateway(self.provider_gateway)
def check_internet_connection(self):
try:
# XXX remove this hardcoded random ip
# ping leap.se or eip provider instead...?
requests.get('http://216.172.161.165')
except (requests.HTTPError, requests.RequestException) as e:
raise exceptions.NoInternetConnection(e.message)
except requests.ConnectionError as e:
error = "Unidentified Connection Error"
if e.message == "[Errno 113] No route to host":
if not self.is_internet_up():
error = "No valid internet connection found."
else:
error = "Provider server appears to be down."
logger.error(error)
raise exceptions.NoInternetConnection(error)
logger.debug('Network appears to be up.')
def is_internet_up(self):
iface, gateway = self.get_default_interface_gateway()
self.ping_gateway(self.provider_gateway)
def check_tunnel_default_interface(self):
"""
Raises an TunnelNotDefaultRouteError
(including when no routes are present)
"""
if not platform.system() == "Linux":
raise NotImplementedError
f = open("/proc/net/route")
route_table = f.readlines()
f.close()
#toss out header
route_table.pop(0)
if not route_table:
raise exceptions.TunnelNotDefaultRouteError()
line = route_table.pop(0)
iface, destination = line.split('\t')[0:2]
if not destination == '00000000' or not iface == 'tun0':
raise exceptions.TunnelNotDefaultRouteError()
def get_default_interface_gateway(self):
"""only impletemented for linux so far."""
if not platform.system() == "Linux":
raise NotImplementedError
# XXX use psutil
f = open("/proc/net/route")
route_table = f.readlines()
f.close()
#toss out header
route_table.pop(0)
default_iface = None
gateway = None
while route_table:
line = route_table.pop(0)
iface, destination, gateway = line.split('\t')[0:3]
if destination == '00000000':
default_iface = iface
break
if not default_iface:
raise exceptions.NoDefaultInterfaceFoundError
if default_iface not in netifaces.interfaces():
raise exceptions.InterfaceNotFoundError
return default_iface, gateway
def ping_gateway(self, gateway):
# TODO: Discuss how much packet loss (%) is acceptable.
# XXX -- validate gateway
# -- is it a valid ip? (there's something in util)
# -- is it a domain?
# -- can we resolve? -- raise NoDNSError if not.
packet_loss = ping.quiet_ping(gateway)[0]
if packet_loss > constants.MAX_ICMP_PACKET_LOSS:
raise exceptions.NoConnectionToGateway
def check_name_resolution(self, domain_name):
try:
socket.gethostbyname(domain_name)
return True
except socket.gaierror:
raise exceptions.CannotResolveDomainError
|