727 lines
33 KiB
C#
727 lines
33 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;
|
|
|
|
|
|
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 NetworkCard(int index, int HostID, string hostname, NicType theType = NicType.eth)
|
|
{
|
|
myNicType = theType;
|
|
_nic_name = myNicType.ToString() + index.ToString();
|
|
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);
|
|
myID = new HostNicID(HostID, UniqueIdentifier,hostname,nInterface.nic_name);
|
|
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)
|
|
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)
|
|
{
|
|
if (index < 0 || index > interfaces.Count())
|
|
return;
|
|
interfaces[index].EditAddress();
|
|
}
|
|
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);
|
|
}
|
|
public void AddInterface()
|
|
{
|
|
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 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) 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, "Found local interface: ip" + nIF.myIP.GetIP.ToIpString() +
|
|
" gw:" + nIF.myIP.GetMask.ToIpString());
|
|
if(Tracker != null && theIP != null)
|
|
Tracker.AddMessage(DebugLevel.routing, myID.HostName, " IP of local: " + theIP.GetIPString + " " + theIP.GetGateway.ToIpString());
|
|
return nIF;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
public NetworkInterface PrimaryInterface()
|
|
{
|
|
if (interfaces.Count == 1)
|
|
return interfaces[0];
|
|
return null;
|
|
}
|
|
|
|
/***************************************
|
|
*
|
|
* *************************************/
|
|
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
|
|
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.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
|
|
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.debug, " No Machine matching that IP address on this subnet. " + nPacket.destIP.GetIPString);
|
|
Network mynet = NB.GetNetwork();
|
|
NetworkDevice nd = mynet.GetDeviceFromID(myID);
|
|
string hostname = "No Host";
|
|
if (nd != null) hostname = nd.hostname;
|
|
nPacket.Tracking.Status = hostname + " No Machine matching that IP address on this subnet. " + 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.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
|
|
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);
|
|
//Now, we masquerade the packet so it looks like it comes fromhere
|
|
nPacket.Tracking.AddMessage(DebugLevel.natting, WhereFrom.hostname, "MASQ: Changing outbound IP to: " + 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, " No Machine matching that IP address on this subnet. " + nPacket.destIP.GetIPString);
|
|
Network mynet = NB.GetNetwork();
|
|
NetworkDevice nd = mynet.GetDeviceFromID(myID);
|
|
string hostname = "No Host";
|
|
if (nd != null) hostname = nd.hostname;
|
|
nPacket.Tracking.Status = hostname + " No Machine matching that IP address on this subnet. " + 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())
|
|
{
|
|
if (nf.isLocal(tPacket.OutboundIP, false))
|
|
{
|
|
//We need to tell the original packet that it is inside another packet
|
|
tPacket.MyStatus = PacketStatus.encapsulated;
|
|
tPacket.TsourceIP = nf.myIP;
|
|
tPacket.destMAC = WhereFrom.LookupArpFromIP(tPacket.OutboundIP.GetIPString);
|
|
|
|
//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;
|
|
}
|
|
}
|
|
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
|
|
nPacket = new Packet(tPacket);
|
|
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, " No Machine matching that IP address on this subnet. " + nPacket.destIP.GetIPString);
|
|
Network mynet = NB.GetNetwork();
|
|
NetworkDevice nd = mynet.GetDeviceFromID(myID);
|
|
string hostname = "No Host";
|
|
if (nd != null) hostname = nd.hostname;
|
|
nPacket.Tracking.Status = hostname + " No Machine matching that IP address on this subnet. " + 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;
|
|
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;
|
|
}
|
|
|
|
//********************Process Packet ********
|
|
public void ProcessOutboundPacket(Packet tPacket)
|
|
{
|
|
//We set the MAC addrss to this nic
|
|
tPacket.sourceMAC = MAC;
|
|
|
|
//If the nic has a special function, we need to do that too.
|
|
// VPN, etc
|
|
}
|
|
|
|
public void ProcessInboundPacket(Packet tPacket)
|
|
{
|
|
Network mynet;
|
|
NetworkDevice nd;
|
|
//We make sure the MAC matches.
|
|
mynet = NB.GetNetwork();
|
|
nd = mynet.GetDeviceFromID(myID);
|
|
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, "MASQ: Changing source IP back to: " + oAddress.GetIPString);
|
|
tPacket.destIP = oAddress;
|
|
}
|
|
}
|
|
else if(!HasIP(tPacket.destIP.GetIP))
|
|
{
|
|
tPacket.AddMessage(DebugLevel.routing, "The packet was rejected by the firewall.");
|
|
tPacket.AddMessage(DebugLevel.debug, " The packet was not expected by the firewall, so it was rejected.");
|
|
mynet = NB.GetNetwork();
|
|
nd = mynet.GetDeviceFromID(myID);
|
|
string hostname = "No Host";
|
|
if (nd != null) hostname = nd.hostname;
|
|
tPacket.Tracking.Status = hostname + " The packet was rejected by the firewall.. Dropped.";
|
|
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,"The Packet was destined for a different machine (MAC Address): Rejected");
|
|
tPacket.AddMessage(DebugLevel.debug, " Device MAC: " + MAC + " did not match packet: " + tPacket.destMAC);
|
|
mynet = NB.GetNetwork();
|
|
nd = mynet.GetDeviceFromID(myID);
|
|
string hostname = "No Host";
|
|
if (nd != null) hostname = nd.hostname;
|
|
tPacket.Tracking.Status = hostname + " Packet destined for another machine. Dropped.";
|
|
tPacket.MyStatus = PacketStatus.finished_failed;
|
|
}
|
|
}
|
|
|
|
public void ClearIPs()
|
|
{
|
|
foreach(NetworkInterface nf in interfaces)
|
|
{
|
|
if(myNicType != NicType.lo)
|
|
nf.myIP = new IPAddress(NB.ZeroIPString);
|
|
}
|
|
}
|
|
|
|
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("The type must be serializable.", "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);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|