using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; //using System.Deployment.Application; using System.Windows.Forms; using System.Globalization; using System.Resources; using System.Xml; using System.Drawing; using System.Media; using System.Reflection; using System.Text.RegularExpressions; using System.Xml.Serialization; using System.IO; namespace EduNetworkBuilder { public enum PacketStatus { processing, //It is inside a device. It needs to be routed, masqueraded, or whatever input, //It is hitting the interface/nic of a device. output, //It is leaving a device. Make sure the mac address is what it should be & that we are going out the right link waiting_for_arp, //It is in the output chain, has been procesed, but is waiting for an arp packet to give it the dest MAC moving, //It is traveling along a link. We increment the distance it has gone and re-draw the packet. encapsulated, //It has been put inside another packet. finished_ok,//The packet has finished and is ready to be removed from the network finished_failed, //The packet is finished (failed) and is ready to be removed from the network. finished //There was an appropriate reason this packet finished. It stopped } public enum VLANTagType { Tagged, Untagged, Forbidden } public enum NetShapeType { none, circle, rectangle, } public enum LinkType { normal, wireless, broken } public enum PacketType { none, ping_request, ping_answer, arp_request, arp_answer, dhcp_request, dhcp_answer, vpn_packet, tun_packet, tracert_request, tracert_reply, bad_packet } public enum ResponseToPacket { none, accept, masq, drop, reject } public enum DebugLevel { none=0, info=1, routing=2, switching=4, natting=8, filtering=16, debug=32 , packet=64, all=127} public enum NetworkComponentType { none, router, net_switch, net_hub, laptop, pc, server, wap , tree, wrouter, wbridge, wrepeater, link, firewall, ip_phone, printer, copier, microwave, fluorescent, cellphone, tablet } public enum NicType { none, lo, eth, wlan, wan, vpn, tun, management_interface, port, wport } public enum IPAddressType { ip, gw, route, ip_only } public enum nb_direction { none, to_src, to_dst } public enum GeneralComponentType { none, link, device } public enum NBSoundType { none, success, saved_ok, saved_failed } public enum RTFWindowContents { help, about, release_notes } public enum NetTestType { NeedsLocalIPTo, NeedsDefaultGW, NeedsLinkToDevice, NeedsRouteToNet, NeedsUntaggedVLAN, NeedsTaggedVLAN, NeedsForbiddenVLAN, SuccessfullyPings, SuccessfullyPingsAgain, SuccessfullyArps, SuccessfullyDHCPs, HelpRequest, ReadContextHelp, FailedPing, DHCPServerEnabled, SuccessfullyTraceroutes, SuccessfullyPingsWithoutLoop, LockAll, LockIP, LockRoute, LockNic, LockDHCP, LockGateway, LockLocation, LockVLANsOnHost, LockNicVLAN, LockInterfaceVLAN, LockVLANNames, DeviceIsFrozen, DeviceBlowsUpWithPower, DeviceNeedsUPS, DeviceNICSprays, } public enum AnimationName { Spark1, Fire1, Smoke1, Explo1, Lightning1 } public enum ContextTest { ping, arp, traceroute } public enum NetTestVerbosity { none, basic, hints, full } public enum LBContents { routes, messages, dhcp, puzzles, regressiontest } public enum HelpTopics { None, DHCP, DHCPServer, Firewall, Gateway, Help, IPAddress, Link, Subnet, Ping, VPN, Hub, Switch, ARP, StaticRoute, Subnetting, WhenToSubnet, ComparingAddresses, MACAddress, Network, Packet, NIC, Interface, Router, PacketCorruption, GeneralWireless, WirelessSSID, WirelessKey, WirelessAP, WirelessRouter, WirelessRepeater, WirelessBridge, VLAN, Power, Traceroute } public enum CaptionType { none=0, full = 1, host =2, ip=3, host_ip=4, } public enum FirewallRuleType { Allow, Drop } public enum SolvedNetworkNames { DHCP, OneNet, TwoNets, ThreeNets, firewalls, VLAN, InternetHomeAndOffice, OfficeBldgWired, OfficeBldgWireless } public enum PuzzleNames { Level0_IP, Level1_NoGateway, Level0_NeedsLink, Level0_NoSwitch, Level1_BadDHCP, Level1_BadGateway, Level0_SimpleDHCP, Level1_BadIP, Level0_Help, Level0_Ping, Level0_HubVsSwitch, Level0_Power, Level0_NetworkLoop2, Level0_BrokenLink, Level0_HiddenSwitch, Level0_Frozen, Level0_BadPower1, Level0_BadPower2, Level0_PacketCorruption1, Level0_PacketCorruption2, Level0_Traceroute, Level1_AddingDevices, Level1_MidDHCP, Level1_OneNetTwoSubnets, Level1_DuplicateIPs, Level0_NetworkLoop, Level1_DuplicateMAC, Level1_BadNetmask, Level1_VPNTraceroute, Level1_Practice1, Level1_Practice2, Level1_Practice3, Level1_Practice4, Level1_Practice5, Level1_Practice6, Level1_Practice7, Level2_FirewallDemo, Level1_OneNetTwoSubnets2, Level2_VPN_Demo, Level2_Bad_VPN_IP, Level2_Bad_Encryption, Level2_Bad_Route, Level2_Blast_From_Past, Level2_Not_Working, Level2_Build_A_VPN, Level2_Connect_The_Dots, Level2_VPN_woes, Level2_FirewallTest2, Level2_CannotConnect, Level3_BlackHole, Level3_Busted, Level3_Middle_Man_Out, Level3_PhoneyNetwork, Level3_VPNify, Level3_EncryptionTroubles, Level3_NowhereToGo, Level3_GrandCentralStation, Level3_Dead, Level3_TwoDHCPServers, Level3_invisible, Level4_DualWans, Level4_SinglesLife, Level4_SmallSubnets, Level4_OneRoute, Level4_RouterReplacement, Level4_InternalSubnetting, Level4_Internalhemorrhage, Level4_WhoDidThat, Level5_WirelessRouters, Level5_WirelessDevices, Level5_WirelessBridge, Level5_WirelessRepeater, Level5_WirelessRepeater2, Level5_WirelessAccessPoint, Level5_WirelessCorruption, Level5_Failed, Level5_LostPacket, Level5_HereComesTrouble, Level5_APProblems, Level5_LineOfSight, Level5_Practice1, Level5_Practice2, Level5_Practice3, Level5_Practice4, Level5_Practice5, Level5_Practice6, Level6_VLAN_Intro, Level6_VLAN_Intro2, Level6_Intro3_LockedOut, Level6_ForbiddenVLAN, Level6_TaggedBetweenSwitches, Level6_VLANRouting, Level6_VLANRouting2, level6_UntaggedAndDHCP, Level6_SorryBoss, Level6_VLANFrustrations, Level6_TwoAccessPoints, Level6_VlanRouting3, Level6_ConnectTheLaptop, Level6_CleanSlate, Level6_WhereFrom, Level6_NeedVLANs, Level6_SwitchedUp, } public enum HomeworkSolvedStatus { NeverChecked, CheckedFailed, CheckedSucceeded } public enum DebugPausePoint { none=0, packet_create=1, packet_kill=2, packet_in=4, packet_out=8, packet_duplicate=16, all=63, dump=256, pause=512} public enum TraversalTechnology { any, none, gateway, static_route, vlan, ethernet, wireless, firewall, vpn, vpn_encryption, vpn_decryption, ip_address, masquerade, forward, arrived, network_interface} public enum HowToBreak { PowerOff, EthernetBreak, EthernetCorrupt, EthernetRemoveLink, LockOutSwitch, WirelessBreakSSID, WirelessBreakKey, DeviceChangeIP, DeviceChangeGW, StaticRouteClear, StaticRouteCorrupt, VLANChange, VPNChangeEndpoint, VPNChangeKey, BreakDevice } public enum NBAction { none, newdevice, changelocation, changecomponent, deletecomponent, ping, traceroute, arp, cleararp, dhcp, replaceUPS, replace, poweroff, poweron, reset, } [Serializable] public struct HostNicID //This holds a unique identifier for a network card. Links use this to know what it is connected to { public int HostID; public int NicID; public string HostName; public string NicName; public HostNicID(int host, int nic, string hostname, string nicname) { HostID = host; NicID = nic; HostName = hostname; NicName = nicname; } public HostNicID(XmlNode theNode) { HostID = 0; NicID = 0; HostName = ""; NicName = ""; foreach (XmlNode Individual in theNode.ChildNodes) { XmlNodeType myNodetype = Individual.NodeType; if (myNodetype == XmlNodeType.Element) { switch (Individual.Name.ToLower()) { case "hostid": int.TryParse(Individual.InnerText, out HostID); break; case "nicid": int.TryParse(Individual.InnerText, out NicID); break; case "hostname": HostName = Individual.InnerText; break; case "nicname": NicName = Individual.InnerText; break; } } } } public void Save(XmlWriter writer, string tag) { writer.WriteStartElement(tag); writer.WriteElementString("hostid", HostID.ToString()); writer.WriteElementString("nicid", NicID.ToString()); writer.WriteElementString("hostname", HostName); writer.WriteElementString("nicname", NicName); writer.WriteEndElement(); } public string HostNicIDString { get { return HostID.ToString()+"-"+NicID.ToString(); } } public bool Equals(HostNicID toCheck) { if (HostID != toCheck.HostID) return false; if (NicID != toCheck.NicID) return false; if (HostName != toCheck.HostName) return false; if (NicName != toCheck.NicName) return false; return true; } } [Serializable] public struct IPConnectionEntry { public NB_IPAddress destIP; //where we are sending the packet to. We expect a response to come from here public PacketType What; //ping, dhcp, etc public ResponseToPacket Response; //accept, masq public NB_IPAddress internalIP; //Used if we are masquerading public IPConnectionEntry(NB_IPAddress dest, PacketType what, ResponseToPacket response) { destIP = dest; What = what; Response = response; internalIP = null; } public IPConnectionEntry(NB_IPAddress dest, PacketType what, ResponseToPacket response, NB_IPAddress internal_ip) { destIP = dest; What = what; Response = response; internalIP = internal_ip; } } [Serializable] public class PingTestStatus { public string Source; public string Dest; public bool Succeeded = false; } [Serializable] public struct ArpEntry { public string MACAddress; public string IPAddr; public HostNicID NicOnWhichItIsFound; public ArpEntry(string mac, string ip, HostNicID thenic) { MACAddress = mac; IPAddr = ip; NicOnWhichItIsFound = thenic; } public bool Equals(ArpEntry toCompare) { if (MACAddress != toCompare.MACAddress) return false; if (IPAddr != toCompare.IPAddr) return false; if (!NicOnWhichItIsFound.Equals(toCompare.NicOnWhichItIsFound)) return false; return true; } } [Serializable] public class PuzzleInfo { public string PuzzleName; public string PuzzleTitle; public string PuzzleDescription; public List PuzzleTags = new List(); public int Level=0; public string strLevel { get { return "Level_" + Level; } } public double SortOrder=0; public LanguageStrings NetMessage; public LanguageStrings NetTitle; public void Load(XmlNode TheNode, string Name) { 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 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 "message": PuzzleDescription = Individual.InnerText; break; case "title": PuzzleTitle = Individual.InnerText; break; case "tag": PuzzleTags.Add(Individual.InnerText); break; case "level": PuzzleTags.Add("Level_" + Individual.InnerText); int.TryParse(Individual.InnerText, out Level); break; case "sortorder": double.TryParse(Individual.InnerText, out SortOrder); break; default: if (Regex.IsMatch(Individual.Name.ToLower(), "message")) { NetMessage.Add(Individual); } else if (Regex.IsMatch(Individual.Name.ToLower(), "title")) { NetTitle.Add(Individual); } break; } } } } } [Serializable] public class FirewallRule { public string Source; public string Destination; public FirewallRuleType Action; public FirewallRule() { } public FirewallRule(string source, string dest, FirewallRuleType action) { Source = source; Destination = dest; Action = action; } public FirewallRule(XmlNode theNode) { foreach (XmlNode Individual in theNode.ChildNodes) { XmlNodeType myNodetype = Individual.NodeType; if (myNodetype == XmlNodeType.Element) { switch (Individual.Name.ToLower()) { case "source": Source = Individual.InnerText; break; case "destination": Destination = Individual.InnerText; break; case "action": Action = NB.ParseEnum(Individual.InnerText); break; } } } } public bool Equals(FirewallRule toCompare) { if (Source != toCompare.Source) return false; if (Destination != toCompare.Destination) return false; if (Action != toCompare.Action) return false; return true; } public void Save(XmlWriter writer, string tag) { writer.WriteStartElement(tag); writer.WriteElementString("source", Source); writer.WriteElementString("destination", Destination); writer.WriteElementString("action", Action.ToString()); writer.WriteEndElement(); } } [Serializable] public class HelpURL { public string URL = ""; public string LangTag = ""; public string HelpTopicString = ""; } static class NB { public static string BroadcastMACString = "FF:FF:FF:FF:FF:FF"; //The broadcast MAC address public static string BroadcastIPString = "255.255.255.255"; //the generic broadcast IP address public static string ZeroIPString = "0.0.0.0"; public static string LoopbackIPString = "127.0.0.1"; public static int LinkStep = 8;//The percentage of the link we move at each "tick" public static int PacketPixelSize = 16; //The size of the packet pixel public static int PacketVersionNum = 2; //2 uses the new stuff. Anything else uses the old stuff public const int GridSize = 10; public static string[,] LanguageChoices = { { NB.Translate("NB_NBEn"), "en" }, { NB.Translate("NB_NBFr"), "fr" } }; public static int WirelessMaxUnsuccessfulLink = 120; //The link will connect, but the packet will drop public static int WirelessMaxSuccessfulLink = 100; //Packets will drop after this distance public static int WirelessReconnectDistance = 70; //Try to find a closer AP if we are this far out. public static int UntaggedVLAN = -1; //If the packet is not tagged. public static int MaxPacketsBeforeOptimizing = 50; public static int DefaultPasswordLen = 6; public static int DefaultMachinePasswordLen = 20; public static int DefaultSaltLen = 50; public static int NormalRotation = 5; public static int PacketDamageDistance = 25; public static bool DebugActions = false; public static bool DebugTests = false; public static int NumBadPackets = 7; //the number of packets to spray out public static string AllowedPasswordCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=!~@#$%^&*()_+{}[]/?<>,."; public static string AllowedUsernameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890._"; public static int MillisecondsBetweenReplays = 500; public static int MillisecondsBetweenPacketMoves = 15; /// /// Find the global random number generator. /// /// A valid random number generator public static Random GetRandom() { BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) return new Random(); if (myWin.GameRandomGen == null) return new Random(); return myWin.GameRandomGen; } /// /// Find the global random number generator. /// /// A valid random number generator public static CultureInfo GetCulture(NBSettings theSettings = null) { BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; CultureInfo CI=null; NBSettings oursettings; if (theSettings == null) oursettings = NB.GetSettings(); else oursettings = theSettings; if (myWin != null) { CI = myWin.GetCulture(); } if(CI == null || myWin == null) { string CL = oursettings.ChosenLanguage; CI = CultureInfo.CreateSpecificCulture(CL); } return CI; } /// /// Find the global random number generator. /// /// A valid random number generator public static ResourceManager GetResource() { ResourceManager myresource = null; BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin != null) { myresource = myWin.GetResource(); } if(myresource == null || myWin == null) { System.Reflection.Assembly MyAssembly; MyAssembly = Assembly.GetCallingAssembly(); myresource = new ResourceManager("EduNetworkBuilder.Resources.languages.edustrings", MyAssembly); } return myresource; } public static NBSettings GetSettings() { //Try getting the user settings PersonClass User = GetUser(); if (User != null) return User.UserSettings; //If no user, get the settings for the program. BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin != null) { return myWin.OurSettings; } return new NBSettings(); //This is only in case we are blowing up. Try to avoid that. } /// /// Determine if we are using Mono or .Net. Some things get killed using Mono. /// /// True if we are using Mono public static bool IsRunningOnMono() { return Type.GetType("Mono.Runtime") != null; } public static void NoteLoopHappened() { Network myNet = GetNetwork(); if (myNet != null) myNet.HadLoop = true; } public static Point GetSnapped(Point Location) { int x = (Location.X / NB.GridSize) * NB.GridSize; int y = (Location.Y / NB.GridSize) * NB.GridSize; Point newlocation = new Point(x, y); return newlocation; } public static Network GetNetwork() { BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) return null; if (myWin.GameRandomGen == null) return null; return myWin.GetNetwork(); } public static void RegisterInvisibleNetwork(Network ToRegister) { BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) return; myWin.RegisterInvisibleNet(ToRegister); } public static void UnregisterInvisibleNetwork() { BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) return; myWin.UnregisterInvisibleNet(); } public static bool ProcessingInvisibleNetwork() { BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) return false; return myWin.ProcessingInvisibleNet(); } /// /// Make sure we update the visuals when we have the opportunity to do so /// public static void MarkToUpdate() { BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) return; myWin.NeedsUpdate = true; } public static int nextPacketID() { BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) return 1; //return something. return myWin.nextPacketID(); } public static BuilderWindow GetBuilderWin() { BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) return null; return myWin; } public static void SetBuilderWindowStatis(string text) { BuilderWindow myWin = GetBuilderWin(); if (myWin != null) myWin.ChangeStatusText(text); } public static PersonProfileForm GetProfileWin() { PersonProfileForm myWin = (PersonProfileForm)Application.OpenForms["PersonProfileForm"]; if (myWin == null) return null; return myWin; } public static PersonClass GetUser() { BuilderWindow BW = GetBuilderWin(); if (BW == null) return null; return BW.CurrentUser; } /// /// Return a translated string in the current chosen language /// /// The key for the item we are translating /// A string of the translated information public static string Translate(string key, NBSettings theSettings=null) { BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) { ResourceManager RM = GetResource(); CultureInfo CI = GetCulture(theSettings); string answer=""; answer = RM.GetString(key, CI); if (answer == null) return ""; return answer; } return myWin.Translate(key); } public static string GetHelpTopicKey(HelpTopics What) { return "H_" + What.ToString() + "_Key"; } public static string GetHelpTopicTitle(HelpTopics What) { return "H_" + What.ToString() + "_Title"; } public static DebugPausePoint GetDebugPauseSetting() { BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) return DebugPausePoint.none; if (myWin.GameRandomGen == null) return DebugPausePoint.none; return myWin.DebugSetting; } public static PuzzleInfo GetPuzzleInfoFromName(string PuzzleName) { BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) return null; return myWin.PuzzleInfoFromName(PuzzleName); } public static string LeftPad(string what, int amount=-1) { int UseAmount = 10; if (amount != -1) UseAmount = amount; string format = "{0," + (0 - UseAmount).ToString() + "}"; string mystring = string.Format(format, what); return mystring; } public static void ChangeLanguage(NBSettings theSettings=null) { //Find the window. If it exists, use /set the language setting there. If not, use / set the default. BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; NBSettings oursettings; if (theSettings == null) oursettings = NB.GetSettings(); else oursettings = theSettings; string lang = oursettings.ChosenLanguage; if (lang == "") lang = "en"; string StartingItem = ""; for (int i = 0; i < LanguageChoices.GetLength(0); i++) { if (lang == LanguageChoices[i, 1]) { StartingItem = LanguageChoices[i, 0]; } } //we need to choose a language: Form LanguageForm = new Form(); LanguageForm.Text = NB.Translate("NB_ChangeLang1"); Label lblText = new Label(); lblText.Location = new Point(5, 5); lblText.AutoSize = true; lblText.Text = NB.Translate("NB_ChangeLang2"); LanguageForm.Icon = Properties.Resources.NBIco; ComboBox cbQuestions = new ComboBox(); cbQuestions.Location = new Point(lblText.Location.X + lblText.Width + 10, lblText.Location.Y); cbQuestions.Width = 60; for (int i = 0; i < LanguageChoices.GetLength(0); i++ ) { cbQuestions.Items.Add(LanguageChoices[i,0]); } if(cbQuestions.Items.Contains(StartingItem)) { cbQuestions.SelectedItem = StartingItem; } else cbQuestions.SelectedIndex = 0; LanguageForm.Width = cbQuestions.Location.X + cbQuestions.Width + 70; LanguageForm.Height = 90; LanguageForm.AutoSize = true; Button btnAccept = new Button(); btnAccept.Location = new Point(cbQuestions.Location.X, cbQuestions.Location.Y + cbQuestions.Height + 10); btnAccept.Text = NB.Translate("_OK"); btnAccept.Click += (s, g) => { Button b = (Button)s; Form f = (Form)b.Parent; f.Close(); }; LanguageForm.Controls.Add(lblText); LanguageForm.Controls.Add(cbQuestions); LanguageForm.Controls.Add(btnAccept); LanguageForm.ShowDialog(); if (cbQuestions.SelectedIndex >= 0) { oursettings.LanguageHasBeenChosen = true; string mychoice = LanguageChoices[cbQuestions.SelectedIndex, 1]; if (myWin == null) { oursettings.ChosenLanguage = mychoice; //oursettings.Save(); //We do this when we exit. No need to save it right this instant. } else { myWin.ChosenLanguage = mychoice; } } } public static void PlaySound(NBSoundType What) { BuilderWindow BW = GetBuilderWin(); if (BW != null && BW.ProcessingInvisibleNet()) return; //Do not ding if we are doing invisible stuff SoundPlayer sndClick; switch (What) { case NBSoundType.none: break; case NBSoundType.success: sndClick = new SoundPlayer(Properties.Resources.wavBellDing); sndClick.Play(); break; case NBSoundType.saved_failed: sndClick = new SoundPlayer(Properties.Resources.noBeep); sndClick.Play(); break; case NBSoundType.saved_ok: sndClick = new SoundPlayer(Properties.Resources.click); sndClick.Play(); break; } } /// /// Serialize any serializable class to an XML string. /// /// The type of object /// The object to serialize /// A string containing the serialized object in XML public static string SerializeObject(T toSerialize) { XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType()); using (StringWriter textWriter = new StringWriter()) { xmlSerializer.Serialize(textWriter, toSerialize); return textWriter.ToString(); } } /// /// Deserialize (oposite of SerializeObject) an object from an xml string. /// /// The type of object to deserialize /// the xml string containing the object /// An object of the specified type public static T Deserialize(string toDeserialize) { XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); StringReader textReader = new StringReader(toDeserialize); return (T)xmlSerializer.Deserialize(textReader); } public static List GetPuzzleTags() { BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) return null; return myWin.GetPuzzleTags(); } public static bool PuzzleLevelHasUnsolved(string LevelName) { BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) return false; return myWin.PuzzleLevelHasUnsolved(LevelName); } public static List GetPuzzleNames() { BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) return null; return myWin.GetPuzzleNames(); } public static void LoadNetworkFromResource(string resource) { BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) return; myWin.LoadNetworkFromResource(resource); } public static void SetProgress(double HowFar, double total) { BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) return; myWin.SetProgress(HowFar, total); } public static void UpdateMessages() { BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"]; if (myWin == null) return; myWin.UpdateMessages(); } public static int GetUniqueIdentifier() { Network myNet = GetNetwork(); if(myNet == null) { //We should never get here. If so, we are in a bad sort of way. Random rnd = GetRandom(); return rnd.Next(1,100); } return myNet.GetUniqueIdentifier(); } public static void Delay(int amount) { System.Threading.Thread.Sleep(amount); } public static T ParseEnum(string value) { // Do not initialize this variable here. return (T)Enum.Parse(typeof(T), value, true); } public static T TryParseEnum(string value, T Default ) { if (!Enum.IsDefined(typeof(T), value)) return Default; return (T)Enum.Parse(typeof(T), value); } public static GeneralComponentType GetComponentType(NetworkComponent What) { GeneralComponentType theType = GeneralComponentType.none; if(What.GetType().ToString() == "EduNetworkBuilder.NetworkDevice") theType = GeneralComponentType.device; if (What.GetType().ToString() == "EduNetworkBuilder.NetworkLink") theType = GeneralComponentType.link; return theType; } public static void ReadContextHelp(HelpTopics What) { RTFWindow tForm = null; //make a new window if needed foreach(Form myfrm in Application.OpenForms) { if(myfrm.Name == NB.Translate("NB_RdCtxtHelp")) { //We have a context window tForm = (RTFWindow)myfrm; break; } } if(tForm == null) { //We do not have one yet. Make a new one tForm = new RTFWindow(RTFWindowContents.help); tForm.Name = NB.Translate("NB_RdCtxtHelp"); } //load help tForm.Show(); //Jump to the correct location if(tForm != null) { tForm.JumpToSelection(What); } } public static string GenerateMACAddress() { var sBuilder = new StringBuilder(); var random = GetRandom(); int number; byte b; for (int i = 0; i < 6; i++) { number = random.Next(0, 255); b = Convert.ToByte(number); if (i == 0) { b = setBit(b, 6); //--> set locally administered b = unsetBit(b, 7); // --> set unicast } sBuilder.Append(number.ToString("X2")); } string mac= sBuilder.ToString().ToUpper(); if (MAC_Exists(mac)) return GenerateMACAddress(); //If it already exists, generate another return mac; } public static string TextPromptBox(string Prompt, Icon theIcon=null, bool isPassword = false) { return TextPromptBox(Prompt, "", "", theIcon, isPassword); } public static string TextPromptBox(string Prompt, string Title, Icon theIcon = null, bool isPassword=false) { return TextPromptBox(Prompt, Title, "", theIcon, isPassword); } public static string TextPromptBox(string Prompt, string Title, string oldtext, Icon theIcon, bool isPassword) { //we need to choose a language: int yspace = 10; Form TextInputForm = new Form(); TextInputForm.Text = Title; Label lblText = new Label(); lblText.Location = new Point(5, 5); lblText.AutoSize = true; lblText.Text = Prompt; if(theIcon != null) TextInputForm.Icon = theIcon; if (oldtext == null) oldtext = ""; TextBox tbEvent = new TextBox(); tbEvent.Location = new Point(lblText.Location.X, lblText.Location.Y + lblText.Height + yspace); tbEvent.Width = 120; tbEvent.Text = oldtext;//Populate it with the old data if we can if (isPassword) tbEvent.PasswordChar = '*'; TextInputForm.Width = tbEvent.Location.X + tbEvent.Width + 30; TextInputForm.Height = 90; TextInputForm.AutoSize = true; Button btnAccept = new Button(); btnAccept.Location = new Point(tbEvent.Location.X, tbEvent.Location.Y + tbEvent.Height + yspace); btnAccept.Text = "OK"; btnAccept.Click += (s, g) => { Button b = (Button)s; Form f = (Form)b.Parent; f.Close(); }; Button btnCancel = new Button(); btnCancel.Location = new Point(btnAccept.Location.X + btnAccept.Width + 10, tbEvent.Location.Y + tbEvent.Height + 10); btnCancel.Text = "Cancel"; btnCancel.Click += (s, g) => { Button b = (Button)s; Form f = (Form)b.Parent; tbEvent.Text = ""; f.Close(); }; TextInputForm.Controls.Add(lblText); TextInputForm.Controls.Add(tbEvent); TextInputForm.Controls.Add(btnAccept); TextInputForm.Controls.Add(btnCancel); TextInputForm.AcceptButton = btnAccept; TextInputForm.CancelButton = btnCancel; TextInputForm.ShowDialog(); return tbEvent.Text; } public static Dictionary CheckPromptBox(Dictionary Checks) { return CheckPromptBox(Checks, "", null); } public static Dictionary CheckPromptBox(Dictionary Checks, string Title) { return CheckPromptBox(Checks, Title, null); } public static Dictionary CheckPromptBox(Dictionary Checks, string Title, Icon theIcon) { //we need to choose a language: Dictionary responses = new Dictionary(); int yspace = 10; Form CheckInputForm = new Form(); CheckInputForm.Text = Title; if (theIcon != null) CheckInputForm.Icon = theIcon; int startx = 20; int y = 0; int lastY = 0; int lastHeight = 0; foreach(KeyValuePair entry in Checks) { //Make a checkbox CheckBox cb = new CheckBox(); cb.Name = entry.Key; //Name it so we can know what it is. cb.Text = entry.Key; //Have it display the right value for a label cb.Checked = entry.Value; //Have it checked, or not, depending on the value we passed in //Put it in the appropriate location cb.Location = new Point(startx, (y * (cb.Height + yspace)) + yspace); cb.AutoSize = true; lastY = cb.Location.Y; lastHeight = cb.Height; CheckInputForm.Controls.Add(cb); y++; } CheckInputForm.AutoSize = true; Button btnAccept = new Button(); btnAccept.Location = new Point(startx, lastY + lastHeight + yspace); btnAccept.Text = "OK"; btnAccept.Click += (s, g) => { Button b = (Button)s; Form f = (Form)b.Parent; f.Close(); }; Button btnCancel = new Button(); btnCancel.Location = new Point(btnAccept.Location.X + btnAccept.Width + 10,btnAccept.Location.Y); btnCancel.Text = "Cancel"; btnCancel.Click += (s, g) => { Button b = (Button)s; Form f = (Form)b.Parent; responses = null; f.Close(); }; CheckInputForm.Controls.Add(btnAccept); CheckInputForm.Controls.Add(btnCancel); CheckInputForm.AcceptButton = btnAccept; CheckInputForm.CancelButton = btnCancel; CheckInputForm.Height = btnCancel.Location.Y + btnCancel.Height + 10; CheckInputForm.ShowDialog(); foreach (KeyValuePair entry in Checks) { if(responses != null && CheckInputForm.Controls[entry.Key] != null && CheckInputForm.Controls[entry.Key] is CheckBox) { CheckBox One = (CheckBox)CheckInputForm.Controls[entry.Key]; responses.Add(One.Name, One.Checked); } } return responses; } public static bool MAC_Exists(string MAC) { Network myNet = GetNetwork(); if(myNet == null) return false; return myNet.MAC_Exists(MAC); } public static List arp(UInt32 IP) { List arps = new List(); Network myNet = GetNetwork(); if (myNet == null) return arps; return myNet.arp(IP); } private static byte setBit(byte b, int BitNumber) { if (BitNumber < 8 && BitNumber > -1) { return (byte)(b | (byte)(0x01 << BitNumber)); } else { throw new InvalidOperationException( string.Format(NB.Translate("NB_BitError"), BitNumber.ToString())); } } private static byte unsetBit(byte b, int BitNumber) { if (BitNumber < 8 && BitNumber > -1) { return (byte)(b | (byte)(0x00 << BitNumber)); } else { throw new InvalidOperationException( string.Format(NB.Translate("NB_BitError"), BitNumber.ToString())); } } /// /// Randomize a list /// /// The type of list to return /// The list to randomize /// a new list that is randomized public static List Randomize(List list) { List randomizedList = new List(list); Random rnd = GetRandom(); int n = randomizedList.Count; int counter = 0; T value; while (n > 1) { n--; int k = rnd.Next(n + 1); value = randomizedList[k]; randomizedList[k] = randomizedList[n]; randomizedList[n] = value; counter++; if (counter > 10) { counter = 0; } } return randomizedList; } public static void AddNetMessage(string host, string message) { Network thenet = GetNetwork(); //Console.WriteLine("Adding message: " + host + " : " + message); if (thenet == null) return; //we cannot add it. do not blow up thenet.AddMessage(new PacketMessage(host, message)); } public static bool OpenURLInExternalBrowser(string URL) { Uri uriResult; bool result = Uri.TryCreate(URL, UriKind.Absolute, out uriResult) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps); if(result) { System.Diagnostics.Process.Start(URL); } return false; } public static List GetAllNodes(this TreeView _self) { List result = new List(); foreach (TreeNode child in _self.Nodes) { result.AddRange(child.GetAllNodes()); } return result; } public static List GetAllNodes(this TreeNode _self) { List result = new List(); result.Add(_self); foreach (TreeNode child in _self.Nodes) { result.AddRange(child.GetAllNodes()); } return result; } public static bool ValidateString(string tovalidate, string AllowedCharacters) { if (tovalidate == null || tovalidate == "") return false; if (AllowedCharacters == null || AllowedCharacters == "") return false; foreach (char one in tovalidate) if (!AllowedCharacters.Contains(one)) return false; return true; } public static bool ValidatePassword(string password) { return ValidateString(password, AllowedPasswordCharacters); } public static bool ValidateUsername(string password) { return ValidateString(password, AllowedUsernameCharacters); } public static bool ValidateFullName(string password) { return ValidateString(password, AllowedUsernameCharacters + " "); } public static OpenFileDialog SelectDirectoryDialog(string Title, string InitialDirectory="") { OpenFileDialog OFD = new OpenFileDialog(); OFD.Title = Title; if (InitialDirectory != "") OFD.InitialDirectory = InitialDirectory; OFD.ValidateNames = false; OFD.CheckFileExists = false; OFD.CheckPathExists = true; OFD.FileName = NB.Translate("PPF_SelectThisFolder"); DialogResult answer = OFD.ShowDialog(); if (answer == DialogResult.Cancel) OFD.FileName = ""; //This is how we cancel out return OFD; } /// /// Move a file out of the way, making a rotating backup at the same time. /// /// A source filename with a directory /// The directory where to put the file /// The number of rotation backups to make public static void MoveFileWithRotation(string SourceFileWithDir, string DestDir, int rotation) { if (!File.Exists(SourceFileWithDir)) return; //we do not rotate if the source does not exist if (!Directory.Exists(DestDir)) Directory.CreateDirectory(DestDir); //Rotate the old file first, then move the new one over. string dest_file = Path.Combine(DestDir, Path.GetFileName(SourceFileWithDir)); RotateFile(dest_file, rotation); File.Move(SourceFileWithDir, dest_file); } /// /// Move a file out of the way, making a rotating backup at the same time. backup to appdata /// /// A source filename with a directory /// The number of rotation backups to make public static void MoveFileWithRotation(string SourceFileWithDir, int rotation) { string StandardDest = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "EduNetworkBuilder"); MoveFileWithRotation(SourceFileWithDir, StandardDest, rotation); } /// /// Move a file out of the way, making a rotating backup at the same time. backup to appdata /// /// A source filename with a directory public static void MoveFileWithRotation(string SourceFileWithDir) { string StandardDest = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "EduNetworkBuilder"); MoveFileWithRotation(SourceFileWithDir, StandardDest, NB.NormalRotation); } /// /// Given a file, rotate it with the specified number of versions. /// /// /// public static void RotateFile(string filename, int count) { if (count < 1) return; string currentfile = GenFilenameWithInt(filename, count); string rotatefile; if (File.Exists(currentfile)) File.Delete(currentfile); //The last rotation gets deleted for(int i=count -1; i >= 1; i--) { currentfile = GenFilenameWithInt(filename, i); rotatefile = GenFilenameWithInt(filename, i + 1); if (File.Exists(currentfile)) File.Move(currentfile, rotatefile); } //The final case is when there is no version number on the file. currentfile = filename; rotatefile = GenFilenameWithInt(filename, 1); if (File.Exists(currentfile)) File.Move(currentfile, rotatefile); } private static string GenFilenameWithInt(string filename, int version) { string FileOnly = Path.GetFileNameWithoutExtension(filename); string FileWithInt = FileOnly + "-" + version.ToString("00") + Path.GetExtension(filename); string Combined = Path.Combine(Path.GetDirectoryName(filename), FileWithInt); return Combined; } public static Font GetFont() { PersonProfileForm PPF = GetProfileWin(); if (PPF != null) return PPF.GetFont(); return new Font(FontFamily.GenericSansSerif, 10.0F, FontStyle.Bold); } public static void NotImplimentedMessage() { MessageBox.Show(Translate("NB_NotImplimented")); } public static string CSVSafeString(string source) { string dest = source; char[] chars = { '\t', '\r', '\n', '\"', ',' }; if (dest.IndexOfAny(chars) >= 0) { dest = '\"' + dest.Replace("\"", "\"\"") + '\"'; //quotes around outside, replace " with "" } return dest; } /// /// return a list of ways to break a given technology /// /// /// public static List WaysToBreakATechnology(TraversalTechnology What) { switch(What) { case TraversalTechnology.ethernet: return new List() { HowToBreak.EthernetBreak, HowToBreak.EthernetCorrupt, HowToBreak.EthernetRemoveLink }; case TraversalTechnology.forward: return new List() { HowToBreak.PowerOff, HowToBreak.LockOutSwitch }; case TraversalTechnology.gateway: return new List() { HowToBreak.DeviceChangeGW }; case TraversalTechnology.firewall: return new List() { }; case TraversalTechnology.ip_address: return new List() { HowToBreak.DeviceChangeIP }; case TraversalTechnology.masquerade: return new List() { }; case TraversalTechnology.static_route: return new List() { HowToBreak.StaticRouteClear, HowToBreak.StaticRouteCorrupt }; case TraversalTechnology.vlan: return new List() { HowToBreak.VLANChange}; case TraversalTechnology.vpn: return new List() { HowToBreak.VPNChangeEndpoint, HowToBreak.VPNChangeKey }; case TraversalTechnology.vpn_decryption: return new List() { HowToBreak.VPNChangeKey }; case TraversalTechnology.vpn_encryption: return new List() { HowToBreak.VPNChangeKey }; case TraversalTechnology.wireless: return new List() { HowToBreak.WirelessBreakKey, HowToBreak.WirelessBreakSSID }; } return new List(); //An empty list } public static TraversalTechnology TechnologyNeededToBreak(HowToBreak How) { switch(How) { case HowToBreak.DeviceChangeGW: return TraversalTechnology.gateway; case HowToBreak.DeviceChangeIP: return TraversalTechnology.network_interface; case HowToBreak.EthernetBreak: case HowToBreak.EthernetCorrupt: case HowToBreak.EthernetRemoveLink: return TraversalTechnology.ethernet; case HowToBreak.LockOutSwitch: return TraversalTechnology.forward; //we can only lock ourselves out of switchs and hubs case HowToBreak.PowerOff: return TraversalTechnology.any; //Any will only return devices case HowToBreak.StaticRouteClear: case HowToBreak.StaticRouteCorrupt: return TraversalTechnology.static_route; case HowToBreak.VLANChange: return TraversalTechnology.vlan; case HowToBreak.VPNChangeEndpoint: return TraversalTechnology.vpn; case HowToBreak.VPNChangeKey: return TraversalTechnology.vpn; case HowToBreak.WirelessBreakKey: case HowToBreak.WirelessBreakSSID: return TraversalTechnology.wireless; case HowToBreak.BreakDevice: return TraversalTechnology.any; } return TraversalTechnology.none; } #region Generic XML Funcs public static T LoadObjectFromXmlFile(string XMLResourceToLoad) where T : new() { //Load in the sprite data XmlSerializer serializer = new XmlSerializer(typeof(T)); System.Reflection.Assembly thisExe; thisExe = System.Reflection.Assembly.GetExecutingAssembly(); // Creates the ResourceManager. System.Resources.ResourceManager myManager = Properties.Resources.ResourceManager; // Retrieves String and Image resources. object titem = myManager.GetObject(XMLResourceToLoad); byte[] item = (byte[])System.Text.Encoding.UTF8.GetBytes((string)titem); try { return (T)serializer.Deserialize(new MemoryStream(item)); } finally { } } /// /// Writes the given object instance to an XML file. /// Only Public properties and variables will be written to the file. These can be any type though, even other classes. /// If there are public properties/variables that you do not want written to the file, decorate them with the [XmlIgnore] attribute. /// Object type must have a parameterless constructor. /// /// The type of object being written to the file. /// The file path to write the object instance to. /// The object instance to write to the file. public static void WriteToXmlFile(string filePath, T objectToWrite) where T : new() { TextWriter writer = null; try { var serializer = new XmlSerializer(typeof(T)); writer = new StreamWriter(filePath); serializer.Serialize(writer, objectToWrite); } finally { if (writer != null) writer.Close(); } } /// /// Reads an object instance from an XML file. /// Object type must have a parameterless constructor. /// /// The type of object to read from the file. /// The file path to read the object instance from. /// Returns a new instance of the object read from the XML file. public static T ReadFromXmlFile(string filePath) where T : new() { TextReader reader = null; try { var serializer = new XmlSerializer(typeof(T)); reader = new StreamReader(filePath); return (T)serializer.Deserialize(reader); } finally { if (reader != null) reader.Close(); } } /// /// Reads an object instance from an XML resource. /// Object type must have a parameterless constructor. /// /// The type of object to read from the file. /// The name of the resource to use. /// Returns a new instance of the object read from the XML resource. public static T ReadFromXmlResource(string resource) where T : new() { System.Reflection.Assembly MyAssembly; BuilderWindow tWin = GetBuilderWin(); MyAssembly = tWin.GetType().Assembly; // Creates the ResourceManager. System.Resources.ResourceManager myManager = new System.Resources.ResourceManager("EduNetworkBuilder.Properties.Resources", MyAssembly); // Retrieves String and Image resources. //System.String myString; byte[] item = Encoding.UTF8.GetBytes((string)myManager.GetObject(resource)); // myString = new StreamReader(new MemoryStream(item), true).ReadToEnd(*/); //myString = System.Text.Encoding.Default.GetString(item); //TextReader reader = null; try { var serializer = new XmlSerializer(typeof(T)); return (T)serializer.Deserialize(new MemoryStream(item)); } catch(Exception e) { MessageBox.Show(e.ToString()); } return default(T); } #endregion #region ActionFunctions public static void RegisterAction(ActionClass What) { if (What == null) return; NBSettings mySettings = GetSettings(); if (mySettings == null) return; mySettings.RegisterActionDone(What); } public static void DoActionMoveDevice(int HostID, Point Location) { //Make an action for the location, register the action, and do the action ActionClass AC = new ActionClass(); AC.Action = NBAction.changelocation; AC.SourceID = HostID; AC.Location = Location; RegisterAction(AC); AC.DoAction(); } public static NetworkComponent DoActionAddDevice(NetworkComponentType WhatType, Point Location) { //Make an action for the location, register the action, and do the action ActionClass AC = new ActionClass(); AC.Action = NBAction.newdevice; AC.newItemType = WhatType; AC.Location = Location; RegisterAction(AC); AC.DoAction(); return AC.ChangedComponent; } public static void DoActionPingDevice(int HostID, NB_IPAddress Destination) { ActionClass AC = new ActionClass(); AC.Action = NBAction.ping; AC.SourceID = HostID; AC.Destination = new NB_IPAddress(Destination); RegisterAction(AC); AC.DoAction(); } public static void DoActionTracertDevice(int HostID, NB_IPAddress Destination) { ActionClass AC = new ActionClass(); AC.Action = NBAction.traceroute; AC.SourceID = HostID; AC.Destination = Destination; RegisterAction(AC); AC.DoAction(); } public static void DoActionDHCP(int HostID) { ActionClass AC = new ActionClass(); AC.Action = NBAction.dhcp; AC.SourceID = HostID; RegisterAction(AC); AC.DoAction(); } public static void DoActionArpDevice(int HostID, NB_IPAddress Destination) { ActionClass AC = new ActionClass(); AC.Action = NBAction.arp; AC.SourceID = HostID; AC.Destination = Destination; RegisterAction(AC); AC.DoAction(); } public static void DoActionClearArpDevice(int HostID) { ActionClass AC = new ActionClass(); AC.Action = NBAction.cleararp; AC.SourceID = HostID; RegisterAction(AC); AC.DoAction(); } public static void DoActionReplaceDevice(int HostID) { ActionClass AC = new ActionClass(); AC.Action = NBAction.replace; AC.SourceID = HostID; RegisterAction(AC); AC.DoAction(); } public static void DoActionResetDevice(int HostID) { ActionClass AC = new ActionClass(); AC.Action = NBAction.reset; AC.SourceID = HostID; RegisterAction(AC); AC.DoAction(); } public static void DoActionReplaceDeviceUPS(int HostID) { ActionClass AC = new ActionClass(); AC.Action = NBAction.replaceUPS; AC.SourceID = HostID; RegisterAction(AC); AC.DoAction(); } public static void DoActionPowerOff(int HostID) { ActionClass AC = new ActionClass(); AC.Action = NBAction.poweroff; AC.SourceID = HostID; RegisterAction(AC); AC.DoAction(); } public static void DoActionPowerOn(int HostID) { ActionClass AC = new ActionClass(); AC.Action = NBAction.poweron; AC.SourceID = HostID; RegisterAction(AC); AC.DoAction(); } public static void DoActionDeleteComponent(int HostID) { ActionClass AC = new ActionClass(); AC.Action = NBAction.deletecomponent; AC.SourceID = HostID; RegisterAction(AC); AC.DoAction(); } public static void DoActionChangeComponent(int HostID, NetworkComponent Changed) { ActionClass AC = new ActionClass(); AC.Action = NBAction.changecomponent; AC.SourceID = HostID; AC.ChangedComponent = NetworkComponent.Clone(Changed); RegisterAction(AC); AC.DoAction(); } /// /// Make an adjustment to a preexisting component /// /// public static void DoActionChangeComponent(NetworkComponent Changed) { DoActionChangeComponent(Changed.GetUniqueIdentifier, Changed); } #endregion ActionFunctions } }