Fix remote packet capture for Dynamips.

This commit is contained in:
grossmj committed 2019-04-01 20:58:18 +07:00
1 parent 4cc5dbc228
commit a17119187b
16 files changed
+76 -49

No files matched your search

+47 -3
View File
@@ -42,6 +42,8 @@ class NIO:
self._filters = {}
self._suspended = False
self._capturing = False
self._pcap_output_file = ""
self._pcap_data_link_type = ""
self._bandwidth = None # no bandwidth constraint by default
self._input_filter = None # no input filter applied by default
self._output_filter = None # no output filter applied by default
@@ -66,6 +68,7 @@ class NIO:
if self._input_filter or self._output_filter:
await self.unbind_filter("both")
self._capturing = False
await self._hypervisor.send("nio delete {}".format(self._name))
log.info("NIO {name} has been deleted".format(name=self._name))
@@ -90,6 +93,30 @@ class NIO:
await self._hypervisor.send("nio set_debug {name} {debug}".format(name=self._name, debug=debug))
async def start_packet_capture(self, pcap_output_file, pcap_data_link_type="DLT_EN10MB"):
"""
Starts a packet capture.
:param pcap_output_file: PCAP destination file for the capture
:param pcap_data_link_type: PCAP data link type (DLT_*), default is DLT_EN10MB
"""
await self.bind_filter("both", "capture")
await self.setup_filter("both", '{} "{}"'.format(pcap_data_link_type, pcap_output_file))
self._capturing = True
self._pcap_output_file = pcap_output_file
self._pcap_data_link_type = pcap_data_link_type
async def stop_packet_capture(self):
"""
Stops a packet capture.
"""
await self.unbind_filter("both")
self._capturing = False
self._pcap_output_file = ""
self._pcap_data_link_type = ""
async def bind_filter(self, direction, filter_name):
"""
Adds a packet filter to this NIO.
@@ -116,9 +143,6 @@ class NIO:
self._input_filter = filter_name
self._output_filter = filter_name
if filter_name == "capture":
self._capturing = True
async def unbind_filter(self, direction):
"""
Removes packet filter for this NIO.
@@ -283,6 +307,26 @@ class NIO:
return self._capturing
@property
def pcap_output_file(self):
"""
Returns the path to the PCAP output file.
:returns: path to the PCAP output file
"""
return self._pcap_output_file
@property
def pcap_data_link_type(self):
"""
Returns the PCAP data link type
:returns: PCAP data link type (DLT_* value)
"""
return self._pcap_data_link_type
def __str__(self):
"""
NIO string representation.
@@ -452,9 +452,7 @@ class ATMSwitch(Device):
if nio.input_filter[0] is not None and nio.output_filter[0] is not None:
raise DynamipsError("Port {} has already a filter applied".format(port_number))
await nio.bind_filter("both", "capture")
await nio.setup_filter("both", '{} "{}"'.format(data_link_type, output_file))
await nio.start_packet_capture(output_file, data_link_type)
log.info('ATM switch "{name}" [{id}]: starting packet capture on port {port}'.format(name=self._name,
id=self._id,
port=port_number))
@@ -469,7 +467,7 @@ class ATMSwitch(Device):
nio = self.get_nio(port_number)
if not nio.capturing:
return
await nio.unbind_filter("both")
await nio.stop_packet_capture()
log.info('ATM switch "{name}" [{id}]: stopping packet capture on port {port}'.format(name=self._name,
id=self._id,
port=port_number))
@@ -212,9 +212,7 @@ class EthernetHub(Bridge):
if nio.input_filter[0] is not None and nio.output_filter[0] is not None:
raise DynamipsError("Port {} has already a filter applied".format(port_number))
await nio.bind_filter("both", "capture")
await nio.setup_filter("both", '{} "{}"'.format(data_link_type, output_file))
await nio.start_packet_capture(output_file, data_link_type)
log.info('Ethernet hub "{name}" [{id}]: starting packet capture on port {port}'.format(name=self._name,
id=self._id,
port=port_number))
@@ -229,7 +227,7 @@ class EthernetHub(Bridge):
nio = self.get_nio(port_number)
if not nio.capturing:
return
await nio.unbind_filter("both")
await nio.stop_packet_capture()
log.info('Ethernet hub "{name}" [{id}]: stopping packet capture on port {port}'.format(name=self._name,
id=self._id,
port=port_number))
@@ -441,9 +441,7 @@ class EthernetSwitch(Device):
if nio.input_filter[0] is not None and nio.output_filter[0] is not None:
raise DynamipsError("Port {} has already a filter applied".format(port_number))
await nio.bind_filter("both", "capture")
await nio.setup_filter("both", '{} "{}"'.format(data_link_type, output_file))
await nio.start_packet_capture(output_file, data_link_type)
log.info('Ethernet switch "{name}" [{id}]: starting packet capture on port {port}'.format(name=self._name,
id=self._id,
port=port_number))
@@ -458,7 +456,7 @@ class EthernetSwitch(Device):
nio = self.get_nio(port_number)
if not nio.capturing:
return
await nio.unbind_filter("both")
await nio.stop_packet_capture()
log.info('Ethernet switch "{name}" [{id}]: stopping packet capture on port {port}'.format(name=self._name,
id=self._id,
port=port_number))
@@ -338,9 +338,7 @@ class FrameRelaySwitch(Device):
if nio.input_filter[0] is not None and nio.output_filter[0] is not None:
raise DynamipsError("Port {} has already a filter applied".format(port_number))
await nio.bind_filter("both", "capture")
await nio.setup_filter("both", '{} "{}"'.format(data_link_type, output_file))
await nio.start_packet_capture(output_file, data_link_type)
log.info('Frame relay switch "{name}" [{id}]: starting packet capture on port {port}'.format(name=self._name,
id=self._id,
port=port_number))
@@ -355,7 +353,7 @@ class FrameRelaySwitch(Device):
nio = self.get_nio(port_number)
if not nio.capturing:
return
await nio.unbind_filter("both")
await nio.stop_packet_capture()
log.info('Frame relay switch "{name}" [{id}]: stopping packet capture on port {port}'.format(name=self._name,
id=self._id,
port=port_number))
+2 -5
View File
@@ -1445,10 +1445,7 @@ class Router(BaseNode):
if nio.input_filter[0] is not None and nio.output_filter[0] is not None:
raise DynamipsError("Port {port_number} has already a filter applied on {adapter}".format(adapter=adapter,
port_number=port_number))
await nio.bind_filter("both", "capture")
await nio.setup_filter("both", '{} "{}"'.format(data_link_type, output_file))
await nio.start_packet_capture(output_file, data_link_type)
log.info('Router "{name}" [{id}]: starting packet capture on port {slot_number}/{port_number}'.format(name=self._name,
id=self._id,
nio_name=nio.name,
@@ -1480,7 +1477,7 @@ class Router(BaseNode):
if not nio.capturing:
return
await nio.unbind_filter("both")
await nio.stop_packet_capture()
log.info('Router "{name}" [{id}]: stopping packet capture on port {slot_number}/{port_number}'.format(name=self._name,
id=self._id,