using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Drawing; using System.Xml; using System.Windows.Forms; namespace EduNetworkBuilder { [Serializable] public class NetworkLink : NetworkComponent { HostNicID SrcNic; HostNicID DstNic; public LinkType theLinkType = LinkType.normal; public bool isVisibleLink = true; //False for wireless. Skip drawing a line if it is there public NetworkLink(HostNicID source, HostNicID dest, LinkType type = LinkType.normal) { SrcNic = source; DstNic = dest; Network myNet = NB.GetNetwork(); myNet.MarkAsLinked(source, GetUniqueIdentifier); myNet.MarkAsLinked(dest, GetUniqueIdentifier); theLinkType = type; NetworkDevice sDev = myNet.GetDeviceFromID(source); NetworkDevice dDev = myNet.GetDeviceFromID(dest); if (sDev == null || dDev == null) return; NetworkCard sNic = sDev.NicFromID(source); NetworkCard dNic = dDev.NicFromID(dest); NetworkCard AccessPoint = null; NetworkCard Client = null; bool IsWireless = false; if(sNic != null && dNic != null) { if(sNic.GetNicType == NicType.wport) { AccessPoint = sNic; Client = dNic; IsWireless = true; } if(dNic.GetNicType == NicType.wport) { AccessPoint = dNic; Client = sNic; IsWireless = true; } if(IsWireless && AccessPoint != null && Client != null && AccessPoint.SSID != null && AccessPoint.SSID != "") { bool donesomething=false; if(AccessPoint.SSID != Client.SSID) { donesomething = true; Client.SSID = AccessPoint.SSID; } if (AccessPoint.WirelessKey != Client.WirelessKey) { donesomething = true; Client.WirelessKey = AccessPoint.WirelessKey; } if(donesomething) { MessageBox.Show(NB.Translate("NL_NetLinkSSID")); } } } } public NetworkLink(XmlNode theNode) { IsDirty = true; Load(theNode); } public HostNicID Src { get { return SrcNic; } } public HostNicID Dst { get { return DstNic; } } public void SetSourceDest(HostNicID src, HostNicID dst) { SrcNic = src; DstNic = dst; } public override void Load(XmlNode theNode) { foreach (XmlNode Individual in theNode.ChildNodes) { XmlNodeType myNodetype = Individual.NodeType; if (myNodetype == XmlNodeType.Element) { switch (Individual.Name.ToLower()) { case "srcnic": SrcNic = new HostNicID(Individual); break; case "dstnic": DstNic = new HostNicID(Individual); break; case "hostname": hostname = Individual.InnerText; break; case "linktype": theLinkType = NB.ParseEnum(Individual.InnerText); break; case "uniqueidentifier": int.TryParse(Individual.InnerText,out UniqueIdentifier); break; case "invisible": case "isinvisible": bool.TryParse(Individual.InnerText, out isInvisible); break; } } } Network myNet = NB.GetNetwork(); NetworkDevice snd = myNet.GetDeviceFromID(SrcNic); NetworkDevice dnd = myNet.GetDeviceFromID(DstNic); if (snd != null && dnd != null && hostname == "") hostname = snd.hostname + "_link_" + dnd.hostname; myNet.MarkAsLinked(SrcNic, GetUniqueIdentifier); myNet.MarkAsLinked(DstNic, GetUniqueIdentifier); } public void MarkAsLinked() { Network myNet = NB.GetNetwork(); if (myNet != null) { myNet.MarkAsLinked(SrcNic, GetUniqueIdentifier); myNet.MarkAsLinked(DstNic, GetUniqueIdentifier); } } public override void Save(XmlWriter writer) { writer.WriteStartElement("link"); SrcNic.Save(writer, "SrcNic"); DstNic.Save(writer, "DstNic"); writer.WriteElementString("hostname", hostname); writer.WriteElementString("linktype", theLinkType.ToString()); writer.WriteElementString("uniqueidentifier", UniqueIdentifier.ToString()); if(isInvisible) writer.WriteElementString("isinvisible", isInvisible.ToString()); writer.WriteEndElement(); } public override void Destroy() { Network myNet = NB.GetNetwork(); if (myNet != null) { myNet.MarkAsUnlinked(SrcNic, GetUniqueIdentifier); myNet.MarkAsUnlinked(DstNic, GetUniqueIdentifier); } } public bool IsSource(int ID) { if (SrcNic.HostID == ID) return true; else return false; } public bool IsDest(int ID) { if (DstNic.HostID == ID) return true; else return false; } //Have func to verify both ends are powered on public bool isLive() { return false; } /// /// Check to see if the link is connected to the specified nic at either end /// /// The unique identifier of the link /// True if it has it public bool HasLink(HostNicID toFind) { if (SrcNic.Equals(toFind) || DstNic.Equals(toFind)) return true; return false; } public double LinkDistance() { Network myNet = NB.GetNetwork(); if (myNet == null) return -1; NetworkDevice sDev = myNet.GetDeviceFromID(SrcNic); NetworkDevice dDev = myNet.GetDeviceFromID(DstNic); if (sDev == null || dDev == null) return -1; double distance = myNet.distance(sDev.myLocation(), dDev.myLocation()); return distance; } /// /// Check that the link works. If not, drop the link. It usually only /// fails in wireless if the ssid and key do not match /// public bool VerifyLinkIntegrity() { Network myNet = NB.GetNetwork(); if (myNet == null) return false; NetworkDevice sDev = myNet.GetDeviceFromID(SrcNic); NetworkDevice dDev = myNet.GetDeviceFromID(DstNic); if (sDev == null || dDev == null) return false; NetworkCard sNic = sDev.NicFromID(SrcNic); NetworkCard dNic = dDev.NicFromID(DstNic); bool deleteme=false; if (sNic != null && dNic != null) { if (sNic.GetNicType == NicType.wport || dNic.GetNicType == NicType.wport) { if (sNic.WirelessKey != dNic.WirelessKey) deleteme = true; if (sNic.SSID == "" || sNic.SSID == null) //if no SSID set deleteme = true; if (dNic.SSID == "" || dNic.SSID == null) //if no SSID set deleteme = true; if (sNic.SSID != dNic.SSID) deleteme = true; if (LinkDistance() > NB.WirelessMaxUnsuccessfulLink) deleteme = true; if (sDev.PowerOff) deleteme = true; if (dDev.PowerOff) deleteme = true; } if (sNic.GetNicType == NicType.wlan) { if (sDev.PowerOff || dDev.PowerOff) deleteme = true; } if (dNic.GetNicType == NicType.wlan) { if (sDev.PowerOff || dDev.PowerOff) deleteme = true; } } if (sNic.isWireless() != dNic.isWireless()) deleteme = true; if(deleteme) { sDev.RemoveLinkTo(dDev.hostname); //this removes this link return true; } return false; } public override void Print(Image BaseImage, CaptionType DrawTitle) { if (isInvisible) return; //We do not print the line if it is invisible //Find the XY of the connected items Network myNet = NB.GetNetwork(); NetworkDevice Src = myNet.HostMatchingHostNicID(SrcNic); NetworkDevice Dst = myNet.HostMatchingHostNicID(DstNic); //Draw a line between them if (Src == null || Dst == null) return; Point sPoint = Src.GetCenter(); Point dPoint = Dst.GetCenter(); Pen tPen = new Pen(Color.Black, 4); if(theLinkType == LinkType.wireless) { //tPen = new Pen(Color.DarkSlateGray); tPen.DashCap = System.Drawing.Drawing2D.DashCap.Round; tPen.DashPattern = new float[] { 8.0F, 2.0F}; } Graphics.FromImage(BaseImage).DrawLine(tPen,sPoint,dPoint); IsDirty = false; //we have printed, we are no longer dirty. } public Point PositionOnLine(nb_direction direction, int Percentage) { Network myNet = NB.GetNetwork(); if(Percentage < 0) Percentage =0; if(Percentage > 100) Percentage = 100; NetworkDevice Src = myNet.HostMatchingHostNicID(SrcNic); NetworkDevice Dst = myNet.HostMatchingHostNicID(DstNic); //Draw a line between them if (Src == null || Dst == null) return new Point(-1,-1); Point sPoint = Src.GetCenter(); Point dPoint = Dst.GetCenter(); double deltax = (sPoint.X - dPoint.X) / 100.0; double deltay = (sPoint.Y - dPoint.Y) / 100.0; Point answer; if(direction == nb_direction.to_dst) answer = new Point(sPoint.X-(int)(deltax * Percentage), sPoint.Y-(int)(deltay * Percentage)); else answer = new Point((int)(deltax * Percentage) + dPoint.X, (int)(deltay * Percentage) + dPoint.Y); return answer; } public HostNicID RandomEndpoint() { Random rnd = NB.GetRandom(); HostNicID theID; if (rnd.Next(2) == 0) theID = SrcNic; else theID = DstNic; return theID; } public List UsedNicIDStrings() { List usedLinks = new List(); //If the nic is a wireless end point, we should not count it. We can have multiple Nics linked to one AP usedLinks.Add(SrcNic.HostNicIDString); usedLinks.Add(DstNic.HostNicIDString); return usedLinks; } public bool AtLocation(Point NetworkPoint) { Network myNet = NB.GetNetwork(); NetworkDevice Src = myNet.HostMatchingHostNicID(SrcNic); NetworkDevice Dst = myNet.HostMatchingHostNicID(DstNic); int Slop = 10; int AutoWin = Slop * 2; //Draw a line between them if (Src == null || Dst == null) return false; Point sPoint = Src.GetCenter(); Point dPoint = Dst.GetCenter(); Rectangle SlopRec = new Rectangle( Math.Min(sPoint.X, dPoint.X) - Slop, Math.Min(sPoint.Y, dPoint.Y) - Slop, Math.Abs(sPoint.X - dPoint.X) + (Slop * 2), Math.Abs(sPoint.Y - dPoint.Y) + (Slop * 2)); Rectangle ActualRec = new Rectangle( Math.Min(sPoint.X, dPoint.X), Math.Min(sPoint.Y, dPoint.Y), Math.Abs(sPoint.X - dPoint.X), Math.Abs(sPoint.Y - dPoint.Y)); if (SlopRec.Contains(NetworkPoint)) { if (ActualRec.Width < AutoWin || ActualRec.Height < AutoWin) return true; //we are close enough //We are inside it. Now to figure out if we are somewhere along the line Rectangle smallrec = new Rectangle(Math.Min(sPoint.X, dPoint.X), Math.Min(sPoint.Y, NetworkPoint.Y), Math.Abs(sPoint.X - NetworkPoint.X), Math.Abs(sPoint.Y - NetworkPoint.Y)); double deltax = smallrec.Width / (double)ActualRec.Width; double deltay = smallrec.Height / (double)ActualRec.Height; double TrueDelta = Math.Abs(Math.Abs(deltax) - Math.Abs(deltay)); if (TrueDelta > .15) return false; return true; } return false; } public void TakeDamageIfNeeded(Point location, Packet tPacket) { Network myNet = NB.GetNetwork(); if (myNet.DeviceIsOverDamaging(theLinkType, location)) { tPacket.health -= 10; //Console.WriteLine(" health=" + tPacket.health.ToString()); } if (theLinkType == LinkType.wireless) { if (myNet.DeviceInTree(theLinkType, location)) { tPacket.health -= 60; } } } /// /// Have the packet traverse the network /// /// public override void DoMoving(Packet tPacket) { NetworkDevice movingTo = null; Network myNet = NB.GetNetwork(); HostNicID target; int oldpercent = tPacket.myLinkPercent; Point oldLocation = PositionOnLine(tPacket.myDirection, tPacket.myLinkPercent); tPacket.IncrementDistance(); Point newLocation = PositionOnLine(tPacket.myDirection, tPacket.myLinkPercent); List PointsToCheck = new List(); PointsToCheck.Add(newLocation); double distance = myNet.pixeldistance(oldLocation, newLocation); if(distance > (double)myNet.itemsize / 2) { //We are traveling too fast to accurately take damage. take some snapshot point along the way int count = (int)(distance / ((double)myNet.itemsize / 2)); int newpercent = tPacket.myLinkPercent; int delta = Math.Abs(newpercent - oldpercent) / (count +1); if (delta < 1) count = 1; if (delta > 5) count = 5; int start = newpercent + delta; int end = oldpercent; if(oldpercent - newpercent < 0) { start = oldpercent + delta; end = newpercent; } for(int percent = start; percent < end; percent+= delta ) { Point next = PositionOnLine(tPacket.myDirection, percent); PointsToCheck.Add(next); } } foreach(Point one in PointsToCheck) TakeDamageIfNeeded(one, tPacket); if(theLinkType == LinkType.wireless) { NetworkDevice sDev = myNet.GetDeviceFromID(SrcNic); NetworkDevice dDev = myNet.GetDeviceFromID(DstNic); distance = myNet.distance(sDev, dDev) * (tPacket.myLinkPercent * 0.01); if(distance > NB.WirelessMaxSuccessfulLink) { //The wireless link is too far. Drop the packet tPacket.Tracking.AddMessage(DebugLevel.info, this, NB.Translate("NL_WirelessDropped")); tPacket.Tracking.Status = NB.Translate("NL_WirelessDropped"); tPacket.Tracking.Finished = true; tPacket.MyStatus = PacketStatus.finished_failed; } } if(tPacket.health <= 0) { //The link is broken. Drop the packet tPacket.Tracking.AddMessage(DebugLevel.info, this, NB.Translate("NL_DoMoveCorruptLight")); tPacket.Tracking.Status = NB.Translate("NL_DoMoveDrop"); tPacket.Tracking.Finished = true; tPacket.MyStatus = PacketStatus.finished_failed; } if(theLinkType == LinkType.broken && tPacket.myLinkPercent > 50) { //The link is broken. Drop the packet tPacket.Tracking.AddMessage(DebugLevel.info, this, NB.Translate("NL_DoMoveCorruptWire")); tPacket.Tracking.Status = NB.Translate("NL_DoMoveDrop"); tPacket.MyStatus = PacketStatus.finished_failed; } if(tPacket.Arrived()) { //We need to pass it to the recieving device if (tPacket.myDirection == nb_direction.to_dst) { movingTo= myNet.GetDeviceFromID(DstNic.HostID); target = DstNic; } else { movingTo = myNet.GetDeviceFromID(SrcNic.HostID); target = SrcNic; } if(movingTo == null) { tPacket.AddMessage(DebugLevel.info, NB.Translate("NL_DoMoveNoEnd")); tPacket.Tracking.Status = NB.LeftPad(hostname) + string.Format(NB.Translate("NL_DoMoveNoEnd2")); tPacket.MyStatus = PacketStatus.finished_failed; } else { movingTo.DoInputFromLink(tPacket, target); } } } } }