using System; using System.Collections.Generic; using System.Net.NetworkInformation; using System.Windows.Forms; namespace Trigger.Events { sealed class Network : EventPlugin { #region Properties private enum EventType : byte { NetworkAvailabilityChanged, NetworkInterfaceAdded = 0, NetworkInterfaceRemoved = 1, IpAddrChanged = 2, NetworkInterfaces, } /// A dictionary containing all the values before the event occurs private Dictionary oldValues = new Dictionary(); /// Whether the event private byte networkAddressChangedEnabled; private bool NetworkAddressChangedEnabled { set { if (value) networkAddressChangedEnabled++; else networkAddressChangedEnabled--; if (value && networkAddressChangedEnabled == 1) NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged; else if (networkAddressChangedEnabled == 0) NetworkChange.NetworkAddressChanged -= NetworkChange_NetworkAddressChanged; } get { return networkAddressChangedEnabled > 0; } } private byte networkAvailabilityChangedEnabled; private bool NetworkAvailabilityChangedEnabled { set { if (value) networkAvailabilityChangedEnabled++; else networkAvailabilityChangedEnabled--; if (value && networkAvailabilityChangedEnabled == 1) NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged; else if (networkAvailabilityChangedEnabled == 0) NetworkChange.NetworkAvailabilityChanged -= NetworkChange_NetworkAvailabilityChanged; } get { return networkAvailabilityChangedEnabled > 0; } } #region Events #region NetworkAvailabilityChanged private EventPlugin.EventValue OnNetworkAvailabilityChanged; public event EventPlugin.EventValue NetworkAvailabilityChanged { add { if (!oldValues.ContainsKey(EventType.NetworkAvailabilityChanged)) oldValues[EventType.NetworkAvailabilityChanged] = Status.Network.IsNetworkAvailable; this.OnNetworkAvailabilityChanged += value; NetworkAvailabilityChangedEnabled = true; } remove { this.OnNetworkAvailabilityChanged -= value; NetworkAvailabilityChangedEnabled = false; } } #endregion #region NetworkAddressChanged private EventPlugin.Event OnNetworkAddressChanged; /// Occurs when the IP address of a network interface changes. public event EventPlugin.Event NetworkAddressChanged { add { if (!oldValues.ContainsKey(EventType.NetworkInterfaces)) oldValues[EventType.NetworkInterfaces] = Status.Network.AllNetworkInterfaces; this.OnNetworkAddressChanged += value; NetworkAddressChangedEnabled = true; } remove { this.OnNetworkAddressChanged -= value; NetworkAddressChangedEnabled = false; // does not have to occur } } #endregion #region - NetworkInterfaceAdded private EventPlugin.EventValue OnNetworkInterfaceAdded; /// Occurs when a new network interface was detected public event EventPlugin.EventValue NetworkInterfaceAdded { add { if (!oldValues.ContainsKey(EventType.NetworkInterfaces)) oldValues[EventType.NetworkInterfaces] = Status.Network.AllNetworkInterfaces; this.OnNetworkInterfaceAdded += value; NetworkAddressChangedEnabled = true; } remove { this.OnNetworkInterfaceAdded -= value; NetworkAddressChangedEnabled = false; // does not have to occur } } #endregion #region - NetworkInterfaceRemoved private EventPlugin.EventValue OnNetworkInterfaceRemoved; /// Occurs when a network interface was removed public event EventPlugin.EventValue NetworkInterfaceRemoved { add { if (!oldValues.ContainsKey(EventType.NetworkInterfaces)) oldValues[EventType.NetworkInterfaces] = Status.Network.AllNetworkInterfaces; this.OnNetworkInterfaceRemoved += value; NetworkAddressChangedEnabled = true; } remove { this.OnNetworkInterfaceRemoved -= value; NetworkAddressChangedEnabled = false; // does not have to occur } } #endregion #region - IpAddressChanged private EventPlugin.EventValues OnIpAddressChanged; /// Occurs when the IP address of a specific network interface was changed public event EventPlugin.EventValues IpAddressChanged { add { if (!oldValues.ContainsKey(EventType.NetworkInterfaces)) oldValues[EventType.NetworkInterfaces] = Status.Network.AllNetworkInterfaces; this.OnIpAddressChanged += value; NetworkAddressChangedEnabled = true; } remove { this.OnIpAddressChanged -= value; NetworkAddressChangedEnabled = false; // does not have to occur } } #endregion #endregion #endregion #region Methods public override EventList EventNames() { EventList list = new EventList(); EventListRow row = list.NewEventListRow(); row.Name = "NetworkAvailabilityChanged"; row.Text = "Network availability changed"; row.Description = "The availability of the network changed"; row.Type = Manager.EventTypes.ChangingValue; list.AddEventListRow(row); row = list.NewEventListRow(); row.Name = "NetworkAddressChanged"; row.Text = "Network address changed"; row.Description = "The IP address of a network interface changed"; row.Type = Manager.EventTypes.ChangingValue; list.AddEventListRow(row); row = list.NewEventListRow(); row.Name = "NetworkInterfaceAdded"; row.Text = "Network Interface added"; row.Description = "A new network interface was detected"; row.Type = Manager.EventTypes.ChangingValue; list.AddEventListRow(row); row = list.NewEventListRow(); row.Name = "NetworkInterfaceRemoved"; row.Text = "Network Interface removed"; row.Description = "A network interface was removed"; row.Type = Manager.EventTypes.ChangingValue; list.AddEventListRow(row); row = list.NewEventListRow(); row.Name = "IPAddressChanged"; row.Text = "IP address changed"; row.Description = "The IP address of a specific network interface was changed"; row.Type = Manager.EventTypes.ChangingValue; list.AddEventListRow(row); return list; } private void handleIpAddresses(NetworkInterface oldNI, NetworkInterface newNI) { if (this.OnIpAddressChanged == null) return; UnicastIPAddressInformationCollection ipsOld = oldNI.GetIPProperties().UnicastAddresses; UnicastIPAddressInformationCollection ipsNew = newNI.GetIPProperties().UnicastAddresses; List ipsNewList = new List(ipsNew); foreach (UnicastIPAddressInformation ipOld in ipsOld) { UnicastIPAddressInformation foundIP = null; foreach (UnicastIPAddressInformation ipNew in ipsNewList) { if (ipOld.Address.ToString() == ipNew.Address.ToString()) { foundIP = ipNew; break; } } if (foundIP == null) { if (this.OnIpAddressChanged != null) this.OnIpAddressChanged(this, new EventArgsValues(oldNI, newNI)); return; } else { ipsNewList.Remove(foundIP); } } if (ipsNewList.Count > 0 && this.OnIpAddressChanged != null) this.OnIpAddressChanged(this, new EventArgsValues(oldNI, newNI)); } public override TreeNode GetStatus() { TreeNode tnMain = new TreeNode("Network"); TreeNode tnEvents = tnMain.Nodes.Add("Registered events"); if (NetworkAddressChangedEnabled) tnEvents.Nodes.Add(new TreeNode("NetworkAddressChanged")); if (NetworkAvailabilityChangedEnabled) tnEvents.Nodes.Add(new TreeNode("NetworkAvailabilityChanged")); return tnMain; } #endregion #region Events /// /// EventHandler of /// Checks all interfaces and calls events accordingly /// /// /// private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e) { if (OnNetworkAddressChanged != null) OnNetworkAddressChanged(this, e); List newNI = Status.Network.AllNetworkInterfaces; List oldNI = (List)oldValues[EventType.NetworkInterfaces]; if (newNI.Equals(oldNI)) return; foreach (NetworkInterface ni in newNI) { NetworkInterface found = oldNI.Find((item) => { return item.Id == ni.Id; }); if (found == null) { if (OnNetworkInterfaceAdded != null) OnNetworkInterfaceAdded(this, new EventArgsValue(ni)); } else { this.handleIpAddresses(found, ni); oldNI.Remove(found); } } if (OnNetworkInterfaceRemoved != null) foreach (NetworkInterface ni in oldNI) OnNetworkInterfaceRemoved(this, new EventArgsValue(ni)); oldValues[EventType.NetworkInterfaces] = newNI; } /// /// EventHandler of /// Throws the event if neccessary /// /// /// private void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e) { if (e.IsAvailable.Equals(oldValues[EventType.NetworkAvailabilityChanged])) return; if (OnNetworkAvailabilityChanged != null) OnNetworkAvailabilityChanged(this, new EventArgsValue(e.IsAvailable)); oldValues[EventType.NetworkAvailabilityChanged] = e.IsAvailable; } #endregion } }