Basic renumbering working. Will blow up on a machine with multiple network interfaces.

This commit is contained in:
Tim Young 2019-03-07 17:02:49 +03:00
parent e27d960403
commit 073cba135e
4 changed files with 365 additions and 21 deletions

View File

@ -242,7 +242,7 @@ namespace EduNetworkBuilder
}
/// <summary>
/// Return the number of hosts in the subnet.
/// Return the list of hosts in the subnet.
/// </summary>
/// <returns></returns>
public IEnumerable<UInt32> Hosts()

View File

@ -6,6 +6,180 @@ using System.Threading.Tasks;
namespace EduNetworkBuilder
{
public class NBRenumberer
{
private bool renumbered = false;
public List<NBRenumberData> ListOfItems = new List<NBRenumberData>();
public void Count(string what)
{
NBRenumberData entry = DataFromName(what);
if(entry != null)
{
entry.ActiveCount++;
return;
}
//If we get here, we have not found it yet.
NBRenumberData One = new NBRenumberData(what, ListOfItems.Count);
One.ActiveCount++;
ListOfItems.Add(One);
}
public void SetAsGateway(string what)
{
NBRenumberData GW = DataFromName(what);
if (GW == null) {
GW = new NBRenumberData(what, ListOfItems.Count);
ListOfItems.Add(GW);
}
GW.isTheGateway = true;
GW.UpdateSortOrder();
//We can only have one gateway. Make sure all the rest are set not to be the GW
foreach(NBRenumberData one in ListOfItems)
{
if (one != GW) {
one.isTheGateway = false;
one.UpdateSortOrder();
}
}
}
public NBRenumberData DataFromName(string hostname)
{
foreach (NBRenumberData NBRD in ListOfItems)
{
if (NBRD.Hostname == hostname)
{
return NBRD;
}
}
return null;
}
public bool TryRenumbering(NB_IPAddress Network, NB_IPAddress Gateway)
{
renumbered = true;
//Separate out the devices by type
// Find the gateway too
int biggestcount = 0;
int spacing = 10;
bool HasGateway = false;
foreach (NBRenumberData NBRD in ListOfItems)
{
if (NBRD.ActiveCount > biggestcount) biggestcount = NBRD.ActiveCount;
}
//now, we can prune off everything that is not part of biggestcount.
for(int i=ListOfItems.Count-1; i>=0; i--)
{
if (ListOfItems[i].ActiveCount != biggestcount)
ListOfItems.RemoveAt(i);
else
{
if (ListOfItems[i].isTheGateway) HasGateway = true;
ListOfItems[i].SuggestedIP = "";
}
}
if (!HasGateway)
for (int i = ListOfItems.Count - 1; i >= 0; i--)
{
if (ListOfItems[i].Device.HasIPAddress(Gateway))
SetAsGateway(ListOfItems[i].Hostname);
}
int switches = 0;
int servers = 0;
int printers = 0;
int wireless = 0;
int clients = 0;
foreach(NBRenumberData NBRD in ListOfItems)
{
switch(NBRD.TypeString())
{
case "client":
clients++;
break;
case "printer":
printers++;
break;
case "switch":
switches++;
break;
case "server":
servers++;
break;
case "wireless":
wireless++;
break;
}
}
//Decide on which way we want to do this.
biggestcount = 0;
if (servers > biggestcount) biggestcount = servers;
if (switches > biggestcount) biggestcount = switches;
if (printers > biggestcount) biggestcount = printers;
if (wireless > biggestcount) biggestcount = wireless;
if (clients > biggestcount) biggestcount = clients;
ListOfItems.Sort((p, q) => p.sortorder.CompareTo(q.sortorder));
//If it works to do 10 for each bunch, do that. Otherwise, see what the smallest bunch that works is.
if (biggestcount < 10)
{
spacing = 10;
}
if (biggestcount > 10)
spacing = 99; //Don't bother with anything fancy. Punt if it does not fit the first time
//Fallback is to simply count up from the gateway.
if (Network.NumberOfHosts < ListOfItems.Count)
return false;
if(spacing * 5 > Network.NumberOfHosts)
{
renumberlist(Network, 1, "");
}
else
{
//We can do this in parts
renumberlist(Network, 1, "Gateway");
renumberlist(Network, 2, "server");
renumberlist(Network, spacing * 1, "switch");
renumberlist(Network, spacing * 2, "wireless");
renumberlist(Network, spacing * 3, "printer");
renumberlist(Network, spacing * 4, "client");
}
return true;
}
private void renumberlist(NB_IPAddress Network, int Base, string filter)
{
int count = Base;
for (int i = 0; i < ListOfItems.Count; i++)
{
if (ListOfItems[i].SuggestedIP != "") continue;
if (filter == "" || ListOfItems[i].TypeString() == filter || filter == "Gateway" && ListOfItems[i].isTheGateway)
{
NB_IPAddress next = new NB_IPAddress(Network);
next._ip += (UInt32)count;
ListOfItems[i].SuggestedIP = next.GetIPString;
count++;
}
}
}
public void DoRenumbering(NB_IPAddress Network, NB_IPAddress Gateway, int vlanID)
{
if (!renumbered) TryRenumbering(Network, Gateway);
//loop through and set all the IPs and the gateway IP if not DHCPS
for(int i = 0; i < ListOfItems.Count; i++)
{
ListOfItems[i].Device.RenumberIP(ListOfItems[i].SuggestedIP, Gateway, vlanID);
}
}
}
public class NBRenumberData
{
public string Hostname = "";
@ -19,7 +193,12 @@ namespace EduNetworkBuilder
public int ActiveCount=0;
public string nicname;
public string SuggestedIP;
public int sortorder = 0;
private int _index = 0;
public NetworkComponentType mytype = NetworkComponentType.none;
public bool isTheGateway = false;
private bool _isRouter = false;
/// <summary>
/// Return true if the Device specified by hostname does routing.
@ -36,5 +215,79 @@ namespace EduNetworkBuilder
return false;
}
}
public NBRenumberData(string hostname, int index)
{
Hostname = hostname;
NetworkDevice nd = Device;
mytype = nd.myType;
_index = index;
UpdateSortOrder();
}
public void UpdateSortOrder()
{
switch (TypeString())
{
case "client":
sortorder=5000;
break;
case "printer":
sortorder = 4000;
break;
case "switch":
sortorder=2000;
break;
case "server":
sortorder=1000;
break;
case "wireless":
sortorder=3000;
break;
}
sortorder = sortorder + _index;
if (isTheGateway) sortorder = 0;
}
public string TypeString()
{
string what = "";
switch (mytype)
{
case NetworkComponentType.cellphone:
case NetworkComponentType.ip_phone:
case NetworkComponentType.laptop:
case NetworkComponentType.pc:
case NetworkComponentType.tablet:
what = "client";
break;
case NetworkComponentType.printer:
case NetworkComponentType.copier:
what = "printer";
break;
case NetworkComponentType.net_hub:
case NetworkComponentType.net_switch:
what = "switch";
break;
case NetworkComponentType.firewall:
case NetworkComponentType.router:
case NetworkComponentType.server:
what = "server";
break;
case NetworkComponentType.wap:
case NetworkComponentType.wbridge:
case NetworkComponentType.wrepeater:
case NetworkComponentType.wrouter:
what = "wireless";
break;
}
return what;
}
}
}

