Fix remote packet capture for Dynamips.

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

View File

@ -489,7 +489,7 @@ class Cloud(BaseNode):
nio = self.get_nio(port_number)
if nio.capturing:
raise NodeError("Packet capture is already activated on port {port_number}".format(port_number=port_number))
nio.startPacketCapture(output_file)
nio.start_packet_capture(output_file)
bridge_name = "{}-{}".format(self._id, port_number)
await self._ubridge_send('bridge start_capture {name} "{output_file}"'.format(name=bridge_name,
output_file=output_file))
@ -507,7 +507,7 @@ class Cloud(BaseNode):
nio = self.get_nio(port_number)
if not nio.capturing:
return
nio.stopPacketCapture()
nio.stop_packet_capture()
bridge_name = "{}-{}".format(self._id, port_number)
await self._ubridge_send("bridge stop_capture {name}".format(name=bridge_name))

View File

@ -1057,8 +1057,7 @@ class DockerVM(BaseNode):
if nio.capturing:
raise DockerError("Packet capture is already activated on adapter {adapter_number}".format(adapter_number=adapter_number))
nio.startPacketCapture(output_file)
nio.start_packet_capture(output_file)
if self.status == "started" and self.ubridge:
await self._start_ubridge_capture(adapter_number, output_file)
@ -1076,7 +1075,7 @@ class DockerVM(BaseNode):
nio = self.get_nio(adapter_number)
if not nio.capturing:
return
nio.stopPacketCapture()
nio.stop_packet_capture()
if self.status == "started" and self.ubridge:
await self._stop_ubridge_capture(adapter_number)

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.

View File

@ -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))

View File

@ -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))

View File

@ -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))

View File

@ -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))

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,

View File

