1
0
mirror of https://github.com/GNS3/gns3-server synced 2025-02-03 20:01:20 +00:00

Check interface is up before connecting a NIO (Linux only). Fixes #277.

This commit is contained in:
grossmj 2015-06-07 13:51:33 -06:00
parent 81d417a2b3
commit 042472f02c
3 changed files with 39 additions and 2 deletions

View File

@ -28,6 +28,7 @@ import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
from uuid import UUID, uuid4 from uuid import UUID, uuid4
from gns3server.utils.interfaces import is_interface_up
from ..config import Config from ..config import Config
from ..utils.asyncio import wait_run_in_executor from ..utils.asyncio import wait_run_in_executor
from .project_manager import ProjectManager from .project_manager import ProjectManager
@ -369,12 +370,17 @@ class BaseManager:
nio = NIOUDP(lport, rhost, rport) nio = NIOUDP(lport, rhost, rport)
elif nio_settings["type"] == "nio_tap": elif nio_settings["type"] == "nio_tap":
tap_device = nio_settings["tap_device"] tap_device = nio_settings["tap_device"]
if not is_interface_up(tap_device):
raise aiohttp.web.HTTPConflict(text="TAP interface {} is down".format(tap_device))
# FIXME: check for permissions on tap device # FIXME: check for permissions on tap device
# if not self._has_privileged_access(executable): # if not self._has_privileged_access(executable):
# raise aiohttp.web.HTTPForbidden(text="{} has no privileged access to {}.".format(executable, tap_device)) # raise aiohttp.web.HTTPForbidden(text="{} has no privileged access to {}.".format(executable, tap_device))
nio = NIOTAP(tap_device) nio = NIOTAP(tap_device)
elif nio_settings["type"] == "nio_generic_ethernet": elif nio_settings["type"] == "nio_generic_ethernet":
nio = NIOGenericEthernet(nio_settings["ethernet_device"]) ethernet_device = nio_settings["ethernet_device"]
if not is_interface_up(ethernet_device):
raise aiohttp.web.HTTPConflict(text="Ethernet interface {} is down".format(ethernet_device))
nio = NIOGenericEthernet(ethernet_device)
elif nio_settings["type"] == "nio_nat": elif nio_settings["type"] == "nio_nat":
nio = NIONAT() nio = NIONAT()
assert nio is not None assert nio is not None

View File

@ -32,7 +32,7 @@ import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
from gns3server.utils.interfaces import get_windows_interfaces from gns3server.utils.interfaces import get_windows_interfaces, is_interface_up
from gns3server.utils.asyncio import wait_run_in_executor from gns3server.utils.asyncio import wait_run_in_executor
from pkg_resources import parse_version from pkg_resources import parse_version
from uuid import UUID, uuid4 from uuid import UUID, uuid4
@ -404,6 +404,8 @@ class Dynamips(BaseManager):
raise DynamipsError("Could not find interface {} on this host".format(ethernet_device)) raise DynamipsError("Could not find interface {} on this host".format(ethernet_device))
else: else:
ethernet_device = npf_interface ethernet_device = npf_interface
if not is_interface_up(ethernet_device):
raise aiohttp.web.HTTPConflict(text="Ethernet interface {} is down".format(ethernet_device))
nio = NIOGenericEthernet(node.hypervisor, ethernet_device) nio = NIOGenericEthernet(node.hypervisor, ethernet_device)
elif nio_settings["type"] == "nio_linux_ethernet": elif nio_settings["type"] == "nio_linux_ethernet":
if sys.platform.startswith("win"): if sys.platform.startswith("win"):
@ -412,6 +414,8 @@ class Dynamips(BaseManager):
nio = NIOLinuxEthernet(node.hypervisor, ethernet_device) nio = NIOLinuxEthernet(node.hypervisor, ethernet_device)
elif nio_settings["type"] == "nio_tap": elif nio_settings["type"] == "nio_tap":
tap_device = nio_settings["tap_device"] tap_device = nio_settings["tap_device"]
if not is_interface_up(tap_device):
raise aiohttp.web.HTTPConflict(text="TAP interface {} is down".format(tap_device))
nio = NIOTAP(node.hypervisor, tap_device) nio = NIOTAP(node.hypervisor, tap_device)
elif nio_settings["type"] == "nio_unix": elif nio_settings["type"] == "nio_unix":
local_file = nio_settings["local_file"] local_file = nio_settings["local_file"]

View File

@ -18,6 +18,8 @@
import sys import sys
import aiohttp import aiohttp
import socket
import struct
import logging import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -78,6 +80,31 @@ def get_windows_interfaces():
return interfaces return interfaces
def is_interface_up(interface):
"""
Checks if an interface is up.
:param interface: interface name
:returns: boolean
"""
if sys.platform.startswith("linux"):
import fcntl
SIOCGIFFLAGS = 0x8913
try:
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
result = fcntl.ioctl(s.fileno(), SIOCGIFFLAGS, interface + '\0' * 256)
flags, = struct.unpack('H', result[16:18])
if flags & 1: # check if the up bit is set
return True
return False
except OSError as e:
raise aiohttp.web.HTTPInternalServerError(text="Exception when checking if {} is up: {}".format(interface, e))
else:
#TODO: Windows & OSX support
return True
def interfaces(): def interfaces():
""" """
Gets the network interfaces on this server. Gets the network interfaces on this server.