diff --git a/EduNetworkBuilder/NetworkCard.cs b/EduNetworkBuilder/NetworkCard.cs index 36c3e73..acc73c1 100644 --- a/EduNetworkBuilder/NetworkCard.cs +++ b/EduNetworkBuilder/NetworkCard.cs @@ -265,9 +265,37 @@ namespace EduNetworkBuilder 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() { - NetworkInterface iface = new NetworkInterface(NicName(), NB.ZeroIPString, NB.ZeroIPString, myID); + 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); } @@ -378,7 +406,11 @@ namespace EduNetworkBuilder /// null if no interface is local. Otherwise, it returns the one that matches the packet public NetworkInterface LocalInterface(IPAddress theIP, PacketMessage Tracker) { - if (myNicType == NicType.port) return null; //ports have no local interfaces + 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)) @@ -431,6 +463,9 @@ namespace EduNetworkBuilder 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 + 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) @@ -480,6 +515,10 @@ namespace EduNetworkBuilder foreach (NetworkInterface nf in interfaces.ToList()) { nPacket = new Packet(tPacket);//Creates a new packet but sets isfresh=false + 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) @@ -553,80 +592,80 @@ namespace EduNetworkBuilder 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 == "") + foreach (NetworkInterface nf in interfaces.ToList()) { - //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; - } + nPacket = new Packet(tPacket); - if (nPacket.destMAC == "") + 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 == "") { - 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; + //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; + 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); } - 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) { diff --git a/EduNetworkBuilder/NetworkDevice.cs b/EduNetworkBuilder/NetworkDevice.cs index 969d434..50ee951 100644 --- a/EduNetworkBuilder/NetworkDevice.cs +++ b/EduNetworkBuilder/NetworkDevice.cs @@ -1078,6 +1078,10 @@ namespace EduNetworkBuilder return true; if (myType == NetworkComponentType.wrouter) return true; + if (myType == NetworkComponentType.firewall) + return true; + if (myType == NetworkComponentType.router) + return true; return false; } diff --git a/EduNetworkBuilder/NetworkInterface.cs b/EduNetworkBuilder/NetworkInterface.cs index 7ef0e92..a61dee9 100644 --- a/EduNetworkBuilder/NetworkInterface.cs +++ b/EduNetworkBuilder/NetworkInterface.cs @@ -156,12 +156,73 @@ namespace EduNetworkBuilder /// public void ProcessOutboundPacket(Packet tPacket) { - tPacket.InboundInterface = null; //forget the interface we had come in on now that we are leaving. - if (tPacket.sourceIP == null || tPacket.sourceIP.GetIP.ToIpString() == NB.ZeroIPString) + //tPacket.InboundInterface = null; //forget the interface we had come in on now that we are leaving. + //if (tPacket.sourceIP == null || tPacket.sourceIP.GetIP.ToIpString() == NB.ZeroIPString) + //{ + // //This happens if we are starting a new packet. We should also do this if we are masquerading. + // tPacket.sourceIP = new IPAddress(myIP.GetIP.ToIpString(), "", IPAddressType.ip_only); //We only want the IP address + //} + //VLAN stuff + VLANInfo VI = GetVLANInfo(tPacket.VLANID); + VLANTagType What = VI.Tag; + Network theNet = NB.GetNetwork(); + NetworkDevice HD = theNet.GetDeviceFromID(AttachedToHostNic); + string hostname = HD.hostname; + + if (What == VLANTagType.Forbidden) { - //This happens if we are starting a new packet. We should also do this if we are masquerading. - tPacket.sourceIP = new IPAddress(myIP.GetIP.ToIpString(), "", IPAddressType.ip_only); //We only want the IP address + //we drop it silently + string errString = string.Format(NB.Translate("NI_VLANOut"), hostname, tPacket.destIP.GetIPString); + tPacket.AddMessage(DebugLevel.switching, errString); + tPacket.Tracking.Status = errString; + tPacket.MyStatus = PacketStatus.finished_ok; + return; } + if(What == VLANTagType.Untagged) + { + //We strip off the tagging + tPacket.VLANID = 1; //set to the default vlan + } + if(What == VLANTagType.Tagged) + { + //We actually do not do anything. The tag remains intact. + tPacket.VLANID = VI.ID; + } + } + + private VLANInfo IncomingVLAN(int ID) + { + //Search through incoming vlan stuff to find the right one + //If the packet is tagged with the ID, and the port is tagged, return that + //If the packet is untagged, return the one that is untagged + VLANInfo newVLANinfo = null; + if (ID != 1) //It is tagged + { + foreach(VLANInfo vi in VLANs) + { + if (vi.ID == ID) return vi; + } + //We do not have one set yet. Add a new one + newVLANinfo = new VLANInfo(ID, VLANTagType.Forbidden); + VLANs.Add(newVLANinfo); + return newVLANinfo; + } + else //the packet is the default vlan (1) so appears untagged. + { + foreach (VLANInfo vi in VLANs) + { + if (vi.Tag == VLANTagType.Untagged) return vi; + } + //We do not have an "untagged" vlan. Return the settings for vlan1 + foreach (VLANInfo vi in VLANs) + { + if (vi.ID == 1) return vi; + } + } + //We should never get here. This is just a fall-through + newVLANinfo = new VLANInfo(ID, VLANTagType.Forbidden); + VLANs.Add(newVLANinfo); + return newVLANinfo; } public void ProcessInboundPacket(Packet tPacket) @@ -177,6 +238,52 @@ namespace EduNetworkBuilder { //anything we should do here? //Mainly vlan if we are a vlan. + VLANInfo VI = IncomingVLAN(tPacket.VLANID); + VLANTagType What = VI.Tag; + Network theNet = NB.GetNetwork(); + NetworkDevice HD = theNet.GetDeviceFromID(AttachedToHostNic); + string hostname = HD.hostname; + + if (What == VLANTagType.Forbidden) + { + //This vlan packet is deliberately forbidden. Reject it (fail) + string errString = string.Format(NB.Translate("NI_VLANInForbidden"), hostname, tPacket.destIP.GetIPString); + tPacket.AddMessage(DebugLevel.switching, errString); + tPacket.Tracking.Status = errString; + tPacket.MyStatus = PacketStatus.finished_ok; + return; + } + if (What == VLANTagType.Untagged) + { + //If it is 1 (default vlan), this is OK. Otherwise drop. + //Untagged means we expect it to be vlan of 1 on the cable side + if(tPacket.VLANID != 1) + { + //Oops. We need to reject the packet + string errString = string.Format(NB.Translate("NI_VLANInUntagged"), hostname, tPacket.destIP.GetIPString); + tPacket.AddMessage(DebugLevel.switching, errString); + tPacket.Tracking.Status = errString; + tPacket.MyStatus = PacketStatus.finished_ok; + return; + } + else //We need to tag the packet with the new VLAN-ID + { + tPacket.VLANID = VI.ID; //The packet is ow tagged + } + } + if (What == VLANTagType.Tagged) + { + //If the packet is tagged, and the vlan expected tagged, all is good. + if(tPacket.VLANID != VI.ID) + { + //Oops. We need to reject the packet + string errString = string.Format(NB.Translate("NI_VLANInMisMatch"), hostname, tPacket.destIP.GetIPString); + tPacket.AddMessage(DebugLevel.switching, errString); + tPacket.Tracking.Status = errString; + tPacket.MyStatus = PacketStatus.finished_ok; + return; + } + } } } diff --git a/EduNetworkBuilder/Resources/languages/edustrings.resx b/EduNetworkBuilder/Resources/languages/edustrings.resx index cec040a..7ea93a3 100644 --- a/EduNetworkBuilder/Resources/languages/edustrings.resx +++ b/EduNetworkBuilder/Resources/languages/edustrings.resx @@ -1513,4 +1513,20 @@ VLANs DeviceConfig bntVLAN = VLANs + + Packet forbidden to enter into this port. + NI_VLANInForbidden = Packet forbidden to enter into this port. + + + Packet and port do not match on VLANs. The packet cannot enter this device + NI_VLANInMisMatch + + + Packet is expected to be untagged, but it is tagged. + NI_VLANInUntagged = Packet is expected to be untagged, but it is tagged. + + + Packed forbidden to go out this port + NI_VLANOut = Packed forbidden to go out this port + \ No newline at end of file