using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Globalization; using System.Xml; using System.Windows.Forms; using System.Text.RegularExpressions; namespace EduNetworkBuilder { [Serializable] public class IPAddress { private UInt32 _ip; private UInt32 _mask; private UInt32 _gw; private IPAddressType myType; public IPAddress(string ip, string mask, IPAddressType WhatType) { myType = WhatType; _ip = ip.ParseIp(); _mask = mask.ParseIp(); } public IPAddress(string ip, string mask, string gw) { myType = IPAddressType.route; _ip = ip.ParseIp(); _mask = mask.ParseIp(); _gw = gw.ParseIp(); } public IPAddress(XmlNode theNode) { foreach (XmlNode Individual in theNode.ChildNodes) { XmlNodeType myNodetype = Individual.NodeType; if (myNodetype == XmlNodeType.Element) { switch (Individual.Name.ToLower()) { case "ip": _ip = Individual.InnerText.ParseIp(); break; case "mask": _mask = Individual.InnerText.ParseIp(); break; case "gateway": _gw = Individual.InnerText.ParseIp(); break; case "type": myType = NB.ParseEnum(Individual.InnerText); break; } } } } public void Save(XmlWriter writer, string tag) { writer.WriteStartElement(tag); writer.WriteElementString("ip", _ip.ToIpString()); writer.WriteElementString("mask", _mask.ToIpString()); writer.WriteElementString("gateway", _gw.ToIpString()); writer.WriteElementString("type", myType.ToString()); writer.WriteEndElement(); } public void Reparse(string ip, string mask, string gw) { _ip = ip.ParseIp(); _mask = mask.ParseIp(); _gw = gw.ParseIp(); } public void Reparse(string ip, string mask) { _ip = ip.ParseIp(); _mask = mask.ParseIp(); } public IPAddressType GetAddressType { get { return myType; } } public bool IsLocal(IPAddress dest) { if (dest == null) return false; UInt32 answer = dest.GetIP & _mask; if ((dest.GetIP & _mask) == NetworkAddress) return true; return false; } public bool Edit(NetworkDevice FromWhat, Form ParentForm, string message="", bool JustPinging = false) { IPAddressEntry IPe = new IPAddressEntry(this, FromWhat, ParentForm, JustPinging); if (message != "") IPe.Text = message; return IPe.Edit(); } public bool Edit(NetworkDevice FromWhat, IPAddress DHCPif, Form ParentForm, bool JustPinging = false) { IPAddressEntry IPe = new IPAddressEntry(this, FromWhat, ParentForm, JustPinging); return IPe.Edit(FromWhat, DHCPif); } public IPAddress(string ip) { if (ip == null) ip = NB.ZeroIPString; myType = IPAddressType.ip; _ip = ip.ParseIp(); var mySplitVal = ip.Split('/'); if (mySplitVal.Count() < 2) { //We do not have a cidr. We need to guess //For now, use 255.255.255.0 _mask = "255.255.255.0".ParseIp(); mySplitVal = ip.Split('.'); if(mySplitVal.Count() > 0) { //If it is not one of these three, we already use 255.255.255.0 if(mySplitVal[0] == "10") { _mask = "255.0.0.0".ParseIp(); } if (mySplitVal[0] == "172") { _mask = "255.255.0.0".ParseIp(); } if (mySplitVal[0] == "192") { _mask = "255.255.255.0".ParseIp(); } } } else { _mask = MaskNumFromCIDRString(mySplitVal[1]); } } static UInt32 MaskNumFromCIDRString(string cidr) { UInt32 tInt = 0; int cdr; int.TryParse(cidr, out cdr); for (int loop = 0; loop < 32; loop++) { tInt = (tInt << 1); if (loop < cdr) tInt++; } return tInt; } public bool Equals(UInt32 IP) { return IP == _ip; } public bool Equals(UInt32 IP, UInt32 mask) { return (IP == _ip && mask == _mask); } public UInt32 NumberOfHosts { get { return ~_mask + 1; } } public UInt32 GetIP { get { return _ip; } } public string GetIPString { get { return _ip.ToIpString(); } } public string GetBroadcastString { get { return BroadcastAddress.ToIpString(); } } public string GetMaskString { get { return _mask.ToIpString(); } } public UInt32 GetMask { get { return _mask; } } public UInt32 GetGateway { get { return _gw; } } public UInt32 NetworkAddress { get { return _ip & _mask; } } public UInt32 BroadcastAddress { get { return NetworkAddress + ~_mask; } } public IEnumerable Hosts() { for (var host = NetworkAddress + 1; host < BroadcastAddress; host++) { yield return host; } } public string IPFormat() { return IPFormat(_gw.ToIpString()); } public string PadIt(string Addr) { string myaddr = Addr.PadRight(12); return myaddr; } public string IPFormat(string gw) { string tstring = string.Format(NB.Translate("IPA_IPFormatStr"), PadIt(_ip.ToIpString()), PadIt(_mask.ToIpString()), PadIt(gw)); return tstring; } /// /// Return the CIDR number for this address. This is the number of 1s before the first 0 /// /// public int CIDRNumber() { string mask = GetMask.ToBitString(); mask = Regex.Replace(mask, "0", ""); return mask.Length; } /// /// Return true if the subnet mask is really a true CIDR string /8, /16, etc. /// It is false if the subnet mask creates a mask that does not map to CIDR. For /// example, 255.255.255.250 is not a real subnet mask. 252 is. /// /// True if there are no 1s after the first 0 public bool ValidCIDR() { int cidr = CIDRNumber(); UInt32 tMask = MaskNumFromCIDRString(cidr.ToString()); if (tMask == _mask) return true; return false; } } public static class IpHelpers { public static string ToIpString(this UInt32 value) { var bitmask = 0xff000000; var parts = new string[4]; for (var i = 0; i < 4; i++) { var masked = (value & bitmask) >> ((3 - i) * 8); bitmask >>= 8; parts[i] = masked.ToString(CultureInfo.InvariantCulture); } return String.Join(".", parts); } public static string ToBitString(this UInt32 value) { var item = System.Convert.ToString(value, 2); return (string)item; } public static UInt32 ParseIp(this string ipAddress) { if (ipAddress == null) ipAddress = ""; var gw = ipAddress.Split('/'); //Pull off any cdr var mySplitVal = gw[0].Split('.'); if (mySplitVal.Count() != 4) return 0; UInt32 ip = 0; uint part; if (mySplitVal.Count() == 4) { for (var i = 0; i < 4; i++) { part = 0; UInt32.TryParse(mySplitVal[i], out part); ip = (ip << 8) + part; } } return ip; } } }