New feature: packet capture for the Ethernet hub and Ethernet, ATM and Frame relay switches.

This commit is contained in:
grossmj committed 2014-06-27 07:26:47 -06:00
1 parent 606f773f3d
commit 33787d486a
13 files changed
+776 -6

No files matched your search

@@ -20,6 +20,7 @@ Interface for Dynamips virtual ATM switch module ("atmsw").
http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L593
"""
import os
from ..dynamips_error import DynamipsError
import logging
@@ -351,3 +352,54 @@ class ATMSwitch(object):
vpi2=vpi2,
vci2=vci2))
del self._mapping[(port1, vpi1, vci1)]
def start_capture(self, port, output_file, data_link_type="DLT_ATM_RFC1483"):
"""
Starts a packet capture.
:param port: allocated port
:param output_file: PCAP destination file for the capture
:param data_link_type: PCAP data link type (DLT_*), default is DLT_ATM_RFC1483
"""
if port not in self._nios:
raise DynamipsError("Port {} is not allocated".format(port))
nio = self._nios[port]
data_link_type = data_link_type.lower()
if data_link_type.startswith("dlt_"):
data_link_type = data_link_type[4:]
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))
try:
os.makedirs(os.path.dirname(output_file))
except FileExistsError:
pass
except OSError as e:
raise DynamipsError("Could not create captures directory {}".format(e))
nio.bind_filter("both", "capture")
nio.setup_filter("both", "{} {}".format(data_link_type, output_file))
log.info("ATM switch {name} [id={id}]: starting packet capture on {port}".format(name=self._name,
id=self._id,
port=port))
def stop_capture(self, port):
"""
Stops a packet capture.
:param port: allocated port
"""
if port not in self._nios:
raise DynamipsError("Port {} is not allocated".format(port))
nio = self._nios[port]
nio.unbind_filter("both")
log.info("ATM switch {name} [id={id}]: stopping packet capture on {port}".format(name=self._name,
id=self._id,
port=port))
@@ -20,6 +20,7 @@ Interface for Dynamips virtual Ethernet switch module ("ethsw").
http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L558
"""
import os
from ..dynamips_error import DynamipsError
import logging
@@ -287,3 +288,54 @@ class EthernetSwitch(object):
"""
self._hypervisor.send("ethsw clear_mac_addr_table {}".format(self._name))
def start_capture(self, port, output_file, data_link_type="DLT_EN10MB"):
"""
Starts a packet capture.
:param port: allocated port
:param output_file: PCAP destination file for the capture
:param data_link_type: PCAP data link type (DLT_*), default is DLT_EN10MB
"""
if port not in self._nios:
raise DynamipsError("Port {} is not allocated".format(port))
nio = self._nios[port]
data_link_type = data_link_type.lower()
if data_link_type.startswith("dlt_"):
data_link_type = data_link_type[4:]
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))
try:
os.makedirs(os.path.dirname(output_file))
except FileExistsError:
pass
except OSError as e:
raise DynamipsError("Could not create captures directory {}".format(e))
nio.bind_filter("both", "capture")
nio.setup_filter("both", "{} {}".format(data_link_type, output_file))
log.info("Ethernet switch {name} [id={id}]: starting packet capture on {port}".format(name=self._name,
id=self._id,
port=port))
def stop_capture(self, port):
"""
Stops a packet capture.
:param port: allocated port
"""
if port not in self._nios:
raise DynamipsError("Port {} is not allocated".format(port))
nio = self._nios[port]
nio.unbind_filter("both")
log.info("Ethernet switch {name} [id={id}]: stopping packet capture on {port}".format(name=self._name,
id=self._id,
port=port))
@@ -20,6 +20,7 @@ Interface for Dynamips virtual Frame-Relay switch module.
http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L642
"""
import os
from ..dynamips_error import DynamipsError
import logging
@@ -273,3 +274,54 @@ class FrameRelaySwitch(object):
port2=port2,
dlci2=dlci2))
del self._mapping[(port1, dlci1)]
def start_capture(self, port, output_file, data_link_type="DLT_FRELAY"):
"""
Starts a packet capture.
:param port: allocated port
:param output_file: PCAP destination file for the capture
:param data_link_type: PCAP data link type (DLT_*), default is DLT_FRELAY
"""
if port not in self._nios:
raise DynamipsError("Port {} is not allocated".format(port))
nio = self._nios[port]
data_link_type = data_link_type.lower()
if data_link_type.startswith("dlt_"):
data_link_type = data_link_type[4:]
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))
try:
os.makedirs(os.path.dirname(output_file))
except FileExistsError:
pass
except OSError as e:
raise DynamipsError("Could not create captures directory {}".format(e))
nio.bind_filter("both", "capture")
nio.setup_filter("both", "{} {}".format(data_link_type, output_file))
log.info("Frame relay switch {name} [id={id}]: starting packet capture on {port}".format(name=self._name,
id=self._id,
port=port))
def stop_capture(self, port):
"""
Stops a packet capture.
:param port: allocated port
"""
if port not in self._nios:
raise DynamipsError("Port {} is not allocated".format(port))
nio = self._nios[port]
nio.unbind_filter("both")
log.info("Frame relay switch {name} [id={id}]: stopping packet capture on {port}".format(name=self._name,
id=self._id,
port=port))
+52
View File
@@ -19,6 +19,7 @@
Hub object that uses the Bridge interface to create a hub with ports.
"""
import os
from .bridge import Bridge
from ..dynamips_error import DynamipsError
@@ -134,3 +135,54 @@ class Hub(Bridge):
del self._mapping[port]
return nio
def start_capture(self, port, output_file, data_link_type="DLT_EN10MB"):
"""
Starts a packet capture.
:param port: allocated port
:param output_file: PCAP destination file for the capture
:param data_link_type: PCAP data link type (DLT_*), default is DLT_EN10MB
"""
if port not in self._mapping:
raise DynamipsError("Port {} is not allocated".format(port))
nio = self._mapping[port]
data_link_type = data_link_type.lower()
if data_link_type.startswith("dlt_"):
data_link_type = data_link_type[4:]
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))
try:
os.makedirs(os.path.dirname(output_file))
except FileExistsError:
pass
except OSError as e:
raise DynamipsError("Could not create captures directory {}".format(e))
nio.bind_filter("both", "capture")
nio.setup_filter("both", "{} {}".format(data_link_type, output_file))
log.info("Ethernet hub {name} [id={id}]: starting packet capture on {port}".format(name=self._name,
id=self._id,
port=port))
def stop_capture(self, port):
"""
Stops a packet capture.
:param port: allocated port
"""
if port not in self._mapping:
raise DynamipsError("Port {} is not allocated".format(port))
nio = self._mapping[port]
nio.unbind_filter("both")
log.info("Ethernet hub {name} [id={id}]: stopping packet capture on {port}".format(name=self._name,
id=self._id,
port=port))
+11 -5
View File
@@ -1578,11 +1578,11 @@ class Router(object):
nio.bind_filter("both", "capture")
nio.setup_filter("both", "{} {}".format(data_link_type, output_file))
log.info("router {name} [id={id}]: capturing on port {slot_id}/{port_id}".format(name=self._name,
id=self._id,
nio_name=nio.name,
slot_id=slot_id,
port_id=port_id))
log.info("router {name} [id={id}]: starting packet capture on port {slot_id}/{port_id}".format(name=self._name,
id=self._id,
nio_name=nio.name,
slot_id=slot_id,
port_id=port_id))
def stop_capture(self, slot_id, port_id):
"""
@@ -1604,6 +1604,12 @@ class Router(object):
nio = adapter.get_nio(port_id)
nio.unbind_filter("both")
log.info("router {name} [id={id}]: stopping packet capture on port {slot_id}/{port_id}".format(name=self._name,
id=self._id,
nio_name=nio.name,
slot_id=slot_id,
port_id=port_id))
def _create_slots(self, numslots):
"""
Creates the appropriate number of slots for this router.