From a018c5b0f57b4336229bdce238e1021da25f77c5 Mon Sep 17 00:00:00 2001 From: grossmj Date: Mon, 14 Mar 2016 18:27:51 -0600 Subject: [PATCH] Get MAC addresses for host interfaces to use for filtering frames from vmnet interfaces. --- gns3server/modules/vmware/vmware_vm.py | 21 +++++++++++++++++++-- gns3server/utils/interfaces.py | 11 ++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/gns3server/modules/vmware/vmware_vm.py b/gns3server/modules/vmware/vmware_vm.py index 516c674c..dbec40a5 100644 --- a/gns3server/modules/vmware/vmware_vm.py +++ b/gns3server/modules/vmware/vmware_vm.py @@ -26,7 +26,7 @@ import asyncio import tempfile from gns3server.utils.telnet_server import TelnetServer -from gns3server.utils.interfaces import get_windows_interfaces +from gns3server.utils.interfaces import interfaces, get_windows_interfaces from gns3server.utils.asyncio import wait_for_file_creation, wait_for_named_pipe_creation from collections import OrderedDict from .vmware_error import VMwareError @@ -318,20 +318,29 @@ class VMwareVM(BaseVM): vmnet_interface = os.path.basename(self._vmx_pairs[vnet]) if sys.platform.startswith("linux"): yield from self._ubridge_hypervisor.send('bridge add_nio_linux_raw {name} "{interface}"'.format(name=vnet, - interface=vmnet_interface)) + interface=vmnet_interface)) elif sys.platform.startswith("win"): windows_interfaces = get_windows_interfaces() npf = None + source_mac = None for interface in windows_interfaces: if "netcard" in interface and vmnet_interface in interface["netcard"]: npf = interface["id"] + source_mac = interface["mac_address"] elif vmnet_interface in interface["name"]: npf = interface["id"] + source_mac = interface["mac_address"] if npf: yield from self._ubridge_hypervisor.send('bridge add_nio_ethernet {name} "{interface}"'.format(name=vnet, interface=npf)) 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)) + elif sys.platform.startswith("darwin"): yield from self._ubridge_hypervisor.send('bridge add_nio_fusion_vmnet {name} "{interface}"'.format(name=vnet, interface=vmnet_interface)) @@ -351,6 +360,14 @@ class VMwareVM(BaseVM): yield from self._ubridge_hypervisor.send('bridge start {name}'.format(name=vnet)) + # TODO: this only work when using PCAP (NIO Ethernet) + # source_mac = None + # for interface in interfaces(): + # if interface["name"] == vmnet_interface: + # source_mac = interface["mac_address"] + # if source_mac: + # yield from self._ubridge_hypervisor.send('bridge set_pcap_filter {name} "not ether src {mac}"'.format(name=vnet, mac=source_mac)) + @asyncio.coroutine def _delete_ubridge_connection(self, adapter_number): """ diff --git a/gns3server/utils/interfaces.py b/gns3server/utils/interfaces.py index 962c4581..2ff5cc0a 100644 --- a/gns3server/utils/interfaces.py +++ b/gns3server/utils/interfaces.py @@ -23,7 +23,7 @@ import struct import psutil if psutil.version_info < (3, 0, 0): - raise Exception("psutil version should >= 3.0.0. If you are under ubuntu/debian install gns3 via apt instead of pip") + raise Exception("psutil version should >= 3.0.0. If you are under Ubuntu/Debian install gns3 via apt instead of pip") import logging log = logging.getLogger(__name__) @@ -59,6 +59,7 @@ def _get_windows_interfaces_from_registry(): interfaces.append({"id": npf_interface, "name": name, "ip_address": ip_address, + "mac_address": "", # TODO: find MAC address in registry "netcard": netcard}) winreg.CloseKey(hkeyinterface) winreg.CloseKey(hkeycon) @@ -99,6 +100,7 @@ def get_windows_interfaces(): interfaces.append({"id": npf_interface, "name": adapter.NetConnectionID, "ip_address": ip_address, + "mac_address": adapter.MACAddress, "netcard": adapter.name}) except (AttributeError, pywintypes.com_error): log.warn("Could not use the COM service to retrieve interface info, trying using the registry...") @@ -148,14 +150,17 @@ def interfaces(): if not sys.platform.startswith("win"): for interface in sorted(psutil.net_if_addrs().keys()): ip_address = "" + mac_address = "" for addr in psutil.net_if_addrs()[interface]: # get the first available IPv4 address only if addr.family == socket.AF_INET: ip_address = addr.address - break + if addr.family == psutil.AF_LINK: + mac_address = addr.address results.append({"id": interface, "name": interface, - "ip_address": ip_address}) + "ip_address": ip_address, + "mac_address": mac_address}) else: try: results = get_windows_interfaces()