Refactor how clients access PCAP capture files. Fixes https://github.com/GNS3/gns3-gui/issues/2438.

* The PCAP file is directly accessed if controller and client are on the same host.
* The PCAP file is streamed from the compute server to the client with the controller as a proxy when the controller is remote for the client.
This commit is contained in:
grossmj committed 2018-10-27 14:47:17 +07:00
1 parent bf1b801cc0
commit 2764828f38
47 files changed
+1071 -473

No files matched your search

@@ -223,6 +223,25 @@ class ATMSwitch(Device):
del self._nios[port_number]
return nio
def get_nio(self, port_number):
"""
Gets a port NIO binding.
:param port_number: port number
:returns: NIO instance
"""
if port_number not in self._nios:
raise DynamipsError("Port {} is not allocated".format(port_number))
nio = self._nios[port_number]
if not nio:
raise DynamipsError("Port {} is not connected".format(port_number))
return nio
async def set_mappings(self, mappings):
"""
Applies VC mappings
@@ -424,11 +443,7 @@ class ATMSwitch(Device):
:param data_link_type: PCAP data link type (DLT_*), default is DLT_ATM_RFC1483
"""
if port_number not in self._nios:
raise DynamipsError("Port {} is not allocated".format(port_number))
nio = self._nios[port_number]
nio = self.get_nio(port_number)
data_link_type = data_link_type.lower()
if data_link_type.startswith("dlt_"):
data_link_type = data_link_type[4:]
@@ -450,10 +465,7 @@ class ATMSwitch(Device):
:param port_number: allocated port number
"""
if port_number not in self._nios:
raise DynamipsError("Port {} is not allocated".format(port_number))
nio = self._nios[port_number]
nio = self.get_nio(port_number)
await nio.unbind_filter("both")
log.info('ATM switch "{name}" [{id}]: stopping packet capture on port {port}'.format(name=self._name,
id=self._id,
@@ -19,8 +19,6 @@
Hub object that uses the Bridge interface to create a hub with ports.
"""
import asyncio
from .bridge import Bridge
from ..nios.nio_udp import NIOUDP
from ..dynamips_error import DynamipsError
@@ -177,6 +175,25 @@ class EthernetHub(Bridge):
del self._mappings[port_number]
return nio
def get_nio(self, port_number):
"""
Gets a port NIO binding.
:param port_number: port number
:returns: NIO instance
"""
if port_number not in self._mappings:
raise DynamipsError("Port {} is not allocated".format(port_number))
nio = self._mappings[port_number]
if not nio:
raise DynamipsError("Port {} is not connected".format(port_number))
return nio
async def start_capture(self, port_number, output_file, data_link_type="DLT_EN10MB"):
"""
Starts a packet capture.
@@ -186,11 +203,7 @@ class EthernetHub(Bridge):
:param data_link_type: PCAP data link type (DLT_*), default is DLT_EN10MB
"""
if port_number not in self._mappings:
raise DynamipsError("Port {} is not allocated".format(port_number))
nio = self._mappings[port_number]
nio = self.get_nio(port_number)
data_link_type = data_link_type.lower()
if data_link_type.startswith("dlt_"):
data_link_type = data_link_type[4:]
@@ -212,10 +225,7 @@ class EthernetHub(Bridge):
:param port_number: allocated port number
"""
if port_number not in self._mappings:
raise DynamipsError("Port {} is not allocated".format(port_number))
nio = self._mappings[port_number]
nio = self.get_nio(port_number)
await nio.unbind_filter("both")
log.info('Ethernet hub "{name}" [{id}]: stopping packet capture on port {port}'.format(name=self._name,
id=self._id,
@@ -300,6 +300,25 @@ class EthernetSwitch(Device):
return nio
def get_nio(self, port_number):
"""
Gets a port NIO binding.
:param port_number: port number
:returns: NIO instance
"""
if port_number not in self._nios:
raise DynamipsError("Port {} is not allocated".format(port_number))
nio = self._nios[port_number]
if not nio:
raise DynamipsError("Port {} is not connected".format(port_number))
return nio
async def set_port_settings(self, port_number, settings):
"""
Applies port settings to a specific port.
@@ -413,14 +432,7 @@ class EthernetSwitch(Device):
:param data_link_type: PCAP data link type (DLT_*), default is DLT_EN10MB
"""
if port_number not in self._nios:
raise DynamipsError("Port {} is not allocated".format(port_number))
nio = self._nios[port_number]
if not nio:
raise DynamipsError("Port {} is not connected".format(port_number))
nio = self.get_nio(port_number)
data_link_type = data_link_type.lower()
if data_link_type.startswith("dlt_"):
data_link_type = data_link_type[4:]
@@ -442,14 +454,7 @@ class EthernetSwitch(Device):
:param port_number: allocated port number
"""
if port_number not in self._nios:
raise DynamipsError("Port {} is not allocated".format(port_number))
nio = self._nios[port_number]
if not nio:
raise DynamipsError("Port {} is not connected".format(port_number))
nio = self.get_nio(port_number)
await nio.unbind_filter("both")
log.info('Ethernet switch "{name}" [{id}]: stopping packet capture on port {port}'.format(name=self._name,
id=self._id,
@@ -209,6 +209,25 @@ class FrameRelaySwitch(Device):
del self._nios[port_number]
return nio
def get_nio(self, port_number):
"""
Gets a port NIO binding.
:param port_number: port number
:returns: NIO instance
"""
if port_number not in self._nios:
raise DynamipsError("Port {} is not allocated".format(port_number))
nio = self._nios[port_number]
if not nio:
raise DynamipsError("Port {} is not connected".format(port_number))
return nio
async def set_mappings(self, mappings):
"""
Applies VC mappings
@@ -309,10 +328,7 @@ class FrameRelaySwitch(Device):
:param data_link_type: PCAP data link type (DLT_*), default is DLT_FRELAY
"""
if port_number not in self._nios:
raise DynamipsError("Port {} is not allocated".format(port_number))
nio = self._nios[port_number]
nio = self.get_nio(port_number)
data_link_type = data_link_type.lower()
if data_link_type.startswith("dlt_"):
@@ -335,10 +351,7 @@ class FrameRelaySwitch(Device):
:param port_number: allocated port number
"""
if port_number not in self._nios:
raise DynamipsError("Port {} is not allocated".format(port_number))
nio = self._nios[port_number]
nio = self.get_nio(port_number)
await nio.unbind_filter("both")
log.info('Frame relay switch "{name}" [{id}]: stopping packet capture on port {port}'.format(name=self._name,
id=self._id,
+31 -4
View File
@@ -1264,7 +1264,7 @@ class Router(BaseNode):
raise DynamipsError("Adapter is missing in slot {slot_number}".format(slot_number=slot_number))
if not adapter.port_exists(port_number):
raise DynamipsError("Port {port_number} does not exist in adapter {adapter}".format(adapter=adapter,
raise DynamipsError("Port {port_number} does not exist on adapter {adapter}".format(adapter=adapter,
port_number=port_number))
try:
@@ -1299,6 +1299,7 @@ class Router(BaseNode):
:param port_number: port number
:param nio: NIO instance to add to the slot/port
"""
await nio.update()
async def slot_remove_nio_binding(self, slot_number, port_number):
@@ -1321,7 +1322,7 @@ class Router(BaseNode):
raise DynamipsError("Adapter is missing in slot {slot_number}".format(slot_number=slot_number))
if not adapter.port_exists(port_number):
raise DynamipsError("Port {port_number} does not exist in adapter {adapter}".format(adapter=adapter,
raise DynamipsError("Port {port_number} does not exist on adapter {adapter}".format(adapter=adapter,
port_number=port_number))
await self.slot_disable_nio(slot_number, port_number)
@@ -1362,6 +1363,32 @@ class Router(BaseNode):
slot_number=slot_number,
port_number=port_number))
def get_nio(self, slot_number, port_number):
"""
Gets an slot NIO binding.
:param slot_number: slot number
:param port_number: port number
:returns: NIO instance
"""
try:
adapter = self._slots[slot_number]
except IndexError:
raise DynamipsError('Slot {slot_number} does not exist on router "{name}"'.format(name=self._name,
slot_number=slot_number))
if not adapter.port_exists(port_number):
raise DynamipsError("Port {port_number} does not exist on adapter {adapter}".format(adapter=adapter,
port_number=port_number))
nio = adapter.get_nio(port_number)
if not nio:
raise DynamipsError("Port {slot_number}/{port_number} is not connected".format(slot_number=slot_number,
port_number=port_number))
return nio
async def slot_disable_nio(self, slot_number, port_number):
"""
Disables a slot NIO binding.
@@ -1402,7 +1429,7 @@ class Router(BaseNode):
raise DynamipsError('Slot {slot_number} does not exist on router "{name}"'.format(name=self._name,
slot_number=slot_number))
if not adapter.port_exists(port_number):
raise DynamipsError("Port {port_number} does not exist in adapter {adapter}".format(adapter=adapter,
raise DynamipsError("Port {port_number} does not exist on adapter {adapter}".format(adapter=adapter,
port_number=port_number))
data_link_type = data_link_type.lower()
@@ -1442,7 +1469,7 @@ class Router(BaseNode):
raise DynamipsError('Slot {slot_number} does not exist on router "{name}"'.format(name=self._name,
slot_number=slot_number))
if not adapter.port_exists(port_number):
raise DynamipsError("Port {port_number} does not exist in adapter {adapter}".format(adapter=adapter,
raise DynamipsError("Port {port_number} does not exist on adapter {adapter}".format(adapter=adapter,
port_number=port_number))
nio = adapter.get_nio(port_number)