882 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			882 lines
		
	
	
		
			40 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 (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);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|     }
 | |
| }
 |