@ -1291,7 +1291,7 @@ class IOUVM(BaseNode):
raise IOUError("Packet capture is already activated on {adapter_number}/{port_number}".format(adapter_number=adapter_number,
port_number=port_number))
nio.startPacketCapture(output_file, data_link_type)
nio.start_packet_capture(output_file, data_link_type)
log.info('IOU "{name}" [{id}]: starting packet capture on {adapter_number}/{port_number} to {output_file}'.format(name=self._name,
id=self._id,
adapter_number=adapter_number,
@ -1317,7 +1317,7 @@ class IOUVM(BaseNode):
nio = self.get_nio(adapter_number, port_number)
if not nio.capturing:
return
nio.stopPacketCapture()
nio.stop_packet_capture()
log.info('IOU "{name}" [{id}]: stopping packet capture on {adapter_number}/{port_number}'.format(name=self._name,
id=self._id,
adapter_number=adapter_number,

View File

@ -34,7 +34,7 @@ class NIO(object):
self._pcap_output_file = ""
self._pcap_data_link_type = ""
def startPacketCapture(self, pcap_output_file, pcap_data_link_type="DLT_EN10MB"):
def start_packet_capture(self, pcap_output_file, pcap_data_link_type="DLT_EN10MB"):
"""
:param pcap_output_file: PCAP destination file for the capture
:param pcap_data_link_type: PCAP data link type (DLT_*), default is DLT_EN10MB
@ -44,7 +44,7 @@ class NIO(object):
self._pcap_output_file = pcap_output_file
self._pcap_data_link_type = pcap_data_link_type
def stopPacketCapture(self):
def stop_packet_capture(self):
self._capturing = False
self._pcap_output_file = ""

View File

@ -1325,8 +1325,7 @@ class QemuVM(BaseNode):
if nio.capturing:
raise QemuError("Packet capture is already activated on adapter {adapter_number}".format(adapter_number=adapter_number))
nio.startPacketCapture(output_file)
nio.start_packet_capture(output_file)
if self.ubridge:
await self._ubridge_send('bridge start_capture {name} "{output_file}"'.format(name="QEMU-{}-{}".format(self._id, adapter_number),
output_file=output_file))
@ -1345,8 +1344,8 @@ class QemuVM(BaseNode):
nio = self.get_nio(adapter_number)
if not nio.capturing:
return
nio.stopPacketCapture()
nio.stop_packet_capture()
if self.ubridge:
await self._ubridge_send('bridge stop_capture {name}'.format(name="QEMU-{}-{}".format(self._id, adapter_number)))

View File

@ -392,8 +392,7 @@ class TraceNGVM(BaseNode):
if nio.capturing:
raise TraceNGError("Packet capture is already activated on port {port_number}".format(port_number=port_number))
nio.startPacketCapture(output_file)
nio.start_packet_capture(output_file)
if self.ubridge:
await self._ubridge_send('bridge start_capture {name} "{output_file}"'.format(name="TraceNG-{}".format(self._id),
output_file=output_file))
@ -412,8 +411,8 @@ class TraceNGVM(BaseNode):
nio = self.get_nio(port_number)
if not nio.capturing:
return
nio.stopPacketCapture()
nio.stop_packet_capture()
if self.ubridge:
await self._ubridge_send('bridge stop_capture {name}'.format(name="TraceNG-{}".format(self._id)))

View File

@ -1117,8 +1117,7 @@ class VirtualBoxVM(BaseNode):
if nio.capturing:
raise VirtualBoxError("Packet capture is already activated on adapter {adapter_number}".format(adapter_number=adapter_number))
nio.startPacketCapture(output_file)
nio.start_packet_capture(output_file)
if self.ubridge:
await self._ubridge_send('bridge start_capture {name} "{output_file}"'.format(name="VBOX-{}-{}".format(self._id, adapter_number),
output_file=output_file))
@ -1137,8 +1136,8 @@ class VirtualBoxVM(BaseNode):
nio = self.get_nio(adapter_number)
if not nio.capturing:
return
nio.stopPacketCapture()
nio.stop_packet_capture()
if self.ubridge:
await self._ubridge_send('bridge stop_capture {name}'.format(name="VBOX-{}-{}".format(self._id, adapter_number)))

View File

@ -900,8 +900,7 @@ class VMwareVM(BaseNode):
if nio.capturing:
raise VMwareError("Packet capture is already activated on adapter {adapter_number}".format(adapter_number=adapter_number))
nio.startPacketCapture(output_file)
nio.start_packet_capture(output_file)
if self._started:
await self._start_ubridge_capture(adapter_number, output_file)
@ -919,8 +918,8 @@ class VMwareVM(BaseNode):
nio = self.get_nio(adapter_number)
if not nio.capturing:
return
nio.stopPacketCapture()
nio.stop_packet_capture()
if self._started:
await self._stop_ubridge_capture(adapter_number)

View File

@ -449,8 +449,7 @@ class VPCSVM(BaseNode):
if nio.capturing:
raise VPCSError("Packet capture is already active on port {port_number}".format(port_number=port_number))
nio.startPacketCapture(output_file)
nio.start_packet_capture(output_file)
if self.ubridge:
await self._ubridge_send('bridge start_capture {name} "{output_file}"'.format(name="VPCS-{}".format(self._id),
output_file=output_file))
@ -469,8 +468,8 @@ class VPCSVM(BaseNode):
nio = self.get_nio(port_number)
if not nio.capturing:
return
nio.stopPacketCapture()
nio.stop_packet_capture()
if self.ubridge:
await self._ubridge_send('bridge stop_capture {name}'.format(name="VPCS-{}".format(self._id)))

View File

@ -767,7 +767,7 @@ def test_add_ubridge_connection(loop, vm):
"rport": 4343,
"rhost": "127.0.0.1"}
nio = vm.manager.create_nio(nio)
nio.startPacketCapture("/tmp/capture.pcap")
nio.start_packet_capture("/tmp/capture.pcap")
vm._ubridge_hypervisor = MagicMock()
vm._namespace = 42