EduNetworkBuilder/EduNetworkBuilder/NetTest.cs

580 lines
26 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Xml;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.IO;
namespace EduNetworkBuilder
{
[Serializable]
public class NetTest
{
public string sHost = "";
public string dHost = "";
public Color WrongColor = Color.Red;
public NetTestType TheTest = NetTestType.NeedsDefaultGW;
public bool TaskWasDone = false;
public int PacketNumber = -1;
public NetTest(string srcHost, string dstHost, NetTestType tTest)
{
sHost = srcHost;
dHost = dstHost;
TheTest = tTest;
SetInitialDoneState();
}
public NetTest(NetTest FromWhat)
{
sHost = FromWhat.sHost;
dHost = FromWhat.dHost;
TheTest = FromWhat.TheTest;
SetInitialDoneState();
}
public NetTest(XmlNode theNode)
{
foreach (XmlNode Individual in theNode.ChildNodes)
{
XmlNodeType myNodetype = Individual.NodeType;
if (myNodetype == XmlNodeType.Element)
{
switch (Individual.Name.ToLower())
{
case "sourcehost":
case "shost":
sHost = Individual.InnerText;
break;
case "desthost":
case "dhost":
dHost = Individual.InnerText;
break;
case "thetest":
TheTest = NB.ParseEnum<NetTestType>(Individual.InnerText);
break;
}
}
}
SetInitialDoneState();
}
public void SetInitialDoneState()
{
switch (TheTest)
{
case NetTestType.LockAll:
case NetTestType.LockDHCP:
case NetTestType.LockGateway:
case NetTestType.LockIP:
case NetTestType.LockNic:
case NetTestType.LockRoute:
case NetTestType.LockInterfaceVLAN:
case NetTestType.LockNicVLAN:
case NetTestType.LockVLANNames:
case NetTestType.LockVLANsOnHost:
TaskWasDone = true;
break;
}
}
public void Save(XmlWriter writer)
{
writer.WriteStartElement("nettest");
writer.WriteElementString("shost", sHost);
writer.WriteElementString("dhost", dHost);
writer.WriteElementString("thetest", TheTest.ToString());
writer.WriteEndElement();
}
public void UpdateValuesFromAnother(NetTest WhatFrom)
{
dHost = WhatFrom.dHost;
sHost = WhatFrom.sHost;
TheTest = WhatFrom.TheTest;
WrongColor = WhatFrom.WrongColor;
}
public bool Equals(NetTest CompareTo)
{
if (sHost != CompareTo.sHost) return false;
if (dHost != CompareTo.dHost) return false;
if (TheTest != CompareTo.TheTest) return false;
if (WrongColor != CompareTo.WrongColor) return false;
return true;
}
public bool Edit()
{
NetTestEditor nte = new NetTestEditor(this);
NetTest copy = new NetTest(this);
nte.ShowDialog();
if (copy.Equals(this)) return false;
return true;
}
private string TestDescription(NetTestVerbosity amount)
{
string toreturn = "";
switch(amount)
{
case NetTestVerbosity.basic:
if(TheTest != NetTestType.ReadContextHelp)
toreturn = NB.Translate("NT_TstDscriptProblem");
else
toreturn = NB.Translate("_ReadContext");
break;
case NetTestVerbosity.hints:
switch (TheTest)
{
case NetTestType.NeedsDefaultGW:
toreturn = NB.Translate("NT_TstDscriptGteway");
break;
// case NetTestType.NeedsPingToHost:
// toreturn = "Cannot ping";
// break;
case NetTestType.NeedsRouteToNet:
toreturn = NB.Translate("NT_TstDscriptRout");
break;
case NetTestType.NeedsLocalIPTo:
toreturn = NB.Translate("NT_TstDscriptIP");
break;
case NetTestType.NeedsLinkToDevice:
toreturn = NB.Translate("NT_TstDiscriptConnect");
break;
case NetTestType.SuccessfullyArps:
toreturn = NB.Translate("NT_TstDiscriptARP");
break;
case NetTestType.SuccessfullyDHCPs:
toreturn = NB.Translate("NT_TstDiscriptDHCPIP");
break;
case NetTestType.SuccessfullyTraceroutes:
toreturn = NB.Translate("NT_TstDiscriptTraceroute");
break;
case NetTestType.SuccessfullyPings:
case NetTestType.SuccessfullyPingsAgain:
toreturn = NB.Translate("NT_TstDiscriptPing");
break;
case NetTestType.HelpRequest:
toreturn = NB.Translate("NT_TstDiscriptHelp");
break;
case NetTestType.FailedPing:
toreturn = NB.Translate("NT_TstDiscriptPingHost");
break;
case NetTestType.DHCPServerEnabled:
toreturn = NB.Translate("NT_TstDiscriptDHCP");
break;
case NetTestType.LockAll:
toreturn = NB.Translate("NT_TstDiscriptLock");
break;
case NetTestType.LockDHCP:
toreturn = NB.Translate("NT_TstDiscriptLockDHCP");
break;
case NetTestType.LockIP:
toreturn = NB.Translate("NT_TstDiscriptLockIP");
break;
case NetTestType.LockNic:
toreturn = NB.Translate("NT_TstDiscriptLockNIC");
break;
case NetTestType.LockRoute:
toreturn = NB.Translate("NT_TstDiscriptLockRout");
break;
case NetTestType.LockGateway:
toreturn = NB.Translate("NT_TstDiscriptGteway");
break;
case NetTestType.LockVLANNames:
toreturn = NB.Translate("NT_TstDiscriptLockVLANNames");
break;
case NetTestType.LockVLANsOnHost:
toreturn = NB.Translate("NT_TstDiscriptLockVLAN");
break;
case NetTestType.LockNicVLAN:
toreturn = NB.Translate("NT_TstDiscriptLockNicVLAN");
break;
case NetTestType.LockInterfaceVLAN:
toreturn = NB.Translate("NT_TstDiscriptLockInterfaceVLAN");
break;
case NetTestType.NeedsTaggedVLAN:
toreturn = NB.Translate("NT_TstDiscriptNeedsTaggedVLAN");
break;
case NetTestType.NeedsUntaggedVLAN:
toreturn = NB.Translate("NT_TstDiscriptNeedsUntaggedVLAN");
break;
case NetTestType.NeedsForbiddenVLAN:
toreturn = NB.Translate("NT_TstDiscriptNeedsForbiddenVLAN");
break;
case NetTestType.ReadContextHelp:
toreturn = NB.Translate("_ReadContext");
break;
}
break;
case NetTestVerbosity.full:
switch (TheTest)
{
case NetTestType.NeedsDefaultGW:
toreturn = NB.Translate("NT_TstDiscriptGteway2");
break;
// case NetTestType.NeedsPingToHost:
// toreturn = "Cannot ping host:";
// break;
case NetTestType.NeedsRouteToNet:
toreturn = NB.Translate("NT_TstDiscriptRout2");
break;
case NetTestType.NeedsLocalIPTo:
toreturn = NB.Translate("NT_TstDiscriptIP2");
break;
case NetTestType.NeedsLinkToDevice:
toreturn = NB.Translate("NT_TstDiscriptLink");
break;
case NetTestType.SuccessfullyArps:
toreturn = NB.Translate("NT_TstDiscriptARP2");
break;
case NetTestType.SuccessfullyDHCPs:
toreturn = NB.Translate("NT_TstDiscriptDHCPIP2");
break;
case NetTestType.SuccessfullyTraceroutes:
toreturn = NB.Translate("NT_TstDiscriptTraceroute2");
break;
case NetTestType.SuccessfullyPings:
case NetTestType.SuccessfullyPingsAgain:
toreturn = NB.Translate("NT_TstDiscriptPing2");
break;
case NetTestType.HelpRequest:
toreturn = NB.Translate("NT_TstDiscriptHelp2");
break;
case NetTestType.FailedPing:
toreturn = NB.Translate("NT_TstDiscriptPingFail");
break;
case NetTestType.DHCPServerEnabled:
toreturn = NB.Translate("NT_TstDiscriptDHCP2");
break;
case NetTestType.LockAll:
toreturn = NB.Translate("NT_TstDiscriptLock") + ":";
break;
case NetTestType.LockDHCP:
toreturn = NB.Translate("NT_TstDiscriptLockDHCP") + ":";
break;
case NetTestType.LockIP:
toreturn = NB.Translate("NT_TstDiscriptLockIP") + ":";
break;
case NetTestType.LockNic:
toreturn = NB.Translate("NT_TstDiscriptLockNIC") + ":";
break;
case NetTestType.LockRoute:
toreturn = NB.Translate("NT_TstDiscriptLockRout") + ":";
break;
case NetTestType.LockGateway:
toreturn = NB.Translate("NT_TstDiscriptGteway") + ":";
break;
case NetTestType.LockVLANNames:
toreturn = NB.Translate("NT_TstDiscriptLockVLANNames") + ":";
break;
case NetTestType.LockVLANsOnHost:
toreturn = NB.Translate("NT_TstDiscriptLockVLAN") + ":";
break;
case NetTestType.LockNicVLAN:
toreturn = NB.Translate("NT_TstDiscriptLockNicVLAN") + ":";
break;
case NetTestType.LockInterfaceVLAN:
toreturn = NB.Translate("NT_TstDiscriptLockInterfaceVLAN") + ":";
break;
case NetTestType.NeedsTaggedVLAN:
toreturn = NB.Translate("NT_TstDiscriptNeedsTaggedVLAN") + ":";
break;
case NetTestType.NeedsUntaggedVLAN:
toreturn = NB.Translate("NT_TstDiscriptNeedsUntaggedVLAN") + ":";
break;
case NetTestType.NeedsForbiddenVLAN:
toreturn = NB.Translate("NT_TstDiscriptNeedsForbiddenVLAN") + ":";
break;
case NetTestType.ReadContextHelp:
toreturn = NB.Translate("_ReadContext");
break;
}
break;
case NetTestVerbosity.none:
toreturn = "";
break;
}
return toreturn;
}
public string GetDescription(NetTestVerbosity amount)
{
string toreturn = "";
if(TheTest == NetTestType.ReadContextHelp)
{
return TestDescription(amount) + " " + sHost;
}
switch(amount)
{
case NetTestVerbosity.basic:
toreturn = sHost + " " + TestDescription(amount);
break;
case NetTestVerbosity.hints:
toreturn = sHost + " " + TestDescription(amount);
break;
case NetTestVerbosity.full:
toreturn = sHost + " " + TestDescription(amount) + " " + dHost;
break;
case NetTestVerbosity.none:
toreturn = "";
break;
}
return toreturn;
}
public bool TestPiecesExist()
{
Network theNet = NB.GetNetwork();
NetworkDevice Source = theNet.GetDeviceFromName(sHost);
NetworkDevice Dest = theNet.GetDeviceFromName(dHost);
if (Source == null) return false;
if (TheTest == NetTestType.DHCPServerEnabled) return true; //dest does not matter
if (Dest == null) return false;
return true;
}
public bool ColorItemsIfNeeded(bool ChangeColor)
{
bool WasDone = TaskWasDone;
if(!TestComplete())
{
if(TheTest == NetTestType.ReadContextHelp && ChangeColor)
{
BuilderWindow myWin = NB.GetBuilderWin();
if(myWin != null)
{
Control ctl = myWin.GetControlNamed(sHost);
if (ctl == null) return false;
ctl.BackColor = WrongColor;
}
return true;
}
if (TheTest == NetTestType.HelpRequest && dHost == "?Button" && ChangeColor)
{
BuilderWindow myWin = NB.GetBuilderWin();
if (myWin != null)
{
Control ctl = myWin.GetControlNamed("btnHelp");
if (ctl == null) return false;
if(ctl.BackColor != WrongColor)
ctl.BackColor = WrongColor;
}
return true;
}
if (TheTest == NetTestType.HelpRequest && dHost == "ViewButton" && ChangeColor)
{
BuilderWindow myWin = NB.GetBuilderWin();
if (myWin != null)
{
Control ctl = myWin.GetControlNamed("cbViewTitles");
if (ctl == null) return false;
if (ctl.BackColor != WrongColor)
ctl.BackColor = WrongColor;
}
return true;
}
Network theNet = NB.GetNetwork();
NetworkDevice Source = theNet.GetDeviceFromName(sHost);
if(Source!= null)
{
if (ChangeColor)
{
Source.BackgroundColor = WrongColor;
Source.IsDirty = true; //Make sure we re-draw it
}
return true; //We have a test that is not completed
}
return true;
}
if(WasDone == false)
{
//We just solved it for the first time
TaskWasDone = true;
NB.PlaySound(NBSoundType.success);
NB.MarkToUpdate();
}
return false; //No need to color anything
}
public void SetDone(int PacketID = -1)
{
if(TaskWasDone == false)
{
if (TheTest == NetTestType.FailedPing || TheTest == NetTestType.SuccessfullyArps
|| TheTest == NetTestType.SuccessfullyDHCPs || TheTest == NetTestType.SuccessfullyPings
|| TheTest == NetTestType.SuccessfullyPingsAgain || TheTest == NetTestType.SuccessfullyTraceroutes)
PacketNumber = PacketID; //Track the packetID of the first packet to complete the task
NB.PlaySound(NBSoundType.success);
NB.MarkToUpdate();
}
TaskWasDone = true;
}
public string GetInterfaceFromVLANInterfaceRequirement()
{
Match result = Regex.Match(dHost, @"(?<interface>[A-z:0-9]+) - (?<id>\d+)");
if (result.Groups["interface"] != null) return result.Groups["interface"].Value;
return "";
}
public int GetIDFromVLANInterfaceRequirement()
{
int answer = -1;
Match result = Regex.Match(dHost, @"(?<interface>[A-z:0-9]+) - (?<id>\d+)");
if (result.Groups["id"] != null) int.TryParse( result.Groups["id"].Value, out answer);
return answer;
}
/// <summary>
/// See if the test has been solved
/// </summary>
/// <returns></returns>
public bool TestComplete(Network UseThisNet = null)
{
Network theNet = UseThisNet;
if(theNet == null) theNet= NB.GetNetwork();
NetworkDevice Source = theNet.GetDeviceFromName(sHost);
NetworkDevice Dest = theNet.GetDeviceFromName(dHost);
IPAddress gw;
IPAddress tAddr;
switch(TheTest)
{
case NetTestType.NeedsDefaultGW:
if (Source == null) return false; //Unable to do it. Do not count it against them.
if (Dest == null) return false; //Unable to do it. Do not count it against them.
gw = Source.GetGateway();
if(Dest.HasIPAddress(gw))
{
//It has the IP. Is it local to the source?
if(Source.LocalNic(gw) != null)
{
//The default gw is set to the IP of the dest
//The IP address chosen is "local" to the source host. So it should ping between them
return true;
}
}
return false; //Something is not set right.
case NetTestType.NeedsRouteToNet:
if (Source == null) return false; //Unable to do it. Do not count it against them.
tAddr = theNet.DNSLookup(Source,dHost);
if (tAddr == null || tAddr.GetIPString == NB.ZeroIPString)
tAddr = new IPAddress(dHost);
if (Source.HasRouteMatching(tAddr))
{
IPAddress route = Source.RouteMatching(tAddr);
if (Source.LocalNic(new IPAddress(route.GetGateway.ToIpString())) == null)
return false; //The gateway specified is not local to the device. We cannot get to it
return true;
}
return false; //if we get here, it has failed somehow
case NetTestType.NeedsLocalIPTo:
if (Source == null) return false; //Unable to do it. Do not count it against them.
if (Dest == null) return false; //Unable to do it. Do not count it against them.
tAddr = Source.LocalDeviceIP(Dest);
IPAddress dAddress = Dest.LocalDeviceIP(Source);
if (Dest.HasIPAddress(tAddr)) return false; //They gave the same address to the source that the dest has.
if (!theNet.HasUniqueIP(tAddr, Source)) return false; //Verify we have not given the IP to someone else
if (tAddr != null &&
tAddr.GetIPString != NB.ZeroIPString)
{
if(dAddress != null & dAddress.GetMask == tAddr.GetMask)
return true;
}
return false; //Something is not set right.
case NetTestType.NeedsLinkToDevice:
if (Source == null) return false; //Unable to do it. Do not count it against them.
if (Dest == null) return false; //Unable to do it. Do not count it against them.
if (Source.HasLinkTo(dHost)) return true;
return false; //Something is not set right.
case NetTestType.SuccessfullyArps:
case NetTestType.SuccessfullyDHCPs:
case NetTestType.SuccessfullyPings:
case NetTestType.SuccessfullyPingsAgain:
case NetTestType.SuccessfullyTraceroutes:
case NetTestType.HelpRequest:
case NetTestType.ReadContextHelp:
case NetTestType.FailedPing:
return TaskWasDone; //This variable will tell us if these tests have been done.
case NetTestType.DHCPServerEnabled:
if (Source == null) return false; //Unable to do it. Do not count it against them.
//dHost is either "true" or "false"
string srvr = Source.GetIsDHCPServer().ToString().ToLower();
string shouldbe = dHost.ToLower();
if (srvr == shouldbe)
return true;
break;
case NetTestType.NeedsForbiddenVLAN:
case NetTestType.NeedsTaggedVLAN:
case NetTestType.NeedsUntaggedVLAN:
if (Source == null) return false; //Unable to do it. Do not count it against them.
string ifname = GetInterfaceFromVLANInterfaceRequirement();
if (ifname == "") return false; //unable to do it.
string nicname = Regex.Replace(ifname, @":\w*","");
int id = GetIDFromVLANInterfaceRequirement();
//Find the nic
NetworkCard nic = Source.NicFromName(nicname);
if (nic == null) return false; //no matching nic
//find the interface
NetworkInterface nif = nic.InterfaceFromName(ifname);
if (nif == null) return false; //no matchint interface
//find the entry for the vlan
VLANInfo vi = nif.GetVLANInfo(id);
if (vi == null) return false; //No such vlan or something.
if (TheTest == NetTestType.NeedsForbiddenVLAN && vi.Tag == VLANTagType.Forbidden) return true;
if (TheTest == NetTestType.NeedsUntaggedVLAN && vi.Tag == VLANTagType.Untagged) return true;
if (TheTest == NetTestType.NeedsTaggedVLAN && vi.Tag == VLANTagType.Tagged) return true;
break;
case NetTestType.LockAll:
case NetTestType.LockDHCP:
case NetTestType.LockIP:
case NetTestType.LockNic:
case NetTestType.LockRoute:
case NetTestType.LockGateway:
case NetTestType.LockInterfaceVLAN:
case NetTestType.LockNicVLAN:
case NetTestType.LockVLANsOnHost:
case NetTestType.LockVLANNames:
return true; //Nothing to solve. We just lock it so it cannot be changed.
}
return false;
}
public static T Clone<T>(T source)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException(NB.Translate("NC_CloneSerialzable"), NB.Translate("_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);
}
}
}
}