View File

@ -1155,6 +1155,13 @@ namespace EduNetworkBuilder
//do it
if (ItemsSelected.Count > 0)
{
//This next entry should never happen.
if (ItemsSelected.Count < 2)
{
MessageBox.Show("You need to have more items selected");
return;
}
int ChosenVlanID = 1;
if(myNetwork != null && myNetwork.VLANsEnabled)
{
@ -1177,13 +1184,6 @@ namespace EduNetworkBuilder
IPAddressEntry IPE = new IPAddressEntry(prompted, null, this, false);
//This next entry should never happen.
if (ItemsSelected.Count < 2)
{
MessageBox.Show("You need to have more items selected");
return;
}
//Read in the settings we will use
IPE.ShowAsSubnetGateway();
@ -1222,10 +1222,59 @@ namespace EduNetworkBuilder
}
if (gwDevice == null) return; //No gateway device selected
NBRenumberer Renumberer = new NBRenumberer();
//If we get here, we have a gateway and a list of items to renumber.
for (int i = ItemsSelected.Count - 1; i >= 0; i--)
//Loop through all the items
//Find find all connected items
//loop through all connected items & count them (excluding them if they are not selected)
//set the gateway.
//count them and exclude items that are not within the threshhold.
foreach(NetworkDevice one in ItemsSelected)
{
List<NetworkDevice> alreadydone = new List<NetworkDevice>();
List<NetworkDevice> connections = one.ConnectedTo();
for(int i=0; i< connections.Count; i++)
{
NetworkDevice connection = connections[i];
//If we have not done it yet
if (!ItemsSelected.Contains(connection))
continue;
if (myNetwork.VLANsEnabled && (ChosenVlanID != connection.PrimaryVLAN() && connection.myType != NetworkComponentType.net_switch))
continue; //Skip the device if it is not on the primary vlan, and is not a switch (asuming switches are taggexd)
if (!alreadydone.Contains(connection))
{
alreadydone.Add(connection);
if(!connection.RoutesPackets() || connection.myType == NetworkComponentType.wrouter)
connections.AddRange(connection.ConnectedTo(true));
Renumberer.Count(connection.hostname);
}
}
}
Renumberer.SetAsGateway(gwDevice.hostname);
Renumberer.TryRenumbering(network, gw);
if (Renumberer.ListOfItems.Count > network.NumberOfHosts)
{
//Not enough room in the subnet for the various items.
MessageBox.Show("There are not enough IP addresses in the subnet you specified for the number of items we need to renumber.");
return;
}
//We should print off the things we are hoping to do.
string message = "What we are trying to do:\n";
foreach(NBRenumberData NBRD in Renumberer.ListOfItems)
{
message += NBRD.Hostname + " " + NBRD.TypeString() + " -> " + NBRD.SuggestedIP + "\n";
}
DialogResult answer = MessageBox.Show(message,"Renumber?",MessageBoxButtons.OKCancel);
if (answer == DialogResult.OK)
Renumberer.DoRenumbering(network, gw, ChosenVlanID);
}
}

