diff --git a/gns3server/modules/dynamips/backends/atmsw.py b/gns3server/modules/dynamips/backends/atmsw.py
index 5f4ab494..2ce0410b 100644
--- a/gns3server/modules/dynamips/backends/atmsw.py
+++ b/gns3server/modules/dynamips/backends/atmsw.py
@@ -16,6 +16,7 @@
# along with this program. If not, see .
import re
+import os
from gns3server.modules import IModule
from ..nodes.atm_switch import ATMSwitch
from ..dynamips_error import DynamipsError
@@ -26,6 +27,8 @@ from ..schemas.atmsw import ATMSW_UPDATE_SCHEMA
from ..schemas.atmsw import ATMSW_ALLOCATE_UDP_PORT_SCHEMA
from ..schemas.atmsw import ATMSW_ADD_NIO_SCHEMA
from ..schemas.atmsw import ATMSW_DELETE_NIO_SCHEMA
+from ..schemas.atmsw import ATMSW_START_CAPTURE_SCHEMA
+from ..schemas.atmsw import ATMSW_STOP_CAPTURE_SCHEMA
import logging
log = logging.getLogger(__name__)
@@ -310,3 +313,83 @@ class ATMSW(object):
return
self.send_response(True)
+
+ @IModule.route("dynamips.atmsw.start_capture")
+ def atmsw_start_capture(self, request):
+ """
+ Starts a packet capture.
+
+ Mandatory request parameters:
+ - id (vm identifier)
+ - port (port identifier)
+ - port_id (port identifier)
+ - capture_file_name
+
+ Optional request parameters:
+ - data_link_type (PCAP DLT_* value)
+
+ Response parameters:
+ - port_id (port identifier)
+ - capture_file_path (path to the capture file)
+
+ :param request: JSON request
+ """
+
+ # validate the request
+ if not self.validate_request(request, ATMSW_START_CAPTURE_SCHEMA):
+ return
+
+ # get the ATM switch instance
+ atmsw = self.get_device_instance(request["id"], self._atm_switches)
+ if not atmsw:
+ return
+
+ port = request["port"]
+ capture_file_name = request["capture_file_name"]
+ data_link_type = request.get("data_link_type")
+
+ try:
+ capture_file_path = os.path.join(atmsw.hypervisor.working_dir, "captures", capture_file_name)
+ atmsw.start_capture(port, capture_file_path, data_link_type)
+ except DynamipsError as e:
+ self.send_custom_error(str(e))
+ return
+
+ response = {"port_id": request["port_id"],
+ "capture_file_path": capture_file_path}
+ self.send_response(response)
+
+ @IModule.route("dynamips.atmsw.stop_capture")
+ def atmsw_stop_capture(self, request):
+ """
+ Stops a packet capture.
+
+ Mandatory request parameters:
+ - id (vm identifier)
+ - port_id (port identifier)
+ - port (port number)
+
+ Response parameters:
+ - port_id (port identifier)
+
+ :param request: JSON request
+ """
+
+ # validate the request
+ if not self.validate_request(request, ATMSW_STOP_CAPTURE_SCHEMA):
+ return
+
+ # get the ATM switch instance
+ atmsw = self.get_device_instance(request["id"], self._atm_switches)
+ if not atmsw:
+ return
+
+ port = request["port"]
+ try:
+ atmsw.stop_capture(port)
+ except DynamipsError as e:
+ self.send_custom_error(str(e))
+ return
+
+ response = {"port_id": request["port_id"]}
+ self.send_response(response)
diff --git a/gns3server/modules/dynamips/backends/ethhub.py b/gns3server/modules/dynamips/backends/ethhub.py
index c09703c2..97c9df7f 100644
--- a/gns3server/modules/dynamips/backends/ethhub.py
+++ b/gns3server/modules/dynamips/backends/ethhub.py
@@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
+import os
from gns3server.modules import IModule
from ..nodes.hub import Hub
from ..dynamips_error import DynamipsError
@@ -25,6 +26,8 @@ from ..schemas.ethhub import ETHHUB_UPDATE_SCHEMA
from ..schemas.ethhub import ETHHUB_ALLOCATE_UDP_PORT_SCHEMA
from ..schemas.ethhub import ETHHUB_ADD_NIO_SCHEMA
from ..schemas.ethhub import ETHHUB_DELETE_NIO_SCHEMA
+from ..schemas.ethhub import ETHHUB_START_CAPTURE_SCHEMA
+from ..schemas.ethhub import ETHHUB_STOP_CAPTURE_SCHEMA
import logging
log = logging.getLogger(__name__)
@@ -236,7 +239,7 @@ class ETHHUB(object):
self.send_response({"port_id": request["port_id"]})
@IModule.route("dynamips.ethhub.delete_nio")
- def ethsw_delete_nio(self, request):
+ def ethhub_delete_nio(self, request):
"""
Deletes an NIO (Network Input/Output).
@@ -268,3 +271,83 @@ class ETHHUB(object):
return
self.send_response(True)
+
+ @IModule.route("dynamips.ethhub.start_capture")
+ def ethhub_start_capture(self, request):
+ """
+ Starts a packet capture.
+
+ Mandatory request parameters:
+ - id (vm identifier)
+ - port (port identifier)
+ - port_id (port identifier)
+ - capture_file_name
+
+ Optional request parameters:
+ - data_link_type (PCAP DLT_* value)
+
+ Response parameters:
+ - port_id (port identifier)
+ - capture_file_path (path to the capture file)
+
+ :param request: JSON request
+ """
+
+ # validate the request
+ if not self.validate_request(request, ETHHUB_START_CAPTURE_SCHEMA):
+ return
+
+ # get the Ethernet hub instance
+ ethhub = self.get_device_instance(request["id"], self._ethernet_hubs)
+ if not ethhub:
+ return
+
+ port = request["port"]
+ capture_file_name = request["capture_file_name"]
+ data_link_type = request.get("data_link_type")
+
+ try:
+ capture_file_path = os.path.join(ethhub.hypervisor.working_dir, "captures", capture_file_name)
+ ethhub.start_capture(port, capture_file_path, data_link_type)
+ except DynamipsError as e:
+ self.send_custom_error(str(e))
+ return
+
+ response = {"port_id": request["port_id"],
+ "capture_file_path": capture_file_path}
+ self.send_response(response)
+
+ @IModule.route("dynamips.ethhub.stop_capture")
+ def ethhub_stop_capture(self, request):
+ """
+ Stops a packet capture.
+
+ Mandatory request parameters:
+ - id (vm identifier)
+ - port_id (port identifier)
+ - port (port number)
+
+ Response parameters:
+ - port_id (port identifier)
+
+ :param request: JSON request
+ """
+
+ # validate the request
+ if not self.validate_request(request, ETHHUB_STOP_CAPTURE_SCHEMA):
+ return
+
+ # get the Ethernet hub instance
+ ethhub = self.get_device_instance(request["id"], self._ethernet_hubs)
+ if not ethhub:
+ return
+
+ port = request["port"]
+ try:
+ ethhub.stop_capture(port)
+ except DynamipsError as e:
+ self.send_custom_error(str(e))
+ return
+
+ response = {"port_id": request["port_id"]}
+ self.send_response(response)
diff --git a/gns3server/modules/dynamips/backends/ethsw.py b/gns3server/modules/dynamips/backends/ethsw.py
index a59ec4b7..e251e158 100644
--- a/gns3server/modules/dynamips/backends/ethsw.py
+++ b/gns3server/modules/dynamips/backends/ethsw.py
@@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
+import os
from gns3server.modules import IModule
from ..nodes.ethernet_switch import EthernetSwitch
from ..dynamips_error import DynamipsError
@@ -25,6 +26,8 @@ from ..schemas.ethsw import ETHSW_UPDATE_SCHEMA
from ..schemas.ethsw import ETHSW_ALLOCATE_UDP_PORT_SCHEMA
from ..schemas.ethsw import ETHSW_ADD_NIO_SCHEMA
from ..schemas.ethsw import ETHSW_DELETE_NIO_SCHEMA
+from ..schemas.ethsw import ETHSW_START_CAPTURE_SCHEMA
+from ..schemas.ethsw import ETHSW_STOP_CAPTURE_SCHEMA
import logging
log = logging.getLogger(__name__)
@@ -297,3 +300,83 @@ class ETHSW(object):
return
self.send_response(True)
+
+ @IModule.route("dynamips.ethsw.start_capture")
+ def ethsw_start_capture(self, request):
+ """
+ Starts a packet capture.
+
+ Mandatory request parameters:
+ - id (vm identifier)
+ - port (port identifier)
+ - port_id (port identifier)
+ - capture_file_name
+
+ Optional request parameters:
+ - data_link_type (PCAP DLT_* value)
+
+ Response parameters:
+ - port_id (port identifier)
+ - capture_file_path (path to the capture file)
+
+ :param request: JSON request
+ """
+
+ # validate the request
+ if not self.validate_request(request, ETHSW_START_CAPTURE_SCHEMA):
+ return
+
+ # get the Ethernet switch instance
+ ethsw = self.get_device_instance(request["id"], self._ethernet_switches)
+ if not ethsw:
+ return
+
+ port = request["port"]
+ capture_file_name = request["capture_file_name"]
+ data_link_type = request.get("data_link_type")
+
+ try:
+ capture_file_path = os.path.join(ethsw.hypervisor.working_dir, "captures", capture_file_name)
+ ethsw.start_capture(port, capture_file_path, data_link_type)
+ except DynamipsError as e:
+ self.send_custom_error(str(e))
+ return
+
+ response = {"port_id": request["port_id"],
+ "capture_file_path": capture_file_path}
+ self.send_response(response)
+
+ @IModule.route("dynamips.ethsw.stop_capture")
+ def ethsw_stop_capture(self, request):
+ """
+ Stops a packet capture.
+
+ Mandatory request parameters:
+ - id (vm identifier)
+ - port_id (port identifier)
+ - port (port number)
+
+ Response parameters:
+ - port_id (port identifier)
+
+ :param request: JSON request
+ """
+
+ # validate the request
+ if not self.validate_request(request, ETHSW_STOP_CAPTURE_SCHEMA):
+ return
+
+ # get the Ethernet switch instance
+ ethsw = self.get_device_instance(request["id"], self._ethernet_switches)
+ if not ethsw:
+ return
+
+ port = request["port"]
+ try:
+ ethsw.stop_capture(port)
+ except DynamipsError as e:
+ self.send_custom_error(str(e))
+ return
+
+ response = {"port_id": request["port_id"]}
+ self.send_response(response)
diff --git a/gns3server/modules/dynamips/backends/frsw.py b/gns3server/modules/dynamips/backends/frsw.py
index cae6923f..ed63f501 100644
--- a/gns3server/modules/dynamips/backends/frsw.py
+++ b/gns3server/modules/dynamips/backends/frsw.py
@@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
+import os
from gns3server.modules import IModule
from ..nodes.frame_relay_switch import FrameRelaySwitch
from ..dynamips_error import DynamipsError
@@ -25,6 +26,8 @@ from ..schemas.frsw import FRSW_UPDATE_SCHEMA
from ..schemas.frsw import FRSW_ALLOCATE_UDP_PORT_SCHEMA
from ..schemas.frsw import FRSW_ADD_NIO_SCHEMA
from ..schemas.frsw import FRSW_DELETE_NIO_SCHEMA
+from ..schemas.frsw import FRSW_START_CAPTURE_SCHEMA
+from ..schemas.frsw import FRSW_STOP_CAPTURE_SCHEMA
import logging
log = logging.getLogger(__name__)
@@ -289,3 +292,83 @@ class FRSW(object):
return
self.send_response(True)
+
+ @IModule.route("dynamips.frsw.start_capture")
+ def frsw_start_capture(self, request):
+ """
+ Starts a packet capture.
+
+ Mandatory request parameters:
+ - id (vm identifier)
+ - port (port identifier)
+ - port_id (port identifier)
+ - capture_file_name
+
+ Optional request parameters:
+ - data_link_type (PCAP DLT_* value)
+
+ Response parameters:
+ - port_id (port identifier)
+ - capture_file_path (path to the capture file)
+
+ :param request: JSON request
+ """
+
+ # validate the request
+ if not self.validate_request(request, FRSW_START_CAPTURE_SCHEMA):
+ return
+
+ # get the Frame relay switch instance
+ frsw = self.get_device_instance(request["id"], self._frame_relay_switches)
+ if not frsw:
+ return
+
+ port = request["port"]
+ capture_file_name = request["capture_file_name"]
+ data_link_type = request.get("data_link_type")
+
+ try:
+ capture_file_path = os.path.join(frsw.hypervisor.working_dir, "captures", capture_file_name)
+ frsw.start_capture(port, capture_file_path, data_link_type)
+ except DynamipsError as e:
+ self.send_custom_error(str(e))
+ return
+
+ response = {"port_id": request["port_id"],
+ "capture_file_path": capture_file_path}
+ self.send_response(response)
+
+ @IModule.route("dynamips.frsw.stop_capture")
+ def frsw_stop_capture(self, request):
+ """
+ Stops a packet capture.
+
+ Mandatory request parameters:
+ - id (vm identifier)
+ - port_id (port identifier)
+ - port (port number)
+
+ Response parameters:
+ - port_id (port identifier)
+
+ :param request: JSON request
+ """
+
+ # validate the request
+ if not self.validate_request(request, FRSW_STOP_CAPTURE_SCHEMA):
+ return
+
+ # get the Frame relay switch instance
+ frsw = self.get_device_instance(request["id"], self._frame_relay_switches)
+ if not frsw:
+ return
+
+ port = request["port"]
+ try:
+ frsw.stop_capture(port)
+ except DynamipsError as e:
+ self.send_custom_error(str(e))
+ return
+
+ response = {"port_id": request["port_id"]}
+ self.send_response(response)
diff --git a/gns3server/modules/dynamips/nodes/atm_switch.py b/gns3server/modules/dynamips/nodes/atm_switch.py
index 00fb967c..0c382c44 100644
--- a/gns3server/modules/dynamips/nodes/atm_switch.py
+++ b/gns3server/modules/dynamips/nodes/atm_switch.py
@@ -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))
diff --git a/gns3server/modules/dynamips/nodes/ethernet_switch.py b/gns3server/modules/dynamips/nodes/ethernet_switch.py
index 9363bafb..45cc25c0 100644
--- a/gns3server/modules/dynamips/nodes/ethernet_switch.py
+++ b/gns3server/modules/dynamips/nodes/ethernet_switch.py
@@ -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))
diff --git a/gns3server/modules/dynamips/nodes/frame_relay_switch.py b/gns3server/modules/dynamips/nodes/frame_relay_switch.py
index e096c137..0b44fbea 100644
--- a/gns3server/modules/dynamips/nodes/frame_relay_switch.py
+++ b/gns3server/modules/dynamips/nodes/frame_relay_switch.py
@@ -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))
diff --git a/gns3server/modules/dynamips/nodes/hub.py b/gns3server/modules/dynamips/nodes/hub.py
index b32ff944..6f7f0e59 100644
--- a/gns3server/modules/dynamips/nodes/hub.py
+++ b/gns3server/modules/dynamips/nodes/hub.py
@@ -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))
diff --git a/gns3server/modules/dynamips/nodes/router.py b/gns3server/modules/dynamips/nodes/router.py
index 7fc15e5a..9c08ec77 100644
--- a/gns3server/modules/dynamips/nodes/router.py
+++ b/gns3server/modules/dynamips/nodes/router.py
@@ -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.
diff --git a/gns3server/modules/dynamips/schemas/atmsw.py b/gns3server/modules/dynamips/schemas/atmsw.py
index cddea592..37669478 100644
--- a/gns3server/modules/dynamips/schemas/atmsw.py
+++ b/gns3server/modules/dynamips/schemas/atmsw.py
@@ -264,3 +264,59 @@ ATMSW_DELETE_NIO_SCHEMA = {
"additionalProperties": False,
"required": ["id", "port"]
}
+
+ATMSW_START_CAPTURE_SCHEMA = {
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "Request validation to start a packet capture on an ATM switch instance port",
+ "type": "object",
+ "properties": {
+ "id": {
+ "description": "ATM switch instance ID",
+ "type": "integer"
+ },
+ "port_id": {
+ "description": "Unique port identifier for the ATM switch instance",
+ "type": "integer"
+ },
+ "port": {
+ "description": "Port number",
+ "type": "integer",
+ "minimum": 1,
+ },
+ "capture_file_name": {
+ "description": "Capture file name",
+ "type": "string",
+ "minLength": 1,
+ },
+ "data_link_type": {
+ "description": "PCAP data link type",
+ "type": "string",
+ "minLength": 1,
+ },
+ },
+ "additionalProperties": False,
+ "required": ["id", "port_id", "port", "capture_file_name"]
+}
+
+ATMSW_STOP_CAPTURE_SCHEMA = {
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "Request validation to stop a packet capture on an ATM switch instance port",
+ "type": "object",
+ "properties": {
+ "id": {
+ "description": "ATM switch instance ID",
+ "type": "integer"
+ },
+ "port_id": {
+ "description": "Unique port identifier for the ATM switch instance",
+ "type": "integer"
+ },
+ "port": {
+ "description": "Port number",
+ "type": "integer",
+ "minimum": 1,
+ },
+ },
+ "additionalProperties": False,
+ "required": ["id", "port_id", "port"]
+}
diff --git a/gns3server/modules/dynamips/schemas/ethhub.py b/gns3server/modules/dynamips/schemas/ethhub.py
index 50470bcc..1002a696 100644
--- a/gns3server/modules/dynamips/schemas/ethhub.py
+++ b/gns3server/modules/dynamips/schemas/ethhub.py
@@ -261,3 +261,59 @@ ETHHUB_DELETE_NIO_SCHEMA = {
"additionalProperties": False,
"required": ["id", "port"]
}
+
+ETHHUB_START_CAPTURE_SCHEMA = {
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "Request validation to start a packet capture on an Ethernet hub instance port",
+ "type": "object",
+ "properties": {
+ "id": {
+ "description": "Ethernet hub instance ID",
+ "type": "integer"
+ },
+ "port_id": {
+ "description": "Unique port identifier for the Ethernet hub instance",
+ "type": "integer"
+ },
+ "port": {
+ "description": "Port number",
+ "type": "integer",
+ "minimum": 1,
+ },
+ "capture_file_name": {
+ "description": "Capture file name",
+ "type": "string",
+ "minLength": 1,
+ },
+ "data_link_type": {
+ "description": "PCAP data link type",
+ "type": "string",
+ "minLength": 1,
+ },
+ },
+ "additionalProperties": False,
+ "required": ["id", "port_id", "port", "capture_file_name"]
+}
+
+ETHHUB_STOP_CAPTURE_SCHEMA = {
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "Request validation to stop a packet capture on an Ethernet hub instance port",
+ "type": "object",
+ "properties": {
+ "id": {
+ "description": "Ethernet hub instance ID",
+ "type": "integer"
+ },
+ "port_id": {
+ "description": "Unique port identifier for the Ethernet hub instance",
+ "type": "integer"
+ },
+ "port": {
+ "description": "Port number",
+ "type": "integer",
+ "minimum": 1,
+ },
+ },
+ "additionalProperties": False,
+ "required": ["id", "port_id", "port"]
+}
diff --git a/gns3server/modules/dynamips/schemas/ethsw.py b/gns3server/modules/dynamips/schemas/ethsw.py
index 92f47b80..aeac7023 100644
--- a/gns3server/modules/dynamips/schemas/ethsw.py
+++ b/gns3server/modules/dynamips/schemas/ethsw.py
@@ -290,3 +290,59 @@ ETHSW_DELETE_NIO_SCHEMA = {
"additionalProperties": False,
"required": ["id", "port"]
}
+
+ETHSW_START_CAPTURE_SCHEMA = {
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "Request validation to start a packet capture on an Ethernet switch instance port",
+ "type": "object",
+ "properties": {
+ "id": {
+ "description": "Ethernet switch instance ID",
+ "type": "integer"
+ },
+ "port_id": {
+ "description": "Unique port identifier for the Ethernet switch instance",
+ "type": "integer"
+ },
+ "port": {
+ "description": "Port number",
+ "type": "integer",
+ "minimum": 1,
+ },
+ "capture_file_name": {
+ "description": "Capture file name",
+ "type": "string",
+ "minLength": 1,
+ },
+ "data_link_type": {
+ "description": "PCAP data link type",
+ "type": "string",
+ "minLength": 1,
+ },
+ },
+ "additionalProperties": False,
+ "required": ["id", "port_id", "port", "capture_file_name"]
+}
+
+ETHSW_STOP_CAPTURE_SCHEMA = {
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "Request validation to stop a packet capture on an Ethernet switch instance port",
+ "type": "object",
+ "properties": {
+ "id": {
+ "description": "Ethernet switch instance ID",
+ "type": "integer"
+ },
+ "port_id": {
+ "description": "Unique port identifier for the Ethernet switch instance",
+ "type": "integer"
+ },
+ "port": {
+ "description": "Port number",
+ "type": "integer",
+ "minimum": 1,
+ },
+ },
+ "additionalProperties": False,
+ "required": ["id", "port_id", "port"]
+}
diff --git a/gns3server/modules/dynamips/schemas/frsw.py b/gns3server/modules/dynamips/schemas/frsw.py
index b5b6ebdb..835e47a7 100644
--- a/gns3server/modules/dynamips/schemas/frsw.py
+++ b/gns3server/modules/dynamips/schemas/frsw.py
@@ -264,3 +264,59 @@ FRSW_DELETE_NIO_SCHEMA = {
"additionalProperties": False,
"required": ["id", "port"]
}
+
+FRSW_START_CAPTURE_SCHEMA = {
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "Request validation to start a packet capture on a Frame relay switch instance port",
+ "type": "object",
+ "properties": {
+ "id": {
+ "description": "Frame relay switch instance ID",
+ "type": "integer"
+ },
+ "port_id": {
+ "description": "Unique port identifier for the Frame relay instance",
+ "type": "integer"
+ },
+ "port": {
+ "description": "Port number",
+ "type": "integer",
+ "minimum": 1,
+ },
+ "capture_file_name": {
+ "description": "Capture file name",
+ "type": "string",
+ "minLength": 1,
+ },
+ "data_link_type": {
+ "description": "PCAP data link type",
+ "type": "string",
+ "minLength": 1,
+ },
+ },
+ "additionalProperties": False,
+ "required": ["id", "port_id", "port", "capture_file_name"]
+}
+
+FRSW_STOP_CAPTURE_SCHEMA = {
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "Request validation to stop a packet capture on a Frame relay switch instance port",
+ "type": "object",
+ "properties": {
+ "id": {
+ "description": "Frame relay switch instance ID",
+ "type": "integer"
+ },
+ "port_id": {
+ "description": "Unique port identifier for the Frame relay instance",
+ "type": "integer"
+ },
+ "port": {
+ "description": "Port number",
+ "type": "integer",
+ "minimum": 1,
+ },
+ },
+ "additionalProperties": False,
+ "required": ["id", "port_id", "port"]
+}