508 lines
20 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|