/// <summary> /// Populates the list with devices connected on LAN /// </summary> /// <param name="view">UI controls</param> /// <param name="InterfaceFriendlyName"></param> public static void StartScan(IView view, string InterfaceFriendlyName) { #region initialization if (capturedevice != null) { GatewayCalled = false; BackgroundScanDisabled = true; capturedevice.StopCapture(); capturedevice.Close(); capturedevice = null; } else { ClientList = new Dictionary <IPAddress, PhysicalAddress>(); Main.Devices = new ConcurrentDictionary <IPAddress, Device>(); } #endregion //Get list of interfaces CaptureDeviceList capturedevicelist = CaptureDeviceList.Instance; //crucial for reflection on any network changes capturedevicelist.Refresh(); capturedevice = (from devicex in capturedevicelist where ((NpcapDevice)devicex).Interface.FriendlyName == InterfaceFriendlyName select devicex).ToList()[0]; //open device in promiscuous mode with 1000ms timeout capturedevice.Open(DeviceMode.Promiscuous, 1000); //Arp filter capturedevice.Filter = "arp"; IPAddress myipaddress = AppConfiguration.LocalIp; //Probe for active devices on the network if (DiscoveryTimer == null) { StartDescoveryTimer(); } #region Retrieving ARP packets floating around and find out the sender's IP and MAC //Scan duration long scanduration = 8000; RawCapture rawcapture = null; //Main scanning task ScannerTask = Task.Run(() => { try { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); while ((rawcapture = capturedevice.GetNextPacket()) != null && stopwatch.ElapsedMilliseconds <= scanduration) { Packet packet = Packet.ParsePacket(rawcapture.LinkLayerType, rawcapture.Data); ArpPacket ArpPacket = packet.Extract <ArpPacket>(); if (!ClientList.ContainsKey(ArpPacket.SenderProtocolAddress) && ArpPacket.SenderProtocolAddress.ToString() != "0.0.0.0" && Tools.AreCompatibleIPs(ArpPacket.SenderProtocolAddress, myipaddress, AppConfiguration.NetworkSize)) { ClientList.Add(ArpPacket.SenderProtocolAddress, ArpPacket.SenderHardwareAddress); string mac = Tools.GetMACString(ArpPacket.SenderHardwareAddress); string ip = ArpPacket.SenderProtocolAddress.ToString(); var device = new Device { IP = ArpPacket.SenderProtocolAddress, MAC = PhysicalAddress.Parse(mac.Replace(":", "")), DeviceName = "Resolving", ManName = "Getting information...", DeviceStatus = "Online" }; //Add device to UI list view.ListView1.BeginInvoke(new Action(() => { view.ListView1.AddObject(device); })); //Add device to main device list _ = Main.Devices.TryAdd(ArpPacket.SenderProtocolAddress, device); //Get hostname and mac vendor for the current device _ = Task.Run(async() => { try { #region Get Hostname IPHostEntry hostEntry = await Dns.GetHostEntryAsync(ip); device.DeviceName = hostEntry?.HostName ?? ip; #endregion #region Get MacVendor var Name = VendorAPI.GetVendorInfo(mac); device.ManName = (Name is null) ? "" : Name.data.organization_name; #endregion view.ListView1.BeginInvoke(new Action(() => { view.ListView1.UpdateObject(device); })); } catch (Exception ex) { try { if (ex is SocketException) { var Name = VendorAPI.GetVendorInfo(mac); device.ManName = (Name is null) ? "" : Name.data.organization_name; view.ListView1.BeginInvoke(new Action(() => { device.DeviceName = ip; view.ListView1.UpdateObject(device); })); } else { view.MainForm.BeginInvoke( new Action(() => { device.DeviceName = ip; device.ManName = "Error"; view.ListView1.UpdateObject(device); })); } } catch { } } }); } int percentageprogress = (int)((float)stopwatch.ElapsedMilliseconds / scanduration * 100); view.MainForm.BeginInvoke(new Action(() => view.StatusLabel.Text = "Scanning " + percentageprogress + "%")); } stopwatch.Stop(); view.MainForm.BeginInvoke(new Action(() => view.StatusLabel.Text = ClientList.Count.ToString() + " device(s) found")); //Initial scanning is over now we start the background scan. Main.OperationIsInProgress = false; //Start passive monitoring BackgroundScanStart(view); } catch { //Show an error in the UI in case something went wrong try { view.MainForm.BeginInvoke(new Action(() => { view.StatusLabel.Text = "Error occurred"; view.PictureBox.Image = Properties.Resources.color_error; })); } catch { } //Swallow exception when the user closes the app during the scan operation } }); #endregion }
/// <summary> /// Actively monitor ARP packets for signs of new clients after the scanner is done. This method should be called from the StartScan method. /// </summary> /// <param name="view">UI controls</param> public static void BackgroundScanStart(IView view) { view.MainForm.BeginInvoke(new Action(() => view.StatusLabel.Text = "Starting background scan...")); BackgroundScanDisabled = false; IPAddress myipaddress = AppConfiguration.LocalIp; #region Assign OnPacketArrival event handler and start capturing capturedevice.OnPacketArrival += (object sender, CaptureEventArgs e) => { if (BackgroundScanDisabled) { return; } Packet packet = Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data); if (packet == null) { return; } ArpPacket ArpPacket = packet.Extract <ArpPacket>(); if (!ClientList.ContainsKey(ArpPacket.SenderProtocolAddress) && ArpPacket.SenderProtocolAddress.ToString() != "0.0.0.0" && Tools.AreCompatibleIPs(ArpPacket.SenderProtocolAddress, myipaddress, AppConfiguration.NetworkSize)) { ClientList.Add(ArpPacket.SenderProtocolAddress, ArpPacket.SenderHardwareAddress); view.ListView1.BeginInvoke(new Action(() => { string mac = Tools.GetMACString(ArpPacket.SenderHardwareAddress); string ip = ArpPacket.SenderProtocolAddress.ToString(); var device = new Device { IP = ArpPacket.SenderProtocolAddress, MAC = PhysicalAddress.Parse(mac.Replace(":", "")), DeviceName = "Resolving", ManName = "Getting information...", DeviceStatus = "Online" }; //Add device to list view.ListView1.BeginInvoke(new Action(() => { view.ListView1.AddObject(device); })); //Add device to main device list _ = Main.Devices.TryAdd(ArpPacket.SenderProtocolAddress, device); //Get hostname and mac vendor for the current device _ = Task.Run(async() => { try { #region Get Hostname IPHostEntry hostEntry = await Dns.GetHostEntryAsync(ip); device.DeviceName = hostEntry?.HostName ?? ip; #endregion #region Get MacVendor var Name = VendorAPI.GetVendorInfo(mac); device.ManName = (Name is null) ? "" : Name.data.organization_name; #endregion view.ListView1.BeginInvoke(new Action(() => { view.ListView1.UpdateObject(device); })); } catch (Exception ex) { try { if (ex is SocketException) { var Name = VendorAPI.GetVendorInfo(mac); device.ManName = (Name is null) ? "" : Name.data.organization_name; view.ListView1.BeginInvoke(new Action(() => { device.DeviceName = ip; view.ListView1.UpdateObject(device); })); } else { view.MainForm.BeginInvoke( new Action(() => { device.DeviceName = ip; device.ManName = "Error"; view.ListView1.UpdateObject(device); })); } } catch { } } }); })); view.MainForm.BeginInvoke(new Action(() => view.StatusLabel.Text = ClientList.Count + " device(s) found")); } else if (ClientList.ContainsKey(ArpPacket.SenderProtocolAddress)) { foreach (var Device in Main.Devices) { if (Device.Key.Equals(ArpPacket.SenderProtocolAddress)) { Device.Value.TimeSinceLastArp = DateTime.Now; break; } } } }; //Start receiving packets capturedevice.StartCapture(); //Update UI state view.MainForm.BeginInvoke(new Action(() => { view.PictureBox.Image = NetStalker.Properties.Resources.color_ok; view.StatusLabel2.Text = "Ready"; view.Tile.Enabled = true; view.Tile2.Enabled = true; })); if (!LoadingBarCalled) { CallTheLoadingBar(view); view.MainForm.BeginInvoke(new Action(() => view.StatusLabel.Text = "Scanning...")); } view.MainForm.BeginInvoke(new Action(() => view.StatusLabel.Text = ClientList.Count + " device(s) found")); #endregion }