EduNetworkBuilder/EduNetworkBuilder/NetworkDevice.cs

2889 lines
118 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Xml;
using System.Drawing.Imaging;
namespace EduNetworkBuilder
{
[Serializable]
public class NetworkDevice : NetworkComponent
{
protected List<NetworkCard> NICs = new List<NetworkCard>();
protected IPAddress DefaultGW = new IPAddress(NB.ZeroIPString, NB.ZeroIPString, IPAddressType.gw);
protected Image MyImage = null;
protected Point MyLocation;
protected int Size;
protected List<ArpEntry> ArpTable = new List<ArpEntry>();
protected NetworkComponentType myType = NetworkComponentType.none;
protected List<IPAddress> RouteTable = new List<IPAddress>();
protected List<IPAddress> DHCPRanges = new List<IPAddress>();
protected List<ArpEntry> DHCPLeases = new List<ArpEntry>();
protected List<IPConnectionEntry> IPConnections = new List<IPConnectionEntry>();
protected bool isDNSServer = false;
protected bool isDHCPServer = false;
public bool CanServeDHCP = false;
public bool CanUseDHCP = false;
public bool MustUseDHCP = false;
public bool CanAddNics = false;
public bool HasAdvFirewall = false;
public Color BackgroundColor = Color.Empty;
protected Color MorphColor = Color.Empty;
public List<FirewallRule> FirewallRules = new List<FirewallRule>();
public NetworkDevice(NetworkComponentType what, string tHostname, Point tLocation, NicType firstNic = NicType.eth)
{
hostname = tHostname;
MyLocation = tLocation;
myType = what;
SetImageFromType(what);
NetworkCard tnic = new NetworkCard(0,GetUniqueIdentifier,hostname,NicType.lo);
NICs.Add(tnic);
if (what == NetworkComponentType.net_switch || what == NetworkComponentType.net_hub)
{
if (firstNic != NicType.none)
{
tnic = new NetworkCard(0, GetUniqueIdentifier, hostname, NicType.management_interface);
NICs.Add(tnic);
}
for(int looper=1; looper < 8; looper++)
{
tnic = new NetworkCard(looper, GetUniqueIdentifier, hostname, NicType.port);
NICs.Add(tnic);
}
}
else
{
if (firstNic != NicType.none)
{
tnic = new NetworkCard(0, GetUniqueIdentifier, hostname);
NICs.Add(tnic);
}
if(what == NetworkComponentType.router)
{
tnic = new NetworkCard(1, GetUniqueIdentifier, hostname);
NICs.Add(tnic);
}
//**********Wireless***********
//Add a wireless network card to laptops, wireless bridge and wireless repeater
if (what == NetworkComponentType.laptop )
{
tnic = new NetworkCard(NICs.Count(), GetUniqueIdentifier, hostname,NicType.wlan); //Add a wireless nic
tnic.UsesDHCP = true;
NICs.Add(tnic);
}
if (what == NetworkComponentType.wbridge)
{
NICs.Clear();
tnic = new NetworkCard(0, GetUniqueIdentifier, hostname, NicType.lo);
NICs.Add(tnic);
//tnic = new NetworkCard(0, GetUniqueIdentifier, hostname, NicType.management_interface);
//NICs.Add(tnic); --we use the wlan port for this
tnic = new NetworkCard(NICs.Count(), GetUniqueIdentifier, hostname, NicType.wlan); //Add a wireless nic
NICs.Add(tnic);
//A bridge is a switch with a wireless link, add 4 ports
for (int a = 0; a < 4; a++)
{
tnic = new NetworkCard(NICs.Count(), GetUniqueIdentifier, hostname, NicType.port); //Add a wireless nic
NICs.Add(tnic);
}
}
if (what == NetworkComponentType.wap)
{
NICs.Clear();
tnic = new NetworkCard(0, GetUniqueIdentifier, hostname, NicType.lo);
NICs.Add(tnic);
//tnic = new NetworkCard(0, GetUniqueIdentifier, hostname, NicType.management_interface);
//NICs.Add(tnic); --we use the wlan port for this
tnic = new NetworkCard(NICs.Count(), GetUniqueIdentifier, hostname, NicType.eth); //Add a physical network card
NICs.Add(tnic);
//A bridge is a switch with an ethernet nic, add some wireless ports
for (int a = 0; a < 6; a++)
{
tnic = new NetworkCard(NICs.Count(), GetUniqueIdentifier, hostname, NicType.wport); //Add a wireless nic
NICs.Add(tnic);
}
}
if (what == NetworkComponentType.wrepeater)
{
NICs.Clear();
tnic = new NetworkCard(0, GetUniqueIdentifier, hostname, NicType.lo);
NICs.Add(tnic);
//tnic = new NetworkCard(0, GetUniqueIdentifier, hostname, NicType.management_interface);
//NICs.Add(tnic); --we use the wlan interface
tnic = new NetworkCard(NICs.Count(), GetUniqueIdentifier, hostname, NicType.wlan); //Add a wireless nic
NICs.Add(tnic);
tnic = new NetworkCard(NICs.Count(), GetUniqueIdentifier, hostname, NicType.wport); //Add a wireless port
NICs.Add(tnic);
}
if (what == NetworkComponentType.wrouter)
{
NICs.Clear();
tnic = new NetworkCard(0, GetUniqueIdentifier, hostname, NicType.lo);
NICs.Add(tnic);
tnic = new NetworkCard(0, GetUniqueIdentifier, hostname, NicType.management_interface);
NICs.Add(tnic);
//A wireless router has multiple ports
for (int a = 0; a < 4; a++)
{
tnic = new NetworkCard(NICs.Count(), GetUniqueIdentifier, hostname, NicType.port); //Add a switched port
NICs.Add(tnic);
}
for (int a = 0; a < 8; a++)
{
tnic = new NetworkCard(NICs.Count(), GetUniqueIdentifier, hostname, NicType.wport); //Add a wireless port
NICs.Add(tnic);
}
//Add one vpn port
tnic = new NetworkCard(0, GetUniqueIdentifier, hostname, NicType.vpn);
NICs.Insert(1, tnic); //Make this first in the list - becomes second
//Add one wan port
tnic = new NetworkCard(0, GetUniqueIdentifier, hostname, NicType.wan);
NICs.Insert(1, tnic); //Make this first in the list
}
if (what == NetworkComponentType.firewall)
{
//Have two lan ports
tnic = new NetworkCard(1, GetUniqueIdentifier, hostname, NicType.eth);
NICs.Add(tnic);
//Add one wan port
tnic = new NetworkCard(0, GetUniqueIdentifier, hostname, NicType.wan);
NICs.Insert(1,tnic); //Make this first in the list
}
if (what == NetworkComponentType.cellphone || what == NetworkComponentType.tablet)
{
NICs.Clear();
tnic = new NetworkCard(0, GetUniqueIdentifier, hostname, NicType.lo);
NICs.Add(tnic);
tnic = new NetworkCard(0, GetUniqueIdentifier, hostname, NicType.wlan);
tnic.UsesDHCP = true;
NICs.Add(tnic);
}
}
ApplyRulesToDevice();
}
public int CountNics(NicType TheType)
{
int count = 0;
foreach(NetworkCard nic in NICs)
{
if(nic.GetNicType == TheType)
{
count++;
}
}
return count;
}
public void AddNic(NicType TheType = NicType.eth)
{
NetworkCard tnic;
int count = CountNics(TheType);
tnic = new NetworkCard(count, GetUniqueIdentifier, hostname, TheType);
NICs.Add(tnic);
ApplyRulesToDevice();
}
private void ApplyRulesToDevice()
{
if (myType == NetworkComponentType.server || myType == NetworkComponentType.firewall)
{
CanServeDHCP = true;
CanUseDHCP = false;
MustUseDHCP = false;
CanAddNics = true;
setNicsCanUseDHCP(false);
}
if (myType == NetworkComponentType.router)
{
CanServeDHCP = false;
CanUseDHCP = false;
MustUseDHCP = false;
CanAddNics = true;
setNicsCanUseDHCP(false);
}
if (myType == NetworkComponentType.pc || myType == NetworkComponentType.laptop ||
myType == NetworkComponentType.copier || myType == NetworkComponentType.printer ||
myType == NetworkComponentType.tablet || myType == NetworkComponentType.cellphone)
{
CanServeDHCP = false;
CanUseDHCP = true;
MustUseDHCP = false;
CanAddNics = true;
setNicsCanUseDHCP(true);
}
if (myType == NetworkComponentType.net_switch || myType == NetworkComponentType.net_hub ||
myType == NetworkComponentType.wap || myType == NetworkComponentType.wbridge ||
myType == NetworkComponentType.wrepeater)
{
CanServeDHCP = false;
CanUseDHCP = true;
MustUseDHCP = false;
CanAddNics = false;
setNicsCanUseDHCP(true);
}
if (myType == NetworkComponentType.ip_phone)
{
CanServeDHCP = false;
CanUseDHCP = true;
MustUseDHCP = true;
CanAddNics = false;
setNicsCanUseDHCP(true);
}
if (myType == NetworkComponentType.wrouter)
{
CanServeDHCP = true;
CanUseDHCP = true;
MustUseDHCP = false;
CanAddNics = false;
setNicsCanUseDHCP(true);
}
}
private void setNicsCanUseDHCP(bool CanUse)
{
foreach(NetworkCard nic in NICs)
{
//if the device must use DHCP. we set it here.
if (MustUseDHCP && nic.CanUseDHCP)
{
nic.UsesDHCP = true;
nic.MustUseDHCP = true;
}
else
{
//we can only turn it off.
nic.CanUseDHCP = CanUse && nic.CanUseDHCP;
nic.MustUseDHCP = false;
}
}
}
public NetworkDevice(XmlNode theNode)
{
IsDirty = true;
Load(theNode);
SetImageFromType(myType);
}
public override void Destroy()
{
Network myNet = NB.GetNetwork();
NetworkLink nl;
if (myNet != null)
{
foreach(NetworkCard nic in NICs)
{
if(nic.ConnectedLink != -1)
{
nl = myNet.GetLinkFromID(nic.ConnectedLink);
if(nl != null)
{
myNet.RemoveComponent(nl);
nl.Destroy();
}
nic.ConnectedLink = -1;
}
}
}
}
public void EditGateway()
{
DefaultGW.Edit(this,NB.Translate("ND_EdtGteway"));
}
public IPAddress GetGateway()
{
if(CanUseDHCP)
{
foreach(NetworkCard nic in NICs)
{
if(nic.UsesDHCP)
{
List<IPAddress> tlist = nic.IPAddressList();
if(tlist.Count > 0)
{
IPAddress newIP = new IPAddress(tlist[0].GetGateway.ToIpString());
return newIP;
}
}
}
}
return DefaultGW;
}
public NetworkComponentType GetNetType()
{
return myType;
}
public override void Load(XmlNode theNode)
{
NetworkCard newNic;
foreach (XmlNode Individual in theNode.ChildNodes)
{
XmlNodeType myNodetype = Individual.NodeType;
if (myNodetype == XmlNodeType.Element)
{
switch(Individual.Name.ToLower())
{
case "location":
string[] pointstr = Individual.InnerText.Split(',');
int x, y;
int.TryParse(pointstr[0], out x);
int.TryParse(pointstr[1], out y);
MyLocation = new Point(x, y);
break;
case "size":
int.TryParse(Individual.InnerText, out Size);
break;
case "uniqueidentifier":
int.TryParse(Individual.InnerText, out UniqueIdentifier);
break;
case "gateway":
DefaultGW = new IPAddress(Individual);
break;
case "hostname":
hostname = Individual.InnerText;
break;
case "mytype":
myType = NB.ParseEnum<NetworkComponentType>(Individual.InnerText);
break;
case "nic":
newNic = new NetworkCard(Individual);
NICs.Add(newNic);
break;
case "route":
IPAddress ip = new IPAddress(Individual);
RouteTable.Add(ip);
break;
case "isdns":
bool.TryParse(Individual.InnerText, out isDNSServer);
break;
case "isdhcp":
bool.TryParse(Individual.InnerText, out isDHCPServer);
break;
case "dhcprange":
IPAddress dhcpip = new IPAddress(Individual);
DHCPRanges.Add(dhcpip);
break;
case "hasadvfirewall":
bool.TryParse(Individual.InnerText, out HasAdvFirewall);
break;
case "firwallrule":
FirewallRule fwr = new FirewallRule(Individual);
FirewallRules.Add(fwr);
break;
case "morphcolor":
MorphColor = Color.FromName(Individual.InnerText);
break;
}
}
}
ApplyRulesToDevice();
}
public override void Save(XmlWriter writer)
{
writer.WriteStartElement("device");
writer.WriteElementString("hostname", hostname);
writer.WriteElementString("size", Size.ToString());
writer.WriteElementString("uniqueidentifier", UniqueIdentifier.ToString());
writer.WriteElementString("location", MyLocation.X.ToString() + "," + MyLocation.Y.ToString());
writer.WriteElementString("mytype", myType.ToString());
writer.WriteElementString("isdns", isDNSServer.ToString());
writer.WriteElementString("isdhcp", isDHCPServer.ToString());
if(HasAdvFirewall)
writer.WriteElementString("hasadvfirewall", HasAdvFirewall.ToString());
if (MorphColor != Color.Empty)
writer.WriteElementString("morphcolor", MorphColor.Name);
DefaultGW.Save(writer, "gateway");
foreach (NetworkCard nic in NICs)
{
nic.Save(writer);
}
foreach (IPAddress ip in RouteTable)
{
ip.Save(writer, "route");
}
foreach (IPAddress dhcp in DHCPRanges)
{
dhcp.Save(writer, "dhcprange");
}
if (HasAdvFirewall)
{
foreach (FirewallRule fwr in FirewallRules)
{
fwr.Save(writer, "firwallrule");
}
}
writer.WriteEndElement();
}
public void SetDNSServer(bool isDNS)
{
isDNSServer = isDNS;
}
public bool GetIsDNSServer()
{
return isDNSServer;
}
public void SetAdvFirewall(bool AdvFirewall)
{
HasAdvFirewall = AdvFirewall;
}
public void SetDHCPServer(bool isDHCP)
{
isDHCPServer = isDHCP;
}
public bool GetIsDHCPServer()
{
return isDHCPServer;
}
public string TooltipString()
{
string answer = hostname;
//Add IP Addresses that are assigned
if (myType == NetworkComponentType.fluorescent)
return NB.Translate("ND_FluorescentTooltip");
if (myType == NetworkComponentType.microwave)
return NB.Translate("ND_MicrowaveTooltip");
foreach (NetworkCard nic in NICs)
{
if (nic.GetNicType == NicType.wport || nic.GetNicType == NicType.port)
continue;
foreach(string addr in nic.IPAddresses())
{
answer += "\n" + addr;
}
}
if(BackgroundColor != Color.Empty)
{
//There is something wrong with it?
Network myNet = NB.GetNetwork();
List<string> DeviceMessages = myNet.GetTestMessages(hostname);
foreach (string tString in DeviceMessages)
{
answer += "\n" + tString;
}
}
return answer;
}
public List<string> ListOfConnectedHosts()
{
List<string> thelist = new List<string>();
foreach(NetworkCard nic in NICs)
{
if(nic.ConnectedLink != -1)
{
Network myNet = NB.GetNetwork();
NetworkLink Link = myNet.GetLinkFromID(nic.ConnectedLink);
if(Link != null)
{
NetworkDevice tmp = myNet.GetDeviceFromID(Link.Src);
if (tmp == null) continue;
if (tmp.hostname != hostname) thelist.Add(tmp.hostname);
tmp = myNet.GetDeviceFromID(Link.Dst);
if (tmp.hostname != hostname) thelist.Add(tmp.hostname);
}
}
}
return thelist;
}
public void RemoveLinkTo(string host)
{
Network myNet = NB.GetNetwork();
NetworkLink Link;
NetworkDevice item;
foreach (NetworkCard nic in NICs)
{
if (nic.ConnectedLink != -1)
{
Link = myNet.GetLinkFromID(nic.ConnectedLink);
if (Link != null)
{
item = myNet.GetDeviceFromID(Link.Dst);
if (item.hostname == host)
{
myNet.RemoveComponent(Link);
return;
}
item = myNet.GetDeviceFromID(Link.Src);
if (item.hostname == host)
{
myNet.RemoveComponent(Link);
return;
}
}
}
}
}
/// <summary>
/// Check to see if the device has a link to the specified host
/// </summary>
/// <param name="host"></param>
public bool HasLinkTo(string host)
{
Network myNet = NB.GetNetwork();
NetworkLink Link;
NetworkDevice item;
foreach (NetworkCard nic in NICs)
{
if (nic.ConnectedLink != -1)
{
Link = myNet.GetLinkFromID(nic.ConnectedLink);
if (Link != null)
{
if (Link.theLinkType == LinkType.broken) return false; //A broken link does not work
item = myNet.GetDeviceFromID(Link.Dst);
if (item.hostname == host)
{
return true;
}
item = myNet.GetDeviceFromID(Link.Src);
if (item.hostname == host)
{
return true;
}
}
}
}
return false;
}
private void SetImageFromType(NetworkComponentType what)
{
switch (what)
{
case NetworkComponentType.laptop:
MyImage = Properties.Resources.Laptop;
break;
case NetworkComponentType.pc:
MyImage = Properties.Resources.PC;
break;
case NetworkComponentType.server:
MyImage = Properties.Resources.Server;
break;
case NetworkComponentType.net_hub:
MyImage = Properties.Resources.Hub;
break;
case NetworkComponentType.net_switch:
MyImage = Properties.Resources.Switch;
break;
case NetworkComponentType.wap:
MyImage = Properties.Resources.wap;
break;
case NetworkComponentType.wrepeater:
MyImage = Properties.Resources.WRepeater;
break;
case NetworkComponentType.wbridge:
MyImage = Properties.Resources.WBridge;
break;
case NetworkComponentType.wrouter:
MyImage = Properties.Resources.WRouter;
break;
case NetworkComponentType.router:
MyImage = Properties.Resources.Router;
break;
case NetworkComponentType.ip_phone:
MyImage = Properties.Resources.ip_phone;
break;
case NetworkComponentType.firewall:
MyImage = Properties.Resources.firewall;
break;
case NetworkComponentType.printer:
MyImage = Properties.Resources.Printer;
break;
case NetworkComponentType.copier:
MyImage = Properties.Resources.Copier;
break;
case NetworkComponentType.fluorescent:
MyImage = Properties.Resources.fluorescent;
break;
case NetworkComponentType.microwave:
MyImage = Properties.Resources.microwave;
break;
case NetworkComponentType.cellphone:
MyImage = Properties.Resources.cellphone;
break;
case NetworkComponentType.tablet:
MyImage = Properties.Resources.tablet;
break;
}
}
//This function heavily borrowed from: http://stackoverflow.com/questions/1563038/fast-work-with-bitmaps-in-c-sharp
public Image ColoredImage(Image BaseImage)
{
Bitmap b = new Bitmap(BaseImage);
BitmapData bData = b.LockBits(new Rectangle(0, 0, BaseImage.Width, BaseImage.Height), ImageLockMode.ReadWrite, b.PixelFormat);
/* GetBitsPerPixel just does a switch on the PixelFormat and returns the number */
int bitsPerPixel = Image.GetPixelFormatSize(bData.PixelFormat);
/*the size of the image in bytes */
int size = bData.Stride * bData.Height;
/*Allocate buffer for image*/
byte[] data = new byte[size];
/*This overload copies data of /size/ into /data/ from location specified (/Scan0/)*/
System.Runtime.InteropServices.Marshal.Copy(bData.Scan0, data, 0, size);
for (int i = 0; i < size; i += bitsPerPixel / 8)
{
//double magnitude = 1 / 3d * (data[i] + data[i + 1] + data[i + 2]);
//data[i] is the first of 3 bytes of color
data[i] = (byte)((data[i] + MorphColor.B) /2);
data[i+1] = (byte)((data[i+1] + MorphColor.G) / 2);
data[i+2] = (byte)((data[i+2] + MorphColor.R) / 2);
}
/* This override copies the data back into the location specified */
System.Runtime.InteropServices.Marshal.Copy(data, 0, bData.Scan0, data.Length);
b.UnlockBits(bData);
return b;
}
public bool AtLocation(Point location)
{
if (location.X >= MyLocation.X && location.X <= MyLocation.X + Size &&
location.Y >= MyLocation.Y && location.Y <= MyLocation.Y + Size)
return true;
return false;
}
public Point myLocation()
{
return MyLocation;
}
/// <summary>
/// returns the centerpoint of the device
/// </summary>
/// <returns>a point that is the center of the device</returns>
public Point GetCenter()
{
int delta = Size / 2;
return new Point(MyLocation.X + delta, MyLocation.Y + delta);
}
public void ChangeLocation(Point Location)
{
MyLocation = NB.GetSnapped(Location);
IsDirty = true;
}
public void SetSize(int tSize)
{
if (Size != tSize)
IsDirty = true;
Size = tSize;
}
public void AddNicInterface(int NicIndex)
{
if (NicIndex >= 0 && NicIndex < NICs.Count())
{
NICs[NicIndex].AddInterface();
}
}
public void EditNicInterface(int NicIndex, int ifIndex)
{
if(NicIndex >=0 && NicIndex < NICs.Count())
{
NICs[NicIndex].EditInterface(ifIndex);
}
}
public void DeleteNicInterface(int NicIndex, int ifIndex)
{
if (NicIndex >= 0 && NicIndex < NICs.Count())
{
NICs[NicIndex].DeleteInterface(ifIndex);
}
}
public void EditNicInterface(string NicName, int ifIndex)
{
NetworkCard nic = NicFromName(NicName);
if (nic != null)
{
nic.EditInterface(ifIndex);
}
}
/// <summary>
/// Duplicate the ssid and key to all NICs of identical type on this device
/// </summary>
/// <param name="SSID">The ssid to set everything to</param>
/// <param name="Key">the Key to set everything to</param>
/// <param name="NType">the type of nic (must be a wireless type)</param>
private void duplicateSSIDnKey(string SSID, string Key, NicType NType)
{
if (NType != NicType.wport && NType != NicType.wlan) return; // Not a wireless port. Do nothing.
foreach(NetworkCard NC in NICs)
{
if(NC.GetNicType == NType)
{
NC.SSID = SSID;
NC.WirelessKey = Key;
}
}
}
public void EditNic(int index)
{
if (index < 0) return;
if (index > NICs.Count) return;
NICs[index].Edit();
//If the nic was a wireless, make sure we copy the ssid and key to all other of identical type
if (NICs[index].GetNicType == NicType.wport || NICs[index].GetNicType == NicType.wlan)
{
duplicateSSIDnKey(NICs[index].SSID, NICs[index].WirelessKey, NICs[index].GetNicType);
}
}
public void DeleteNic(int index)
{
if (index < 0) return;
if (index > NICs.Count) return;
if (NICs[index].GetNicType == NicType.lo) return;
if (NICs[index].GetNicType == NicType.management_interface) return;
if (NICs[index].GetNicType == NicType.none) return;
Network theNet = NB.GetNetwork();
if(!theNet.ItemIsLocked(hostname,NICs[index].NicName(),NetTestType.LockNic))
{
if (theNet != null) theNet.RemoveLinksToNic(NICs[index].myID);
NICs.RemoveAt(index);
}
else
{
MessageBox.Show(string.Format(NB.Translate("ND_DelNicNicLockStr"), NICs[index].NicName()), NB.Translate("ND_DelNicNicLock"));
}
}
public bool AutoJoinWireless()
{
bool didsomething = false;
bool tryit = false;
Network myNet = NB.GetNetwork();
foreach(NetworkCard nic in NICs)
{
tryit = false;
if (nic.GetNicType != NicType.wlan) continue;
if (nic.SSID == "") continue;
if (!nic.isConnected(false))
tryit = true;
if(!tryit)
{
//Check distance
NetworkComponent nc = myNet.GetComponentFromID(nic.ConnectedLink);
if(nc != null)
{
NetworkLink nl = (NetworkLink)nc;
double distance = nl.LinkDistance();
if (distance > NB.WirelessReconnectDistance)
tryit = true;
}
}
//Tryit tells us if we should try to reconnect.
if (tryit)
{
if(nic.isConnected(false))
{
//remove old connection
NetworkLink oNL = myNet.GetLinkFromID(nic.ConnectedLink);
if(oNL != null)
{
myNet.RemoveComponent(oNL);
oNL.Destroy();
}
}
//We want to find the closest device with an open wport that matches ssid/key and connect to it.
NetworkCard Closest = myNet.BestWirelessLinkForDevice(nic);
if(Closest != null)
{
NetworkLink newLink = new NetworkLink(nic.myID, Closest.myID, LinkType.wireless);
nic.ConnectedLink = newLink.GetUniqueIdentifier;
Closest.ConnectedLink = newLink.GetUniqueIdentifier;
myNet.AddItem(newLink);
didsomething = true;
}
}
}
return didsomething;
}
public NetworkCard HasWPortSSIDKey(string SSID, string Key)
{
if (SSID == null) return null;
if (Key == null) return null;
foreach(NetworkCard nic in NICs)
{
if(nic.GetNicType == NicType.wport && !nic.isConnected(false))
{
if (nic.SSID == SSID && nic.EncryptionKey == Key)
return nic;
}
}
return null;
}
public List<string> NetworkCardStrings(bool OnlyUnused=true, bool OnlyLinkable=false, NicType fromNic = NicType.none)
{
List<string> macStrings = new List<string>();
int counter = 0;
bool CanUse = true;
if (myType == NetworkComponentType.microwave || myType == NetworkComponentType.fluorescent)
return macStrings;
foreach (NetworkCard nic in NICs)
{
if (OnlyUnused)
CanUse = nic.ConnectedLink == -1; //if it is not linked to anything
if (OnlyLinkable && nic.GetNicType == NicType.vpn) CanUse = false;
if (OnlyLinkable && nic.GetNicType == NicType.tun) CanUse = false;
if (fromNic != NicType.none &&
fromNic == NicType.wlan && nic.GetNicType != NicType.wport) CanUse = false;
if (fromNic != NicType.none &&
fromNic == NicType.wport && nic.GetNicType != NicType.wlan) CanUse = false;
if (nic.GetNicType != NicType.lo && (nic.GetNicType != NicType.management_interface || OnlyUnused == false))
{
if(CanUse)
macStrings.Add(nic.NicString(counter++));
}
}
return macStrings;
}
public List<string> NetworkCardInterfaceStrings(int index)
{
List<string> myList = new List<string>();
if (myType == NetworkComponentType.microwave || myType == NetworkComponentType.fluorescent)
return myList;
if (index >= 0 && index < NICs.Count)
{
myList.AddRange(NICs[index].IPAddresses());
}
return myList;
}
public List<string> NetworkCardInterfaceStrings(string NicName)
{
List<string> myList = new List<string>();
NetworkCard nic = NicFromName(NicName);
if(nic != null)
{
myList.AddRange(nic.IPAddresses());
}
return myList;
}
public NetworkCard NicFromID(int ID)
{
foreach (NetworkCard nic in NICs)
{
if (nic.GetUniqueIdentifier == ID)
return nic;
}
return null;
}
public NetworkCard NicFromID(HostNicID ID)
{
return NicFromID(ID.NicID);
}
public NetworkCard NicFromName(string name)
{
string tstr = name;
tstr = Regex.Replace(name, " .*", "");
foreach (NetworkCard nic in NICs)
{
if (nic.NicName() == tstr)
return nic;
}
return null;
}
/// <summary>
/// returns true if it has a connection to something.
/// </summary>
/// <returns></returns>
public bool isConnected()
{
return false;
}
private void ValidateSize()
{
if (Size > 200) Size = 200;
if (Size < 10) Size = 10;
DateTime Test = DateTime.UtcNow + TimeSpan.FromMilliseconds(100);
}
public void CenterString(Image BaseImage, int x, int y, string ToPrint, Color ToDraw)
{
string measureString = ToPrint;
Font stringFont = new Font("Consolas", 17);
Color othercolor = Color.White;
if (ToDraw == Color.White)
othercolor = Color.Black;
// Measure string.
SizeF stringSize = new SizeF();
Graphics myGraphics = Graphics.FromImage(BaseImage);
stringSize = myGraphics.MeasureString(measureString, stringFont);
Brush myBrush = new SolidBrush(ToDraw);
Brush otherBrush = new SolidBrush(othercolor);
// Draw string to screen.
myGraphics.DrawString(measureString, stringFont, otherBrush, new PointF(x - (stringSize.Width / 2) +1, y +1));
myGraphics.DrawString(measureString, stringFont, myBrush, new PointF(x - (stringSize.Width / 2), y));
}
public override void Print(Image BaseImage, bool DrawTitle)
{
ValidateSize();
if (MyImage == null) return; //nothing to print
if (BaseImage == null) return; //nothing to print on
if (MyLocation.X < 0 || MyLocation.X > BaseImage.Width) return;
if (MyLocation.Y < 0 || MyLocation.Y > BaseImage.Height) return;
Rectangle Location = new Rectangle(MyLocation.X, MyLocation.Y, Size, Size);
if(BackgroundColor != Color.Empty)
{
Brush brush = new SolidBrush(Color.FromArgb(128, BackgroundColor.R, BackgroundColor.G, BackgroundColor.B));
Graphics.FromImage(BaseImage).FillRectangle(brush, Location);
Network myNet = NB.GetNetwork();
myNet.Invalidate(Location);
}
if(MorphColor == Color.Empty)
Graphics.FromImage(BaseImage).DrawImage(MyImage, MyLocation.X, MyLocation.Y, Size, Size);
else
{
//ColorMap colorMap = new ColorMap();
//int width = MyImage.Width;
//int height = MyImage.Height;
//colorMap.OldColor = Color.FromArgb(33,39,63); // opaque red
//colorMap.NewColor = MorphColor; // opaque blue
//ColorMap[] remapTable = { colorMap };
//ImageAttributes imageAttributes = new ImageAttributes();
//imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);
//using (Graphics G = Graphics.FromImage(BaseImage))
//{
// G.DrawImage(
// MyImage,
// new Rectangle(MyLocation.X, MyLocation.Y, Size, Size), // destination rectangle
// 0, 0, // upper-left corner of source rectangle
// width, // width of source rectangle
// height, // height of source rectangle
// GraphicsUnit.Pixel,
// imageAttributes);
//}
//---------------------------
//Color color = MorphColor; //Your desired colour
//Bitmap bmp = new Bitmap(MyImage);
//for (int x = 0; x < bmp.Width; x++)
//{
// for (int y = 0; y < bmp.Height; y++)
// {
// int a = 0;
// int r = 0;
// int g = 0;
// int b = 0;
// Color gotColor = bmp.GetPixel(x, y);
// a = gotColor.A;
// r = (gotColor.R + color.R) / 2;
// g = (gotColor.G + color.G) / 2;
// b = (gotColor.B + color.B) / 2;
// gotColor = Color.FromArgb(a, r, g, b);
// bmp.SetPixel(x, y, gotColor);
// }
//}
//Graphics.FromImage(BaseImage).DrawImage(bmp, MyLocation.X, MyLocation.Y, Size, Size);
//------------------------------------
Image NewBMP = ColoredImage(MyImage);
Graphics.FromImage(BaseImage).DrawImage(NewBMP, MyLocation.X, MyLocation.Y, Size, Size);
}
if(DrawTitle)
{
int x = MyLocation.X + (Size / 2);
int y = MyLocation.Y + Size - (Size / 6);
int gap = 22;
int counter = 0;
CenterString(BaseImage, x, y + (counter * gap), hostname, Color.Black);
counter++;
if (myType != NetworkComponentType.microwave && myType != NetworkComponentType.fluorescent)
{
foreach (NetworkCard nic in NICs)
{
if (nic.GetNicType != NicType.lo && nic.GetNicType != NicType.port && nic.GetNicType != NicType.wport)
{
string title = "";
if (nic.GetNicType == NicType.management_interface)
title += "if: ";
else
title += nic.NicName() + ": ";
foreach (string addr_str in nic.IPAddresses(true))
{
CenterString(BaseImage, x, y + (counter * gap), title + addr_str, Color.Black);
counter++;
}
}
}
}
}
IsDirty = false; //We printed it, now we are content that we are clean
}
/// <summary>
/// Check all the network cards on this device to see if it has a nic with the given MAC address
/// </summary>
/// <param name="MAC">The MAC address we are looking for</param>
/// <returns>True if we have it, false if we do not.</returns>
public override bool HasMac(string MAC)
{
foreach(NetworkCard nic in NICs)
{
if (nic.MAC == MAC) return true;
}
return false;
}
/// <summary>
/// Get the host nic IDentifier for the specified MAC address
/// </summary>
/// <param name="MacIndex">The index of the network card</param>
/// <returns>The unique host-nic-ID</returns>
public HostNicID GetHostNicID(int MacIndex)
{
if (MacIndex < 0 || MacIndex > NICs.Count())
return new HostNicID(-1, -1, hostname, "");
return NICs[MacIndex].myID;
}
/// <summary>
/// Get the host nic IDentifier for the specified MAC address
/// </summary>
/// <param name="MacIndex">The index of the network card</param>
/// <returns>The unique host-nic-ID</returns>
public List<HostNicID> GetHostNicIDs()
{
List<HostNicID> tList = new List<HostNicID>();
for (int looper = 0; looper < NICs.Count; looper++)
{
tList.Add(NICs[looper].myID);
}
return tList;
}
public bool HasIPAddress(IPAddress dest)
{
foreach(NetworkCard nic in NICs)
{
if (nic.HasIPAddresses(dest))
return true;
}
return false;
}
public IPAddress RouteMatching(IPAddress dest)
{
//If we are comparing a route that has a 'special' netmask, make sure it is the right netmask
foreach (IPAddress ip in RouteTable)
{
if (dest.GetMask != 0 && dest.GetMask.ToIpString() != "255.255.255.0")
{
if (dest.GetMask == ip.GetMask && ip.IsLocal(dest))
return ip;
}
else
{
if (ip.IsLocal(dest))
return ip;
}
}
return null;
}
public bool HasRouteMatching(IPAddress dest)
{
IPAddress matched = RouteMatching(dest);
if (matched != null) return true;
return false;
}
public bool HasRouteMatching(string destString)
{
IPAddress dest = new IPAddress(destString);
if (dest.GetIPString == NB.ZeroIPString) return false;
return HasRouteMatching(dest);
}
//public bool HasBroadcastAddress(IPAddress dest)
//{
// foreach (NetworkCard nic in NICs)
// {
// if (nic.HasBroadcastAddresses(dest))
// return true;
// }
// return false;
//}
public bool HasBroadcastAddress(IPAddress dest)
{
if (dest.BroadcastAddress == dest.GetIP) return true;
foreach(NetworkCard nic in NICs)
{
if (nic.HasBroadcastAddresses(dest))
return true;
}
return false;
}
public bool HasBroadcastAddress(Packet tPacket)
{
return HasBroadcastAddress(tPacket.destIP);
}
public bool DoesRouting()
{
if (myType == NetworkComponentType.router) return true;
if (myType == NetworkComponentType.firewall) return true;
if (myType == NetworkComponentType.wap) return true;
return false;
}
public bool CanBeLockedOut()
{
if (myType == NetworkComponentType.net_switch) return true;
//if (myType == NetworkComponentType.wrouter) return true;
return false;
}
public bool DoesForwarding()
{
if (myType == NetworkComponentType.net_hub)
return true;
if (myType == NetworkComponentType.net_switch)
return true;
if (myType == NetworkComponentType.wap)
return true;
if (myType == NetworkComponentType.wbridge)
return true;
if (myType == NetworkComponentType.wrepeater)
return true;
if (myType == NetworkComponentType.wrouter)
return true;
return false;
}
public bool DoesFirewall()
{
if (myType == NetworkComponentType.firewall)
return true;
if (myType == NetworkComponentType.wrouter)
return true;
return false;
}
public bool DoesVLANs()
{
if (myType == NetworkComponentType.net_switch)
return true;
//if (myType == NetworkComponentType.wrouter)
// return true;
if (myType == NetworkComponentType.firewall)
return true;
if (myType == NetworkComponentType.router)
return true;
return false;
}
public override List<string> arp(UInt32 IP)
{
List<string> arps = new List<string>();
foreach (NetworkCard nic in NICs)
{
if (nic.HasIP(IP)) arps.Add(nic.MAC);
}
return arps;
}
public override void UpdateFromComponent(NetworkComponent CopyFrom)
{
if (CopyFrom.GetType() != this.GetType()) return; //we cannot copy from it if it is different
NetworkDevice ndCopyFrom = (NetworkDevice)CopyFrom;
hostname = ndCopyFrom.hostname;
Size = ndCopyFrom.Size;
DefaultGW = ndCopyFrom.DefaultGW;
MyImage = new Bitmap(ndCopyFrom.MyImage);
CanAddNics = ndCopyFrom.CanAddNics;
CanServeDHCP = ndCopyFrom.CanServeDHCP;
CanUseDHCP = ndCopyFrom.CanUseDHCP;
MustUseDHCP = ndCopyFrom.MustUseDHCP;
isDHCPServer = ndCopyFrom.isDHCPServer;
isDNSServer = ndCopyFrom.isDNSServer;
HasAdvFirewall = ndCopyFrom.HasAdvFirewall;
MyLocation = ndCopyFrom.MyLocation;
NICs.Clear();
foreach(NetworkCard nic in ndCopyFrom.NICs)
{
NICs.Add(NetworkCard.Clone(nic));
}
FirewallRules.Clear();
FirewallRules.AddRange(ndCopyFrom.FirewallRules);
RouteTable.Clear();
RouteTable.AddRange(ndCopyFrom.RouteTable);
DHCPRanges.Clear();
DHCPRanges.AddRange(ndCopyFrom.DHCPRanges);
DHCPLeases.Clear();
DHCPLeases.AddRange(ndCopyFrom.DHCPLeases);
}
public void DHCPRequestFromHere()
{
bool tryit = false;
if (CanUseDHCP)
{
foreach (NetworkCard tnic in NICs)
{
if (tnic.UsesDHCP)
tryit = true;
}
}
if (tryit)
{
//We need to create a packet
foreach (NetworkCard nic in NICs)
{
nic.SetIPForDHCP(); //clear the source IP
}
Packet DHCPPacket = new Packet(this, "", NB.BroadcastMACString, NB.Translate("NB_NetViewDHCP"), PacketType.dhcp_request);
DHCPPacket.destIP = new IPAddress(NB.BroadcastIPString);
Network myNet = NB.GetNetwork();
myNet.addPacket(DHCPPacket);
}
}
public void PingFromHere(IPAddress Destination)
{
//We need to create a packet
Packet PingPacket = new Packet(this,Destination, NB.Translate("H_Ping_Title"), PacketType.ping_request);
Network myNet = NB.GetNetwork();
string dHost = myNet.ReverseDNSLookup(this, Destination);
myNet.RegisterPingTest(hostname, dHost);
myNet.addPacket(PingPacket);
}
public void AskArpFromHere(IPAddress Destination, PacketMessage Tracker=null)
{
//We need to create a packet
Packet ArpPacket = new Packet(this, Destination, NB.Translate("H_ARP_Title2"), PacketType.arp_request);
if (Tracker != null)
ArpPacket.ReplaceMessage(Tracker);
Network myNet = NB.GetNetwork();
myNet.addPacket(ArpPacket);
}
public void TunnelPacketFromHere(IPAddress Destination, Packet Payload, string Encryption = "")
{
if(Destination == null)
{
Payload.MyStatus = PacketStatus.finished_failed;
Payload.Tracking.AddMessage(DebugLevel.info, hostname, NB.Translate("ND_TunnelPacketFromHere_Error"));
return;
}
PacketType TunType = PacketType.tun_packet;
if (Encryption != "")
TunType = PacketType.vpn_packet;
Packet TunnelPacket = new Packet(this, Destination, NB.Translate("ND_TunlPckTunl"), TunType);
TunnelPacket.payloadPacket = Payload;
TunnelPacket.EncryptionString = Encryption;
if(Payload != null)
Payload.Tracking.AddMessage(DebugLevel.info, this, NB.Translate("ND_TunnelPacketFromHere_Message"));
Network myNet = NB.GetNetwork();
myNet.addPacket(TunnelPacket);
}
public void StoreOutgoingPacketInfo(Packet tpacket, ResponseToPacket response = ResponseToPacket.accept)
{
IPConnectionEntry ipc;
if (response == ResponseToPacket.accept)
{
ipc = new IPConnectionEntry(tpacket.destIP, tpacket.MyType, ResponseToPacket.accept);
}else
{
ipc = new IPConnectionEntry(tpacket.destIP, tpacket.MyType, ResponseToPacket.masq, tpacket.sourceIP);
}
IPConnections.Add(ipc);
}
public void ClearIPConnectionInfo()
{
IPConnections.Clear();
}
public ResponseToPacket HowToRespondToPacket(Packet tPacket)
{
bool typesMatch=false;
if (tPacket.sourceIP == null) return ResponseToPacket.reject;
if (tPacket.TsourceIP != null && !tPacket.TsourceIP.IsLocal(tPacket.destIP) && !HasBroadcastAddress(tPacket.destIP)) return ResponseToPacket.none;
foreach(IPConnectionEntry ipc in IPConnections)
{
if (ipc.destIP.GetIP == tPacket.sourceIP.GetIP || HasBroadcastAddress(ipc.destIP))
{
if (ipc.What == PacketType.arp_request && tPacket.MyType == PacketType.arp_answer)
typesMatch = true;
if (ipc.What == PacketType.dhcp_request && tPacket.MyType == PacketType.dhcp_answer)
{
//Console.WriteLine(" " + NB.LeftPad(hostname) + ": True");
typesMatch = true;
}
if (ipc.What == PacketType.ping_request && tPacket.MyType == PacketType.ping_answer)
typesMatch = true;
if(typesMatch)
{
return ipc.Response;
}
}
}
//If we get here, we were not expecting the packet
return ResponseToPacket.reject;
}
public IPAddress PacketMasqueradeSource(Packet tPacket)
{
bool typesMatch = false;
foreach (IPConnectionEntry ipc in IPConnections)
{
if (ipc.destIP.GetIP == tPacket.sourceIP.GetIP && ipc.Response == ResponseToPacket.masq)
{
if (ipc.What == PacketType.ping_request && tPacket.MyType == PacketType.ping_answer)
typesMatch = true;
if (typesMatch)
{
return ipc.internalIP;
}
}
}
//If we get here, we were not expecting the packet
return null;
}
public bool IsWirelessForwarder()
{
if (myType == NetworkComponentType.wrepeater) return true;
if (myType == NetworkComponentType.wap) return true;
if (myType == NetworkComponentType.wbridge) return true;
if (myType == NetworkComponentType.wrouter) return true;
return false;
}
public bool LocalMatches(Packet tPacket)
{
//return false;
//the tSourceIP is local to something on the device
//The dest IP exists on the device.
//If we have multiple IPs, the tdest is one, and the actual dest is another
bool MatchesSource = false;
bool MatchesDest = false;
foreach(NetworkCard nic in NICs)
{
//If no IPs are defined, is it 0.0.0.0/0.0.0.0 which is local to everything
if (nic.GetNicType == NicType.port) continue;
if (nic.GetNicType == NicType.wport) continue;
if (nic.HasLocalInterface(tPacket.TsourceIP))
MatchesSource = true;
if (nic.HasIPAddresses(tPacket.destIP))
MatchesDest = true;
}
if (MatchesDest && MatchesSource) return true;
return false;
}
public override void ProcessPacket(Packet tPacket)
{
//Psuedo code for processing a packet
//We have already come in the interface and nic
//We will set the outbound nic in this process here
//All packets terminate in the device and either stop or are duplicated and sent out the next link
//Store the nic this came from so we skip sending the packet back out the same one
// We only skip sending it out the same one if it is a port.
//See if it arrives here.
// We route it if the dmac is this machine, but the dstIP does not match the IP of this machine
// if the dstIP matches exactly, it ends here.
// if the dstIP matches (broadcast), we process it but it still continues
// Set the "we have processed it" flag
// and we process arrival
bool MacAddressMatch = HasMac(tPacket.destMAC);
//It is an exact match if it is coming from a local source.
bool HasIp = HasIPAddress(tPacket.destIP);
bool ExactMatch = HasIp && (tPacket.TsourceIP == null || tPacket.TsourceIP.IsLocal(tPacket.destIP));
bool LocalMatch = LocalMatches(tPacket);
bool BroadcastMatch = HasBroadcastAddress(tPacket.destIP);
bool NeedsRouting = MacAddressMatch && (!ExactMatch && !BroadcastMatch);
if(ExactMatch || BroadcastMatch || LocalMatch)
{
//Change this. Need a new ProcessArrival
if (tPacket.MyType != PacketType.dhcp_answer) //If it is a match, it should be handled elsewhere
ProcessArrival(tPacket);
if (ExactMatch && tPacket.isFinshed())
return;
}
if (tPacket.DebugOn)
Console.WriteLine("Debug");
//Routing
//if we are supposed to route (do-not-route flag not set) or if the packet is "fresh"
// determine which nic it is supposed to exit.
// loop through all the routes and nics to see if local delivery or if we use a gateway
if(MacAddressMatch || tPacket.isFresh)
{
//It was destined for here, or it is starting from scratch. See if we need to route it.
if (tPacket.destIP == null) tPacket.destIP = new IPAddress(NB.ZeroIPString);
IPAddress dest = DestinationFromIP(tPacket.destIP); //Get the IP, or GW
if(dest.GetIPString == NB.ZeroIPString && tPacket.destIP.GetIPString != NB.BroadcastIPString)
{
//No gateway set and no route...
string errString = string.Format(NB.Translate("ND_NoRouteStr"), hostname, tPacket.destIP.GetIPString);
tPacket.AddMessage(DebugLevel.info, errString);
tPacket.Tracking.Status = errString;
tPacket.MyStatus = PacketStatus.finished_failed;
return;
}
if(dest.GetIP == tPacket.destIP.GetIP)
{
//It is a local packet. Let it go out the interface it needs to go out
tPacket.OutboundIP = tPacket.destIP;
tPacket.TsourceIP = null;
}
else if(tPacket.destIP.GetIPString != NB.BroadcastIPString)
{
//it needs to go to a gateway. Set the next destination is the GW
tPacket.OutboundIP = dest;
tPacket.TsourceIP = null;
}
else
{
tPacket.OutboundIP = tPacket.destIP;
tPacket.TsourceIP = null;
}
}
if (tPacket.isFinshed() && !BroadcastMatch) return;
NetworkCard dNic = null;
NetworkCard sNic = null;
if (DoesForwarding())
{
foreach (ArpEntry arp in ArpTable)
{
if (arp.MACAddress == tPacket.destMAC)
{
dNic = NicFromID(arp.NicOnWhichItIsFound);
break;
}
//if (arp.MACAddress == tPacket.sourceMAC)
//{
// sNic = NicFromID(arp.NicOnWhichItIsFound);
//}
}
}
sNic = tPacket.InboundNic; //We get the inbound nic from here.
//Delivery
//Loop through all nics (skip the interface) it came in on
// if it is a port, gen a new packet and send it out the port
// if it is broadcast, or if we have not processed it.
// if it is lo or management interface, skip the nic
// if it is a nic and we are supposed to route it, pass it to the nic.
// The nic will send it out all its interfaces
// If we need arp, the nic/interface holds onto it until the arp returns
// Store the nic on the packet, store the interface on the packet
// Resume processing at the nic level, not the device level when the arp comes back
int count = 0;
bool PacketSentOutWAN = false;
foreach (NetworkCard nic in NICs)
{
NicType NT = nic.GetNicType;
//bridges and waps are basically switches
if (myType == NetworkComponentType.wap || myType == NetworkComponentType.wbridge)
NT = NicType.port;
switch(NT)
{
case NicType.lo:
case NicType.management_interface:
case NicType.none:
break; //Do nothing
case NicType.eth:
case NicType.tun:
case NicType.vpn:
case NicType.wan:
case NicType.wlan:
//If the packet is a new packet and is not connecting to itself
//or, if it is routing away.
if ((tPacket.isFresh && !ExactMatch ) || (NeedsRouting && DoesRouting()) ||
IsWirelessForwarder())
{
// if (nic == tPacket.InboundNic) break; //this case is dealt with in nic.SendPacketOutNic
//Pass it to the NIC to send out each nic+interface.
//The nic checks to see if it works and then processes it
if(myType != NetworkComponentType.wbridge && myType != NetworkComponentType.wrepeater)
if (!tPacket.isFresh && HasBroadcastAddress(tPacket.destIP))
break;
string tMAC = tPacket.destMAC;
string ttMAC = tPacket.OutboundDestMAC;
tPacket.VLANID = NB.UntaggedVLAN; //we are routing, so we adopt the outgoing vlanID - state it needs to be tagged
if (BroadcastMatch && tPacket.MyType != PacketType.dhcp_answer)
tPacket.OutboundDestMAC = NB.BroadcastMACString;
tPacket.destMAC = tPacket.OutboundDestMAC;
if (nic.SendPacketOutNIC(tPacket))
{
count++;
if (nic.GetNicType == NicType.wan)
PacketSentOutWAN = true;
}
tPacket.destMAC = tMAC;
tPacket.OutboundDestMAC = ttMAC;
}
break;
case NicType.port:
case NicType.wport:
if (PacketSentOutWAN)
{
continue; //do not send packets out of ports if they have been sent out a WAN nic
}
NetworkCard tdNic = dNic;
if (myType == NetworkComponentType.wrouter)
{
//On wRouters, the wPorts are hubs, but the ports are switches
if (dNic != null && dNic.GetNicType == NicType.wport && nic.GetNicType == NicType.wport)
tdNic = null;
}
else
{
if (nic.GetNicType == NicType.port && myType == NetworkComponentType.net_hub)
tdNic = null; //Hubs/WAPs never know the dnic. They still need the sNic, however
if (nic.GetNicType == NicType.wport)
tdNic = null; //Hubs/WAPs never know the dnic. They still need the sNic, however
}
if (!ExactMatch && (!MacAddressMatch || ForwardsPackets()))
{
//If the packet does not terminate here, and we are not routing it to here...
//Pass it to the port. The port duplicates it and sends it out
//Do not send it out the port it came in on (sNic)
//If we know the dNic, only send it out that
//But if we do not know a dnic, send it out all of them (except the sNic)
if (sNic != nic && (tdNic == null || (tdNic != null && tdNic.ConnectedLink == -1) || tdNic == nic))
{
if (nic.SendPacketOutNIC(tPacket))
{
count++;
}
}
}
break;
}
}
//The packet has either been duplicated or has finished
if(count == 0)
{
if (tPacket.destMAC == "")
{
if (tPacket.MyType == PacketType.arp_request)
{
//The packet was not successfully sent anywhere. DMac = "". This means no host with the specified IP
tPacket.AddMessage(DebugLevel.info, string.Format(NB.Translate("ND_ArpNoIPLocalStr"), hostname));
tPacket.Tracking.Status = string.Format(NB.Translate("ND_NoIPLocalStr"), hostname);
tPacket.MyStatus = PacketStatus.finished_failed;
}
else
{
//The packet was not successfully sent anywhere. DMac = "". This means no host with the specified IP
tPacket.AddMessage(DebugLevel.info, string.Format(NB.Translate("ND_NoIPStr"), hostname));
tPacket.Tracking.Status = string.Format(NB.Translate("ND_NoIPStr"), hostname);
tPacket.MyStatus = PacketStatus.finished_failed;
}
}
else
{
//The packet was not successfully sent anywhere. No interface to send out the packet
tPacket.AddMessage(DebugLevel.info, string.Format(NB.Translate("ND_NoLocalIfStr"), hostname));
tPacket.Tracking.Status = string.Format(NB.Translate("ND_NoLocalIfStr"), hostname);
tPacket.MyStatus = PacketStatus.finished_failed;
}
}
if (tPacket.MyStatus != PacketStatus.finished_failed && tPacket.MyStatus != PacketStatus.finished_ok)
{
tPacket.MyStatus = PacketStatus.finished;
}
}
public void ProcessArrival(Packet tPacket)
{
Packet nPacket;
Network myNet = NB.GetNetwork();
if (tPacket.MyType == PacketType.tun_packet || tPacket.MyType == PacketType.vpn_packet)
{
tPacket.Tracking.AddMessage(DebugLevel.info,this,NB.Translate("ND_ProcessArrival_Arrived"));
tPacket.Tracking.Status = NB.Translate("ND_ProcessArrival_Arrived");
//If the encryption matches, we succeed. Otherwise, we fail
tPacket.MyStatus = PacketStatus.finished_ok; //It stops here
nPacket = tPacket.payloadPacket;
NetworkCard nc = LocalNic(nPacket.TsourceIP, true);
nPacket.TsourceIP = null;
if (nc != null)
{
if (nPacket != null)
{
if(nPacket.destMAC != nc.MAC)
{
nPacket.Tracking.Status = NB.Translate("ND_ProssArr_Error1");
nPacket.Tracking.AddMessage(DebugLevel.info, this, NB.Translate("ND_ProssArr_Error"));
nPacket.MyStatus = PacketStatus.finished_failed;
myNet.addPacket(nPacket); //so it gets pulled out apropriately
tPacket.payloadPacket = null;
return;
}
else
if (tPacket.EncryptionString == nc.EncryptionKey)
{
nPacket.destMAC = nc.MAC; //This is already the case, but we need to set it again for some reason.
nPacket.MyStatus = PacketStatus.processing;
nPacket.WhereAmI = this;
nPacket.Tracking.AddMessage(DebugLevel.info, this, NB.Translate("ND_ProcessArrival_CommingOut"));
myNet.addPacket(nPacket);
tPacket.payloadPacket = null;
return;
}
else
{
nPacket.Tracking.Status = NB.Translate("ND_ProcessArrival_EncryptErr1");
nPacket.Tracking.AddMessage(DebugLevel.info, this, NB.Translate("ND_ProcessArrival_EncryptErr2"));
nPacket.MyStatus = PacketStatus.finished_failed;
myNet.addPacket(nPacket); //so it gets pulled out apropriately
tPacket.payloadPacket = null;
return;
}
}
else
{
//There is no nic that matches the incoming IP
nPacket.Tracking.Status = NB.Translate("ND_ProssArr_Error1");
nPacket.Tracking.AddMessage(DebugLevel.info, this, NB.Translate("ND_ProssArr_Error"));
nPacket.MyStatus = PacketStatus.finished_failed;
myNet.addPacket(nPacket); //so it gets pulled out apropriately
return;
}
}
}
if (tPacket.MyType == PacketType.ping_request)
{
myNet.RegisterTimeOfArrival();
bool isbroadcast = HasBroadcastAddress(tPacket);
if (!isbroadcast || (isbroadcast && HasLocalNic(tPacket.sourceIP)))
{
//We would be responding to it. We have an odd case for switches.
//Verify that the management IP can talk to the packet
if(CanBeLockedOut())
{
//only a few devices have management ips
NetworkCard nic = HubManagementCard();
if(nic != null)
{
NetworkInterface nif = nic.GetInterface(0); //management interfaces only have one ip
if(nif != null)
{
VLANTagType VTT = nif.GetVLANTag(tPacket.VLANID);
if(VTT == VLANTagType.Forbidden)
{
//we cannot ping! The packet is blocked by vlan
//Console.WriteLine("blocked by vlan");
tPacket.AddMessage(DebugLevel.info, NB.Translate("ND_PrepPackVLANErr"));
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_PrepPackVLANErr")) + tPacket.sourceIP.GetIP.ToIpString() + " -> " + hostname;
tPacket.MyStatus = PacketStatus.finished_failed;
return;
}
}
}
}
nPacket = new Packet(this, tPacket.sourceIP, "", PacketType.ping_answer, tPacket.packetID);
nPacket.OriginalDestIP = tPacket.destIP;
nPacket.isFresh = true; //So it starts from here
nPacket.Tracking = new PacketMessage();
myNet.addPacket(nPacket);
tPacket.AddMessage(DebugLevel.info, NB.Translate("ND_ProcessArrival_PingReached1"));
tPacket.Tracking.Status = NB.LeftPad(hostname) + " Ping " + NB.Translate("ND_ProcessArrival_PingReached1") + tPacket.sourceIP.GetIP.ToIpString() + "-> " + tPacket.destIP.GetIP.ToIpString();
tPacket.MyStatus = PacketStatus.finished_ok;
IPAddress tip = nPacket.sourceIP;
if (!HasBroadcastAddress(tPacket.destIP))
{
nPacket.sourceIP = tPacket.destIP;
nPacket.TsourceIP = tPacket.destIP;
}
else
{
nPacket.sourceIP = new IPAddress(NB.ZeroIPString);
nPacket.TsourceIP = new IPAddress(NB.ZeroIPString);
}
if (tip.GetIP.ToIpString() != NB.ZeroIPString)
nPacket.destIP = tip;
if (tPacket.isFresh)
{
//The packet reached itself. At this moment, the packet does not yet have the source information set
//We just need to set the dest
//
nPacket.destIP = new IPAddress(NB.LoopbackIPString);
}
if (myType == NetworkComponentType.net_hub || myType == NetworkComponentType.net_switch ||
myType == NetworkComponentType.wrouter)
{
//put mac of management interface on packet
//dmac is originating mac
nPacket.destMAC = tPacket.sourceMAC;
nPacket.OutboundDestMAC = tPacket.sourceMAC;
nPacket.sourceMAC = HubManagementMAC();
}
else
{
nPacket.destMAC = "";
nPacket.sourceMAC = "";
}
nPacket.MyType = PacketType.ping_answer;
nPacket.MyStatus = PacketStatus.processing;
}
else
{
tPacket.AddMessage(DebugLevel.info, NB.Translate("ND_ProssArr_PingErr"));
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_ProssArr_PingErr")) + tPacket.sourceIP.GetIP.ToIpString() + " -> " + hostname;
tPacket.MyStatus = PacketStatus.finished_ok;
}
return;
}
if (tPacket.MyType == PacketType.ping_answer)
{
ResponseToPacket response = HowToRespondToPacket(tPacket);
if (response == ResponseToPacket.none) return; //We do not do anything with it here.
if (response == ResponseToPacket.accept || (HasIPAddress(tPacket.destIP) && (tPacket.TsourceIP == null || tPacket.destIP.IsLocal(tPacket.TsourceIP))))
{
if (tPacket.health < 100)
{
tPacket.AddMessage(DebugLevel.info, string.Format(NB.Translate("ND_ProssArrSomeLostStr"), tPacket.health.ToString()) );
int left = 100 - tPacket.health;
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_ProssArrPartialStr"), left , tPacket.sourceIP.GetIP.ToIpString(),tPacket.destIP.GetIP.ToIpString());
tPacket.MyStatus = PacketStatus.finished_ok;
}
else
{
tPacket.AddMessage(DebugLevel.info, NB.Translate("ND_ProcessArrival_PingReturn1"));
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_ProssArrSuccessStr"), tPacket.sourceIP.GetIP.ToIpString(), tPacket.destIP.GetIP.ToIpString());
tPacket.MyStatus = PacketStatus.finished_ok;
if (tPacket.sourceIP.GetIP != 0)
{
myNet.NotePacketArrived(tPacket.MyType, this, tPacket.destIP, tPacket.OriginalDestIP, tPacket.packetID);
}
else
{
myNet.NotePacketArrived(tPacket.MyType, this, tPacket.destIP, tPacket.sourceIP, tPacket.packetID);
}
}
}
else
{
tPacket.AddMessage(DebugLevel.info, NB.Translate("ND_ProcessArrival_PackReturnErr1"));
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_ProssArrPngFailStr"), tPacket.sourceIP.GetIP.ToIpString(), tPacket.destIP.GetIP.ToIpString());
tPacket.MyStatus = PacketStatus.finished_failed;
}
return;
}
if(tPacket.MyType == PacketType.arp_request)
{
//The arp request may not be asking for this IP.
if(HasIPAddress(tPacket.destIP))
{
nPacket = new Packet(tPacket);
nPacket.isFresh = true; //So it starts from here
nPacket.Tracking = new PacketMessage();
myNet.addPacket(nPacket);
NetworkCard nic = LocalNic(nPacket.sourceIP);
HostNicID theID = new HostNicID();
if (nic != null) theID = nic.myID;
if (nPacket.TsourceIP == null) nPacket.TsourceIP = nPacket.sourceIP;
StoreArp(nPacket.sourceMAC, nPacket.TsourceIP.GetIP.ToIpString(), theID);
//This is the IP we are looking for, send response back
IPAddress tip = nPacket.sourceIP;
nPacket.sourceIP = nPacket.destIP;
nPacket.TsourceIP = nPacket.destIP;
nPacket.destIP = tip;
if (myType == NetworkComponentType.net_hub || myType == NetworkComponentType.net_switch ||
myType == NetworkComponentType.wrouter)
{
//put mac of management interface on packet
//dmac is originating mac
nPacket.destMAC = nPacket.sourceMAC;
nPacket.OutboundDestMAC = nPacket.sourceMAC;
List<string> tstrings = new List<string>();
foreach(NetworkCard tNic in NICs)
{
tstrings.Clear();
tstrings.AddRange(tNic.IPAddresses());
if (tstrings.Count > 0 && !Regex.IsMatch(tstrings[0], "127.0.0.1"))
{
nPacket.sourceMAC = tNic.MAC;
break;
}
}
}
else
{
nPacket.destMAC = "";
tPacket.sourceMAC = "";
}
nPacket.MyType = PacketType.arp_answer;
nPacket.MyStatus = PacketStatus.processing;
tPacket.AddMessage(DebugLevel.info, NB.Translate("ND_ProcessArrival_ArpReached1"));
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_ProssArrArp")) + "IP: " + tPacket.sourceIP.GetIPString + " MAC: "+ nPacket.sourceMAC;
tPacket.MyStatus = PacketStatus.finished_ok;
}
else
{
tPacket.MyStatus = PacketStatus.finished; //We just drop it
}
return;
}
if (tPacket.MyType == PacketType.arp_answer)
{
ResponseToPacket response = HowToRespondToPacket(tPacket);
if (response == ResponseToPacket.accept)
{
NetworkCard nic = LocalNic(tPacket.destIP);
HostNicID myid = nic.myID;
StoreArp(tPacket.sourceMAC, tPacket.TsourceIP.GetIP.ToIpString(), myid);
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_ProssArrArpSuccessStr"), tPacket.sourceIP.GetIP.ToIpString(), tPacket.sourceIP.GetIP.ToIpString(), tPacket.sourceMAC);
tPacket.MyStatus = PacketStatus.finished_ok; //Yay!
myNet.NotePacketArrived(tPacket.MyType, this, tPacket.destIP, tPacket.sourceIP, tPacket.packetID);
}
else
{
tPacket.AddMessage(DebugLevel.info, NB.Translate("ND_ProcessArrival_PackReturnErr1"));
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_ProssArrArpFailStr"), tPacket.sourceIP.GetIP.ToIpString(), tPacket.destIP.GetIP.ToIpString());
tPacket.MyStatus = PacketStatus.finished_failed;
}
return;
}
if(tPacket.MyType == PacketType.dhcp_request && isDHCPServer)
{
nPacket = new Packet(tPacket);
nPacket.isFresh = true; //So it starts from here
nPacket.Tracking = new PacketMessage();
myNet.addPacket(nPacket);
//We need to find a dhcp IP for this.
IPAddress dst;
if (tPacket.InboundInterface == null)
{
dst = RequestDHCPLease(tPacket.sourceMAC, tPacket.OutboundIP);
nPacket.OutboundIP = tPacket.OutboundIP;
}
else
{
dst = RequestDHCPLease(tPacket.sourceMAC, tPacket.InboundInterface.myIP);
nPacket.OutboundIP = tPacket.InboundInterface.myIP;
}
//if the packet came in on a port...
if (tPacket.InboundNic != null && (tPacket.InboundNic.GetNicType == NicType.wport || tPacket.InboundNic.GetNicType == NicType.port))
{
IPAddress theIP = HubManagementIP();
if (theIP != null)
dst = RequestDHCPLease(tPacket.sourceMAC, theIP);
}
string tmac = nPacket.sourceMAC;
nPacket.sourceMAC = tPacket.OutboundMAC;
if (tPacket.InboundInterface != null)
nPacket.sourceIP = tPacket.InboundInterface.myIP;
else
nPacket.sourceIP = tPacket.OutboundIP;
nPacket.destMAC = tmac;
nPacket.OutboundDestMAC = tmac;
nPacket.payloadIP = dst;
nPacket.MyType = PacketType.dhcp_answer;
nPacket.OutboundMAC = "";
nPacket.OutboundIP = null;
nPacket.MyStatus = PacketStatus.processing;
tPacket.AddMessage(DebugLevel.info, NB.Translate("ND_ProcessArrival_DHCPReach1"));
string IP = "";
if (nPacket.sourceIP != null) IP = nPacket.sourceIP.GetIPString;
if(IP == "" && nPacket.WhereAmI != null) {
IPAddress tIP = HubManagementIP();
if (tIP != null) IP = tIP.GetIPString;
}
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_ProssArrDHCPStr"), IP);
//If we are a wireless router, we need to keep passing the broadcast request on
if(!DoesForwarding())
tPacket.MyStatus = PacketStatus.finished_ok;
return;
}
if (tPacket.MyType == PacketType.dhcp_answer)
{
ResponseToPacket response = HowToRespondToPacket(tPacket);
if (response == ResponseToPacket.accept)
{
NetworkCard tnic = tPacket.OutboundNic;
if (tnic == null || tnic.GetNicType == NicType.port || tnic.GetNicType == NicType.wport)
tnic = HubManagementCard();
if (tnic != null)
{
if (tPacket.payloadIP == null)
tPacket.payloadIP = new IPAddress(NB.ZeroIPString);
tnic.SetIPForDHCP(tPacket.payloadIP);
IsDirty = true; //If we need to redraw the device IP
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_ProssArrDHCPAnsStr"), tPacket.payloadIP.GetIP.ToIpString());
tPacket.MyStatus = PacketStatus.finished_ok; //Yay!
myNet.NotePacketArrived(tPacket.MyType, this, tPacket.payloadIP, tPacket.sourceIP, tPacket.packetID);
return;
}
}
else if(!tPacket.isFresh && !ForwardsPackets())
{
tPacket.AddMessage(DebugLevel.info, NB.Translate("ND_ProcessArrival_PackReturnErr1"));
string sIP = "?.?.?.?";
if (tPacket.sourceIP != null)
sIP = tPacket.sourceIP.GetIP.ToIpString();
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_ProssArrDHCPFailStr"), sIP, tPacket.destIP.GetIP.ToIpString());
tPacket.MyStatus = PacketStatus.finished_failed;
}
return;
}
//Fall-through, if nothing else happens
tPacket.MyStatus = PacketStatus.finished; //Different things may have different finished things.
}
public IPAddress LocalDeviceIP(NetworkDevice FromWhat)
{
NetworkInterface nif;
List<IPAddress> myList = FromWhat.IPAddressList();
foreach (IPAddress ip in myList.ToList())
{
foreach (NetworkCard tNic in NICs)
{
if (tNic.GetNicType == NicType.lo) continue; //Don't check loopback nics
if (tNic.GetNicType == NicType.port) continue; //Don't check ports
nif = tNic.LocalInterface(ip, null);
if(nif != null && nif.myIP.GetIPString != NB.ZeroIPString)
{
return nif.myIP;
}
}
}
//If we get here, we do not have a local IP
return null;
}
public IPAddress HubManagementIP()
{
List<IPAddress> IPAddresses = new List<IPAddress>();
foreach (NetworkCard tNic in NICs)
{
if(tNic.GetNicType == NicType.management_interface)
{
IPAddresses.AddRange(tNic.IPAddressList());
}
}
if (IPAddresses.Count > 0)
return IPAddresses[0];
return null;
}
public NetworkCard HubManagementCard()
{
foreach (NetworkCard tNic in NICs)
{
if (tNic.GetNicType == NicType.management_interface)
{
return tNic;
}
}
return null;
}
public string HubManagementMAC()
{
foreach(NetworkCard nic in NICs)
{
if (nic.GetNicType == NicType.management_interface)
return nic.MAC;
}
return null;
}
public bool DeviceIsLockedOutByVLANs()
{
if (!CanBeLockedOut())
return false; //We can only be locked out of a few things.
NetworkCard nic = HubManagementCard();
if (nic == null) return false; //this should never happen. Eject for now.
NetworkInterface nif = nic.GetInterface(0);
if (nif == null) return false;//this should never happen. Eject for now.
int managementID = nif.GetNonForbiddenVLANID();
bool lockedOUT = true;
foreach(NetworkCard tCard in NICs)
{
if (tCard.GetNicType == NicType.lo) continue;
if (tCard.GetNicType == NicType.management_interface) continue;
NetworkInterface tNIF = tCard.InterfaceFromVlanTag(managementID);
if(tNIF != null)
{
lockedOUT = false;
break;
}
}
return lockedOUT;
}
public List<IPAddress> IPAddressList()
{
List<IPAddress> thelist = new List<IPAddress>();
foreach(NetworkCard nic in NICs)
{
thelist.AddRange(nic.IPAddressList());
}
return thelist;
}
public List<string> SubnetList()
{
List<string> thelist = new List<string>();
foreach(IPAddress taddr in IPAddressList())
{
if(!thelist.Contains(taddr.NetworkAddress.ToIpString()))
{
thelist.Add(taddr.NetworkAddress.ToIpString());
}
}
return thelist;
}
public List<string> BroadcastList()
{
List<string> thelist = new List<string>();
foreach (IPAddress taddr in IPAddressList())
{
if (!thelist.Contains(taddr.BroadcastAddress.ToIpString()))
{
thelist.Add(taddr.BroadcastAddress.ToIpString());
}
}
return thelist;
}
/// <summary>
/// Return either the destination IP or the gateway IP
/// </summary>
/// <param name="dest">The target IP</param>
/// <returns>The IP the packet should be going to</returns>
public IPAddress DestinationFromIP(IPAddress dest, NetworkCard oNic = null)
{
NetworkInterface nIF = null;
NetworkCard tCard = null;
IPAddress DestAddr;
string DHCPGW = "";
foreach( IPAddress ip in RouteTable)
{
if (ip.IsLocal(dest))
return new IPAddress(ip.GetGateway.ToIpString());//We return the gateway
}
foreach (NetworkCard nic in NICs)
{
tCard = nic;
if(nic.UsesDHCP && nic.CanUseDHCP && DHCPGW == "")
{
DHCPGW = nic.FirstIP().GetGateway.ToIpString();
}
nIF = nic.LocalInterface(dest,null);
if (nIF != null && nIF.myIP.GetIPString != NB.ZeroIPString)
{
DestAddr = dest; //We found it. Send it to the destination
return DestAddr;
}
}
if (oNic != null)
{
List<IPAddress> tlist = oNic.IPAddressList();
if(tlist.Count > 0 && tlist[0].GetGateway.ToIpString() != NB.ZeroIPString)
{
return new IPAddress(tlist[0].GetGateway.ToIpString());
}
}
if (DHCPGW != "")
return new IPAddress(DHCPGW);
//if we get here, we do not know where to send it. Use the default gw.
return DefaultGW;
}
public bool PrepPacketForSending(Packet tPacket, IPAddress dest)
{
if((tPacket.OutboundMAC == null || tPacket.OutboundMAC == "") &&
tPacket.MyType == PacketType.dhcp_request &&
(tPacket.sourceMAC == "" || tPacket.sourceMAC == null))
{
//
Network myNet = NB.GetNetwork();
foreach(NetworkCard nic in NICs)
{
//Make one DHCP request for every nic that is a DHCP nic
if(nic.UsesDHCP && CanUseDHCP)
{
nic.SetIPForDHCP();
Packet nPacket = new Packet(tPacket);
nPacket.OutboundIP = new IPAddress(NB.ZeroIPString);
nPacket.OutboundMAC = nic.MAC;
nPacket.OutboundNic = nic;
nPacket.OutboundIF = nic.GetInterface(0);
nPacket.Tracking = new PacketMessage(); //we are starting. Each one should have a different tracker
myNet.addPacket(nPacket);
}
}
tPacket.MyStatus = PacketStatus.finished; //we have replaced it with other ones
return false;
}
if ((tPacket.OutboundMAC == null || tPacket.OutboundMAC == "") &&
HasBroadcastAddress(tPacket.destIP) &&
(tPacket.sourceMAC == "" || tPacket.sourceMAC == null))
{
//
Network myNet = NB.GetNetwork();
foreach (NetworkCard nic in NICs)
{
if (!nic.HasIP(new IPAddress("127.0.0.1").GetIP)) //don't bother pinging on the loopback
{
//Make one Broadcast ping for every nic that has an IP
Packet nPacket = new Packet(tPacket);
nPacket.OutboundIP = new IPAddress(NB.ZeroIPString);
nPacket.OutboundMAC = nic.MAC;
nPacket.destMAC = NB.BroadcastMACString;
nPacket.OutboundNic = nic;
nPacket.OutboundIF = nic.GetInterface(0);
nPacket.Tracking = new PacketMessage(); //we are starting. Each one should have a different tracker
myNet.addPacket(nPacket);
}
}
tPacket.MyStatus = PacketStatus.finished; //we have replaced it with other ones
return false;
}
if (tPacket.OutboundIP == null || tPacket.OutboundIP.GetIP.ToIpString() == NB.ZeroIPString && tPacket.MyType != PacketType.dhcp_request)
{
tPacket.OutboundIP = DestinationFromIP(dest,tPacket.OutboundNic);
if (tPacket.OutboundIP.GetIP.ToIpString() == NB.ZeroIPString)
{
if (tPacket.MyType == PacketType.dhcp_answer)
{
tPacket.AddMessage(DebugLevel.info, NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_PrepPackGtewyErr")) + " " + tPacket.OutboundIP.GetIP.ToIpString());
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_PrepPackGtewyErr"));
tPacket.MyStatus = PacketStatus.finished_failed;
return false;
}
else
{
tPacket.AddMessage(DebugLevel.info, NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_PrepPackRoutErr")) +" "+ tPacket.OutboundIP.GetIP.ToIpString());
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + NB.Translate("ND_PrepPackRoutErr");
tPacket.MyStatus = PacketStatus.finished_failed;
return false;
}
}
}
//If we get here, we have the local destination (dest or gateway) we are looking for.
//Now we find the nic and interface
if (tPacket.OutboundNic == null)
{
tPacket.OutboundNic = LocalNic(tPacket.OutboundIP);
if (tPacket.OutboundNic == null)
{
tPacket.AddMessage(DebugLevel.info, NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_PrepPackNICErr")) + " :"+ tPacket.OutboundIP.GetIP.ToIpString());
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + NB.Translate("ND_PrepPackNICErr");
tPacket.MyStatus = PacketStatus.finished_failed;
return false;
}
}
//If we get here, the nic is not null. Find the IF corresponding to the outbound IP
if (tPacket.OutboundIF == null)
{
tPacket.OutboundIF = tPacket.OutboundNic.LocalInterface(tPacket.OutboundIP, tPacket.Tracking);
if (tPacket.OutboundIF == null)
{
tPacket.AddMessage(DebugLevel.info, NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_PrepPackRoutErr")) + " :" + tPacket.OutboundIP.GetIP.ToIpString());
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + NB.Translate("ND_PrepPackRoutErr");
tPacket.MyStatus = PacketStatus.finished_failed;
return false;
}
}
tPacket.TsourceIP = tPacket.OutboundIF.myIP;
//
if (tPacket.destMAC == "" || tPacket.destMAC == null) //was != broadcast-mac
{
tPacket.OutboundMAC = ArpFromIP(tPacket.OutboundIP);
}
else
{
tPacket.OutboundMAC = tPacket.destMAC;
}
if (tPacket.OutboundMAC == "")
{
bool todo = true;
if (tPacket.OutboundNic != null && tPacket.OutboundNic.GetNicType == NicType.lo)
todo = false;
if (HasBroadcastAddress(tPacket.destIP))
{
tPacket.OutboundMAC = NB.BroadcastMACString;
todo = false;
}
if (todo)
{
AskArpFromHere(tPacket.OutboundIP);
//we do not have a mac address for it. Need to do an arp.
tPacket.TickTTL = 300;
tPacket.MyStatus = PacketStatus.waiting_for_arp;
return false;
}
}
return true;
}
/// <summary>
/// Return the network card that is considered "local" for the given IP
/// </summary>
/// <param name="toFind">The IP Address we are looking for</param>
/// <returns>a network card, or null if nothing matches</returns>
public NetworkCard LocalNic(IPAddress toFind, bool skipZero= false)
{
NetworkInterface nIF;
foreach (NetworkCard nic in NICs)
{
nIF = nic.LocalInterface(toFind, null);
if (nIF != null) {
if (nIF.myIP.GetIPString == NB.ZeroIPString)
continue;
return nic;
}
}
if(!skipZero)
{
foreach (NetworkCard nic in NICs)
{
nIF = nic.LocalInterface(toFind, null);
if (nIF != null)
{
return nic;
}
}
}
return null;
}
public List<string> NICRouteStrings()
{
List<string> answer = new List<string>();
string GW = DefaultGW.GetIP.ToIpString();
foreach(NetworkCard nic in NICs)
{
answer.AddRange(nic.NICRouteStrings(GW));
}
return answer;
}
public List<string> NICNames()
{
List<string> answer = new List<string>();
string GW = DefaultGW.GetIP.ToIpString();
foreach (NetworkCard nic in NICs)
{
answer.Add(nic.NicName());
}
return answer;
}
private IPAddress IPFromTypeNic(NicType What)
{
foreach(NetworkCard nic in NB.Randomize(NICs).ToList())
{
if(nic.GetNicType == What)
{
foreach(IPAddress ip in nic.IPAddressList())
{
if (ip.GetIPString != NB.ZeroIPString && ip.GetIPString != NB.LoopbackIPString)
return ip;
}
}
}
return null;
}
public IPAddress BestIPForThis(NetworkDevice Source=null)
{
IPAddress answer=null;
if(Source != null)
{
answer = LocalDeviceIP(Source);
if (answer != null && answer.GetIPString != NB.ZeroIPString)
return answer;
}
//If we have a WAN Nic, use that first
answer = IPFromTypeNic(NicType.wan);
if (answer != null)
return answer;
answer = IPFromTypeNic(NicType.management_interface);
if (answer != null)
return answer;
//Otherwise, choose an eth nic
answer = IPFromTypeNic(NicType.eth);
if (answer != null)
return answer;
return null;
}
public List<string> DeviceRouteStrings()
{
List<string> answer = new List<string>();
foreach (IPAddress ip in RouteTable)
{
answer.Add(ip.IPFormat());
}
return answer;
}
public void AddRoute(IPAddress route)
{
RouteTable.Add(route);
}
public List<IPAddress> ListRoutes()
{
return RouteTable;
}
public void EditRoute(int index)
{
if (index < 0) return;
if (index >= RouteTable.Count) return;
RouteTable[index].Edit(this);
}
public void DeleteRoute(int index)
{
if (index < 0) return;
if (index >= RouteTable.Count) return;
RouteTable.RemoveAt(index);
}
public override void DoInput(Packet tPacket)
{
}
public void DoInputFromLink(Packet tPacket, HostNicID arrivalNic)
{
//We are entering into the computer
NetworkCard nc = NicFromID(arrivalNic);
//Say tell the packet that we are no longer on the link
tPacket.WhereAmI = this;
tPacket.MyStatus = PacketStatus.processing;
//
tPacket.PacketDump(hostname, DebugPausePoint.packet_in);
if(nc == null)
{
tPacket.AddMessage(DebugLevel.info, NB.Translate("ND_DoInputFromLink_CardFail1"));
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_DoInputFromLink_CardFail2"));
tPacket.MyStatus = PacketStatus.finished_failed;
return;
}
if(tPacket.MyType == PacketType.dhcp_answer)
if(tPacket.destMAC == nc.MAC )
{
//We have arrived back
tPacket.OutboundNic = nc;
ProcessArrival(tPacket);
return;
}
NetworkInterface nf = nc.LocalInterface(tPacket.sourceIP, tPacket.Tracking);
if(nf == null)
{
nf = nc.LocalInterface(tPacket.TsourceIP, tPacket.Tracking);
}
if(nf == null)
{
nf = nc.PrimaryInterface();
}
if (nf == null && tPacket.MyType == PacketType.dhcp_request && isDHCPServer )
{
//It is a broadcast. We need to figure out which nic it came in on
// And then, figure out which interface, so we know which IP to dole out
NetworkInterface inif = nc.InterfaceFromVlanTag(tPacket);
tPacket.InboundInterface = inif;
List<IPAddress> addresses = nc.IPAddressList();
if (addresses.Count > 0)
{
if (tPacket.TsourceIP == null) tPacket.TsourceIP = tPacket.sourceIP;
tPacket.OutboundIP = addresses[0];
tPacket.OutboundNic = nc;
tPacket.OutboundMAC = nc.MAC;
tPacket.WhereAmI = this;
ProcessArrival(tPacket);
return;
}
}
if (!ForwardsPackets())
{
if (tPacket.MyType == PacketType.dhcp_request && !isDHCPServer)
{
tPacket.AddMessage(DebugLevel.debug, NB.LeftPad(hostname) + " " +string.Format(NB.Translate("ND_DoInFromLnkDeaf")));
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_DoInFromLnkNoDHCP"));
tPacket.MyStatus = PacketStatus.finished_failed;
return;
}
if ((tPacket.MyType == PacketType.ping_answer || tPacket.MyType== PacketType.ping_request) &&
!RoutesPackets() && (!HasIPAddress(tPacket.destIP) && !HasBroadcastAddress(tPacket.destIP)))
{
tPacket.AddMessage(DebugLevel.debug, NB.LeftPad(hostname) + " " +string.Format(NB.Translate("ND_NotRouter")));
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_NotRouter2"));
tPacket.MyStatus = PacketStatus.finished_failed;
return;
}
}
if(nf == null && myType != NetworkComponentType.net_switch && myType != NetworkComponentType.net_hub &&
myType != NetworkComponentType.wbridge && myType != NetworkComponentType.wrepeater &&
myType != NetworkComponentType.wrouter)
{
tPacket.AddMessage(DebugLevel.debug, NB.LeftPad(hostname) + string.Format(NB.Translate("ND_NoLocIP")));
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_NoLocIP2"));
tPacket.MyStatus = PacketStatus.finished_failed;
return;
}
//Now we pass it to the interface
if (nf != null)
nf.ProcessInboundPacket(tPacket);
//Now we pass it to the nic
if (nc != null)
nc.ProcessInboundPacket(tPacket);
//if (hostname != null)
// Console.WriteLine("Starting on device: " + hostname + " VLANID = " + tPacket.VLANID.ToString());
if(!tPacket.ready_to_delete)
tPacket.StartOnDevice(this);
}
/// <summary>
/// Return true if this is a switch/hub/wap
/// </summary>
/// <returns></returns>
public bool ForwardsPackets()
{
if (myType == NetworkComponentType.net_hub) return true;
if (myType == NetworkComponentType.net_switch) return true;
if (myType == NetworkComponentType.wap) return true;
if (myType == NetworkComponentType.wrouter) return true;
if (myType == NetworkComponentType.wrepeater) return true;
if (myType == NetworkComponentType.wbridge) return true;
return false;
}
/// <summary>
/// Return true if this device routes packets. Router, firewall, etc.
/// </summary>
/// <returns></returns>
public bool RoutesPackets()
{
if (myType == NetworkComponentType.router) return true;
if (myType == NetworkComponentType.firewall) return true;
if (myType == NetworkComponentType.wrouter) return true;
return false;
}
public bool IsNotNetDevice()
{
if (GetNetType() == NetworkComponentType.fluorescent)
return false;
if (GetNetType() == NetworkComponentType.microwave)
return false;
return true;
}
public override void DoOutput(Packet tPacket)
{
}
public string ArpFromIP(string IPAddress)
{
foreach(ArpEntry arp in ArpTable)
{
if (arp.IPAddr == IPAddress)
return arp.MACAddress;
}
return "";
}
public string IPFromArp(string MAC)
{
foreach (ArpEntry arp in ArpTable)
{
if (arp.MACAddress == MAC)
return arp.IPAddr;
}
return "";
}
public HostNicID NicIDFromArp(string MAC)
{
foreach (ArpEntry arp in ArpTable)
{
if (arp.MACAddress == MAC)
return arp.NicOnWhichItIsFound;
}
return new HostNicID(-1,-1,"","");
}
public HostNicID NicIDFromIP(string IP)
{
foreach (ArpEntry arp in ArpTable)
{
if (arp.IPAddr == IP)
return arp.NicOnWhichItIsFound;
}
return new HostNicID(-1, -1, "", "");
}
public string LookupArpFromIP(string IPAddress)
{
string arp = ArpFromIP(IPAddress);
if (arp == "")
{
Network mynet = NB.GetNetwork();
if (mynet != null)
{
List<string> arps = mynet.arp(IPAddress.ParseIp());
if (arps.Count > 0)
{
return arps[0];
}
}
}
return arp;
}
public string ArpFromIP(IPAddress IPAddress)
{
return ArpFromIP(IPAddress.GetIP.ToIpString());
}
public void StoreArp(string mac, string ip, HostNicID NicID)
{
ArpEntry AE = new ArpEntry(mac, ip, NicID);
string found = ArpFromIP(ip);
if (found == "")
{
ArpTable.Add(AE);
}
if(IPFromArp(mac) != ip && ip != NB.ZeroIPString)
{
foreach (ArpEntry arp in ArpTable.ToList())
{
if (arp.MACAddress == mac)
{
ArpTable.Remove(arp);
}
}
ArpTable.Add(AE);
}
}
public void ChangeColor(Color ColorTo)
{
MorphColor = ColorTo;
}
public List<ArpEntry> GetArps()
{
return ArpTable;
}
public void ClearArps()
{
ArpTable.Clear();
}
/// <summary>
/// Clear out all the IP addresses on the device
/// </summary>
public void ClearIPs()
{
ClearArps();
RouteTable.Clear();
DefaultGW = new IPAddress(NB.ZeroIPString);
foreach(NetworkCard nic in NICs)
{
nic.ClearIPs();
}
}
/********************************************
* DHCP Stuff
********************************************/
public void CheckDHCPRangesAgainstInterfaces()
{
bool found = false;
List<IPAddress> theInterfaces = IPAddressList();
foreach(IPAddress dhcpIP in DHCPRanges.ToList())
{
found = false;
foreach (IPAddress interfaceIP in theInterfaces)
{
if(interfaceIP.GetIP == dhcpIP.GetIP)
{
found = true;
break;
}
}
if(!found)
{
DHCPRanges.Remove(dhcpIP);
}
}
foreach (IPAddress interfaceIP in theInterfaces)
{
found = false;
foreach (IPAddress dhcpIP in DHCPRanges)
{
if (interfaceIP.GetIP == dhcpIP.GetIP)
{
found = true;
break;
}
}
if (!found)
{
DHCPRanges.Add(new IPAddress(interfaceIP.GetIP.ToIpString(),NB.ZeroIPString,NB.ZeroIPString));
}
}
}
public List<string> DHCPStrings(bool WithAdditionalInfo=true)
{
List<string> theStrings = new List<string>();
foreach(IPAddress ip in DHCPRanges)
{
if (ip.GetIP.ToIpString() != "127.0.0.1")
{
if (WithAdditionalInfo)
{
theStrings.Add(string.Format(NB.Translate("ND_DHCPStrIFStr"), ip.GetIP.ToIpString().PadLeft(15),
ip.GetMask.ToIpString(),ip.GetGateway.ToIpString()));
}
else
{
theStrings.Add(ip.GetIP.ToIpString());
}
}
}
return theStrings;
}
public IPAddress DHCPRangeMatchingInterface(IPAddress InterfaceIP)
{
if (InterfaceIP == null) return null;
foreach (IPAddress ip in DHCPRanges)
{
if (ip.GetIP.ToIpString() != "127.0.0.1" && InterfaceIP.IsLocal(ip))
return ip;
}
return null;
}
public void EditDHCP(int index)
{
if (index > DHCPRanges.Count) return;
if (index < 0) return;
bool found = false;
IPAddress ifIP = null;
List<IPAddress> theInterfaces = IPAddressList();
foreach (IPAddress interfaceIP in theInterfaces)
{
if(interfaceIP.GetIP == DHCPRanges[index].GetIP)
{
ifIP = interfaceIP;
found = true;
}
}
if (!found) return;
DHCPRanges[index].Edit(this, ifIP); //We need to pass the interface that is local to this
DHCPLeases.Clear();
}
public IPAddress LookupDHCPLease(string MAC, IPAddress NIC_IP)
{
IPAddress gateway;
if (myType != NetworkComponentType.firewall)
{
gateway = GetGateway();
}
else
{
gateway = NIC_IP; //Return the firewall IP that it came in on
}
foreach(ArpEntry dhcp in DHCPLeases)
{
if (dhcp.MACAddress == MAC && dhcp.IPAddr != NB.ZeroIPString && NIC_IP != null && gateway != null)
{
IPAddress addr = new IPAddress(dhcp.IPAddr, NIC_IP.GetMask.ToIpString(), gateway.GetIP.ToIpString());
if (addr.IsLocal(NIC_IP))
return addr;
}
}
return null;
}
public bool IPAlreadyUsed(string IP)
{
foreach (ArpEntry dhcp in DHCPLeases)
{
if (dhcp.IPAddr == IP)
return true;
}
return false;
}
public void MakeDHCPLease(string IP, string MAC)
{
ArpEntry me = new ArpEntry(MAC, IP, new HostNicID());
DHCPLeases.Add(me);
}
/// <summary>
/// Look up the MAC address and return the appropriate IP, or make a new IP. Uses the interface IP of the server to know what range to use.
/// </summary>
/// <param name="MAC">The mac of the requesting machine</param>
/// <param name="NIC_IP">the IP of the server nic</param>
/// <returns>an IPAddress IP/Mask/GW</returns>
public IPAddress RequestDHCPLease(string MAC, IPAddress NIC_IP)
{
if (NIC_IP == null)
NIC_IP = HubManagementIP();
IPAddress tAddress = LookupDHCPLease(MAC, NIC_IP);
if (tAddress != null && NIC_IP.IsLocal(tAddress))
return tAddress;
//if we are here, we need to find an address to give.
bool stillOK = true;
IPAddress startaddress = DHCPRangeMatchingInterface(NIC_IP);
if (startaddress == null) return null;
UInt32 sIPNum = startaddress.GetMask;
UInt32 eIPNum = startaddress.GetGateway;
string ipstring;
while(stillOK)
{
ipstring = sIPNum.ToIpString();
tAddress = new IPAddress(ipstring, NIC_IP.GetMask.ToIpString(),NB.ZeroIPString);
if (!IPAlreadyUsed(ipstring))
{
MakeDHCPLease(ipstring, MAC);
IPAddress gateway = GetGateway();
//If the gateway is not local to the IP address we are giving out, give the IP of this device
if(!tAddress.IsLocal(gateway))
{
gateway = NIC_IP; //Return the firewall IP that it came in on
}
return new IPAddress(ipstring,NIC_IP.GetMask.ToIpString(),gateway.GetIP.ToIpString());
}
sIPNum++;
if(sIPNum > eIPNum)
{
//We have used up all the range
stillOK = false;
break;
}
}
return null; //If we get here, we are done for. Nothing to give out
}
/// <summary>
/// Return true if this device has at least one nic that can be configured from DHCP
/// </summary>
/// <returns>True if the device has a nic that can be configured with DHCP</returns>
public bool HasDHCPNic()
{
foreach(NetworkCard card in NICs)
{
if (card.UsesDHCP)
return true;
}
return false;
}
public bool HasLocalNic(IPAddress dest)
{
foreach(NetworkCard nic in NICs)
{
if (nic.HasLocalInterface(dest)) return true;
}
return false;
}
public bool FirewallAllows(string inIF, string outIF)
{
foreach(FirewallRule fwr in FirewallRules)
{
if(fwr.Source == inIF && fwr.Destination == outIF)
{
if (fwr.Action == FirewallRuleType.Allow)
return true;
if (fwr.Action == FirewallRuleType.Drop)
return false;
}
}
return true;
}
}
}