EduNetworkBuilder/EduNetworkBuilder/NetworkLink.cs

508 lines
20 KiB
C#

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
{
public HostNicID SrcNic;
public HostNicID DstNic;
public LinkType theLinkType = LinkType.normal;
public bool isVisibleLink = true; //False for wireless. Skip drawing a line if it is there
public NetworkLink() { }
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"));
NB.DoActionChangeComponent(myNet.GetDeviceFromID(Client.myID));
}
}
}
}
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 bool Equals(NetworkComponent toCompare)
{
if (!(toCompare is NetworkLink)) return false; //comparing a link to a device
NetworkLink CompareLink = (NetworkLink)toCompare;
if (!SrcNic.Equals(CompareLink.SrcNic)) return false;
if (!DstNic.Equals(CompareLink.DstNic)) return false;
if (theLinkType != CompareLink.theLinkType) return false;
if (isInvisible != CompareLink.isInvisible) return false;
if (IsDirty != CompareLink.IsDirty) return false;
if (UniqueIdentifier != CompareLink.UniqueIdentifier) return false;
if (hostname != CompareLink.hostname) return false;
if (isInvisible != CompareLink.isInvisible) return false;
return true;
}
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<LinkType>(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;
}
/// <summary>
/// Check to see if the link is connected to the specified nic at either end
/// </summary>
/// <param name="toFind">The unique identifier of the link</param>
/// <returns>True if it has it</returns>
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;
}
/// <summary>
/// Check that the link works. If not, drop the link. It usually only
/// fails in wireless if the ssid and key do not match
/// </summary>
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 != null && dNic != null)
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<string> UsedNicIDStrings()
{
List<string> usedLinks = new List<string>();
//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 -= 40;
}
}
}
/// <summary>
/// Have the packet traverse the network
/// </summary>
/// <param name="tPacket"></param>
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<Point> PointsToCheck = new List<Point>();
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);
}
}
}
}
}