EduNetworkBuilder/EduNetworkBuilder/NetworkCard.cs

1026 lines
47 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.IO;
using System.Xml;
using System.Windows.Forms;
using System.Text.RegularExpressions;
namespace EduNetworkBuilder
{
[Serializable]
public class NetworkCard
{
public string MAC = NB.GenerateMACAddress(); //Technically we should make sure it is unique
public List<NetworkInterface> interfaces = new List<NetworkInterface>();
public bool UsesDHCP = false;
public bool CanUseDHCP = false;
public bool MustUseDHCP = false;
public NicType myNicType = NicType.eth;
public HostNicID myID;
public int ConnectedLink=-1; //The link that is connected to this nic.
public int UniqueIdentifier = NB.GetUniqueIdentifier();
public string _nic_name="";
public NB_IPAddress TunnelEndpoint;
public string EncryptionKey;
public string SSID;
public string WirelessKey
{
get { return EncryptionKey; }
set { EncryptionKey = value; }
}
public int IFCount { get { return interfaces.Count; } }
public NetworkCard() { }
public NetworkCard(int index, int HostID, string hostname, NicType theType = NicType.eth)
{
myNicType = theType;
_nic_name = myNicType.ToString() + index.ToString();
myID = new HostNicID(HostID, UniqueIdentifier, hostname, _nic_name);
NetworkInterface nInterface = new NetworkInterface(NicName(), NB.ZeroIPString, NB.ZeroIPString, myID);
if(theType == NicType.lo)
nInterface = new NetworkInterface(NicName(), "127.0.0.1", "255.0.0.0", myID);
interfaces.Add(nInterface);
ApplyNicRules();
SetIPForDHCP();
}
public NetworkCard(NetworkCard old, bool duplicateID = false)
{
if (old == null) return;
MAC = old.MAC;
foreach(NetworkInterface one in old.interfaces)
{
NetworkInterface nInterface = new NetworkInterface(one);
interfaces.Add(nInterface);
}
UsesDHCP = old.UsesDHCP;
CanUseDHCP = old.CanUseDHCP;
MustUseDHCP = old.MustUseDHCP;
myNicType = old.myNicType;
myID = old.myID;
if(duplicateID == false)
myID = new HostNicID(old.myID.HostID, UniqueIdentifier, old.myID.HostName, old.NicName());
ConnectedLink = old.ConnectedLink;
if (duplicateID == false)
ConnectedLink = -1; //It should be a new card, not connected to anything.
TunnelEndpoint = old.TunnelEndpoint;
EncryptionKey = old.EncryptionKey;
SSID = old.SSID;
}
public NetworkCard(XmlNode theNode)
{
foreach (XmlNode Individual in theNode.ChildNodes)
{
XmlNodeType myNodetype = Individual.NodeType;
if (myNodetype == XmlNodeType.Element)
{
switch (Individual.Name.ToLower())
{
case "nictype":
myNicType = NB.ParseEnum<NicType>(Individual.InnerText);
break;
case "nicname":
_nic_name = Individual.InnerText;
break;
case "myid":
myID = new HostNicID(Individual);
break;
case "usesdhcp":
bool.TryParse(Individual.InnerText, out UsesDHCP);
break;
case "uniqueidentifier":
int.TryParse(Individual.InnerText, out UniqueIdentifier);
break;
case "interface":
NetworkInterface newIF = new NetworkInterface(Individual,myID);
interfaces.Add(newIF);
break;
case "mac":
string tmac = Individual.InnerText;
if (tmac.Length == MAC.Length)
MAC = tmac.ToUpper(); //Make sure it is all uppercase
break;
case "tunnelendpoint":
TunnelEndpoint = new NB_IPAddress(Individual);
break;
case "encryptionkey":
EncryptionKey = Individual.InnerText;
break;
case "ssid":
SSID = Individual.InnerText;
break;
}
}
}
ApplyNicRules();
SetIPForDHCP();
}
public void ChangeType(NicType newtype)
{
NicType oldType = myNicType;
myNicType = newtype;
string index = Regex.Match(_nic_name, @"\d+$").Value;
if (index == "") index = "0";
string OldName = oldType.ToString() + index.ToString();
_nic_name = myNicType.ToString() + index.ToString();
foreach (NetworkInterface NI in interfaces)
{
//NI.nic_name = Regex.Replace(NI.nic_name, OldName, _nic_name);
NI.nic_name = _nic_name; //This does not work when we have eth0:1...
NI.AttachedToHostNic.NicName = _nic_name;
}
myID.NicName = _nic_name;
if (newtype == NicType.port || newtype == NicType.wport)
interfaces.Clear();
}
public bool Equals(NetworkCard compareWith)
{
if (MAC != compareWith.MAC) return false;
//List<NetworkInterface> interfaces = new List<NetworkInterface>();
if (interfaces.Count != compareWith.interfaces.Count) return false;
for (int i = 0; i < interfaces.Count; i++)
if (!interfaces[i].Equals(compareWith.interfaces[i])) return false;
if (UsesDHCP != compareWith.UsesDHCP) return false;
if (CanUseDHCP != compareWith.CanUseDHCP) return false;
if (MustUseDHCP != compareWith.MustUseDHCP) return false;
if (myNicType != compareWith.myNicType) return false;
if (myID.HostID != compareWith.myID.HostID) return false;
if (ConnectedLink != compareWith.ConnectedLink) return false;
if (UniqueIdentifier != compareWith.UniqueIdentifier) return false;
if (_nic_name != compareWith._nic_name) return false;
if (TunnelEndpoint != compareWith.TunnelEndpoint) return false;
if (EncryptionKey != compareWith.EncryptionKey) return false;
if (SSID != compareWith.SSID) return false;
return true;
}
private void ApplyNicRules()
{
//These are the defaults for the various nic types. They can be overridden by the device.
if(myNicType == NicType.eth || myNicType == NicType.management_interface || myNicType == NicType.wlan)
{
CanUseDHCP = true;
}
else
{
CanUseDHCP = false;
}
}
public void Save(XmlWriter writer)
{
writer.WriteStartElement("nic");
writer.WriteElementString("nictype", myNicType.ToString());
writer.WriteElementString("nicname", _nic_name);
myID.Save(writer, "myid");
writer.WriteElementString("nictype", myNicType.ToString());
writer.WriteElementString("uniqueidentifier", UniqueIdentifier.ToString());
writer.WriteElementString("usesdhcp", UsesDHCP.ToString());
if(EncryptionKey != "")
writer.WriteElementString("encryptionkey", EncryptionKey);
if (SSID != "")
writer.WriteElementString("ssid", SSID);
if (TunnelEndpoint != null)
{
TunnelEndpoint.Save(writer, "tunnelendpoint");
}
foreach (NetworkInterface nIF in interfaces)
{
nIF.Save(writer);
}
writer.WriteEndElement();
}
public int GetUniqueIdentifier
{
get { return UniqueIdentifier; }
}
public NicType GetNicType
{
get { return myNicType; }
}
public bool isWireless()
{
if (myNicType == NicType.wport || myNicType == NicType.wlan)
return true;
return false;
}
public bool HasIP(UInt32 IP)
{
if (myNicType == NicType.port) return false;
if (myNicType == NicType.none) return false;
foreach (NetworkInterface IF in interfaces)
{
if (IF.myIP.Equals(IP))
return true;
}
return false;
}
public string NicName()
{
return _nic_name;
}
public string NicString(int index)
{
string connected = " ";
if (isConnected(true)) connected = "*";
if (myNicType == NicType.port || myNicType == NicType.wport)
{
NetworkDevice ND = ConnectedTo();
if(ND != null)
return NicName() + connected + " -> " + ND.hostname;
return NicName() + connected;
}
return NicName() + connected + " " + MAC;
}
public List<string> NICRouteStrings(string GW)
{
List<string> thestrings = new List<string>();
if (myNicType == NicType.port) return thestrings;
if (myNicType == NicType.none) return thestrings;
foreach (NetworkInterface iface in interfaces)
{
thestrings.Add(iface.RouteString(_nic_name,GW));
}
return thestrings;
}
public List<string> IPAddresses(bool UseCidr = false)
{
List<string> theIPs = new List<string>();
if (myNicType == NicType.port) return theIPs;
if (myNicType == NicType.wport) return theIPs;
if (myNicType == NicType.none) return theIPs;
string DHCPString = "";
if (UsesDHCP && CanUseDHCP) DHCPString = "DHCP: ";
foreach (NetworkInterface iface in interfaces)
{
theIPs.Add(DHCPString + iface.InterfaceString(UseCidr));
}
return theIPs;
}
public List<NB_IPAddress> IPAddressList()
{
List<NB_IPAddress> theIPs = new List<NB_IPAddress>();
if (myNicType == NicType.port) return theIPs;
if (myNicType == NicType.none) return theIPs;
foreach (NetworkInterface iface in interfaces)
{
theIPs.Add(iface.myIP);
}
return theIPs;
}
public bool HasIPAddresses(NB_IPAddress dest)
{
if (myNicType == NicType.port) return false;
if (myNicType == NicType.none) return false;
if (dest == null) return false;
foreach (NetworkInterface iface in interfaces)
{
if (iface.myIP.GetIP == dest.GetIP)
return true;
}
return false;
}
public bool HasBroadcastAddresses(NB_IPAddress dest)
{
if (myNicType == NicType.port) return false;
if (myNicType == NicType.none) return false;
if (myNicType == NicType.lo) return false;
if (dest == null) return false;
foreach (NetworkInterface iface in interfaces)
{
if (iface.myIP.BroadcastAddress == 0) continue; //a netmask of 0.0.0.0 causes grief
if (iface.myIP.BroadcastAddress == dest.GetIP)
return true;//If they are pinging the broadcast IP
if (iface.myIP.GetIPString == NB.BroadcastIPString)
return true;
}
return false;
}
public void EditInterface(int index, Form ParentForm)
{
if (index < 0 || index > interfaces.Count())
return;
interfaces[index].EditAddress(ParentForm);
}
public void DeleteInterface(int index)
{
if (index < 0 || index > interfaces.Count())
return;
if (interfaces.Count < 2)
return; //We cannot delete the sole remaining interface
interfaces.RemoveAt(index);
}
private int NextInterfaceNum()
{
string NICName = NicName();
string testname = "";
bool foundone = true;
int which = 0;
while(foundone)
{
foundone = false;
testname = NICName;
if (which != 0)
testname = testname + ":" + which.ToString();
foreach(NetworkInterface oneif in interfaces)
{
if(oneif.nic_name == testname)
{
foundone = true;
break;
}
}
if (foundone)
which++;
}
return which;
}
public void AddInterface()
{
string NICName = NicName();
int Plus = NextInterfaceNum();
if (Plus != 0) NICName += ":"+Plus.ToString();
NetworkInterface iface = new NetworkInterface(NICName, NB.ZeroIPString, NB.ZeroIPString, myID);
interfaces.Add(iface);
}
public NetworkInterface GetInterface(int index)
{
if (index < 0 || index > interfaces.Count())
return null;
return interfaces[index];
}
public bool isConnected(bool CheckForBrokenLink)
{
if(ConnectedLink != -1)
{
if (!CheckForBrokenLink) return true; //We only care if there is any link
Network myNet = NB.GetNetwork();
NetworkLink NL = myNet.GetLinkFromID(ConnectedLink);
if(NL != null)
{
if (NL.theLinkType != LinkType.broken) return true;
else return false;
}
}
return false;
}
public NetworkDevice ConnectedTo()
{
if (ConnectedLink != -1)
{
Network myNet = NB.GetNetwork();
NetworkLink NL = myNet.GetLinkFromID(ConnectedLink);
if (NL != null)
{
if (NL.IsSource(myID.HostID)) return myNet.GetDeviceFromID(NL.Dst);
else return myNet.GetDeviceFromID(NL.Src);
}
}
return null;
}
public void Edit()
{
NetworkCardEditor nce = new NetworkCardEditor(this);
nce.ShowDialog();
//Now. update the interfaces if we need to do so.
SetIPForDHCP();
}
public void SetIPForDHCP()
{
if (UsesDHCP && CanUseDHCP)
{
//remove any extra interfaces.
//set the one interface to 0.0.0.0
switch(myNicType)
{
case NicType.eth:
case NicType.wlan:
interfaces.Clear(); //empty out all interfaces
//Give it an interface with an empty IP
NetworkInterface nInterface = new NetworkInterface(NicName(), NB.ZeroIPString, NB.ZeroIPString,myID);
interfaces.Add(nInterface);
break;
}
}
}
public void SetIPForDHCP(NB_IPAddress newIP)
{
if (UsesDHCP && CanUseDHCP)
{
bool doIt = true;
if (interfaces.Count > 0 && interfaces[0].myIP.GetIPString == NB.ZeroIPString)
{
doIt = true;
}
else
{
if(interfaces.Count > 0)
{
//The IP address is not zero. This means it already has an IP.
Random rnd = NB.GetRandom();
int chance = rnd.Next(6);
if (chance > 3)
doIt = false;
}
}
if (doIt && interfaces.Count > 0)
{
interfaces[0].myIP = newIP;
}
}
}
public bool HasLocalInterface(NB_IPAddress theIP)
{
foreach(NetworkInterface nIF in interfaces)
{
if (nIF.isLocal(theIP))
return true;
}
return false;
}
/// <summary>
/// Return the interface that is considered "local" to the IP address we are trying to reach
/// </summary>
/// <param name="theIP">An IP address we are trying to send out</param>
/// <returns>null if no interface is local. Otherwise, it returns the one that matches the packet</returns>
public NetworkInterface LocalInterface(NB_IPAddress theIP, PacketMessage Tracker)
{
if (myNicType == NicType.port)
{
if (interfaces.Count == 1) return interfaces[0];
return null; //ports have no local interfaces
}
foreach (NetworkInterface nIF in interfaces)
{
if (nIF.isLocal(theIP))
{
if(Tracker != null)
Tracker.AddMessage(DebugLevel.routing, myID.HostName, string.Format(NB.Translate("NC_FoundLocalIF"), nIF.myIP.GetIP.ToIpString(), nIF.myIP.GetMask.ToIpString()));
if (Tracker != null && theIP != null)
Tracker.AddMessage(DebugLevel.routing, myID.HostName, " " + string.Format(NB.Translate("NC_IfOfLocal"),theIP.GetIPString, theIP.GetGateway.ToIpString()));
return nIF;
}
}
return null;
}
public NetworkInterface PrimaryInterface()
{
if (interfaces.Count == 1)
return interfaces[0];
return null;
}
public bool NicCanDoVLANs()
{
if (myNicType == NicType.eth) return true;
if (myNicType == NicType.port) return true;
if (myNicType == NicType.wan) return true;
return false;
}
/***************************************
*
* *************************************/
public bool SendPacketOutNIC(Packet tPacket)
{
bool madeprogress = false;
Packet nPacket = null;
Network myNet = NB.GetNetwork();
NetworkLink nl;
if (NB.GetComponentType(tPacket.WhereAmI) != GeneralComponentType.device) return false; //we cannot do this.
NetworkDevice WhereFrom = (NetworkDevice)tPacket.WhereAmI;
NicType what = GetNicType;
if (!tPacket.isFresh && WhereFrom.IsWirelessForwarder() && (what == NicType.wlan || (WhereFrom.GetNetType() == NetworkComponentType.wap && what == NicType.eth)))
what = NicType.wport;
if (myNet.ItemHasTest(WhereFrom.hostname, NicName(), NetTestType.DeviceNICSprays))
{
if (!myNet.ItemTestIsComplete(WhereFrom.hostname, NicName(), NetTestType.DeviceNICSprays))
{
if (tPacket.MyType == PacketType.bad_packet) return false;
//We should drop the current packet.
tPacket.AddMessage(DebugLevel.info, NB.Translate("N_ProssShouldContinTime"));
tPacket.Tracking.Status = NB.Translate("N_ProssShouldContinTime");
tPacket.MyStatus = PacketStatus.finished_failed;
//Then, we make a bad packet go out from here
WhereFrom.BadSprayCount = NB.NumBadPackets;
WhereFrom.BadPacketFromHere();
return false;
}
}
switch (what)
{
case NicType.lo:
case NicType.management_interface:
case NicType.none:
break; //Do nothing
case NicType.eth:
case NicType.wlan:
//see if it the packet dest is local to this nic
//if (tPacket.MyType == PacketType.dhcp_answer)
// Console.WriteLine("DHCP Answer");
foreach (NetworkInterface nf in interfaces.ToList())
{
if (tPacket.InboundNic != null && tPacket.InboundNic == this &&
tPacket.InboundInterface != null && tPacket.InboundInterface == nf)
continue; //skip sending it out this interface if it came in this interface.
if (tPacket.MyType == PacketType.dhcp_answer && tPacket.isFresh && tPacket.payloadIP != null && !nf.isLocal(tPacket.payloadIP))
continue; //If it is a dhcp broadcast, only send it out the interface it belongs to
if (tPacket.MyType == PacketType.arp_request && !nf.isLocal(tPacket.destIP))
continue; //only send out arp requests on local networks
nPacket = new Packet(tPacket);//Creates a new packet but sets isfresh=false
nPacket.OutboundIF = nf;
if(nf != null)
nPacket.TsourceIP = nf.myIP;
nPacket.InboundInterface = tPacket.InboundInterface;
nf.ProcessOutboundPacket(nPacket);
if (nPacket.MyStatus == PacketStatus.finished || nPacket.MyStatus == PacketStatus.finished_failed || nPacket.MyStatus == PacketStatus.finished_ok)
continue; //If the packet cannot be sent out (VLAN stuff)
if (tPacket.OutboundIP == null || (nf.isLocal(tPacket.OutboundIP) || (tPacket.OutboundIP.GetIPString == NB.BroadcastIPString && tPacket.isFresh)))
{
if ((nf != null && nf.myIP.GetIPString != NB.ZeroIPString) || nPacket.MyType == PacketType.dhcp_request)
{
//this means we have a local interface to send it out of
//if(nPacket.sourceMAC == null || nPacket.sourceMAC == "" || nPacket.isFresh)
nPacket.sourceMAC = MAC;
//If the source IP is empty then it is a new packet. We set the source to be us
if (nPacket.sourceIP == null || nPacket.sourceIP.GetIPString == NB.ZeroIPString)
nPacket.sourceIP = nf.myIP;
nPacket.TsourceIP = nf.myIP;
if (nPacket.destMAC == null || nPacket.destMAC == "")
{
nPacket.destMAC = WhereFrom.LookupArpFromIP(tPacket.OutboundIP.GetIPString);
if (nPacket.MyType == PacketType.arp_request)
{
nPacket.destMAC = NB.BroadcastMACString;
}
if(nPacket.destMAC == "")
{
nPacket.AddMessage(DebugLevel.info, string.Format(NB.Translate("NC_NoIPOnSubStr"), nPacket.destIP.GetIPString));
Network mynet = NB.GetNetwork();
NetworkDevice nd = mynet.GetDeviceFromID(myID);
string hostname = NB.Translate("NC_NoHost");
if (nd != null) hostname = nd.hostname;
nPacket.Tracking.Status = NB.LeftPad(hostname) + string.Format(NB.Translate("NC_NoIPOnSubStr"), hostname, nPacket.destIP.GetIPString);
nPacket.Tracking.Finished = true;
nPacket.MyStatus = PacketStatus.finished_failed;
return false;
}
}
nl = myNet.GetLinkFromID(ConnectedLink);
nPacket.StartOnLink(nl, WhereFrom); //This sends the packet down the link.
//Store outbound information here - som we expect the returning packet
WhereFrom.StoreOutgoingPacketInfo(nPacket);
myNet.addPacket(nPacket);
nPacket.PacketDump(myID.HostName + "-" + _nic_name, DebugPausePoint.packet_out);
madeprogress = true;
}
}
}
break;
case NicType.wan:
//see if it the packet dest is local to this nic
if (tPacket.MyType == PacketType.dhcp_answer && tPacket.isFresh)
break; //We do not broadcast out the WAN port
foreach (NetworkInterface nf in interfaces.ToList())
{
nPacket = new Packet(tPacket);//Creates a new packet but sets isfresh=false
nPacket.OutboundIF = nf;
nPacket.InboundInterface = tPacket.InboundInterface;
if (nf != null)
nPacket.TsourceIP = nf.myIP;
nf.ProcessOutboundPacket(nPacket);
if (nPacket.MyStatus == PacketStatus.finished || nPacket.MyStatus == PacketStatus.finished_failed || nPacket.MyStatus == PacketStatus.finished_ok)
continue; //If the packet cannot be sent out (VLAN stuff)
if (tPacket.OutboundIP != null && (nf.isLocal(tPacket.OutboundIP) || tPacket.OutboundIP.GetIPString == NB.BroadcastIPString))
{
if ((nf != null && nf.myIP != null && nf.myIP.GetIPString != NB.ZeroIPString) || nPacket.MyType == PacketType.dhcp_request)
{
//this means we have a local interface to send it out of
nPacket.sourceMAC = MAC;
//If the source IP is empty then it originated from here. We set the source to be us
if (nPacket.sourceIP == null || nPacket.sourceIP.GetIPString == NB.ZeroIPString)
{
nPacket.sourceIP = nf.myIP;
WhereFrom.StoreOutgoingPacketInfo(nPacket); //the packet is not masqueraded, just accepted
}
else
{
//When we leave the WAN port, we are masqueraded. Track that.
WhereFrom.StoreOutgoingPacketInfo(nPacket, ResponseToPacket.masq);
tPacket.TraversalInformation.AddPath(WhereFrom.hostname, TraversalTechnology.masquerade,""); //We just masqueraded
//Now, we masquerade the packet so it looks like it comes fromhere
nPacket.Tracking.AddMessage(DebugLevel.natting, WhereFrom.hostname, string.Format(NB.Translate("NC_ChangeIPStr"), nf.myIP.GetIPString));
nPacket.sourceIP = nf.myIP;
}
nPacket.TsourceIP = nf.myIP;
if (nPacket.destMAC == null || nPacket.destMAC == "")
{
nPacket.destMAC = WhereFrom.LookupArpFromIP(tPacket.OutboundIP.GetIPString);
if (nPacket.destMAC == "")
{
nPacket.AddMessage(DebugLevel.debug, string.Format(NB.Translate("NC_NoIPOnSubStr"), nPacket.destIP.GetIPString));
Network mynet = NB.GetNetwork();
NetworkDevice nd = mynet.GetDeviceFromID(myID);
string hostname = NB.Translate("NC_NoHost");
if (nd != null) hostname = nd.hostname;
nPacket.Tracking.Status = NB.LeftPad(hostname) + string.Format(NB.Translate("NC_NoIPOnSubStr"), nPacket.destIP.GetIPString);
nPacket.MyStatus = PacketStatus.finished_failed;
return false;
}
}
nl = myNet.GetLinkFromID(ConnectedLink);
nPacket.StartOnLink(nl, WhereFrom); //This sends the packet down the link.
//Store outbound information here - som we expect the returning packet
WhereFrom.StoreOutgoingPacketInfo(nPacket);
myNet.addPacket(nPacket);
nPacket.PacketDump(myID.HostName + "-" + _nic_name, DebugPausePoint.packet_out);
madeprogress = true;
}
}
}
break;
case NicType.tun:
case NicType.vpn:
foreach (NetworkInterface nf in interfaces.ToList())
{
//make sure the firewall allows this.
if (tPacket.WhereAmI != null && tPacket.WhereAmI is NetworkDevice)
{
NetworkDevice ND = (NetworkDevice)tPacket.WhereAmI;
if (tPacket.InboundInterface != null && nf != null && !ND.FirewallAllows(tPacket.InboundInterface.nic_name, nf.nic_name))
{
//The firewall might block it. Check to see if it is a response packet
ResponseToPacket rtp = ND.HowToRespondToPacket(tPacket);
if (rtp != ResponseToPacket.accept)
{
//If we are here, the packet is rejected.
string message = string.Format(NB.Translate("P_FirewallDropped"), ND.hostname);
tPacket.AddMessage(DebugLevel.filtering, message);
tPacket.Tracking.Status = message;
tPacket.Tracking.AddMessage(DebugLevel.info, ND, message);
tPacket.AddMessage(DebugLevel.info, message);
tPacket.MyStatus = PacketStatus.finished_ok;
break;
}
}
}
if (nf != null && nf.myIP != null && nf.myIP.GetIPString != NB.ZeroIPString)
{
//If the source IP is empty then it originated from here. We set the source to be us
if (tPacket.sourceIP == null || tPacket.sourceIP.GetIPString == NB.ZeroIPString)
{
tPacket.sourceIP = nf.myIP;
WhereFrom.StoreOutgoingPacketInfo(tPacket); //the packet is not yet tunneled
}
}
if (nf.isLocal(tPacket.OutboundIP, false))
{
//We need to tell the original packet that it is inside another packet
tPacket.MyStatus = PacketStatus.encapsulated;
tPacket.TraversalInformation.AddPath(WhereFrom.hostname, TraversalTechnology.vpn, NicName()); //We just started a VPN
tPacket.TsourceIP = nf.myIP;
tPacket.destMAC = WhereFrom.LookupArpFromIP(tPacket.OutboundIP.GetIPString);
if (nf != null)
tPacket.TsourceIP = nf.myIP;
//We need to make a new, tunnel packet
if (myNicType == NicType.tun)
EncryptionKey = "";
Packet rnPacket = new Packet(tPacket);
WhereFrom.TunnelPacketFromHere(TunnelEndpoint, rnPacket, EncryptionKey);
//We need to send the new packet on (pass it back to the device to process)
madeprogress = true;
if(EncryptionKey != "")
tPacket.TraversalInformation.AddPath(WhereFrom.hostname, TraversalTechnology.vpn_encryption,NicName()); //We the packet is "encrypted"
}
}
break;
case NicType.port:
case NicType.wport:
if (tPacket.InboundNic == this)
break; //This is the port we came in on. Do not sent it back out this port
foreach (NetworkInterface nf in interfaces.ToList())
{
nPacket = new Packet(tPacket);
nPacket.OutboundIF = nf;
nPacket.InboundInterface = tPacket.InboundInterface;
nf.ProcessOutboundPacket(nPacket);
if (nPacket.MyStatus == PacketStatus.finished || nPacket.MyStatus == PacketStatus.finished_failed || nPacket.MyStatus == PacketStatus.finished_ok)
continue; //If the packet cannot be sent out (VLAN stuff)
if ((tPacket.InboundNic != null && tPacket.InboundNic.GetNicType == NicType.wan) || tPacket.InboundNic == null || tPacket.destMAC == "")
{
//We need to find destination MAC and set source MAC
if (nPacket.sourceMAC == null || nPacket.sourceMAC == "" || nPacket.isFresh)
nPacket.sourceMAC = MAC;
//Update the MAC
string getMAC = "";
if (tPacket.OutboundIP != null)
getMAC = WhereFrom.LookupArpFromIP(tPacket.OutboundIP.GetIPString);
else if (tPacket.destIP != null)
getMAC = WhereFrom.LookupArpFromIP(tPacket.destIP.GetIPString);
if (getMAC != "") nPacket.destMAC = getMAC;
if (nPacket.MyType == PacketType.arp_request)
{
nPacket.destMAC = NB.BroadcastMACString;
}
if (nPacket.destMAC == "")
{
nPacket.AddMessage(DebugLevel.debug, String.Format(NB.Translate("NC_NoIPOnSubStr"), nPacket.destIP.GetIPString));
Network mynet = NB.GetNetwork();
NetworkDevice nd = mynet.GetDeviceFromID(myID);
string hostname = NB.Translate("NC_NoHost");
if (nd != null) hostname = nd.hostname;
nPacket.Tracking.Status = NB.LeftPad(hostname) + String.Format(NB.Translate("NC_NoIPOnSubStr"), nPacket.destIP.GetIPString);
nPacket.MyStatus = PacketStatus.finished_failed;
return false;
}
}
if (HasBroadcastAddresses(tPacket.destIP))
{
//Broadcast packets will go to everything and we want a response from all of them.
nPacket.Tracking = PacketMessage.Clone(tPacket.Tracking);
}
if (nPacket.sourceMAC == null || nPacket.sourceMAC == "")
{
//Need to find the managament interface MAC
nPacket.sourceMAC = WhereFrom.HubManagementMAC();
}
if ((nPacket.sourceIP == null || nPacket.sourceIP.GetIPString == NB.ZeroIPString) && nPacket.MyType != PacketType.dhcp_request)
{
//set it to be the ip of management interface
nPacket.sourceIP = WhereFrom.HubManagementIP();
nPacket.sourceMAC = MAC;
}
if (nPacket.destMAC == null || nPacket.destMAC == "" && tPacket.OutboundIP != null)
{
nPacket.destMAC = WhereFrom.LookupArpFromIP(tPacket.OutboundIP.GetIPString);
}
if (nPacket.TsourceIP == null)
nPacket.TsourceIP = WhereFrom.HubManagementIP();
nl = myNet.GetLinkFromID(ConnectedLink);
if (nl == null)
break;
if ((nPacket.sourceIP == null || nPacket.sourceIP.GetIPString == NB.ZeroIPString) && tPacket.MyType != PacketType.dhcp_request) return false; //We still have no IP. Do not send the packet out.
nPacket.StartOnLink(nl, WhereFrom); //This sends the packet down the link.
myNet.addPacket(nPacket);
if (tPacket.isFresh)
WhereFrom.StoreOutgoingPacketInfo(nPacket); //if it originated from here...
madeprogress = true;
nPacket.PacketDump(myID.HostName, DebugPausePoint.packet_out);
}
break;
}
return madeprogress;
}
public void ProcessInboundPacket(Packet tPacket)
{
Network mynet;
NetworkDevice nd;
//We make sure the MAC matches.
mynet = NB.GetNetwork();
nd = mynet.GetDeviceFromID(myID);
if (mynet.ItemHasTest(nd.hostname, NicName(), NetTestType.DeviceNICSprays))
{
if (!mynet.ItemTestIsComplete(nd.hostname, NicName(), NetTestType.DeviceNICSprays))
{
//We should drop the current packet.
tPacket.AddMessage(DebugLevel.info, NB.Translate("N_ProssShouldContinTime"));
tPacket.Tracking.Status = NB.Translate("N_ProssShouldContinTime");
tPacket.MyStatus = PacketStatus.finished_failed;
//Then, we make a bad packet go out from here
nd.BadPacketFromHere();
nd.BadSprayCount = NB.NumBadPackets;
}
}
if (mynet.ItemHasTest(nd.hostname,NetTestType.DeviceIsFrozen))
{
if(!mynet.ItemTestIsComplete(nd.hostname, NetTestType.DeviceIsFrozen))
{
//the device is busted and nonfunctional. No response.
tPacket.AddMessage(DebugLevel.info, NB.Translate("N_ProssShouldContinTimeout"));
tPacket.Tracking.Status = NB.Translate("N_ProssShouldContinTimeout");
tPacket.MyStatus = PacketStatus.finished_failed;
}
}
if (nd.IsBurned)
{
//the device is busted and nonfunctional. No response.
tPacket.AddMessage(DebugLevel.info, NB.Translate("NC_Burned"));
tPacket.Tracking.Status = NB.Translate("NC_Burned");
tPacket.MyStatus = PacketStatus.finished_failed;
}
if (tPacket == null) return;
tPacket.InboundNic = this; //track which nic we came in on.
if (myNicType == NicType.port || myNicType == NicType.wport || (nd.IsWirelessForwarder() && (myNicType == NicType.wlan ||
(myNicType == NicType.eth && nd.GetNetType() == NetworkComponentType.wap ))))
{
//Try tracking the arp if we can
if (tPacket.TsourceIP == null) tPacket.TsourceIP = tPacket.sourceIP;
nd.StoreArp(tPacket.sourceMAC, tPacket.TsourceIP.GetIP.ToIpString(), myID);
//If it is a return DHCP packet. We should try to update the MAC
if (tPacket.MyType == PacketType.dhcp_answer)
{
HostNicID otherid = nd.NicIDFromArp(tPacket.destMAC);
if (otherid.HostID != -1)
{
string ipstring = NB.ZeroIPString;
if (tPacket.payloadIP != null)
ipstring = tPacket.payloadIP.GetIPString;
nd.StoreArp(tPacket.destMAC, ipstring, otherid);
}
}
return;
}
if(myNicType == NicType.wan)
{
mynet = NB.GetNetwork();
nd = mynet.GetDeviceFromID(myID);
if (nd.HowToRespondToPacket(tPacket) == ResponseToPacket.masq)
{
NB_IPAddress oAddress = nd.PacketMasqueradeSource(tPacket);
if(oAddress != null)
{
tPacket.Tracking.AddMessage(DebugLevel.natting, nd.hostname, string.Format(NB.Translate("NC_ChangeIPBackStr"), oAddress.GetIPString));
tPacket.destIP = oAddress;
}
}
else if(!HasIP(tPacket.destIP.GetIP))
{
tPacket.AddMessage(DebugLevel.routing, NB.Translate("NC_ProssInPackReject"));
tPacket.AddMessage(DebugLevel.debug, NB.Translate("NC_ProssInPackExpect"));
mynet = NB.GetNetwork();
nd = mynet.GetDeviceFromID(myID);
string hostname = NB.Translate("NC_NoHost");
if (nd != null) hostname = nd.hostname;
tPacket.Tracking.Status = string.Format(NB.Translate("NC_PackRejectStr"), hostname) ;
tPacket.MyStatus = PacketStatus.finished_failed;
}
}
if(tPacket.destMAC == MAC || tPacket.destMAC == NB.BroadcastMACString || myNicType == NicType.port)
{
//It matches. We are ok. Anything to do?
//If the NIC is a vpn, do that here.
}
else
{
tPacket.AddMessage(DebugLevel.routing,NB.Translate("NC_ProcessInboundPacket_DifferentMachine1"));
tPacket.AddMessage(DebugLevel.debug, string.Format(" " + NB.Translate("NC_ProcessInboundPacket_DifferentMachine2"), MAC, tPacket.destMAC));
mynet = NB.GetNetwork();
nd = mynet.GetDeviceFromID(myID);
string hostname = NB.Translate("NC_NoHost");
if (nd != null) hostname = nd.hostname;
tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + NB.Translate("NC_ProcessInboundPacket_DifferentMachine3");
tPacket.MyStatus = PacketStatus.finished_failed;
}
}
public void ClearIPs()
{
foreach(NetworkInterface nf in interfaces)
{
if (myNicType != NicType.lo)
{
if(myNicType != NicType.port)
nf.myIP = new NB_IPAddress(NB.ZeroIPString); //do not do this for ports (have no IP)
nf.SetVLANTag(1, VLANTagType.Untagged);
}
}
}
public void UpdateAllNicsVLANInfoAfterClone()
{
foreach (NetworkInterface nf in interfaces)
{
nf.UpdateVLANsAfterClone();
}
}
public void LockUsOutOfCard()
{
foreach (NetworkInterface nf in interfaces)
{
if (myNicType != NicType.lo)
{
nf.myIP = new NB_IPAddress(NB.ZeroIPString);
nf.LockOutVLANInterface();
}
}
}
public NetworkInterface InterfaceFromVlanTag(Packet tPacket)
{
int ID = tPacket.VLANID;
return InterfaceFromVlanTag(ID);
}
public NetworkInterface InterfaceFromVlanTag(int ID)
{
foreach (NetworkInterface oneIF in interfaces)
{
if (oneIF.GetVLANTag(ID) != VLANTagType.Forbidden)
return oneIF;
}
return null;
}
public NetworkInterface InterfaceFromName(string InterfaceName)
{
foreach (NetworkInterface oneIF in interfaces)
{
if (oneIF.nic_name == InterfaceName)
return oneIF;
}
return null;
}
public string AllInterfacesString(bool UseCidr= false)
{
string thestring = "";
foreach (NetworkInterface oneIF in interfaces)
{
if (thestring != "") thestring += ",";
thestring += oneIF.InterfaceString(UseCidr);
}
return thestring;
}
public NB_IPAddress FirstIP()
{
List<NB_IPAddress> addresses = IPAddressList();
if (addresses.Count > 0)
return addresses[0];
else
return new NB_IPAddress(NB.ZeroIPString);
}
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);
}
}
}
}