From 851ba074e7ab0bca1b9c7909dec8d9d597d005c4 Mon Sep 17 00:00:00 2001 From: grossmj Date: Mon, 23 May 2016 14:14:42 -0600 Subject: [PATCH 1/6] Set default VMware VM adapter type to e1000. --- gns3server/modules/vmware/vmware_vm.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/gns3server/modules/vmware/vmware_vm.py b/gns3server/modules/vmware/vmware_vm.py index ecd27f26..3bbaa29c 100644 --- a/gns3server/modules/vmware/vmware_vm.py +++ b/gns3server/modules/vmware/vmware_vm.py @@ -253,12 +253,17 @@ class VMwareVM(BaseVM): for adapter_number in range(0, self._adapters): # add/update the interface + if self._adapter_type == "default": + # force default to e1000 because some guest OS don't detect the adapter (i.e. Windows 2012 server) + # when 'virtualdev' is not set in the VMX file. + adapter_type = "e1000" + else: + adapter_type = self._adapter_type ethernet_adapter = {"ethernet{}.present".format(adapter_number): "TRUE", "ethernet{}.addresstype".format(adapter_number): "generated", - "ethernet{}.generatedaddressoffset".format(adapter_number): "0"} + "ethernet{}.generatedaddressoffset".format(adapter_number): "0", + "ethernet{}.virtualdev".format(adapter_number): adapter_type} self._vmx_pairs.update(ethernet_adapter) - if self._adapter_type != "default": - self._vmx_pairs["ethernet{}.virtualdev".format(adapter_number)] = self._adapter_type connection_type = "ethernet{}.connectiontype".format(adapter_number) if not self._use_any_adapter and connection_type in self._vmx_pairs and self._vmx_pairs[connection_type] in ("nat", "bridged", "hostonly"): From 3fd0a6d638535000997af57a90af23cbbaaaf200 Mon Sep 17 00:00:00 2001 From: grossmj Date: Mon, 23 May 2016 15:53:03 -0600 Subject: [PATCH 2/6] Do not delete adapters when stopping a VMware VM. Ref #1066. Allocate a new vmnet interface if vmnet 0 1 or 8 is set to a custom adapter. Set adapter type to all adapters regardless if already configured or added by GNS3. --- gns3server/modules/vmware/vmware_vm.py | 32 +++++--------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/gns3server/modules/vmware/vmware_vm.py b/gns3server/modules/vmware/vmware_vm.py index 3bbaa29c..d2843ca3 100644 --- a/gns3server/modules/vmware/vmware_vm.py +++ b/gns3server/modules/vmware/vmware_vm.py @@ -230,24 +230,6 @@ class VMwareVM(BaseVM): if self._get_vmx_setting(connected): del self._vmx_pairs[connected] - # check for adapter type - if self._adapter_type != "default": - adapter_type = "ethernet{}.virtualdev".format(adapter_number) - if adapter_type in self._vmx_pairs and self._vmx_pairs[adapter_type] != self._adapter_type: - raise VMwareError("Existing VMware network adapter {} is not of type {}, please fix or set adapter type to default in GNS3".format(adapter_number, - self._adapter_type)) - - # # check if any vmnet interface managed by GNS3 is being used on existing VMware adapters - # if self._get_vmx_setting("ethernet{}.present".format(adapter_number), "TRUE"): - # connection_type = "ethernet{}.connectiontype".format(adapter_number) - # if connection_type in self._vmx_pairs and self._vmx_pairs[connection_type] in ("hostonly", "custom"): - # vnet = "ethernet{}.vnet".format(adapter_number) - # if vnet in self._vmx_pairs: - # vmnet = os.path.basename(self._vmx_pairs[vnet]) - # #nio = self._ethernet_adapters[adapter_number].get_nio(0) - # if self.manager.is_managed_vmnet(vmnet): - # raise VMwareError("Network adapter {} is already associated with VMnet interface {} which is managed by GNS3, please remove".format(adapter_number, vmnet)) - # then configure VMware network adapters self.manager.refresh_vmnet_list(ubridge=self._use_ubridge) for adapter_number in range(0, self._adapters): @@ -268,8 +250,8 @@ class VMwareVM(BaseVM): connection_type = "ethernet{}.connectiontype".format(adapter_number) if not self._use_any_adapter and connection_type in self._vmx_pairs and self._vmx_pairs[connection_type] in ("nat", "bridged", "hostonly"): continue - self._vmx_pairs["ethernet{}.connectiontype".format(adapter_number)] = "custom" + self._vmx_pairs["ethernet{}.connectiontype".format(adapter_number)] = "custom" if self._use_ubridge: # make sure we have a vmnet per adapter if we use uBridge allocate_vmnet = False @@ -278,7 +260,7 @@ class VMwareVM(BaseVM): vnet = "ethernet{}.vnet".format(adapter_number) if vnet in self._vmx_pairs: vmnet = os.path.basename(self._vmx_pairs[vnet]) - if self.manager.is_managed_vmnet(vmnet) or vmnet == "vmnet0": + if self.manager.is_managed_vmnet(vmnet) or vmnet in ("vmnet0", "vmnet1", "vmnet8"): # vmnet already managed, try to allocate a new one allocate_vmnet = True else: @@ -513,17 +495,15 @@ class VMwareVM(BaseVM): self._vmnets.clear() # remove the adapters managed by GNS3 for adapter_number in range(0, self._adapters): - if self._get_vmx_setting("ethernet{}.vnet".format(adapter_number)) or \ - self._get_vmx_setting("ethernet{}.connectiontype".format(adapter_number)) is None: - vnet = "ethernet{}.vnet".format(adapter_number) + vnet = "ethernet{}.vnet".format(adapter_number) + if self._get_vmx_setting(vnet) or self._get_vmx_setting("ethernet{}.connectiontype".format(adapter_number)) is None: if vnet in self._vmx_pairs: vmnet = os.path.basename(self._vmx_pairs[vnet]) if not self.manager.is_managed_vmnet(vmnet): continue log.debug("removing adapter {}".format(adapter_number)) - for key in list(self._vmx_pairs.keys()): - if key.startswith("ethernet{}.".format(adapter_number)): - del self._vmx_pairs[key] + self._vmx_pairs[vnet] = "vmnet1" + self._vmx_pairs["ethernet{}.connectiontype".format(adapter_number)] = "custom" # re-enable any remaining network adapters for adapter_number in range(self._adapters, self._maximum_adapters): From e497e98ca1f9fbaa58d6f6cf4a64d8374a3f486d Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Fri, 27 May 2016 14:45:02 +0200 Subject: [PATCH 3/6] Warn if you can not export a file due to permission issue Fix #543 --- gns3server/modules/project.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gns3server/modules/project.py b/gns3server/modules/project.py index d659a8cb..eeee6c0a 100644 --- a/gns3server/modules/project.py +++ b/gns3server/modules/project.py @@ -538,6 +538,14 @@ class Project: for file in files: path = os.path.join(root, file) + # Try open the file + try: + open(path).close() + except OSError as e: + msg = "Could not export file {}: {}".format(path, e) + log.warn(msg) + self.emit("log.warning", {"message": msg}) + continue # We rename the .gns3 project.gns3 to avoid the task to the client to guess the file name if file.endswith(".gns3"): self._export_project_file(path, z, include_images) From 8e3e3c08f8f7793c51c55eb9cdda8040005a6a76 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Fri, 27 May 2016 16:08:37 +0200 Subject: [PATCH 4/6] Fix an import error when you have no GNS3 VM --- gns3server/handlers/api/project_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gns3server/handlers/api/project_handler.py b/gns3server/handlers/api/project_handler.py index 000724d8..b56e703f 100644 --- a/gns3server/handlers/api/project_handler.py +++ b/gns3server/handlers/api/project_handler.py @@ -405,7 +405,7 @@ class ProjectHandler: if not packet: break temp.write(packet) - project.import_zip(temp, gns3vm=bool(request.GET.get("gns3vm", "1"))) + project.import_zip(temp, gns3vm=bool(int(request.GET.get("gns3vm", "1")))) except OSError as e: raise aiohttp.web.HTTPInternalServerError(text="Could not import the project: {}".format(e)) From 914fe7e7502eca5464448d37c194f9841acdb9a6 Mon Sep 17 00:00:00 2001 From: grossmj Date: Fri, 27 May 2016 23:00:05 -0600 Subject: [PATCH 5/6] Randomize the 4th and 5th bytes when provided with a base mac address. Fixes #522. --- gns3server/modules/qemu/qemu_vm.py | 5 +++-- gns3server/utils/__init__.py | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/gns3server/modules/qemu/qemu_vm.py b/gns3server/modules/qemu/qemu_vm.py index d0305ccc..2006a285 100644 --- a/gns3server/modules/qemu/qemu_vm.py +++ b/gns3server/modules/qemu/qemu_vm.py @@ -28,6 +28,7 @@ import subprocess import shlex import asyncio import socket +import random import gns3server from gns3server.utils import parse_version @@ -493,9 +494,9 @@ class QemuVM(BaseVM): """ if not mac_address: - self._mac_address = "00:00:ab:%s:%s:00" % (self.id[-4:-2], self.id[-2:]) + self._mac_address = "12:34:%02x:%02x:%02x:00" % (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) else: - self._mac_address = mac_address + self._mac_address = mac_address[:8] + ":%02x:%02x:00" % (random.randint(0, 255), random.randint(0, 255)) log.info('QEMU VM "{name}" [{id}]: MAC address changed to {mac_addr}'.format(name=self._name, id=self._id, diff --git a/gns3server/utils/__init__.py b/gns3server/utils/__init__.py index 9f8ea4a7..06b56d0d 100644 --- a/gns3server/utils/__init__.py +++ b/gns3server/utils/__init__.py @@ -30,19 +30,20 @@ def force_unix_path(path): return posixpath.normpath(path) -def macaddress_to_int(macaddress): +def macaddress_to_int(mac_address): """ Convert a macaddress with the format 00:0c:29:11:b0:0a to a int - :param macaddress: The mac address + :param mac_address: The mac address + :returns: Integer """ - return int(macaddress.replace(":", ""), 16) + return int(mac_address.replace(":", ""), 16) def int_to_macaddress(integer): """ - Convert an integer to a macaddress + Convert an integer to a mac address """ return ":".join(textwrap.wrap("%012x" % (integer), width=2)) From ea7754f1c8547db833d2b41844fa4a1974dc9bfc Mon Sep 17 00:00:00 2001 From: grossmj Date: Sat, 28 May 2016 13:39:21 -0600 Subject: [PATCH 6/6] Allow to block network traffic originating from the host OS for vmnet interfaces (Windows only). --- gns3server/modules/vmware/vmware_vm.py | 13 ++++++++----- gns3server/version.py | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/gns3server/modules/vmware/vmware_vm.py b/gns3server/modules/vmware/vmware_vm.py index d2843ca3..fe75b5fa 100644 --- a/gns3server/modules/vmware/vmware_vm.py +++ b/gns3server/modules/vmware/vmware_vm.py @@ -300,6 +300,7 @@ class VMwareVM(BaseVM): :param adapter_number: adapter number """ + block_host_traffic = self.manager.config.get_section_config("VMware").getboolean("block_host_traffic", False) vnet = "ethernet{}.vnet".format(adapter_number) if vnet not in self._vmx_pairs: raise VMwareError("vnet {} not in VMX file".format(vnet)) @@ -325,10 +326,12 @@ class VMwareVM(BaseVM): else: raise VMwareError("Could not find NPF id for VMnet interface {}".format(vmnet_interface)) - # TODO: should provide that as an option - #if source_mac: - # yield from self._ubridge_hypervisor.send('bridge set_pcap_filter {name} "not ether src {mac}"'.format(name=vnet, - # mac=source_mac)) + if block_host_traffic: + if source_mac: + yield from self._ubridge_hypervisor.send('bridge set_pcap_filter {name} "not ether src {mac}"'.format(name=vnet, + mac=source_mac)) + else: + log.warn("Could not block host network traffic on {} (no MAC address found)".format(vmnet_interface)) elif sys.platform.startswith("darwin"): yield from self._ubridge_hypervisor.send('bridge add_nio_fusion_vmnet {name} "{interface}"'.format(name=vnet, @@ -349,7 +352,7 @@ class VMwareVM(BaseVM): yield from self._ubridge_hypervisor.send('bridge start {name}'.format(name=vnet)) - # TODO: this only work when using PCAP (NIO Ethernet) + # TODO: this only work when using PCAP (NIO Ethernet): current default on Linux is NIO RAW LINUX # source_mac = None # for interface in interfaces(): # if interface["name"] == vmnet_interface: diff --git a/gns3server/version.py b/gns3server/version.py index 7bd35cd5..68f0ba27 100644 --- a/gns3server/version.py +++ b/gns3server/version.py @@ -23,5 +23,5 @@ # or negative for a release candidate or beta (after the base version # number has been incremented) -__version__ = "1.5.0dev4" +__version__ = "1.5.0dev5" __version_info__ = (1, 5, 0, -99)