893 lines
41 KiB
C#
893 lines
41 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;
|
|
|
|
|
|
namespace EduNetworkBuilder
|
|
{
|
|
[Serializable]
|
|
public class NetworkCard
|
|
{
|
|
public string MAC = NB.GenerateMACAddress(); //Technically we should make sure it is unique
|
|
List<NetworkInterface> interfaces = new List<NetworkInterface>();
|
|
public bool UsesDHCP = false;
|
|
public bool CanUseDHCP = false;
|
|
public bool MustUseDHCP = false;
|
|
private NicType myNicType = NicType.eth;
|
|
public HostNicID myID;
|
|
public int ConnectedLink=-1; //The link that is connected to this nic.
|
|
private int UniqueIdentifier = NB.GetUniqueIdentifier();
|
|
private string _nic_name="";
|
|
public 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(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(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 IPAddress(Individual);
|
|
break;
|
|
case "encryptionkey":
|
|
EncryptionKey = Individual.InnerText;
|
|
break;
|
|
case "ssid":
|
|
SSID = Individual.InnerText;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
ApplyNicRules();
|
|
SetIPForDHCP();
|
|
}
|
|
|
|
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<IPAddress> IPAddressList()
|
|
{
|
|
List<IPAddress> theIPs = new List<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(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(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(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(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(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;
|
|
|
|
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.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,NetTestType.DeviceIsBad))
|
|
{
|
|
if(!mynet.ItemTestIsComplete(nd.hostname, NetTestType.DeviceIsBad))
|
|
{
|
|
//the device is busted and nonfunctional. No response.
|
|
tPacket.AddMessage(DebugLevel.info, "");
|
|
tPacket.Tracking.Status = "";
|
|
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)
|
|
{
|
|
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)
|
|
{
|
|
nf.myIP = new IPAddress(NB.ZeroIPString);
|
|
nf.SetVLANTag(1, VLANTagType.Untagged);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void LockUsOutOfCard()
|
|
{
|
|
foreach (NetworkInterface nf in interfaces)
|
|
{
|
|
if (myNicType != NicType.lo)
|
|
{
|
|
nf.myIP = new 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 IPAddress FirstIP()
|
|
{
|
|
List<IPAddress> addresses = IPAddressList();
|
|
if (addresses.Count > 0)
|
|
return addresses[0];
|
|
else
|
|
return new 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);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|