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