View File

@ -658,14 +658,19 @@ namespace EduNetworkBuilder
/// <summary>
/// Return the list of devices connected to this device
/// </summary>
/// <returns>A list of devices</returns>
List<NetworkDevice> ConnectedTo()
/// <param name="skipwan">For routers, do not show things connected on the WAN</param>
/// <returns>A list of devices</returns>
public List<NetworkDevice> ConnectedTo(bool skipwan= false)
{
List<NetworkDevice> connected = new List<NetworkDevice>();
foreach (NetworkCard nic in NICs)
{
NetworkDevice nd = ConnectedTo(nic);
if (nd != null) connected.Add(nd);
//We want to skip connections through the wan when searching a broadcast network
if (!(myType == NetworkComponentType.wrouter && skipwan && nic.GetNicType == NicType.wan))
{
NetworkDevice nd = ConnectedTo(nic);
if (nd != null) connected.Add(nd);
}
}
return connected;
}
@ -675,7 +680,7 @@ namespace EduNetworkBuilder
/// </summary>
/// <param name="NIC"></param>
/// <returns></returns>
NetworkDevice ConnectedTo(NetworkCard NIC)
public NetworkDevice ConnectedTo(NetworkCard NIC)
{
return NIC.ConnectedTo();
}
@ -684,7 +689,7 @@ namespace EduNetworkBuilder
/// </summary>
/// <param name="NIC">the network card ID</param>
/// <returns></returns>
NetworkDevice ConnectedTo(HostNicID NIC)
public NetworkDevice ConnectedTo(HostNicID NIC)
{
NetworkCard nic = NicFromID(NIC);
if (nic == null) return null;
@ -695,15 +700,16 @@ namespace EduNetworkBuilder
/// </summary>
/// <param name="nicname">The network card name</param>
/// <returns></returns>
NetworkDevice ConnectedTo(string nicname)
public NetworkDevice ConnectedTo(string nicname)
{
NetworkCard nic = NicFromName(nicname);
if (nic == null) return null;
return nic.ConnectedTo();
}
public int VLANFromNIF(NetworkInterface nif)
public int VLANFromNIF(NetworkInterface nif, int level = 0)
{
level++;
if (DoesVLANs())
{
//This device itself does vlans
@ -716,17 +722,21 @@ namespace EduNetworkBuilder
if (nif == null) return NB.InvalidVLAN;
NetworkCard nic = NicFromID(nif.AttachedToHostNic);
if (nic == null) return NB.InvalidVLAN; //Nothing
return VLANFromNIC(nic);
if (level > 5) return NB.InvalidVLAN;
return VLANFromNIC(nic, level);
}
public int VLANFromNIC(NetworkCard nic)
public int VLANFromNIC(NetworkCard nic, int level=0)
{
level++;
int vlan = NB.InvalidVLAN;
if (DoesVLANs())
{
foreach (NetworkInterface nif in nic.interfaces)
{
int tvlan = VLANFromNIF(nif);
int tvlan = NB.InvalidVLAN;
if(DoesVLANs())
tvlan = VLANFromNIF(nif, level);
if (tvlan != NB.InvalidVLAN)
{
if (vlan != NB.InvalidVLAN && vlan != tvlan)
@ -1358,6 +1368,38 @@ namespace EduNetworkBuilder
return null;
}
public bool RenumberIP(string newip, NB_IPAddress gateway, int vlanID)
{
DefaultGW = new NB_IPAddress(gateway);
//figure out which interface to change.
if (!RenumberIP(newip, gateway, NicType.management_interface, vlanID))
if (!RenumberIP(newip, gateway, NicType.eth, vlanID))
return RenumberIP(newip, gateway, NicType.wlan, vlanID);
return true;
}
private bool RenumberIP(string newip, NB_IPAddress gateway, NicType what, int vlan)
{
List<NetworkCard> smalllist = NICsFromTypeNic(what);
smalllist.Sort((p, q) => p._nic_name.CompareTo(q._nic_name));
foreach (NetworkCard nic in smalllist)
{
//see if we can renumber this one
//It cannot be dhcp, and must be connected.
if((!nic.UsesDHCP && nic.isConnected(false)) || nic.GetNicType == NicType.management_interface)
{
//If we are doing vlans, the vlan should match the interface if eth
//If we are doing vlans, the vlan should match if we are doing management interface
//
//right now, just do it.
nic.PrimaryInterface().myIP = new NB_IPAddress(newip, gateway._mask.ToIpString(), IPAddressType.ip);
return true;
}
}
return false;
}
public NetworkCard NicFromIP(string IP)
{
foreach (NetworkCard nic in NICs)