/// <summary>
 /// Adds an IP address and the corresponding subnetmask to this interface
 /// </summary>
 /// <param name="ipa">The IPAddress to add</param>
 /// <param name="smMask">The subnetmask to add</param>
 public void AddAddress(IPAddress ipa, Subnetmask smMask)
 {
     dictAddresses.Add(ipa, smMask);
     subNetmasks.Add(smMask);
     ipaIpAddresses.Add(ipa);
     InvokeAddressAdded(new AddressEventArgs(ipa, smMask, this));
 }
        /// <summary>
        /// Removes an IPAddress and its corresponding subnetmask from this interface
        /// </summary>
        /// <param name="ipa">The IPAddress to remove</param>
        public void RemoveAddress(IPAddress ipa)
        {
            int iIndex = ipaIpAddresses.IndexOf(ipa);

            ipaIpAddresses.RemoveAt(iIndex);
            Subnetmask smMask = subNetmasks[iIndex];

            subNetmasks.RemoveAt(iIndex);
            dictAddresses.Remove(ipa);
            InvokeAddressRemoved(new AddressEventArgs(ipa, smMask, this));
        }
        /// <summary>
        /// Tries to parse an integer to a subnetmask.
        /// </summary>
        /// <param name="iSlashNotation">The short slash notation of the subnetmask, e.g /24 as integer.</param>
        /// <param name="afDesiredAddress">The address family of the subnet mask, InterNetwork or InterNetworkV6</param>
        /// <param name="sSubnetmask">When this method returns, contains the parsed subnet mask if parsing was a success.</param>
        /// <returns>A bool indicating whether parsing was successfull</returns>
        public static bool TryParse(int iSlashNotation, AddressFamily afDesiredAddress, out Subnetmask sSubnetmask)
        {
            sSubnetmask = null;

            if (iSlashNotation >= 0)
            {
                if (afDesiredAddress == AddressFamily.InterNetwork)
                {
                    if (iSlashNotation <= 32)
                    {
                        byte[] bData = new byte[4];

                        for (int iC1 = 0; iC1 < 32 && iSlashNotation > 0; iC1++)
                        {
                            SetBit(bData, iC1, true);
                            iSlashNotation--;
                        }

                        if (CheckBytes(bData))
                        {
                            sSubnetmask = new Subnetmask(bData);
                        }
                    }
                }
                else if (afDesiredAddress == AddressFamily.InterNetworkV6)
                {
                    if (iSlashNotation <= 128)
                    {
                        byte[] bData = new byte[16];

                        for (int iC1 = 0; iC1 < 128 && iSlashNotation > 0; iC1++)
                        {
                            SetBit(bData, iC1, true);
                            iSlashNotation--;
                        }

                        if (CheckBytes(bData))
                        {
                            sSubnetmask = new Subnetmask(bData);
                        }
                    }
                }
            }

            return(sSubnetmask != null);
        }
        /// <summary>
        /// Determines whether this subnetmask equals another subnetmask
        /// </summary>
        /// <param name="obj">An object to compare to this subnetmask</param>
        /// <returns>True, if the <paramref name="obj"/>equals this subnetmask, false if not.</returns>
        public override bool Equals(object obj)
        {
            if (obj is Subnetmask)
            {
                Subnetmask sObj = (Subnetmask)obj;

                if (sObj.bSubnetMask.Length != this.bSubnetMask.Length)
                {
                    return(false);
                }

                for (int iC1 = 0; iC1 < bSubnetMask.Length; iC1++)
                {
                    if (sObj.bSubnetMask[iC1] != this.bSubnetMask[iC1])
                    {
                        return(false);
                    }
                }

                return(true);
            }

            return(false);
        }
 /// <summary>
 /// Creates a new instance of this class
 /// </summary>
 /// <param name="ipa">The IPAddress</param>
 /// <param name="smMask">The subnetmask</param>
 /// <param name="ipiInterface">The interface</param>
 public AddressEventArgs(IPAddress ipa, Subnetmask smMask, IPInterface ipiInterface)
 {
     this.ipa          = ipa;
     this.smMask       = smMask;
     this.ipiInterface = ipiInterface;
 }
        /// <summary>
        /// Tries to parse a string to a subnetmask. Possible inputs are: <br />
        /// A string in the format of XXX.XXX.XXX.XXX, where XXX is a number between 0 and 255 for IPv4 subnet masks. <br />
        /// A string in the format of XXXX, where XXXX will be put into the subnet portion of an IPv6 subnet mask. <br />
        /// A string in the format of XXXX:XXXX:XXXX:XXXX:XXXX:XXXX, where XXXX is a hex value between 0 and FFFF for IPv6 subnet masks.
        /// </summary>
        /// <param name="strString">The string to parse</param>
        /// <param name="sSubnetmask">When this method returns, contains the parsed subnet mask if parsing was a success.</param>
        /// <returns>A bool indicating whether parsing was successfull</returns>
        public static bool TryParse(string strString, out Subnetmask sSubnetmask)
        {
            byte[] bMaskData;
            int    iParse = 0;

            sSubnetmask = null;

            if (strString.Contains("."))
            {
                string[] strSplit = strString.Split('.');
                if (strSplit.Length == 4)
                {
                    bMaskData = new byte[4];
                    for (int iC1 = 0; iC1 < 4; iC1++)
                    {
                        if (Int32.TryParse(strSplit[iC1], out iParse))
                        {
                            bMaskData[iC1] = (byte)iParse;
                        }
                        else
                        {
                            return(false);
                        }
                    }

                    if (CheckBytes(bMaskData))
                    {
                        sSubnetmask = new Subnetmask(bMaskData);
                    }
                }
            }
            else if (strString.Contains(":"))
            {
                string[] strSplit = strString.Split(':');

                if (strSplit.Length == 8)
                {
                    bMaskData = new byte[16];
                    for (int iC1 = 0; iC1 < 16; iC1 += 2)
                    {
                        if (Int32.TryParse(strSplit[iC1 / 2], System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.CurrentCulture, out iParse))
                        {
                            bMaskData[iC1]     = (byte)((iParse >> 8) & 0xFF);
                            bMaskData[iC1 + 1] = (byte)(iParse & 0xFF);
                        }
                        else
                        {
                            return(false);
                        }
                    }

                    if (CheckBytes(bMaskData))
                    {
                        sSubnetmask = new Subnetmask(bMaskData);
                    }
                }
            }
            else if (strString.Length <= 4)
            {
                Subnetmask sDummy;
                if (TryParse("FFFF:FFFF:FFFF:FFFF:" + strString + ":0:0:0", out sDummy))
                {
                    sSubnetmask = sDummy;
                }
            }

            return(sSubnetmask != null);
        }