EduNetworkBuilder/EduNetworkBuilder/Network.cs

2701 lines
107 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows.Forms;
using System.Xml;
using System.IO;
using System.Text.RegularExpressions;
using System.ComponentModel;
using System.Drawing.Imaging;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace EduNetworkBuilder
{
/// <summary>
/// This is a whole network. LAN, WAN, Internet; everything combined
/// </summary>
[Serializable]
public class Network
{
public string PuzzleName = "";
public int myHeight = 1024;
public int myWidth = 1024;
public int Level = 0;
public double SortOrder = 0;
public CaptionType OptionShowLabels = CaptionType.none;
public CaptionType ShowLabelsHere = CaptionType.none;
public bool VLANsEnabled = false;
public bool VLANPacketColors = false;
private bool _LoadedFromResource = false; //If we are a puzzle that is built-into the program
public bool LoadedFromResource {
get { return _LoadedFromResource; }
private set { _LoadedFromResource = value; }
}
public LanguageStrings NetMessage;
public LanguageStrings NetTitle;
public LanguageStrings NetURL;
List<NetworkComponent> NetComponents = new List<NetworkComponent>();
//should have background image
Image TheNetImage = new Bitmap(1024, 1024);
Image TheNetImageBackground = new Bitmap(1024, 1024);
public int itemsize = 100; //The size of network components
[NonSerialized]
PictureBox myPBox = null;
private int UniqueIdentifier = 100; //This gets used for all sorts of things. is auto-incremented every time someone asks for one
private List<Packet> myPackets = new List<Packet>();
private List<PacketMessage> myMessages = new List<PacketMessage>();
private bool _isDirty = false;
private NB_IPAddress lastAddress = new NB_IPAddress("0.0.0.0/24");
public string NetworkFilename = "";
public List<NetTest> NetTests = new List<NetTest>();
private bool AlreadyDisplayedMessage = false;
public NetTestVerbosity HintsToDisplay = NetTestVerbosity.none;
public NetTestVerbosity StartingHelpLevel = NetTestVerbosity.none;
public bool PuzzleIsSolved = true; //only set to false if we load a puzzle
public List<HelpTopics> SuggestedReadings = new List<HelpTopics>();
private DateTime NetworkStartTime = DateTime.Now;
private DateTime NextSprayTime = DateTime.Now;
private bool AlreadyChosenTimeout = false;
private int DefaultTimeout = 10;
private int NumberOfSecondsForTimeout = 10;
private List<Rectangle> PacketRectangles = new List<Rectangle>();
public BindingList<VLANName> VlanNames = new BindingList<VLANName>() { new VLANName(1, "Default") };
public TraversalClass LastTraversal = null;
private bool previously_had_packets = false; //used on "tick" to determine if we are starting from scratch
private DateTime NextPacketMovement = DateTime.UtcNow;
private List<string> PacketColors = new List<string>();
private List<Image> PacketImages = new List<Image>();
private List<PingTestStatus> PingTestStats = new List<PingTestStatus>();
private List<string> BrokenItems = new List<string>();
public List<NetShape> Shapes = new List<NetShape>(); //For storing simple shapes which are drawn on the network
public bool IsRandomNetwork = false;
public bool InShapeEditMode = false;
public bool HadLoop = false;
private List<AnimationClass> Animations = new List<AnimationClass>();
public bool ReplayInProgress = false;
public DateTime NextReplayAction = DateTime.UtcNow;
public int NextReplayIndex = -1;
public bool StartedNewReplayAction = false;
public bool ProcessingNonVisually = false;
/// <summary>
/// WhatFrom: If we are launched from a homework, we remember it here.
/// </summary>
public SchoolworkClass WhatFrom = null;
public List<string> ColorNames = new List<string>() { "Black", "White", "Green", "LightGreen", "Blue", "LightBlue", "Gray", "Brown", "SaddleBrown", "Empty" };
public Network(string Name)
{
TheNetImage = new Bitmap(myWidth, myHeight);
PuzzleName = Name;
NetMessage = new LanguageStrings("message"); //Do not translate this string "message" It is an important word
NetTitle = new LanguageStrings("title"); //Do not translate this string "title". It is an important word
NetURL = new LanguageStrings("url"); //Do not translate this string "url". It is an important word
}
public Network() {
NetMessage = new LanguageStrings("message");
NetTitle = new LanguageStrings("title"); //Do not translate this string "title". It is an important word
NetURL = new LanguageStrings("url"); //Do not translate this string "url". It is an important word
} //simple constructor
private bool isDirty()
{
if (_isDirty) return true;
foreach (NetworkComponent nc in NetComponents)
{
if (nc.IsDirty) return true;
}
return false;
}
public static void Clone(Network source, Network dest)
{
int lastID = 0;
dest.AlreadyDisplayedMessage = false;
dest.DefaultTimeout = source.DefaultTimeout;
dest.HintsToDisplay = source.HintsToDisplay;
dest.itemsize = source.itemsize;
dest.Level = source.Level;
dest.myHeight = source.myHeight;
dest.myWidth = source.myWidth;
dest.UniqueIdentifier = source.UniqueIdentifier;
//dest.NetComponents
foreach (NetworkComponent NC in source.NetComponents)
{
if (NC.GetUniqueIdentifier > lastID) lastID = NC.GetUniqueIdentifier;
dest.NetComponents.Add(NetworkComponent.Clone(NC));
}
//dest.NetTests
foreach(NetTest NT in source.NetTests)
{
dest.NetTests.Add(NetTest.Clone(NT));
}
dest.NetTitle = source.NetTitle;
dest.NetURL = source.NetURL;
dest.NetworkFilename = source.NetworkFilename;
dest.OptionShowLabels = source.OptionShowLabels;
//dest.PacketColors = source.PacketColors;
dest.PuzzleName = source.PuzzleName;
dest.NetMessage = new LanguageStrings(source.NetMessage);
dest.WhatFrom = source.WhatFrom; //We remember the schoolwork class we came from.
dest.PuzzleIsSolved = source.PuzzleIsSolved;
//In case the number was incorrect. Fix it.
if (lastID >= dest.UniqueIdentifier) dest.UniqueIdentifier = lastID + 1;
}
public Network Clone()
{
Network newitem = new Network();
Network.Clone(this, newitem);
return newitem;
}
//from: http://stackoverflow.com/questions/78536/cloning-objects-in-c
public static T DeepClone<T>(T source)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", "source");
}
// Don't serialize a null object, simply return the default for that object
if (Object.ReferenceEquals(source, null))
{
return default(T);
}
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream();
using (stream)
{
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
public bool Equals(Network CompareTo)
{
if (PuzzleName != CompareTo.PuzzleName) return false;
if (myHeight != CompareTo.myHeight) return false;
if (myWidth != CompareTo.myWidth) return false;
if (Level != CompareTo.Level) return false;
if (SortOrder != CompareTo.SortOrder) return false;
if (OptionShowLabels != CompareTo.OptionShowLabels) return false;
if (ShowLabelsHere != CompareTo.ShowLabelsHere) return false;
if (VLANsEnabled != CompareTo.VLANsEnabled) return false;
if (VLANPacketColors != CompareTo.VLANPacketColors) return false;
if (_LoadedFromResource != CompareTo._LoadedFromResource) return false;
if (!NetMessage.Equals(CompareTo.NetMessage)) return false;
if (!NetTitle.Equals(CompareTo.NetTitle)) return false;
if (!NetURL.Equals(CompareTo.NetURL)) return false;
if (itemsize != CompareTo.itemsize) return false;
if (UniqueIdentifier != CompareTo.UniqueIdentifier) return false;
if (IsRandomNetwork != CompareTo.IsRandomNetwork) return false;
if (NetworkFilename != CompareTo.NetworkFilename) return false;
if (AlreadyDisplayedMessage != CompareTo.AlreadyDisplayedMessage) return false;
if (HintsToDisplay != CompareTo.HintsToDisplay) return false;
if (StartingHelpLevel != CompareTo.StartingHelpLevel) return false;
if (PuzzleIsSolved != CompareTo.PuzzleIsSolved) return false;
if (NetTests.Count != CompareTo.NetTests.Count) return false;
for (int i = 0; i < NetTests.Count; i++)
if (!NetTests[i].Equals(CompareTo.NetTests[i])) return false;
if (BrokenItems.Count != CompareTo.BrokenItems.Count) return false;
for (int i = 0; i < BrokenItems.Count; i++)
if (BrokenItems[i] != CompareTo.BrokenItems[i]) return false;
if (NetComponents.Count != CompareTo.NetComponents.Count) return false;
for (int i = 0; i < NetComponents.Count; i++)
{
if (!NetComponents[i].Equals(CompareTo.NetComponents[i])) return false;
}
if (Shapes.Count != CompareTo.Shapes.Count) return false;
for (int i = 0; i < Shapes.Count; i++)
if (!Shapes[i].Equals(CompareTo.Shapes[i])) return false;
if (PingTestStats.Count != CompareTo.PingTestStats.Count) return false;
if (SuggestedReadings.Count != CompareTo.SuggestedReadings.Count) return false;
if (myMessages.Count != CompareTo.myMessages.Count) return false;
if (VlanNames.Count != CompareTo.VlanNames.Count) return false;
for (int i = 0; i < VlanNames.Count; i++)
if (!VlanNames[i].Equals(CompareTo.VlanNames[i])) return false;
return true;
}
public void ClearComponents()
{
NetComponents.Clear();
}
public void ClearPackets()
{
myPackets.Clear();
}
public void ClearMessages()
{
myMessages.Clear();
}
/// <summary>
/// Load the file from a xml resource
/// </summary>
public void Load()
{
Load(@"C:\Users\tyoung\Desktop\Test.enbx");
}
public void Load(string filename)
{
NetworkFilename = filename;
XmlDocument xmlDoc = new XmlDocument();
PuzzleName = Path.GetFileNameWithoutExtension(filename);
if (File.Exists(filename))
{
xmlDoc.Load(filename);
Load(xmlDoc,PuzzleName);
}
}
public void Load(XmlNode TheNode, string Name, bool FromResource=false, bool skipOpeningWindows = false)
{
_isDirty = true;
NetworkDevice newND;
NetworkLink newNL;
int newUnique=-1;
PuzzleName = Name;
LoadedFromResource = FromResource;
IsRandomNetwork = false; //right now, it is set up from disk. We set this when we randomize the network
foreach (XmlNode Individual in TheNode.ChildNodes)
{
XmlNodeType myNodetype = Individual.NodeType;
if (myNodetype == XmlNodeType.Element)
{
switch (Individual.Name.ToLower())
{
case "edunetworkbuilder":
case "network":
Load(Individual,PuzzleName, FromResource);
break;
case "puzzlename":
PuzzleName = Individual.InnerText;
break;
case "showlabels":
bool tf_answer = false;
if(bool.TryParse(Individual.InnerText, out tf_answer))
{
//compatibility with the old simple true/false
if (tf_answer) { ShowLabelsHere = CaptionType.full; }
else { ShowLabelsHere = CaptionType.none; }
}
else
{
ShowLabelsHere = NB.TryParseEnum<CaptionType>(Individual.InnerText, CaptionType.none);
}
OptionShowLabels = ShowLabelsHere;
break;
case "vlansenabled":
bool.TryParse(Individual.InnerText, out VLANsEnabled);
break;
case "vlanpacketcolors":
bool.TryParse(Individual.InnerText, out VLANPacketColors);
if (VLANPacketColors)
VLANsEnabled = true; //If we do colors, we need to do vlans
break;
case "itemsize":
int.TryParse(Individual.InnerText, out itemsize);
break;
case "height":
int.TryParse(Individual.InnerText, out myHeight);
break;
case "width":
int.TryParse(Individual.InnerText, out myWidth);
break;
case "uniqueidentifier":
int.TryParse(Individual.InnerText, out UniqueIdentifier);
newUnique = UniqueIdentifier;
break;
case "link":
newNL = new NetworkLink(Individual);
NetComponents.Add(newNL);
break;
case "device":
newND = new NetworkDevice(Individual);
NetComponents.Add(newND);
break;
case "nettest":
NetTest nt = new NetTest(Individual);
NetTests.Add(nt);
break;
case "tag":
HelpTopics tempHelpTopic = NB.TryParseEnum<HelpTopics>(Individual.InnerText, HelpTopics.None);
if (tempHelpTopic != HelpTopics.None)
{
SuggestedReadings.Add(tempHelpTopic);
}
break;
case "packetmessages":
myMessages = NB.Deserialize<List<PacketMessage>>(Individual.InnerText);
break;
case "level":
int.TryParse(Individual.InnerText, out Level);
//Tags.Add("Level_" + Individual.InnerText);
break;
case "sortorder":
double.TryParse(Individual.InnerText, out SortOrder);
break;
case "startinghelplevel":
StartingHelpLevel = NB.ParseEnum<NetTestVerbosity>(Individual.InnerText);
HintsToDisplay = StartingHelpLevel;
break;
case "shape":
NetShape nShape = new NetShape(Individual);
Shapes.Add(nShape);
break;
case "vlanname":
if (Individual.Attributes != null && Individual.Attributes["ID"] != null)
{
int ID;
int.TryParse(Individual.Attributes["ID"].Value, out ID);
string colorname = "Blue";
if (Individual.Attributes["Color"] != null)
colorname = Individual.Attributes["Color"].Value;
Color PacketColor = Color.FromName(colorname);
if (ID > 1)
{
VlanNames.Add(new VLANName(ID, Individual.InnerText, PacketColor));
VLANsEnabled = true;
}
else
{
VlanNames.RemoveAt(0);
VlanNames.Insert(0,new VLANName(ID, Individual.InnerText, PacketColor));
VLANsEnabled = true;
}
}
break;
default:
if(Regex.IsMatch(Individual.Name.ToLower(),"message"))
{
NetMessage.Add(Individual);
}
else
if (Regex.IsMatch(Individual.Name.ToLower(), "title"))
{
NetTitle.Add(Individual);
}
else
if (Regex.IsMatch(Individual.Name.ToLower(), "url"))
{
NetURL.Add(Individual);
}
break;
}
}
}
DoAllRemoveAllWirelessLinks(); //remove all wireless links. They will be rebuilt below
DoAllVerifyLinks();
DoAllAutoJoin();
OpenHelpIfNeeded(skipOpeningWindows);
if (NetTests.Count > 0)
PuzzleIsSolved = false; //When we load the puzzle.
if (newUnique != -1)
UniqueIdentifier = newUnique;
int maxUI = 0;
foreach(NetworkComponent nc in NetComponents)
{
if (maxUI < nc.GetUniqueIdentifier)
maxUI = nc.GetUniqueIdentifier;
}
if (maxUI <= UniqueIdentifier) UniqueIdentifier = maxUI + 1;
//Register this in the user settings
NBSettings tSettings = NB.GetSettings();
if (tSettings != null) tSettings.RegisterNetAsStarted(this);
}
public void OpenHelpIfNeeded(bool skipOpeningWindows)
{
if (NetMessage.GetText() != "" && !AlreadyDisplayedMessage & !skipOpeningWindows)
{
//We have a message loaded on this network. Display it
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
if (myWin != null)
{
myWin.OpenNetHelpWindow();
}
else
{
MessageBox.Show(NetMessage.GetText(), NetTitle.GetText(), MessageBoxButtons.OK);
}
AlreadyDisplayedMessage = true;
}
}
public void Save()
{
if (NetworkFilename == "")
Save(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Test.enbx"));
else
Save(NetworkFilename);
}
public void Save(string filename)
{
NetworkFilename = filename;
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.NewLineOnAttributes = true;
XmlWriter writer = XmlWriter.Create(filename, settings);
//Now we write the file:
writer.WriteStartDocument();
writer.WriteStartElement("EduNetworkBuilder");
writer.WriteComment("This is a network file for EduNetworkBuilder.");
Save(writer);
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Flush();
writer.Close();
}
public void Save(XmlWriter writer, bool StraightToFile = true, bool SaveMessages = false)
{
//Save the language name
//save the number of items
//Save all the items
writer.WriteStartElement("Network");
if(NetMessage != null)
NetMessage.Save(writer);
if(NetTitle != null)
NetTitle.Save(writer);
if (NetURL != null)
NetURL.Save(writer);
writer.WriteElementString("height", myHeight.ToString());
writer.WriteElementString("width", myWidth.ToString());
writer.WriteElementString("itemsize", itemsize.ToString());
writer.WriteElementString("showlabels", OptionShowLabels.ToString());
writer.WriteElementString("level", Level.ToString());
writer.WriteElementString("sortorder", SortOrder.ToString());
writer.WriteElementString("uniqueidentifier", UniqueIdentifier.ToString());
writer.WriteElementString("startinghelplevel", StartingHelpLevel.ToString());
writer.WriteElementString("vlansenabled", VLANsEnabled.ToString());
writer.WriteElementString("VLANPacketColors", VLANPacketColors.ToString());
if (!StraightToFile)
writer.WriteElementString("PuzzleName", PuzzleName);
if(SaveMessages)
{
string serializedstring = NB.SerializeObject<List<PacketMessage>>(myMessages);
writer.WriteElementString("PacketMessages", serializedstring);
}
//Save all the devices
for (int loop = 0; loop < NetComponents.Count; loop++)
{
if (NB.GetComponentType(NetComponents[loop]) == GeneralComponentType.device)
NetComponents[loop].Save(writer);
}
//Then save the links
for (int loop = 0; loop < NetComponents.Count; loop++)
{
if (NB.GetComponentType(NetComponents[loop]) == GeneralComponentType.link)
if(((NetworkLink)NetComponents[loop]).theLinkType != LinkType.wireless )
NetComponents[loop].Save(writer); //Wireless links are rebuilt automatically
}
foreach(NetTest nt in NetTests)
{
nt.Save(writer);
}
foreach(HelpTopics HT in SuggestedReadings)
{
writer.WriteElementString("tag",HT.ToString());
}
foreach(NetShape shape in Shapes)
{
shape.Save(writer);
}
foreach(VLANName VLAN in VlanNames)
{
writer.WriteStartElement("VLANName");
writer.WriteAttributeString("ID", VLAN.ID.ToString());
writer.WriteAttributeString("Color", VLAN.PacketColorString);
writer.WriteString(VLAN.Name);
writer.WriteEndElement();
}
writer.WriteEndElement();
}
public void UpdateDeviceSizes()
{
NetworkDevice nd;
foreach (NetworkComponent NC in NetComponents)
{
if (NB.GetComponentType(NC) == GeneralComponentType.device)
{
nd = (NetworkDevice)NC;
nd.SetSize(itemsize);
}
}
}
public bool MAC_Exists(string MAC)
{
foreach (NetworkComponent nc in NetComponents)
{
if (nc.HasMac(MAC)) return true;
}
return false;
}
public void RegisterDisplayArea(PictureBox What)
{
myPBox = What;
myPBox.BackgroundImage = TheNetImageBackground;
myPBox.BackgroundImageLayout = ImageLayout.Stretch;
myPBox.SizeMode = PictureBoxSizeMode.StretchImage;
Print();
myPBox.Invalidate();
}
public Point clickedPos(Point pixelClickedOn)
{
if (myPBox == null) return new Point(-1, -1);
double deltaX = (double)TheNetImage.Width / myPBox.Width;
double deltaY = (double)TheNetImage.Height / myPBox.Height;
Point Dest = new Point((int)(pixelClickedOn.X * deltaX), (int)(pixelClickedOn.Y * deltaY));
if (Dest.X > TheNetImage.Width) Dest = new Point(TheNetImage.Width, Dest.Y);
if (Dest.Y > TheNetImage.Height) Dest = new Point(Dest.X, TheNetImage.Height);
if (Dest.X <0) Dest = new Point(0, Dest.Y);
if (Dest.Y <0) Dest = new Point(Dest.X, 0);
return Dest;
}
/// <summary>
/// this is a reverse of clickedPos. Translate an image x/y to a picturebox location
/// </summary>
/// <param name="ImageLocation">The location on the backgroundimage</param>
/// <returns></returns>
public Point PictureBoxPoint(Point ImageLocation)
{
if (myPBox == null) return new Point(-1, -1);
double deltaX = (double)TheNetImage.Width / myPBox.Width;
double deltaY = (double)TheNetImage.Height / myPBox.Height;
Point Dest = new Point((int)(ImageLocation.X / deltaX), (int)(ImageLocation.Y / deltaY));
if (Dest.X > TheNetImage.Width) Dest = new Point(TheNetImage.Width, Dest.Y);
if (Dest.Y > TheNetImage.Height) Dest = new Point(Dest.X, TheNetImage.Height);
if (Dest.X < 0) Dest = new Point(0, Dest.Y);
if (Dest.Y < 0) Dest = new Point(Dest.X, 0);
return Dest;
}
public Point clickedPosCentered(Point pixelClickedOn)
{
Point NetPoint = clickedPos(pixelClickedOn);
int shift = (itemsize / 2);
Point Dest = new Point((int)(NetPoint.X - shift), (int)(NetPoint.Y - shift));
if (Dest.X + itemsize > TheNetImage.Width) Dest = new Point(TheNetImage.Width - itemsize, Dest.Y);
if (Dest.Y + itemsize > TheNetImage.Height) Dest = new Point(Dest.X, TheNetImage.Height - itemsize);
if (Dest.X < 0) Dest = new Point(0, Dest.Y);
if (Dest.Y < 0) Dest = new Point(Dest.X, 0);
return Dest;
}
public NetworkDevice ItemAtPosition(Point NetworkLocation)
{
NetworkDevice tDevice;
foreach (NetworkComponent tItem in NetComponents)
{
if (tItem.GetType().ToString() == "EduNetworkBuilder.NetworkDevice")
{
tDevice = (NetworkDevice)tItem;
if (tDevice.AtLocation(NetworkLocation) && tDevice.GetNetType() != NetworkComponentType.tree)
return tDevice; //We do not return trees. Trees cannot be edited
}
}
return null;
}
public bool BlockedByTree(Point NetworkLocation)
{
NetworkDevice tDevice;
foreach (NetworkComponent tItem in NetComponents)
{
if (tItem is NetworkDevice)
{
tDevice = (NetworkDevice)tItem;
if (tDevice.GetNetType() != NetworkComponentType.tree) continue; //We only care about trees
Rectangle myRec = tDevice.GetMyRectangle();
if (myRec.Contains(NetworkLocation))
return true;
}
}
return false;
}
public NetworkLink LinkAtPosition(Point NetworkLocation)
{
NetworkLink tLink;
foreach (NetworkComponent tItem in NetComponents)
{
if (tItem is NetworkLink)
{
tLink = (NetworkLink)tItem;
if (tLink.AtLocation(NetworkLocation))
return tLink;
}
}
return null;
}
public List<NetworkDevice> DevicesInRectangle(Rectangle area)
{
NetworkDevice tDevice;
Point tPoint;
List<NetworkDevice> thelist = new List<NetworkDevice>();
foreach (NetworkComponent tItem in NetComponents)
{
if (tItem is NetworkDevice)
{
tDevice = (NetworkDevice)tItem;
if (tDevice.IsLockedInLocation()) continue; //some items cannot be moved
int tsize = tDevice.Size;
tPoint = tDevice.myLocation();
if (tPoint.X + tsize >= area.X && tPoint.Y +tsize >= area.Y)
{
if (tPoint.X <= area.X + area.Width && tPoint.Y <= area.Y + area.Height)
{
thelist.Add(tDevice);
}
}
}
}
return thelist;
}
public NetworkDevice DeviceFromName(string hostname)
{
NetworkDevice tDevice;
foreach (NetworkComponent tItem in NetComponents)
{
if (tItem.GetType().ToString() == "EduNetworkBuilder.NetworkDevice")
{
tDevice = (NetworkDevice)tItem;
if (tDevice.hostname == hostname)
return tDevice;
}
}
return null;
}
public NetworkComponent ComponentFromName(string hostname)
{
foreach (NetworkComponent tItem in NetComponents)
{
if (tItem.hostname == hostname)
return tItem;
}
return null;
}
public bool HasItemCalled(string itemname)
{
NetworkDevice tDevice;
foreach(NetworkComponent tItem in NetComponents)
{
if(tItem.GetType().ToString() == "EduNetworkBuilder.NetworkDevice")
{
tDevice = (NetworkDevice)tItem;
if (tDevice.hostname == itemname) return true;
}
}
return false;
}
public NetworkComponent AddItem(NetworkComponentType WhatType, Point location)
{
if (WhatType == NetworkComponentType.none) return null; //Do not put none in
if (WhatType == NetworkComponentType.link) return null; //We need to add links another way
string basename = WhatType.ToString();
int count=0;
while (HasItemCalled(basename + count))
count++;
Point newlocation = NB.GetSnapped(location);
NetworkComponent NewItem = new NetworkDevice(WhatType, basename + count, newlocation);
((NetworkDevice)NewItem).SetSize(itemsize);
NetComponents.Add(NewItem);
TestForCompletion(true);
myPBox.Invalidate(); //redraw the screen
return NewItem;
}
/// <summary>
/// Search throuh all the network components and delete any links that are attacked to the specified nic.
/// </summary>
/// <param name="NicStr"></param>
public void RemoveLinksToNic(HostNicID NicID)
{
for(int looper=NetComponents.Count()-1; looper >=0; looper--)
{
if(NetComponents[looper].GetType().ToString() == "EduNetworkBuilder.NetworkLink")
{
NetworkLink nLink = (NetworkLink)NetComponents[looper];
if (nLink.HasLink(NicID))
{
nLink.Destroy();
NetComponents.RemoveAt(looper);
_isDirty = true;
}
}
}
}
/// <summary>
/// Search throuh all the network components and delete any links that are attacked to the specified nic.
/// </summary>
/// <param name="NicStr"></param>
public List<NetworkLink> AllLinksConnectedToComponent(int UniqueID)
{
List<NetworkLink> theList = new List<NetworkLink>();
for (int looper = NetComponents.Count() - 1; looper >= 0; looper--)
{
if (NetComponents[looper] is NetworkLink)
{
NetworkLink nLink = (NetworkLink)NetComponents[looper];
if (nLink.Src.HostID == UniqueID || nLink.Dst.HostID == UniqueID)
theList.Add(nLink);
}
}
return theList;
}
public NetworkComponent AddItem(NetworkComponent ToAdd)
{
NetComponents.Add(ToAdd);
TestForCompletion(true);
return ToAdd;
}
public List<string> UnavailableNics()
{
NetworkLink myLink;
List<string> usedList = new List<string>();
foreach (NetworkComponent NC in NetComponents)
{
if (NC.GetType().ToString() == "EduNetworkBuilder.NetworkLink")
{
myLink = (NetworkLink)NC;
usedList.AddRange(myLink.UsedNicIDStrings());
}
}
return usedList;
}
public void RemoveComponent(NetworkComponent tItem)
{
if (tItem == null) return; //Exit early if we are not removing anything
for (int i = NetComponents.Count -1; i >= 0; i--)
{
if (NetComponents[i] == tItem)
NetComponents.RemoveAt(i);
// NetComponents.Remove(tItem);
}
tItem.Destroy();
_isDirty = true;
}
public void StoreLastIP(NB_IPAddress ip)
{
lastAddress = ip;
}
public NB_IPAddress RetrieveLastIP()
{
return lastAddress;
}
public List<string> GetTestMessages(string host)
{
string tString;
List<string> tMessages = new List<string>();
foreach(NetTest nt in NetTests)
{
if(nt.sHost == host && !nt.TestComplete())
{
tString = nt.GetDescription(HintsToDisplay);
if(tString != "")
tMessages.Add(tString);
}
}
return tMessages;
}
public List<string> GetIncompleteTestDestinations(string Source, ContextTest WhatFor=ContextTest.ping)
{
List<string> tDests = new List<string>();
foreach (NetTest nt in NetTests)
{
if (nt.sHost == Source && !nt.TestComplete())
{
if (WhatFor == ContextTest.ping && (nt.TheTest == NetTestType.FailedPing
|| nt.TheTest == NetTestType.SuccessfullyPings
|| nt.TheTest == NetTestType.SuccessfullyPingsWithoutLoop
|| nt.TheTest == NetTestType.SuccessfullyPingsAgain))
tDests.Add(nt.dHost);
if (WhatFor == ContextTest.arp && nt.TheTest == NetTestType.SuccessfullyArps)
tDests.Add(nt.dHost);
if (WhatFor == ContextTest.traceroute && nt.TheTest == NetTestType.SuccessfullyTraceroutes)
tDests.Add(nt.dHost);
}
}
return tDests;
}
public void TestForCompletion(bool report_as_done, bool MarkAsDoneIfNotReporting=false)
{
NetworkDevice TmpDevice;
bool PreviouslyUnsolved = !PuzzleIsSolved; //Only if we have an unsolved puzzle
int PuzzleCount = 0;
foreach (NetworkComponent nc in NetComponents)
{
if (NB.GetComponentType(nc) == GeneralComponentType.device)
{
TmpDevice = (NetworkDevice)nc;
if (TmpDevice.BackgroundColor != Color.Empty)
{
TmpDevice.BackgroundColor = Color.Empty;
TmpDevice.IsDirty = true;
}
}
}
foreach (NetTest nt in NetTests)
{
if (nt.ColorItemsIfNeeded(HintsToDisplay != NetTestVerbosity.none)) //only change the color if we are not "none"
{
PuzzleCount++;
}
if(nt.TheTest == NetTestType.DeviceBlowsUpWithPower && !nt.TaskWasDone)
{
NetworkDevice ND = DeviceFromName(nt.sHost);
if (ND != null) ND.PowerOff = true;
}
if (nt.TheTest == NetTestType.DeviceNeedsUPS && !nt.TaskWasDone)
{
NetworkDevice ND = DeviceFromName(nt.sHost);
if (ND != null) ND.PowerOff = true;
}
}
if (PuzzleCount == 0 && PreviouslyUnsolved)
{
if(report_as_done || MarkAsDoneIfNotReporting)
PuzzleIsSolved = true; //Only change this when we need to report it
if (NB.DebugTests) Console.WriteLine("Recognizing puzzle is solved: " + PuzzleName);
if (report_as_done)
{
//The puzzle was just solved
MarkAsSolved();
}
}
}
public void UpdateImage()
{
TestForCompletion(false);
//we have the whole thing to print, and the display image already done
if (isDirty() || _isDirty)
{
if(TheNetImage == null)
TheNetImage = new Bitmap(TheNetImage.Width, TheNetImage.Height);
SolidBrush theBrush = new SolidBrush(SystemColors.Control);
Graphics.FromImage(TheNetImage).FillRectangle(theBrush, new Rectangle(0,0, TheNetImage.Width, TheNetImage.Height));
//re-generate the image
foreach (NetShape shape in Shapes)
shape.Draw(TheNetImage, InShapeEditMode); //Draw any shapes
//Do all the links first
foreach (NetworkComponent NC in NetComponents)
{
if (NC.GetType().ToString() == "EduNetworkBuilder.NetworkLink")
NC.Print(TheNetImage, CaptionType.none);
}
//Now, do all the devices
foreach (NetworkComponent NC in NetComponents)
{
if (NC.GetType().ToString() == "EduNetworkBuilder.NetworkDevice")
NC.Print(TheNetImage, ShowLabelsHere);
}
//Write the whole thing to the background image.
Graphics.FromImage(TheNetImageBackground).DrawImage(TheNetImage, 0, 0);
}
myPBox.Invalidate();//redraw it
_isDirty = false;
}
public void EraseOldPackets()
{
//Make sure we draw a fresh image.
//Graphics.FromImage(TheNetImageBackground).DrawImage(TheNetImage, 0, 0);
Graphics G = Graphics.FromImage(TheNetImageBackground);
foreach(Rectangle rec in PacketRectangles.Distinct())
{
G.DrawImage(TheNetImage, rec, rec, GraphicsUnit.Pixel);
Invalidate(rec);
}
PacketRectangles.Clear();
G.Dispose();
}
public void DrawPackets()
{
foreach (Packet pkt in myPackets)
{
//If we do not already have something at the current rectangle, print it
if (!PacketRectangles.Contains(pkt.PacketRectangle()))
{
pkt.Print(TheNetImageBackground); //Print all the packets over the network image
Invalidate(pkt.PacketRectangle());
PacketRectangles.Add(pkt.PacketRectangle());
}
}
//myPBox.Refresh();
}
public void Print()
{
//we have the whole thing to print, and the display image already done
InvalidateEverything();
UpdateImage();
EraseOldPackets();
DrawPackets();
_isDirty = false;
}
public void InvalidateEverything()
{
foreach(NetworkComponent nc in NetComponents)
{
nc.IsDirty = true;
}
_isDirty = true;
UpdateImage();
}
public void Invalidate(Rectangle area)
{
//Figure out the area we are looking at
if (myPBox.BackgroundImageLayout == ImageLayout.Stretch)
{
double width_ratio = myPBox.ClientRectangle.Width / TheNetImage.Width;
double height_ratio = myPBox.ClientRectangle.Height / TheNetImage.Height;
int x, y, width, height;
x = (int)(area.X * width_ratio);
y = (int)(area.Y * height_ratio);
width = (int)(area.Width * width_ratio);
height = (int)(area.Height * height_ratio);
Rectangle newRec = new Rectangle(x, y, width, height);
//Now we invalidate the adjusted rectangle
myPBox.Invalidate(newRec);
}
}
public List<string> arp(UInt32 IP)
{
List<string> arps = new List<string>();
List<string> tlist;
foreach (NetworkComponent nc in NB.Randomize(NetComponents))
{
tlist = nc.arp(IP);
if (tlist.Count() > 0)
{
foreach (string mac in tlist)
{
arps.Add(mac);
}
}
}
return arps;
}
public int GetUniqueIdentifier()
{
return UniqueIdentifier++;
}
public void SortNetComponents()
{
NetComponents.Sort((x, y) => x.hostname.CompareTo(y.hostname));
}
public NetworkDevice HostMatchingHostNicID(HostNicID ToFind)
{
NetworkDevice tDevice;
//We cheat. the first portion of the host/nic ID is the host_id so we just find that
foreach (NetworkComponent nc in NetComponents)
{
if (NB.GetComponentType(nc) == GeneralComponentType.device)
{
if (nc.GetUniqueIdentifier == ToFind.HostID)
{
tDevice = (NetworkDevice)nc;
return tDevice;
}
}
}
return null;
}
/// <summary>
/// Search all the devices and make sure the one device is the only one that has the specified IP
/// </summary>
/// <param name="ToFind">The IP address to find</param>
/// <param name="Source">The device that has it</param>
/// <returns></returns>
public bool HasUniqueIP(NB_IPAddress ToFind, NetworkDevice Source)
{
NetworkDevice ND;
foreach (NetworkComponent nc in NetComponents)
{
if (NB.GetComponentType(nc) == GeneralComponentType.device)
{
ND = (NetworkDevice)nc;
if(ND != Source) //Skip the source
{
if (ND.HasIPAddress(ToFind))
return false; //Something has that IP
}
}
}
return true; //We did not find any device with that IP
}
public bool ItemIsCritical(string host)
{
foreach(NetTest nt in NetTests)
{
if (nt.dHost == host) return true;
if (nt.sHost == host) return true;
}
return false;
}
public bool ItemIsCritical(HostNicID host)
{
NetworkDevice ND = GetDeviceFromID(host);
if (ND == null) return false; //cannot find it
foreach (NetTest nt in NetTests)
{
if (nt.dHost == ND.hostname) return true;
if (nt.sHost == ND.hostname) return true;
}
return false;
}
public bool ItemIsLocked(string host, string dest, NetTestType WhatToCheck)
{
foreach (NetTest nt in NetTests)
{
if(nt.sHost == host || WhatToCheck == NetTestType.LockVLANNames)
{
if (nt.TheTest == NetTestType.LockAll)
return true;
if (WhatToCheck == nt.TheTest && WhatToCheck == NetTestType.LockVLANNames) //no dest to check
return true;
if (WhatToCheck == nt.TheTest && WhatToCheck == NetTestType.LockVLANsOnHost) //no dest to check
return true;
if (WhatToCheck == nt.TheTest && dest == nt.dHost)
return true;
}
}
return false;
}
public bool ItemHasTest(string host, string dest, NetTestType WhatToCheck)
{
foreach (NetTest nt in NetTests)
{
if (nt.sHost == host)
{
if (WhatToCheck == nt.TheTest)
{
if(nt.TheTest == NetTestType.LockLocation)
{
if(dest == "" && (nt.dHost == "" || nt.dHost == "--")) //It cannot be moved at all
{
return true;
}
return false;
}
else if (dest == "" || dest == nt.dHost)
return true;
}
}
}
return false;
}
public bool ItemHasTest(string host, NetTestType WhatToCheck)
{
return ItemHasTest(host, "", WhatToCheck);
}
public bool ItemTestIsComplete(string host, string dest, NetTestType WhatToCheck)
{
foreach (NetTest nt in NetTests)
{
if (nt.sHost == host)
{
if (WhatToCheck == nt.TheTest && (dest == "" || dest == nt.dHost))
return nt.TestComplete(this);
}
}
return false;
}
public bool ItemTestIsComplete(string host, NetTestType WhatToCheck)
{
return ItemTestIsComplete(host, "", WhatToCheck);
}
private void MarkAsSolved()
{
PuzzleIsSolved = true;
if (LoadedFromResource) //Save the fact that we solved it only if we loaded it from resource.
{
if (PuzzleName != "" && PuzzleName != null)
{
NBSettings oursettings = NB.GetSettings();
oursettings.MarkAsDone(PuzzleName);
}
}
//kill all extra windows that no longer need to be open.
if(!NB.ProcessingInvisibleNetwork())
KillAllExtraWindows();
if (WhatFrom == null)
{
if (!IsRandomNetwork)
{
DialogResult answer;
NBSettings oursettings = NB.GetSettings();
if(oursettings != null && oursettings.ReplayMode)
{
ActionCollection AC = oursettings.GetUserActionCollection();
if(AC != null)
{
NetworkAction pastTry = AC.GetActionlistFromNet(this);
//If we never had an action list
if(AC.CurrentNeedsStoring)
{
if(pastTry == null)
answer = MessageBox.Show(NB.Translate("N_StoreReplay"), NB.Translate("_Solved"), MessageBoxButtons.YesNo);
else
answer = MessageBox.Show(NB.Translate("N_StoreReplayAgain"), NB.Translate("_Solved"), MessageBoxButtons.YesNo);
if (answer == DialogResult.Yes)
AC.PushActionToList();
}
}
}
//If we are processing an invisible replay, do not prompt...
if (!(NB.ProcessingInvisibleNetwork() && oursettings != null && oursettings.ReplayMode))
{
answer = MessageBox.Show(NB.Translate("N_MarkAsSolvedDone"), NB.Translate("_Solved"), MessageBoxButtons.YesNo);
if (answer == DialogResult.Yes)
{
KillAllExtraWindows(true);
ListBoxWindow LBW = new ListBoxWindow();
LBW.ShowDialog();
}
}
else
{
//We should go back to our replay window.
}
}
else
{
//It was a randomly generated puzzle. Let them know it was solved. But we do not auto-load a new one.
MessageBox.Show(NB.Translate("N_MarkRandomAsSolvedDone"), NB.Translate("_Solved"), MessageBoxButtons.OK);
}
}
else
{
PersonClass CurrentUser = NB.GetUser();
if (CurrentUser != null && CurrentUser.isAdmin)
{
//It was homework. Ask if we want to submit it.
DialogResult answer = MessageBox.Show(NB.Translate("N_PromptToGrade"), NB.Translate("_Solved"), MessageBoxButtons.YesNo);
if (answer == DialogResult.Yes)
{
KillAllExtraWindows(true);
BuilderWindow BW = NB.GetBuilderWin();
BW.MarkAsGraded();
}
}
else
{
if (!WhatFrom.IsGraded)
{
//It was homework. Ask if we want to submit it.
DialogResult answer = MessageBox.Show(NB.Translate("N_PromptToSubmit"), NB.Translate("_Solved"), MessageBoxButtons.YesNo);
if (answer == DialogResult.Yes)
{
KillAllExtraWindows(true);
BuilderWindow BW = NB.GetBuilderWin();
BW.SubmitHomework();
}
}
else
{
//It was homework. Ask if we want to submit it.
DialogResult answer = MessageBox.Show(NB.Translate("N_SolvedAlreadyGraded"), NB.Translate("_Solved"), MessageBoxButtons.YesNo);
if (answer == DialogResult.Yes)
{
KillAllExtraWindows(true);
BuilderWindow BW = NB.GetBuilderWin();
BW.ReturnToProfile();
}
}
}
}
}
public void AddShape(NetShape what)
{
Shapes.Add(what);
}
public void RemoveShape(NetShape What)
{
Shapes.Remove(What);
}
public NetShape ShapeAtPoint(Point location)
{
foreach(NetShape shape in Shapes)
{
if (shape.CornersAreClickedOn(location))
return shape;
if (shape.CenterIsClickedOn(location))
return shape;
}
return null;
}
public List<string> ShapeDescriptions()
{
List<string> Descriptions = new List<string>();
foreach(NetShape NS in Shapes)
{
Descriptions.Add(NS.ToString());
}
return Descriptions;
}
/// <summary>
/// This is used by the NetTest editor to list all the shape names we can lock a device into
/// </summary>
/// <returns>A list of the names of all the rectangles</returns>
public List<string> RectangleNames()
{
List<string> Descriptions = new List<string>();
foreach (NetShape NS in Shapes)
{
if(NS.MyShape == NetShapeType.rectangle)
Descriptions.Add(NS.Name);
}
return Descriptions;
}
public Rectangle RectangleByNamedShape(string Name)
{
foreach (NetShape NS in Shapes)
{
if (NS.Name == Name)
return NS.InArea;
}
return new Rectangle(0, 0, myWidth, myHeight); //return the biggest one we can do
}
public List<string> DeviceLockedToShapes(string Host)
{
List<string> ShapeNames = new List<string>();
foreach(NetTest NS in NetTests)
{
if(NS.sHost == Host && NS.TheTest == NetTestType.LockLocation)
{
ShapeNames.Add(NS.dHost);
}
}
return ShapeNames;
}
void KillAllExtraWindows(bool EvenRTF=false)
{
for(int i = Application.OpenForms.Count -1; i >=0; i--)
{
if (Application.OpenForms[i].Name == "BuilderWindow") continue; //We do not kill the builder window
if (EvenRTF && Application.OpenForms[i].Name == "RTFWindow") continue; //We do not kill the rtf window
//if (EvenRTF && Application.OpenForms[i].Name == "ListBoxWindow") continue; //Testing because listbox window is accidentally closed
Application.OpenForms[i].Hide(); //make them disappear
Application.OpenForms[i].Close(); //actually close them
}
}
/// <summary>
/// See if we have any tests that are supposed to check for packet arrival.
/// </summary>
/// <param name="packet_type">The type of packet that arrived</param>
/// <param name="sHost">The host it originated from</param>
/// <param name="dHost">The machine it went to</param>
public void NotePacketArrived(PacketType packet_type, NetworkDevice source, NB_IPAddress sIP, NB_IPAddress dIP, int PacketID)
{
string sHost = ReverseDNSLookup(source, sIP);
string dHost = ReverseDNSLookup(source, dIP);
if (packet_type == PacketType.ping_answer)
{
RegisterPingSuccess(sHost, dHost);
}
//If we are checking a ping, but we already have done it, we see if there is a ping-again
foreach (NetTest nt in NetTests)
{
if (nt.TheTest == NetTestType.SuccessfullyArps && packet_type == PacketType.arp_answer && sHost == nt.sHost && dHost == nt.dHost)
nt.SetDone();
if (nt.TheTest == NetTestType.SuccessfullyDHCPs && packet_type == PacketType.dhcp_answer && sHost == nt.sHost && dHost == nt.dHost)
nt.SetDone();
if(HasCompletedPingTest(packet_type,source,sIP,dIP, PacketID))
{
if (nt.TheTest == NetTestType.SuccessfullyPingsAgain && packet_type == PacketType.ping_answer && sHost == nt.sHost && dHost == nt.dHost)
nt.SetDone(PacketID);
if (nt.TheTest == NetTestType.SuccessfullyPingsAgain && packet_type == PacketType.ping_answer && sHost == nt.sHost && dHost == null && dIP != null && dIP.BroadcastAddress == dIP.GetIP && dIP.GetIPString == nt.dHost)
nt.SetDone(PacketID);
}
if (nt.TheTest == NetTestType.SuccessfullyPings && packet_type == PacketType.ping_answer && sHost == nt.sHost && dHost == nt.dHost)
nt.SetDone(PacketID);
if (nt.TheTest == NetTestType.SuccessfullyPings && packet_type == PacketType.ping_answer && sHost == nt.sHost && dHost == null && dIP != null && dIP.BroadcastAddress == dIP.GetIP && dIP.GetIPString == nt.dHost)
nt.SetDone(PacketID);
if (nt.TheTest == NetTestType.SuccessfullyPingsWithoutLoop && !HadLoop && packet_type == PacketType.ping_answer && sHost == nt.sHost && dHost == nt.dHost)
nt.SetDone(PacketID);
if (nt.TheTest == NetTestType.SuccessfullyPingsWithoutLoop && !HadLoop && packet_type == PacketType.ping_answer && sHost == nt.sHost && dHost == null && dIP != null && dIP.BroadcastAddress == dIP.GetIP && dIP.GetIPString == nt.dHost)
nt.SetDone(PacketID);
if (nt.TheTest == NetTestType.SuccessfullyTraceroutes && packet_type == PacketType.tracert_reply && sHost == nt.sHost && dHost == nt.dHost)
nt.SetDone(PacketID);
if (nt.TheTest == NetTestType.SuccessfullyTraceroutes && packet_type == PacketType.tracert_reply && sHost == nt.sHost && dHost == null && dIP != null && dIP.BroadcastAddress == dIP.GetIP && dIP.GetIPString == nt.dHost)
nt.SetDone(PacketID);
}
}
public bool HasCompletedPingTest(PacketType packet_type, NetworkDevice source, NB_IPAddress sIP, NB_IPAddress dIP, int PacketID)
{
if (packet_type != PacketType.ping_answer) return false; //This only works with pings.
string sHost = ReverseDNSLookup(source, sIP);
string dHost = ReverseDNSLookup(source, dIP);
//If this matches a ping test which is already set to "done", return true
foreach (NetTest nt in NetTests)
{
if (nt.TheTest == NetTestType.SuccessfullyPings && sHost == nt.sHost && dHost == nt.dHost && nt.TaskWasDone && nt.PacketNumber != PacketID)
return true;
if (nt.TheTest == NetTestType.SuccessfullyPings && sHost == nt.sHost && dHost == null && dIP != null && dIP.BroadcastAddress == dIP.GetIP && dIP.GetIPString == nt.dHost && nt.TaskWasDone && nt.PacketNumber != PacketID)
return true;
}
return false;
}
public bool NoteActionDone(NetTestType theTest, string sHost, string dHost)
{
bool OldVal = false;
NB_IPAddress sourceIP;
string sourceIPstring;
NB_IPAddress destIP;
string destIPstring;
foreach (NetTest nt in NetTests)
{
sourceIP = new NB_IPAddress(sHost);
sourceIPstring = ReverseDNSLookup(null, sourceIP); //this will either be an ip address or the host name
destIP = new NB_IPAddress(dHost);
destIPstring = ReverseDNSLookup(null, destIP); //this will either be an ip address or the host name
if ((nt.TheTest == NetTestType.HelpRequest || nt.TheTest == NetTestType.FailedPing || nt.TheTest == NetTestType.ReadContextHelp) &&
(sHost == nt.sHost || sourceIPstring == nt.sHost) &&
(dHost == nt.dHost || destIPstring == nt.dHost))
{
OldVal = nt.TaskWasDone;
nt.SetDone();
if (nt.TaskWasDone != OldVal)
return true;
}
if (nt.TheTest == NetTestType.HelpRequest && sHost == "" && dHost == nt.dHost && dHost == "?Button")
{
OldVal = nt.TaskWasDone;
nt.SetDone();
if (nt.TaskWasDone != OldVal)
{
BuilderWindow myWin = NB.GetBuilderWin();
if (myWin == null) return true;
Control ctl = myWin.GetControlNamed("btnHelp");
if (ctl == null) return false;
ctl.BackColor = Control.DefaultBackColor;
return true;
}
}
if (nt.TheTest == NetTestType.HelpRequest && sHost == "" && dHost == nt.dHost && dHost == "ViewButton")
{
OldVal = nt.TaskWasDone;
nt.SetDone();
if (nt.TaskWasDone != OldVal)
{
BuilderWindow myWin = NB.GetBuilderWin();
if (myWin == null) return true;
Control ctl = myWin.GetControlNamed("btnCaptions");
if (ctl == null) return false;
ctl.BackColor = Control.DefaultBackColor;
return true;
}
}
}
return false;
}
public List<string> NetworkCardForHostList(string hostname, bool OnlyUnused = true, bool OnlyLinkable = false, NicType fromNIC = NicType.none)
{
List<string> theList = new List<string>();
NetworkDevice tDevice;
foreach (NetworkComponent nc in NetComponents)
{
if (nc.GetType().ToString() == "EduNetworkBuilder.NetworkDevice")
{
if(nc.hostname == hostname)
{
tDevice = (NetworkDevice)nc;
theList.AddRange(tDevice.NetworkCardStrings(OnlyUnused,OnlyLinkable, fromNIC));
}
}
}
return theList;
}
public List<string> GetMessageStrings()
{
List<string> themessages = new List<string>();
foreach (PacketMessage msg in myMessages)
{
themessages.AddRange(msg.GetMessagesSummary());
}
return themessages;
}
public int CountMessages()
{
return myMessages.Count();
}
public PacketMessage GetMessageAtIndex(int index)
{
if (index < 0 || index > myMessages.Count()) return null;
return myMessages[index];
}
public List<PacketMessage> GetAllMessages()
{
List<PacketMessage> newlist = new List<PacketMessage>();
foreach(PacketMessage one in myMessages)
{
newlist.Add(PacketMessage.Clone<PacketMessage>(one));
}
return newlist;
}
public void addPacket(Packet toadd)
{
if (toadd != null && !myPackets.Contains(toadd))
{
if (myPackets.Count > NB.MaxPacketsBeforeOptimizing)
{
bool foundit = false;
foreach(Packet pkt in myPackets)
{
if(pkt.MyType == toadd.MyType && pkt.WhereAmI == toadd.WhereAmI &&
(pkt.sourceIP != null && pkt.sourceIP.Equals(toadd.sourceIP)) &&
(pkt.destIP != null && pkt.destIP.Equals(toadd.destIP)))
{
foundit = true;
break;
}
}
if (!foundit)
myPackets.Add(toadd);
}
else
{
myPackets.Add(toadd);
}
}
}
public int CountPackets(PacketType WhatType)
{
int count = 0;
foreach (Packet pkt in myPackets)
{
if (pkt.MyType == WhatType)
count++;
}
return count;
}
public void ProcessPacketsOnce()
{
foreach(Packet tpackets in myPackets.ToList())
{
if(tpackets != null)
tpackets.ProcessTick();
if (tpackets.DebugOn)
Console.WriteLine(NB.Translate("N_ProssPackOnceDbug"));
}
for(int loop=myPackets.Count -1; loop >=0; loop--)
{
//we delete if it has finished.
if (myPackets[loop].DebugOn)
Console.WriteLine(NB.Translate("N_ProssPackOnceDbug"));
if (myPackets[loop].TickTTL < 1) //If the packet has been around too long, get rid of it
{
myPackets[loop].AddMessage(DebugLevel.info, NB.Translate("N_ProssPackOnceTickCounter"));
myPackets[loop].PrepareToDelete();
myPackets.RemoveAt(loop);
}
else if (myPackets[loop].ready_to_delete)
{
myPackets[loop].PrepareToDelete();
if(myPackets[loop].MyStatus == PacketStatus.finished_ok)
{
if (myPackets[loop].TraversalInformation != null)
{
LastTraversal = myPackets[loop].TraversalInformation;
}
}
myPackets.RemoveAt(loop);
}
}
GC.Collect();//Try to clean up memory.
myPackets = NB.Randomize(myPackets);
}
/// <summary>
/// This checks to see if there is any reason we should stop processing the packets
/// </summary>
/// <returns>true if we should continue, false if we should pause</returns>
public bool ProcessingShouldContinue()
{
TimeSpan Duration = DateTime.Now - NetworkStartTime;
NB.SetProgress(Duration.TotalSeconds, NumberOfSecondsForTimeout);
if (Duration.TotalSeconds > NumberOfSecondsForTimeout)
{
Console.WriteLine(string.Format(NB.Translate("N_ProssShouldContinSec"), Duration.TotalSeconds.ToString()));
foreach (Packet pkt in myPackets)
{
pkt.Tracking.AddMessage(DebugLevel.packet, NB.Translate("N_ProssShouldContinNet"), NB.Translate("N_ProssShouldContinTime"));
pkt.Tracking.Status = NB.Translate("N_ProssShouldContinTimeout");
pkt.MyStatus = PacketStatus.finished_failed;
pkt.PrepareToDelete();
}
ClearPackets();
return false;
}
return true;
}
public void RegisterTimeOfArrival()
{
TimeSpan Duration = DateTime.Now - NetworkStartTime;
int MaxTime = (int)Duration.TotalSeconds + 2;
if(!AlreadyChosenTimeout)
{
NumberOfSecondsForTimeout = MaxTime * 2;
AlreadyChosenTimeout = true;
}
}
public void ProcessPackets()
{
//This functionality is now done in 'Tick'
return; //exit early. Rest is done in tick
}
public void ResetPacketTimeout()
{
//We should only do this when we know we are starting new packets.
//Traceroute does this when resetting
AlreadyChosenTimeout = false; //we do this at the beginning of processing
NumberOfSecondsForTimeout = DefaultTimeout;
NetworkStartTime = DateTime.Now;
}
public void Tick(bool SkipVisuals = false)
{
if (!SkipVisuals && NB.ProcessingInvisibleNetwork()) return; //We skip visual ticks while doing invisible ones
if (DateTime.UtcNow < NextPacketMovement && !SkipVisuals) return; //we are supposed to be seeing something, but it is not time yet
if (!SkipVisuals)
{
foreach (AnimationClass one in Animations)
one.EraseAnimation(TheNetImageBackground, myPBox, TheNetImage);
EraseOldPackets();
for(int i= Animations.Count-1; i>=0; i--)
{
if (Animations[i].AnimationDone) Animations.RemoveAt(i);
}
if(DateTime.Now > NextSprayTime)
{
Random myRnd = NB.GetRandom();
int ms = (myRnd.Next(20) + 2) * 100;
NextSprayTime = DateTime.Now.AddMilliseconds(ms);
foreach(NetworkComponent NC in NetComponents)
{
if(NC is NetworkDevice)
{
NetworkDevice ND = (NetworkDevice)NC;
ND.BadPacketIfIShould();
}
}
}
}
if(ReplayInProgress && myPackets.Count == 0)
{
if(DateTime.UtcNow >= NextReplayAction)
{
//We are doing a replay and enough time has passed from the last replay...
NBSettings Settings = NB.GetSettings();
ActionCollection AC = Settings.GetUserActionCollection();
ActionClass Success = AC.RunAction(NextReplayIndex++, true); //note all changes as we do them
NextReplayAction = DateTime.UtcNow.AddMilliseconds(NB.MillisecondsBetweenReplays);
DoAllAutoJoin(); //Connect network links if we need to do so
if(Success != null)
{
//we did something. keep replaying
NB.MarkToUpdate();
StartedNewReplayAction = true;
previously_had_packets = false; //This will make sure we reset packet counters
}
else
{
//replay finished
ReplayInProgress = false;
//Try testing for completion?
TestForCompletion(false, true);
//If we have succeeded, we need to mark it as passed
if (PuzzleIsSolved) Settings.RegisterReplayPassed();
//If we have failed to complete, we need to mark it as failed
else Settings.RegisterReplayFailed();
}
}
}
//if (myPackets.Count > 50)
//Console.WriteLine("Packets: " + myPackets.Count.ToString());
if (myPackets.Count > 0)
{
if (!previously_had_packets)
{
AlreadyChosenTimeout = false; //we do this at the beginning of processing
NumberOfSecondsForTimeout = DefaultTimeout;
NetworkStartTime = DateTime.Now;
ClearPacketCounters();
}
ProcessPacketsOnce();
NBSettings Settings = NB.GetSettings();
NextPacketMovement = DateTime.UtcNow.AddMilliseconds(Settings.MillisecondsBetweenPacketMoves);
if(!ProcessingShouldContinue())
{
//It has all been taken care of
}
if (!SkipVisuals)
{
DrawPackets();
}
//myPBox.Refresh();
previously_had_packets = true;
}
else
{
if(previously_had_packets)
{
//remove any IP connection tracking info
NetworkDevice ND;
foreach (NetworkComponent nc in NetComponents)
{
if (NB.GetComponentType(nc) == GeneralComponentType.device)
{
ND = (NetworkDevice)nc;
ND.ClearIPConnectionInfo();
}
}
foreach(PingTestStatus PTS in PingTestStats)
{
if (PTS.Succeeded == false)
{
//We mark it as failed
NoteActionDone(NetTestType.FailedPing, PTS.Source, PTS.Dest);
}
}
PingTestStats.Clear(); //empty it for now.
DebugPausePoint WhatIsSet = NB.GetDebugPauseSetting();
if (WhatIsSet != 0)
{
Console.WriteLine(NB.Translate("N_ProssPackDone"));
}
TestForCompletion(true); //Now, report on the progress if we solved something in the middle of the packets going out
AlreadyChosenTimeout = false;
NB.SetProgress(0, NumberOfSecondsForTimeout);
NB.UpdateMessages();
NB.MarkToUpdate();
ClearPacketCounters();
}
previously_had_packets = false;
}
if (!SkipVisuals)
{
foreach (AnimationClass one in Animations)
{
one.DrawAnimation(TheNetImageBackground, myPBox);
}
myPBox.Refresh();
}
}
public void ClearPacketCounters()
{
HadLoop = false;
foreach(NetworkComponent NC in NetComponents)
{
if(NC is NetworkDevice)
{
NetworkDevice ND = (NetworkDevice)NC;
ND.PacketIDsPassedThrough.Clear();
}
}
}
public void AddAnimation(AnimationName What, Rectangle Where)
{
Animations.Add(new AnimationClass(What, Where));
}
public void AddMessage(PacketMessage toAdd)
{
//Only add this if it has not already been added
if(myMessages.IndexOf(toAdd) <0 )
{
myMessages.Add(toAdd);
}
}
public NetworkComponent GetComponentFromID(int TheID)
{
foreach(NetworkComponent nc in NetComponents)
{
if(nc.GetUniqueIdentifier == TheID)
{
return nc;
}
}
return null;
}
public NetworkLink GetLinkFromID(int TheID)
{
NetworkComponent nc = GetComponentFromID(TheID);
if (nc == null) return null;
if (nc.GetType().ToString() == "EduNetworkBuilder.NetworkLink")
return (NetworkLink)nc;
return null;
}
public NetworkDevice GetDeviceFromID(int ID)
{
NetworkComponent nc = GetComponentFromID(ID);
if (nc == null) return null;
if (nc.GetType().ToString() == "EduNetworkBuilder.NetworkDevice")
return (NetworkDevice)nc;
return null;
}
public NetworkDevice GetDeviceFromID(HostNicID LinkedNic)
{
return GetDeviceFromID(LinkedNic.HostID);
}
public NetworkDevice GetDeviceFromName(string DeviceName)
{
NetworkComponent nc = DeviceFromName(DeviceName);
if (nc == null) return null;
if (NB.GetComponentType(nc) == GeneralComponentType.device)
return (NetworkDevice)nc;
return null;
}
public List<string> GetHostnames(bool EvenNonNetworked = false, bool includeTrees = false)
{
List<string> tList = new List<string>();
NetworkDevice ND;
foreach(NetworkComponent NC in NetComponents)
{
if(NB.GetComponentType(NC) == GeneralComponentType.device)
{
ND = (NetworkDevice)NC;
if (!EvenNonNetworked && (ND.GetNetType() == NetworkComponentType.microwave || ND.GetNetType() == NetworkComponentType.fluorescent))
continue;
if (ND.GetNetType() == NetworkComponentType.tree && !includeTrees) continue;
tList.Add(ND.hostname);
}
}
tList.Sort();
return tList;
}
public List<string> GetSubnets()
{
List<string> tList = new List<string>();
NetworkDevice ND;
List<string> subnets;
foreach (NetworkComponent NC in NetComponents)
{
if (NB.GetComponentType(NC) == GeneralComponentType.device)
{
ND = (NetworkDevice)NC;
subnets = ND.SubnetList();
foreach(string subnet in subnets)
{
if (!tList.Contains(subnet))
tList.Add(subnet);
}
}
}
tList.Sort();
return tList;
}
public List<string> GetBroadcasts()
{
List<string> tList = new List<string>();
NetworkDevice ND;
List<string> subnets;
foreach (NetworkComponent NC in NetComponents)
{
if (NB.GetComponentType(NC) == GeneralComponentType.device)
{
ND = (NetworkDevice)NC;
subnets = ND.BroadcastList();
foreach (string subnet in subnets)
{
if (!tList.Contains(subnet))
tList.Add(subnet);
}
}
}
tList.Sort();
return tList;
}
public void MarkAsLinked(HostNicID LinkedNic, int LinkID)
{
NetworkDevice nd = GetDeviceFromID(LinkedNic);
//If the host exists, now mark the nic
if(nd != null)
{
NetworkCard nic = nd.NicFromID(LinkedNic);
if(nic != null)
nic.ConnectedLink = LinkID;
}
}
public void MarkAsUnlinked(HostNicID LinkedNic, int LinkID)
{
NetworkDevice nd = GetDeviceFromID(LinkedNic);
//If the host exists, now mark the nic
if (nd != null)
{
NetworkCard nic = nd.NicFromID(LinkedNic);
if ((nic != null && nic.ConnectedLink == LinkID) || LinkID == -1)
{
nic.ConnectedLink = -1;
}
}
}
public NB_IPAddress DNSLookup(NetworkDevice source, string toFind)
{
foreach(NetworkComponent nc in NB.Randomize(NetComponents))
{
NetworkDevice nd;
if(NB.GetComponentType(nc) == GeneralComponentType.device)
{
nd = (NetworkDevice)nc;
if(nd.hostname == toFind)
{
NB_IPAddress found = nd.BestIPForThis(source);
return found;
}
}
}
return null;
}
public string ReverseDNSLookup(NetworkDevice source, NB_IPAddress toFind)
{
if (source != null && source.HasIPAddress(toFind))
return source.hostname; //if the host is 127.0.0.1 or something.
foreach (NetworkComponent nc in NB.Randomize(NetComponents))
{
NetworkDevice nd;
if (NB.GetComponentType(nc) == GeneralComponentType.device)
{
nd = (NetworkDevice)nc;
if (nd.HasIPAddress(toFind))
return nd.hostname;
}
}
return null;
}
public bool DeviceInTree(LinkType myLink, Point location)
{
NetworkDevice ND = null;
if (myLink != LinkType.wireless) return false; //we do not care
foreach (NetworkComponent NC in NetComponents)
{
if (NB.GetComponentType(NC) == GeneralComponentType.device)
{
ND = (NetworkDevice)NC;
if (ND.GetNetType() == NetworkComponentType.tree)
{
if (ND.GetMyRectangle().Contains(location))
return true;
}
}
}
return false;
}
public bool DeviceIsOverDamaging(LinkType myLink, Point location)
{
NetworkDevice ND;
int countDistance = NB.PacketDamageDistance;
double HowFar;
foreach(NetworkComponent NC in NetComponents)
{
if (NB.GetComponentType(NC) == GeneralComponentType.device)
{
ND = (NetworkDevice)NC;
if(myLink == LinkType.wireless && ND.GetNetType() == NetworkComponentType.microwave)
{
HowFar = distance(location, ND.myLocation());
//Console.WriteLine("position=" + HowFar.ToString());
if (HowFar < countDistance)
if (HowFar < countDistance)
{
return true;
}
}
if (myLink != LinkType.wireless && ND.GetNetType() == NetworkComponentType.fluorescent)
{
HowFar = distance(location, ND.myLocation());
//Console.WriteLine("position=" + HowFar.ToString());
if (HowFar < countDistance)
{
return true;
}
}
}
}
return false;
}
public double distance(Point start, Point dest)
{
return Math.Sqrt(Math.Pow((start.X - dest.X),2) + Math.Pow((start.Y - dest.Y),2)) / 5; //use grid size...
}
public double pixeldistance(Point start, Point dest)
{
return Math.Sqrt(Math.Pow((start.X - dest.X), 2) + Math.Pow((start.Y - dest.Y), 2)); //pixel size, not grid size
}
public double distance(NetworkDevice start, NetworkDevice dest)
{
if (start == null || dest == null) return 0;
return distance(start.myLocation(), dest.myLocation());
}
/// <summary>
/// Return the closest wireless device we can connect to
/// </summary>
/// <param name="start"></param>
/// <returns></returns>
public NetworkCard BestWirelessLinkForDevice(NetworkCard start)
{
NetworkDevice starting = GetDeviceFromID(start.myID);
NetworkCard found = null;
NetworkDevice checking = null;
double l_distance = 10000;
if (starting == null) return null;
NetworkCard answer=null;
foreach(NetworkComponent nc in NetComponents)
{
if(NB.GetComponentType(nc) == GeneralComponentType.device)
{
checking = (NetworkDevice)nc;
if (checking.PowerOff) continue; //we cannot connect to a powered-off device
if (checking == starting) continue;
answer = checking.HasWPortSSIDKey(start.SSID, start.EncryptionKey);
if(answer != null)
{
double tdist = distance(starting, checking);
if(tdist < l_distance && tdist < NB.WirelessMaxUnsuccessfulLink)
{
l_distance = tdist;
found = answer;
}
}
}
}
return found;
}
public void RegisterPingTest(string source, string dest)
{
PingTestStatus PTS = new PingTestStatus();
PTS.Source = source;
PTS.Dest = dest;
PTS.Succeeded = false;
PingTestStats.Add(PTS);
}
public void RegisterPingSuccess(string source, string dest)
{
foreach (PingTestStatus PST in PingTestStats)
{
if (PST.Source == source &&
PST.Dest == dest)
{
PST.Succeeded = true;
break;
}
}
}
public void RegisterDeviceReset(string source)
{
foreach(NetTest one in NetTests)
{
if(one.sHost == source && one.TheTest == NetTestType.DeviceIsFrozen)
{
one.SetDone();
}
if (one.sHost == source && one.TheTest == NetTestType.DeviceNICSprays)
{
one.SetDone();
}
}
}
public void RegisterDeviceReplaced(string source)
{
foreach (NetTest one in NetTests)
{
if (one.sHost == source && one.TheTest == NetTestType.DeviceBlowsUpWithPower)
{
one.SetDone();
}
}
}
public void RegisterNICAdded(string source, string nicname)
{
foreach (NetTest one in NetTests)
{
if (one.sHost == source && one.TheTest == NetTestType.DeviceNICSprays && one.dHost == nicname)
{
one.SetDone();
}
}
}
public void RegisterUPSAdded(string source)
{
foreach (NetTest one in NetTests)
{
if (one.sHost == source && one.TheTest == NetTestType.DeviceNeedsUPS)
{
one.SetDone();
}
}
}
/****************************************
* Do On All Devices
* **************************************/
public void DoAllDHCP()
{
NetworkDevice nd;
foreach (NetworkComponent nc in NetComponents)
{
if(NB.GetComponentType(nc) == GeneralComponentType.device)
{
nd = (NetworkDevice)nc;
if (nd.IsBurned || nd.isFrozen() || nd.PowerOff) continue; //skip if burnt, off or frozen
NB.DoActionDHCP(nd.GetUniqueIdentifier);
//nd.DHCPRequestFromHere();
}
}
}
public void DoAllClearDHCP()
{
NetworkDevice nd;
foreach (NetworkComponent nc in NetComponents)
{
if (NB.GetComponentType(nc) == GeneralComponentType.device)
{
nd = (NetworkDevice)nc;
nd.ClearDHCPInfo();
}
}
}
public bool DoAllVerifyLinks()
{
NetworkLink nl;
bool didanything = false;
NetworkComponent nc;
for (int i = NetComponents.Count -1; i >= 0; i-- )
{
nc = NetComponents[i];
if (NB.GetComponentType(nc) == GeneralComponentType.link)
{
nl = (NetworkLink)nc;
didanything = nl.VerifyLinkIntegrity() || didanything;
}
}
return didanything;
}
public bool DoAllRemoveAllWirelessLinks()
{
NetworkLink nl;
bool didanything = false;
NetworkComponent nc;
for (int i = NetComponents.Count - 1; i >= 0; i--)
{
nc = NetComponents[i];
if (nc is NetworkLink)
{
nl = (NetworkLink)nc;
if(nl.theLinkType == LinkType.wireless)
{
didanything = true;
nl.Destroy(); //We will rebuild it later
NetComponents.RemoveAt(i);
}
}
}
return didanything;
}
public bool DoAllMarkAsLinked()
{
bool didanything = false;
NetworkLink nl;
foreach (NetworkComponent nc in NetComponents.ToList())
{
if (NB.GetComponentType(nc) == GeneralComponentType.link)
{
nl = (NetworkLink)nc;
nl.MarkAsLinked();
didanything = true;
}
}
return didanything;
}
public bool DoAllAutoJoin()
{
bool didanything = false;
NetworkDevice nd;
_isDirty = true;
DoAllRemoveAllWirelessLinks(); //Remove them before we re-join them all
foreach (NetworkComponent nc in NetComponents.ToList())
{
if (NB.GetComponentType(nc) == GeneralComponentType.device)
{
nd = (NetworkDevice)nc;
didanything = nd.AutoJoinWireless() || didanything;
}
}
UpdateImage();
return didanything;
}
public int VLANIDFromName(string name)
{
foreach(VLANName VN in VlanNames)
{
if (VN.Name.Equals(name))
return VN.ID;
}
return -1;
}
/// <summary>
/// For solved puzzles. We can add options to them
/// </summary>
public void OverrideFromResources()
{
LoadedFromResource = false;
}
public void DoAllClearArp()
{
NetworkDevice nd;
foreach (NetworkComponent nc in NetComponents)
{
if (NB.GetComponentType(nc) == GeneralComponentType.device)
{
nd = (NetworkDevice)nc;
nd.ClearArps();
}
}
}
public void DoAllPing(NB_IPAddress destination)
{
NetworkDevice nd;
foreach (NetworkComponent nc in NetComponents)
{
if (NB.GetComponentType(nc) == GeneralComponentType.device)
{
nd = (NetworkDevice)nc;
nd.PingFromHere(destination);
}
}
}
public void DoAllClearIPs()
{
NetworkDevice nd;
foreach (NetworkComponent nc in NetComponents)
{
if (NB.GetComponentType(nc) == GeneralComponentType.device)
{
nd = (NetworkDevice)nc;
nd.ClearIPs();
}
}
}
public Image GetPacketImage(Color PacketColor, Color VLANColor)
{
if (VLANColor == Color.Blue) VLANColor = PacketColor;
string ColorNames = PacketColor.Name + VLANColor.Name;
if(PacketColors.Contains(ColorNames))
{
return PacketImages[PacketColors.IndexOf(ColorNames)];
}
PacketColors.Add(ColorNames);
Image newPacketImage = new Bitmap(NB.PacketPixelSize, NB.PacketPixelSize);
using (Graphics G = Graphics.FromImage(newPacketImage))
{
G.Clear(Color.Transparent);
// Pen myPen = new Pen(PacketColor, NB.PacketPixelSize);
Brush tBrush = new SolidBrush(VLANColor);
G.FillEllipse(tBrush, 0,0, NB.PacketPixelSize, NB.PacketPixelSize);
tBrush = new SolidBrush(PacketColor);
int dist = NB.PacketPixelSize / 4;
G.FillEllipse(tBrush, dist, dist, NB.PacketPixelSize / 2, NB.PacketPixelSize / 2);
}
PacketImages.Add(newPacketImage);
return newPacketImage;
}
public Color ColorFromPacketVLAN(int id)
{
if (!VLANPacketColors) return Color.Blue; //If we are not set up to do vlan colors.
foreach(VLANName VN in VlanNames)
{
if (VN.ID == id)
return VN.PacketColor;
}
return Color.Blue;
}
//This function heavily borrowed from: http://stackoverflow.com/questions/1563038/fast-work-with-bitmaps-in-c-sharp
public Image ColoredImage(Image BaseImage, Color MorphColor)
{
Bitmap b = new Bitmap(BaseImage);
BitmapData bData = b.LockBits(new Rectangle(0, 0, BaseImage.Width, BaseImage.Height), ImageLockMode.ReadWrite, b.PixelFormat);
/* GetBitsPerPixel just does a switch on the PixelFormat and returns the number */
int bitsPerPixel = Image.GetPixelFormatSize(bData.PixelFormat);
/*the size of the image in bytes */
int size = bData.Stride * bData.Height;
/*Allocate buffer for image*/
byte[] data = new byte[size];
/*This overload copies data of /size/ into /data/ from location specified (/Scan0/)*/
System.Runtime.InteropServices.Marshal.Copy(bData.Scan0, data, 0, size);
for (int i = 0; i < size; i += bitsPerPixel / 8)
{
//double magnitude = 1 / 3d * (data[i] + data[i + 1] + data[i + 2]);
//data[i] is the first of 3 bytes of color
data[i] = (byte)((data[i] + MorphColor.B) / 2);
data[i + 1] = (byte)((data[i + 1] + MorphColor.G) / 2);
data[i + 2] = (byte)((data[i + 2] + MorphColor.R) / 2);
}
/* This override copies the data back into the location specified */
System.Runtime.InteropServices.Marshal.Copy(data, 0, bData.Scan0, data.Length);
b.UnlockBits(bData);
return b;
}
public void DumpInvisibleNetMessages()
{
List<string> messages = GetMessageStrings();
foreach(string one in messages)
{
Console.WriteLine(one);
}
}
/// <summary>
/// This func tries to non-visually process all the tests, seeing if the network is
/// "solved." This is for homework that is "submitted."
/// </summary>
public HomeworkSolvedStatus CheckThatHomeworkIsSolved()
{
bool HadIssues = false;
NB.RegisterInvisibleNetwork(this);
DoAllMarkAsLinked();
myMessages.Clear(); //Erase any old messages we might have
//do dhcp request on everything.
DoAllDHCP();
NonVisualProcessPacketsOnce(); //loop until we "timeout" or all packets are done.
foreach (NetTest NT in NetTests)
{
NB_IPAddress destination;
NetworkDevice src = null;
//Here we do any pings or actions
switch (NT.TheTest)
{
case NetTestType.FailedPing:
case NetTestType.SuccessfullyPings:
case NetTestType.SuccessfullyPingsAgain:
//We need to generate a ping request
src = GetDeviceFromName(NT.sHost);
if (src == null) continue;
destination = DNSLookup(src, NT.dHost);
if (destination == null || destination.GetIPString == NB.ZeroIPString)
destination = new NB_IPAddress(NT.dHost);
src.PingFromHere(destination);
break;
case NetTestType.SuccessfullyArps:
src = GetDeviceFromName(NT.sHost);
if (src == null) continue;
destination = DNSLookup(src, NT.dHost);
if (destination == null || destination.GetIPString == NB.ZeroIPString)
destination = new NB_IPAddress(NT.dHost);
src.AskArpFromHere(destination);
break;
case NetTestType.SuccessfullyTraceroutes:
src = GetDeviceFromName(NT.sHost);
if (src == null) continue;
destination = DNSLookup(src, NT.dHost);
if (destination == null || destination.GetIPString == NB.ZeroIPString)
destination = new NB_IPAddress(NT.dHost);
src.TracerouteFromHere(destination);
break;
}
NonVisualProcessPacketsOnce(); //loop until we "timeout" or all packets are done.
}
foreach (NetTest NT in NetTests)
{
//Here we test it.
bool WasComplete = NT.TestComplete(this);
string tMessage = NT.GetDescription(NetTestVerbosity.full) + " done: " + WasComplete.ToString();
//Console.WriteLine(NT.GetDescription(NetTestVerbosity.full) + " done: " + WasComplete.ToString());
AddMessage(new PacketMessage("NetTest", tMessage));
}
//DumpInvisibleNetMessages();
NB.UnregisterInvisibleNetwork();
if(HadIssues)
return HomeworkSolvedStatus.CheckedFailed;
return HomeworkSolvedStatus.NeverChecked; //for now. We want to change this later. Just so we keep re-testing
}
public TraversalClass NonVisualPingOneHost(string source, string dest)
{
LastTraversal = null;
NB.RegisterInvisibleNetwork(this);
NetworkDevice src = GetDeviceFromName(source);
if (src == null) return null;
NB_IPAddress destination = DNSLookup(src, dest);
src.PingFromHere(destination);
NonVisualProcessPacketsOnce();
NB.UnregisterInvisibleNetwork();
return LastTraversal;
}
public void NonVisualDoDHCPOnAll()
{
NB.RegisterInvisibleNetwork(this);
DoAllDHCP();
NonVisualProcessPacketsOnce();
NB.UnregisterInvisibleNetwork();
}
public void NonVisualProcessPacketsOnce()
{
int counter = 0;
while(counter < 1000 && myPackets.Count >0)
{
Tick(true); //Skip visuals
counter++;
}
}
/// <summary>
/// This is used when we are doing a replay behind the scenes.
/// We may have many things that we do. We still want to time-out if
/// a packet needs to drop. So we loop through, but have a timeout on each
/// individual action.
/// </summary>
public void NonVisualProcessPacketsMultipleTimes()
{
int counter = 0;
while (counter < 1000 && myPackets.Count > 0)
{
Tick(true); //Skip visuals
if(StartedNewReplayAction)
{
counter = 0; //reset counter to zero
StartedNewReplayAction = false; //reset it
}
counter++;
}
}
int BreakNetComponent(NetworkComponent What, HowToBreak How, string Data)
{
int didit = 0;
if (What == null) return 0;
string WhatBreak = What.hostname + "-" + How.ToString() + "-" + Data;
if (BrokenItems.Contains(WhatBreak)) return 0; //it was already done
NetworkDevice tDevice = null;
NetworkLink tLink = null;
NetTest tTest = null;
if (What is NetworkDevice) tDevice = (NetworkDevice)What;
if (What is NetworkLink) tLink = (NetworkLink)What;
switch(How)
{
case HowToBreak.PowerOff:
//power the device off
tDevice.PowerOff = true;
didit = 1;
break;
case HowToBreak.DeviceChangeGW:
//Change the IP of the gateway
if (tDevice.BreakGateway())
didit = 2;
break;
case HowToBreak.DeviceChangeIP:
//Change the IP on the outbound nic
if (tDevice.BreakIPAddress(Data))
didit = 2;
break;
case HowToBreak.EthernetBreak:
//break the link itself
if (tLink.theLinkType == LinkType.normal)
{
tLink.theLinkType = LinkType.broken;
didit = 1;
}
break;
case HowToBreak.EthernetRemoveLink:
if (tLink.theLinkType == LinkType.normal)
{
tLink.Destroy();
RemoveComponent(tLink);
didit = 1;
}
break;
case HowToBreak.EthernetCorrupt:
//Add a flourescent light
break;
case HowToBreak.LockOutSwitch:
//Lock it out
if (tDevice.DoesForwarding()) tDevice.LockUsOutOfDevice();
didit = 1;
break;
case HowToBreak.StaticRouteClear:
//Clear out the static route(s)
break;
case HowToBreak.StaticRouteCorrupt:
//corrupt the static route(s)
break;
case HowToBreak.VLANChange:
//Change the vlan on the port we use.
break;
case HowToBreak.VPNChangeEndpoint:
//Change the ip-address on the VPN endpoint
break;
case HowToBreak.VPNChangeKey:
//change the key for the VPN encryption
if (tDevice.BreakVPNKey(Data))
didit = 2;
break;
case HowToBreak.WirelessBreakKey:
case HowToBreak.WirelessBreakSSID:
//choose one of the two ends & return the device
HostNicID TheID = tLink.RandomEndpoint();
NetworkDevice rndEnd = GetDeviceFromID(TheID);
NetworkCard tnic = rndEnd.NicFromID(TheID);
//change the wireless ssid - have small list of bad keys to choose from
if (How == HowToBreak.WirelessBreakSSID && rndEnd.BreakSSID(tnic.NicName()))
didit = 2;
//Change the wireless key
if (How == HowToBreak.WirelessBreakKey && rndEnd.BreakWirelessKey(tnic.NicName()))
didit = 2;
break;
case HowToBreak.BreakDevice:
//The device can be frozen, have bad power, or need a UPS, or just be burnt
Random rnd = NB.GetRandom();
int i = rnd.Next(4);
if(i==0)
{
How = HowToBreak.BreakDevice;
Data = "frozen";
tTest = new NetTest(What.hostname, What.hostname, NetTestType.DeviceIsFrozen);
NetTests.Add(tTest);
}
else if(i == 1)
{
How = HowToBreak.BreakDevice;
Data = "BlowsUp";
tTest = new NetTest(What.hostname, What.hostname, NetTestType.DeviceBlowsUpWithPower);
NetTests.Add(tTest);
}
else if (i == 2)
{
How = HowToBreak.BreakDevice;
Data = "Needs UPS";
tTest = new NetTest(What.hostname, What.hostname, NetTestType.DeviceNeedsUPS);
NetTests.Add(tTest);
}
else if (i == 3)
{
How = HowToBreak.BreakDevice;
Data = "burnt";
tDevice.IsBurned = true; //Burn the device
}
didit = 1;
break;
}
if(didit > 0)
BrokenItems.Add(WhatBreak);
if (didit > 0) Console.WriteLine("Broke it:" + What.hostname + " : " + How + " : " + Data);
if (didit == 0) Console.WriteLine("Did not break it:" + What.hostname + " : " + How + " : " + Data);
return didit;
}
bool AlreadyHasPingTest(string source, string dest)
{
foreach (NetTest NT in NetTests)
{
if (NT.TheTest == NetTestType.SuccessfullyPings)
{
if (NT.sHost == source && NT.dHost == dest) return true;
if (NT.sHost == dest && NT.dHost == source) return true;
}
}
return false;
}
public int BreakNetworkPath(TraversalClass ThePath, HowToBreak How)
{
//find the device name it belongs to
//try to break it. If it fails, try a different device.
//Fail if we cannot do it
TraversalTechnology WhatNeeded = NB.TechnologyNeededToBreak(How);
if (How == HowToBreak.BreakDevice)
Console.WriteLine("Trying to break it");
int count = 0;
while(count < 3)
{
string host = ThePath.HostnameFromTechnology(WhatNeeded);
if (host != "")
{
string data = ThePath.DataFromTechnologyAndHost(WhatNeeded, host);
//We have a host, see if we can break it.
NetworkComponent NC = ComponentFromName(host);
if(NC != null)
{
int answer = BreakNetComponent(NC, How, data);
if (answer > 0)
{
if(!AlreadyHasPingTest(ThePath.Source(), ThePath.Destination()))
{
//Add a test to show this is broken.
NetTest NT = new NetTest(ThePath.Source(), ThePath.Destination(), NetTestType.SuccessfullyPings);
NetTests.Add(NT);
}
return answer;
}
}
}
count++;
}
return 0;
}
}
}