private void ForwardToReceiver(EthernetFrame frame, IMACInterface sender) { this.Log(LogLevel.Noisy, "Received frame from interface {0}", sender.MAC); if (!frame.DestinationMAC.HasValue) { this.Log(LogLevel.Warning, "Destination MAC not set, the frame has unsupported format."); return; } FrameProcessed?.Invoke(this, sender, frame.Bytes); if (!started) { return; } lock (innerLock) { var interestingIfaces = macMapping.TryGetValue(frame.DestinationMAC.Value, out var destIface) ? ifaces.Where(x => (x.PromiscuousMode && x.Interface != sender) || x.Interface == destIface) : ifaces.Where(x => x.Interface != sender); if (!TimeDomainsManager.Instance.TryGetVirtualTimeStamp(out var vts)) { // it happens when sending from tap interface vts = new TimeStamp(default(TimeInterval), EmulationManager.ExternalWorld); } foreach (var iface in interestingIfaces) { this.Log(LogLevel.Noisy, "Forwarding frame to interface {0}", iface.Interface.MAC); if (iface.AsTap != null) { iface.AsTap.ReceiveFrame(frame.Clone()); continue; } iface.Machine.HandleTimeDomainEvent(iface.Interface.ReceiveFrame, frame.Clone(), vts, () => { FrameTransmitted?.Invoke(this, sender, iface.Interface, frame.Bytes); }); } } // at the same we will potentially add current MAC address assigned to the source if (!frame.SourceMAC.HasValue) { this.Log(LogLevel.Warning, "Source MAC not set, cannot update switch cache."); return; } lock (innerLock) { macMapping[frame.SourceMAC.Value] = sender; } }