diff --git a/entities/GlobalNetwork.cs b/entities/GlobalNetwork.cs index 1bcdcef..97cbd5b 100644 --- a/entities/GlobalNetwork.cs +++ b/entities/GlobalNetwork.cs @@ -14,6 +14,7 @@ using System.Globalization; using ln.types.threads; using ln.types.odb.values; using ln.types.net; +using System.Runtime.Serialization.Formatters; namespace ln.skyscanner.entities { @@ -50,7 +51,6 @@ namespace ln.skyscanner.entities subnet = new Subnet(network); SkyEntities.subnetCollection.Upsert(subnet); } - } public Node GetNode(Guid id) @@ -65,29 +65,32 @@ namespace ln.skyscanner.entities public IEnumerable FindHostsInSubnet(Network4 network) { - Query nodeByIpQuery = Query.Equals("Interfaces[].ConfiguredIPs[].Network", network); + ODBValue firstIP = ODBMapper.Default.MapValue(network.First); + ODBValue lastIP = ODBMapper.Default.MapValue(network.Last); + + Query nodeByIpQuery = Query.OR( + Query.Equals("Interfaces[].ConfiguredIPs[].Network", network), + Query.IF("PrimaryIP", (ip) => ((firstIP <= ip) && (ip <= lastIP))) + ); return SkyEntities.nodeCollection.Select(nodeByIpQuery); } public IEnumerable FindNeighbors(Node node) { + HashSet networks = new HashSet(); HashSet nodes = new HashSet(); if (node.Interfaces.Count > 0) { foreach (Network4 network in node.Networks) - { - foreach (Node neighbor in FindHostsInSubnet(network)) - nodes.Add(neighbor); - } - } - else - { - Subnet subnet = FindSubnetForIP(node.PrimaryIP); - IEnumerable nodelist = FindHostsInSubnet(subnet.Network); - foreach (Node n in nodelist) - nodes.Add(n); + networks.Add(network); } + Subnet subnet = FindSubnetForIP(node.PrimaryIP); + networks.Add(subnet.Network); + + foreach (Network4 network in networks) + foreach (Node neighbor in FindHostsInSubnet(network)) + nodes.Add(neighbor); return nodes; } @@ -254,6 +257,8 @@ namespace ln.skyscanner.entities { node.Vendor = "MicroTik"; } + if (crawledHost.GetHint("http.server", "").Equals("Viprinet")) + node.Vendor = "Viprinet"; if (crawledHost.GetHint("snmp.orids",new string[0]).Contains("1.3.6.1.4.1.41112")) { diff --git a/entities/HopMap.cs b/entities/HopMap.cs index 9c3def4..28a43eb 100644 --- a/entities/HopMap.cs +++ b/entities/HopMap.cs @@ -13,16 +13,23 @@ using System.Collections; using Castle.Core.Logging; using ln.types.odb; using System.Linq; +using ln.types.btree; +using Castle.Components.DictionaryAdapter.Xml; +using Newtonsoft.Json; +using ln.types.net; +using System.Net.Sockets; namespace ln.skyscanner.entities { public class HopMap : Persistent { - public Node Node { get; private set; } + public Node TopNode { get; private set; } public GlobalNetwork GlobalNetwork => SkyScanner.Instance.Entities.GlobalNetwork; - public int MaxDepth { get; set; } = 2; + public int MaxDepth { get; set; } = 16; - Dictionary hops = new Dictionary(); + private BTree hopNodes = new BTree(CompareNodes); + + private HashSet networks = new HashSet(); public HopMap() { @@ -30,62 +37,170 @@ namespace ln.skyscanner.entities public HopMap(Node node) { - Node = node; - AddNode(node, 0); + Reset(node); } public void Reset(Node node) { - hops.Clear(); - Node = node; - AddNode(node, 0); - } - - private void AddNodes(IEnumerable nodes,int level) - { - foreach (Node node in nodes) - AddNode(node, level); - } - - public void AddNode(Node node,int level) - { - if (Node == null) - Node = node; - - if (!hops.ContainsKey(node) || (hops[node] > level)) - { - hops[node] = level; - if (level < MaxDepth) - AddNodes(GlobalNetwork.FindNeighbors(node), level + 1); - } + hopNodes.Clear(); + TopNode = node; + HopNode hopNode = new HopNode(this, node); } public int GetHopCount(Node node) { - if (!hops.ContainsKey(node)) + if (!hopNodes.ContainsKey(node)) return -1; - return hops[node]; + return hopNodes[node].HopCount; } public HopNode[] HopNodes { get { - return hops.Select((h) => new HopNode(h.Key,h.Value)).ToArray(); + return hopNodes.Values.ToArray(); } } - public struct HopNode - { - public Node Node; - public int HopCount; - public HopNode(Node node,int hopCount) + public class HopNode : IComparable + { + [JsonIgnore] + public HopMap HopMap { get; } + [JsonIgnore] + public HopNode Parent { get; private set; } + + public Node Node; + + [JsonIgnore] + public HopNode[] Peers => peers.ToArray(); + private HashSet peers = new HashSet(); + + private int hopCount = 0; + + public HopNode(HopMap hopMap, Node node) { + HopMap = hopMap; Node = node; - HopCount = hopCount; + + HopMap.hopNodes.Add(node, this); + + FindPeers(); } + public HopNode(HopNode parent, Node node) + { + HopMap = parent.HopMap; + Node = node; + + Attach(parent); + + FindPeers(); + } + + private void FindPeers() + { + foreach (Network4 network in Node.Networks) + { + EnsureNetwork(network); + } + EnsureNetwork(HopMap.GlobalNetwork.FindSubnetForIP(Node.PrimaryIP).Network); + } + private void EnsureNetwork(Network4 network) + { + if (!HopMap.networks.Contains(network)) + { + HopMap.networks.Add(network); + FindPeers(network); + } + } + private void FindPeers(Network4 network) + { + foreach (Node peerNode in HopMap.GlobalNetwork.FindHostsInSubnet(network)) + { + if (!HopMap.hopNodes.ContainsKey(peerNode)) + { + new HopNode(this, peerNode); + } + else + { + HopNode existingHopNode = HopMap.hopNodes[peerNode]; + if (existingHopNode.HopCount > (HopCount + 1)) + { + existingHopNode.Detach(); + existingHopNode.Attach(this); + } + } + } + } + + + public int HopCount + { + get => hopCount; + set + { + hopCount = value; + foreach (HopNode peer in peers) + { + peer.HopCount = hopCount + 1; + } + } + } + + public void Attach(HopNode parent) + { + Detach(); + + Parent = parent; + if (!Object.ReferenceEquals(null, Parent)) + { + HopMap.hopNodes.Add(this.Node, this); + Parent.peers.Add(this); + + HopCount = parent.hopCount + 1; + } + else + { + HopCount = 0; + } + + } + public void Detach() + { + if (!Object.ReferenceEquals(null, Parent)) + { + Parent.peers.Remove(this); + Parent = null; + HopMap.hopNodes.Remove(this.Node); + } + } + + public int CompareTo(object obj) + { + if (obj is HopNode) + { + HopNode you = obj as HopNode; + return Node.ID.CompareTo(you.Node.ID); + } + return this.GetHashCode() - obj.GetHashCode(); + } + + public IPv4[] Path => _path().ToArray(); + private List _path() + { + if (Parent == null) + return new List(new IPv4[] { Node.PrimaryIP }); + List l = Parent._path(); + l.Add(Node.PrimaryIP); + return l; + } + + } + + private static int CompareNodes(Node a, Node b) + { + return a.ID.CompareTo(b.ID); } } diff --git a/http/NetworkApi.cs b/http/NetworkApi.cs index 023ca00..fcc3af2 100644 --- a/http/NetworkApi.cs +++ b/http/NetworkApi.cs @@ -49,12 +49,7 @@ namespace ln.skyscanner.http [Callable] public HopMap.HopNode[] GetHopTable() { - HopMap hopMap = new HopMap(); - //foreach (Node node in GlobalNetwork.Nodes) - //hopMap.AddNode(node, 0); - - hopMap.AddNode(GlobalNetwork.FindNodeByIP(IPv4.Parse("10.10.10.2")),0); - + HopMap hopMap = new HopMap(GlobalNetwork.FindNodeByIP(IPv4.Parse("10.10.10.2"))); return hopMap.HopNodes; } diff --git a/templates/static/css/style.css b/templates/static/css/style.css index b77834f..c3ceb62 100644 --- a/templates/static/css/style.css +++ b/templates/static/css/style.css @@ -249,7 +249,7 @@ button { fieldset { display: inline-block; - min-width: 350px; + min-width: 280px; max-width: 500px; } diff --git a/templates/static/network/hoptable.html b/templates/static/network/hoptable.html index 7af3bca..cc1c83a 100644 --- a/templates/static/network/hoptable.html +++ b/templates/static/network/hoptable.html @@ -25,6 +25,10 @@ +
+ +