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; namespace EduNetworkBuilder { /// /// This is a whole network. LAN, WAN, Internet; everything combined /// public class Network { public string PuzzleName=""; public int myHeight = 1024; public int myWidth = 1024; public int Level = 0; public double SortOrder = 0; public bool OptionShowLabels = false; public bool ShowLabelsHere = false; public bool VLANsEnabled = false; public bool VLANPacketColors = false; public LanguageStrings NetMessage; public LanguageStrings NetTitle; List NetComponents = new List(); //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 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 myPackets = new List(); private List myMessages = new List(); private bool _isDirty = false; private IPAddress lastAddress = new IPAddress("0.0.0.0/24"); public string NetworkFilename = ""; public List NetTests = new List(); 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 SuggestedReadings = new List(); private DateTime NetworkStartTime = DateTime.Now; private bool AlreadyChosenTimeout = false; private int DefaultTimeout = 10; private int NumberOfSecondsForTimeout = 10; private List PacketRectangles = new List(); public BindingList VlanNames = new BindingList() { new VLANName(1,"Default") }; private bool previously_had_packets = false; //used on "tick" to determine if we are starting from scratch private List PacketColors = new List(); private List PacketImages = new List(); private List PingTestStats = new List(); 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 } private bool isDirty() { if (_isDirty) return true; foreach (NetworkComponent nc in NetComponents) { if (nc.IsDirty) return true; } return false; } public void ClearComponents() { NetComponents.Clear(); } public void ClearPackets() { myPackets.Clear(); } public void ClearMessages() { myMessages.Clear(); } /// /// Load the file from a xml resource /// 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) { _isDirty = true; NetworkDevice newND; NetworkLink newNL; int newUnique=-1; PuzzleName = Name; 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); break; case "showlabels": bool.TryParse(Individual.InnerText, out OptionShowLabels); ShowLabelsHere = OptionShowLabels; 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(Individual.InnerText, HelpTopics.None); if (tempHelpTopic != HelpTopics.None) { SuggestedReadings.Add(tempHelpTopic); } 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(Individual.InnerText); HintsToDisplay = StartingHelpLevel; 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); } break; } } } DoAllVerifyLinks(); DoAllAutoJoin(); if (NetMessage.GetText() != "" && !AlreadyDisplayedMessage) { //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; } if(NetTests.Count > 0) PuzzleIsSolved = false; //When we load the puzzle. if (newUnique != -1) UniqueIdentifier = newUnique; } public void Save() { Save(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Test.enbx")); } 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) { //Save the language name //save the number of items //Save all the items writer.WriteStartElement("Network"); NetMessage.Save(writer); NetTitle.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()); //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) NetComponents[loop].Save(writer); } foreach(NetTest nt in NetTests) { nt.Save(writer); } foreach(HelpTopics HT in SuggestedReadings) { writer.WriteElementString("tag",HT.ToString()); } 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; 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; } 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)) return tDevice; } } return null; } public NetworkDevice ItemFromName(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 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; } /// /// Search throuh all the network components and delete any links that are attacked to the specified nic. /// /// 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; } } } } public NetworkComponent AddItem(NetworkComponent ToAdd) { NetComponents.Add(ToAdd); TestForCompletion(true); return ToAdd; } public List UnavailableNics() { NetworkLink myLink; List usedList = new List(); 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) { 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(IPAddress ip) { lastAddress = ip; } public IPAddress RetrieveLastIP() { return lastAddress; } public List GetTestMessages(string host) { string tString; List tMessages = new List(); foreach(NetTest nt in NetTests) { if(nt.sHost == host && !nt.TestComplete()) { tString = nt.GetDescription(HintsToDisplay); if(tString != "") tMessages.Add(tString); } } return tMessages; } public List GetIncompleteTestDestinations(string Source, bool forPing=true) { List tDests = new List(); foreach (NetTest nt in NetTests) { if (nt.sHost == Source && !nt.TestComplete()) { if (forPing && (nt.TheTest == NetTestType.FailedPing || nt.TheTest == NetTestType.SuccessfullyPings || nt.TheTest == NetTestType.SuccessfullyPingsAgain)) tDests.Add(nt.dHost); if (!forPing && nt.TheTest == NetTestType.SuccessfullyArps) tDests.Add(nt.dHost); } } return tDests; } public void TestForCompletion(bool report_as_done) { 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 (report_as_done && PuzzleCount == 0 && PreviouslyUnsolved) { //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 //Do all the links first foreach (NetworkComponent NC in NetComponents) { if (NC.GetType().ToString() == "EduNetworkBuilder.NetworkLink") NC.Print(TheNetImage, false); } //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); foreach(Rectangle rec in PacketRectangles) { Invalidate(rec); } PacketRectangles.Clear(); } 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 arp(UInt32 IP) { List arps = new List(); List 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; } /// /// Search all the devices and make sure the one device is the only one that has the specified IP /// /// The IP address to find /// The device that has it /// public bool HasUniqueIP(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; } private void MarkAsSolved() { PuzzleIsSolved = true; if (PuzzleName != "" && PuzzleName != null) { if (Properties.Settings.Default.ScoreList == null) Properties.Settings.Default.ScoreList = new System.Collections.Specialized.StringCollection(); if (!Properties.Settings.Default.ScoreList.Contains(PuzzleName)) { Properties.Settings.Default.ScoreList.Add(PuzzleName); Properties.Settings.Default.Save(); } } DialogResult answer = MessageBox.Show(NB.Translate("N_MarkAsSolvedDone"),NB.Translate("_Solved"),MessageBoxButtons.YesNo); if(answer == DialogResult.Yes) { ListBoxWindow LBW = new ListBoxWindow(); LBW.ShowDialog(); } } /// /// See if we have any tests that are supposed to check for packet arrival. /// /// The type of packet that arrived /// The host it originated from /// The machine it went to public void NotePacketArrived(PacketType packet_type, NetworkDevice source, IPAddress sIP, 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); } } public bool HasCompletedPingTest(PacketType packet_type, NetworkDevice source, IPAddress sIP, 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; IPAddress sourceIP; string sourceIPstring; IPAddress destIP; string destIPstring; foreach (NetTest nt in NetTests) { sourceIP = new IPAddress(sHost); sourceIPstring = ReverseDNSLookup(null, sourceIP); //this will either be an ip address or the host name destIP = new 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("cbViewTitles"); if (ctl == null) return false; ctl.BackColor = Control.DefaultBackColor; return true; } } } return false; } public List NetworkCardForHostList(string hostname, bool OnlyUnused = true, bool OnlyLinkable = false, NicType fromNIC = NicType.none) { List theList = new List(); 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 GetMessageStrings() { List themessages = new List(); 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 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(); myPackets.RemoveAt(loop); } } GC.Collect();//Try to clean up memory. myPackets = NB.Randomize(myPackets); } /// /// This checks to see if there is any reason we should stop processing the packets /// /// true if we should continue, false if we should pause 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 Tick() { EraseOldPackets(); //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; } ProcessPacketsOnce(); if(!ProcessingShouldContinue()) { //We it has all been taken care of } 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(); } previously_had_packets = false; } } 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 = ItemFromName(DeviceName); if (nc == null) return null; if (NB.GetComponentType(nc) == GeneralComponentType.device) return (NetworkDevice)nc; return null; } public List GetHostnames(bool EvenNonNetworked = false) { List tList = new List(); 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; tList.Add(ND.hostname); } } tList.Sort(); return tList; } public List GetSubnets() { List tList = new List(); NetworkDevice ND; List 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 GetBroadcasts() { List tList = new List(); NetworkDevice ND; List 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 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) { IPAddress found = nd.BestIPForThis(source); return found; } } } return null; } public string ReverseDNSLookup(NetworkDevice source, 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 DeviceIsOverDamaging(LinkType myLink, Point location) { NetworkDevice ND; int countDistance = 25; 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 distance(NetworkDevice start, NetworkDevice dest) { if (start == null || dest == null) return 0; return distance(start.myLocation(), dest.myLocation()); } /// /// Return the closest wireless device we can connect to /// /// /// 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 == 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; } } } /**************************************** * Do On All Devices * **************************************/ public void DoAllDHCP() { NetworkDevice nd; foreach (NetworkComponent nc in NetComponents) { if(NB.GetComponentType(nc) == GeneralComponentType.device) { nd = (NetworkDevice)nc; nd.DHCPRequestFromHere(); } } } 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 DoAllAutoJoin() { bool didanything = false; NetworkDevice nd; foreach (NetworkComponent nc in NetComponents.ToList()) { if (NB.GetComponentType(nc) == GeneralComponentType.device) { nd = (NetworkDevice)nc; didanything = nd.AutoJoinWireless() || didanything; } } return didanything; } public int VLANIDFromName(string name) { foreach(VLANName VN in VlanNames) { if (VN.Name.Equals(name)) return VN.ID; } return -1; } public void DoAllClearArp() { NetworkDevice nd; foreach (NetworkComponent nc in NetComponents) { if (NB.GetComponentType(nc) == GeneralComponentType.device) { nd = (NetworkDevice)nc; nd.ClearArps(); } } } public void DoAllPing(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; } } }