WIP
parent
b71f5cc279
commit
c1174d29a4
|
@ -14,6 +14,7 @@ using System.Globalization;
|
||||||
using ln.types.threads;
|
using ln.types.threads;
|
||||||
using ln.types.odb.values;
|
using ln.types.odb.values;
|
||||||
using ln.types.net;
|
using ln.types.net;
|
||||||
|
using System.Runtime.Serialization.Formatters;
|
||||||
|
|
||||||
namespace ln.skyscanner.entities
|
namespace ln.skyscanner.entities
|
||||||
{
|
{
|
||||||
|
@ -50,7 +51,6 @@ namespace ln.skyscanner.entities
|
||||||
subnet = new Subnet(network);
|
subnet = new Subnet(network);
|
||||||
SkyEntities.subnetCollection.Upsert(subnet);
|
SkyEntities.subnetCollection.Upsert(subnet);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node GetNode(Guid id)
|
public Node GetNode(Guid id)
|
||||||
|
@ -65,29 +65,32 @@ namespace ln.skyscanner.entities
|
||||||
|
|
||||||
public IEnumerable<Node> FindHostsInSubnet(Network4 network)
|
public IEnumerable<Node> FindHostsInSubnet(Network4 network)
|
||||||
{
|
{
|
||||||
Query nodeByIpQuery = Query.Equals<Node>("Interfaces[].ConfiguredIPs[].Network", network);
|
ODBValue firstIP = ODBMapper.Default.MapValue(network.First);
|
||||||
|
ODBValue lastIP = ODBMapper.Default.MapValue(network.Last);
|
||||||
|
|
||||||
|
Query nodeByIpQuery = Query.OR(
|
||||||
|
Query.Equals<Node>("Interfaces[].ConfiguredIPs[].Network", network),
|
||||||
|
Query.IF<Node>("PrimaryIP", (ip) => ((firstIP <= ip) && (ip <= lastIP)))
|
||||||
|
);
|
||||||
return SkyEntities.nodeCollection.Select(nodeByIpQuery);
|
return SkyEntities.nodeCollection.Select(nodeByIpQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Node> FindNeighbors(Node node)
|
public IEnumerable<Node> FindNeighbors(Node node)
|
||||||
{
|
{
|
||||||
|
HashSet<Network4> networks = new HashSet<Network4>();
|
||||||
HashSet<Node> nodes = new HashSet<Node>();
|
HashSet<Node> nodes = new HashSet<Node>();
|
||||||
|
|
||||||
if (node.Interfaces.Count > 0)
|
if (node.Interfaces.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (Network4 network in node.Networks)
|
foreach (Network4 network in node.Networks)
|
||||||
{
|
networks.Add(network);
|
||||||
foreach (Node neighbor in FindHostsInSubnet(network))
|
|
||||||
nodes.Add(neighbor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Subnet subnet = FindSubnetForIP(node.PrimaryIP);
|
|
||||||
IEnumerable<Node> nodelist = FindHostsInSubnet(subnet.Network);
|
|
||||||
foreach (Node n in nodelist)
|
|
||||||
nodes.Add(n);
|
|
||||||
}
|
}
|
||||||
|
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;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
@ -254,6 +257,8 @@ namespace ln.skyscanner.entities
|
||||||
{
|
{
|
||||||
node.Vendor = "MicroTik";
|
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"))
|
if (crawledHost.GetHint("snmp.orids",new string[0]).Contains("1.3.6.1.4.1.41112"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,16 +13,23 @@ using System.Collections;
|
||||||
using Castle.Core.Logging;
|
using Castle.Core.Logging;
|
||||||
using ln.types.odb;
|
using ln.types.odb;
|
||||||
using System.Linq;
|
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
|
namespace ln.skyscanner.entities
|
||||||
{
|
{
|
||||||
public class HopMap : Persistent
|
public class HopMap : Persistent
|
||||||
{
|
{
|
||||||
public Node Node { get; private set; }
|
public Node TopNode { get; private set; }
|
||||||
public GlobalNetwork GlobalNetwork => SkyScanner.Instance.Entities.GlobalNetwork;
|
public GlobalNetwork GlobalNetwork => SkyScanner.Instance.Entities.GlobalNetwork;
|
||||||
|
|
||||||
public int MaxDepth { get; set; } = 2;
|
public int MaxDepth { get; set; } = 16;
|
||||||
|
|
||||||
Dictionary<Node, int> hops = new Dictionary<Node, int>();
|
private BTree<Node, HopNode> hopNodes = new BTree<Node, HopNode>(CompareNodes);
|
||||||
|
|
||||||
|
private HashSet<Network4> networks = new HashSet<Network4>();
|
||||||
|
|
||||||
public HopMap()
|
public HopMap()
|
||||||
{
|
{
|
||||||
|
@ -30,62 +37,170 @@ namespace ln.skyscanner.entities
|
||||||
|
|
||||||
public HopMap(Node node)
|
public HopMap(Node node)
|
||||||
{
|
{
|
||||||
Node = node;
|
Reset(node);
|
||||||
AddNode(node, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reset(Node node)
|
public void Reset(Node node)
|
||||||
{
|
{
|
||||||
hops.Clear();
|
hopNodes.Clear();
|
||||||
Node = node;
|
TopNode = node;
|
||||||
AddNode(node, 0);
|
HopNode hopNode = new HopNode(this, node);
|
||||||
}
|
|
||||||
|
|
||||||
private void AddNodes(IEnumerable<Node> 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetHopCount(Node node)
|
public int GetHopCount(Node node)
|
||||||
{
|
{
|
||||||
if (!hops.ContainsKey(node))
|
if (!hopNodes.ContainsKey(node))
|
||||||
return -1;
|
return -1;
|
||||||
return hops[node];
|
return hopNodes[node].HopCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HopNode[] HopNodes
|
public HopNode[] HopNodes
|
||||||
{
|
{
|
||||||
get
|
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<HopNode> peers = new HashSet<HopNode>();
|
||||||
|
|
||||||
|
private int hopCount = 0;
|
||||||
|
|
||||||
|
public HopNode(HopMap hopMap, Node node)
|
||||||
{
|
{
|
||||||
|
HopMap = hopMap;
|
||||||
Node = node;
|
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<IPv4> _path()
|
||||||
|
{
|
||||||
|
if (Parent == null)
|
||||||
|
return new List<IPv4>(new IPv4[] { Node.PrimaryIP });
|
||||||
|
List<IPv4> l = Parent._path();
|
||||||
|
l.Add(Node.PrimaryIP);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int CompareNodes(Node a, Node b)
|
||||||
|
{
|
||||||
|
return a.ID.CompareTo(b.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,12 +49,7 @@ namespace ln.skyscanner.http
|
||||||
[Callable]
|
[Callable]
|
||||||
public HopMap.HopNode[] GetHopTable()
|
public HopMap.HopNode[] GetHopTable()
|
||||||
{
|
{
|
||||||
HopMap hopMap = new HopMap();
|
HopMap hopMap = new HopMap(GlobalNetwork.FindNodeByIP(IPv4.Parse("10.10.10.2")));
|
||||||
//foreach (Node node in GlobalNetwork.Nodes)
|
|
||||||
//hopMap.AddNode(node, 0);
|
|
||||||
|
|
||||||
hopMap.AddNode(GlobalNetwork.FindNodeByIP(IPv4.Parse("10.10.10.2")),0);
|
|
||||||
|
|
||||||
return hopMap.HopNodes;
|
return hopMap.HopNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,7 @@ button {
|
||||||
|
|
||||||
fieldset {
|
fieldset {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
min-width: 350px;
|
min-width: 280px;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,10 @@
|
||||||
<select id="dInterfaces" size="12">
|
<select id="dInterfaces" size="12">
|
||||||
</select>
|
</select>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<select id="dPath" size="12">
|
||||||
|
</select>
|
||||||
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
@ -46,6 +50,7 @@
|
||||||
|
|
||||||
$("#dURIs").empty();
|
$("#dURIs").empty();
|
||||||
$("#dInterfaces").empty();
|
$("#dInterfaces").empty();
|
||||||
|
$("#dPath").empty();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$("#dName").prop("disabled", false).val(node.Name);
|
$("#dName").prop("disabled", false).val(node.Name);
|
||||||
|
@ -65,11 +70,11 @@
|
||||||
$("#dInterfaces").empty();
|
$("#dInterfaces").empty();
|
||||||
$.each( node.Interfaces, function(){
|
$.each( node.Interfaces, function(){
|
||||||
var intf = this;
|
var intf = this;
|
||||||
$.each( intf.IPs, function(){
|
$.each( intf.ConfiguredIPs, function(){
|
||||||
$("#dInterfaces").append( $( "<option value='"+ this +"'>" + this + "[ " + intf.Name + " ]</option>" ) );
|
$("#dInterfaces").append( $( "<option value='"+ this.Network +"'>" + this.IP + "[ " + intf.Name + " ]</option>" ) );
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
skyapi().call("api/network","GetHopTable", [ node.ID ], function(neighbors){
|
skyapi().call("api/network","GetHopTable", [ node.ID ], function(neighbors){
|
||||||
$("#nodeTable").DataTable().clear().rows.add( neighbors ).draw();
|
$("#nodeTable").DataTable().clear().rows.add( neighbors ).draw();
|
||||||
});
|
});
|
||||||
|
@ -97,6 +102,13 @@
|
||||||
{
|
{
|
||||||
var selNode = dt.rows( indexes ).data()[0];
|
var selNode = dt.rows( indexes ).data()[0];
|
||||||
showNode(selNode.Node);
|
showNode(selNode.Node);
|
||||||
|
|
||||||
|
$("#dPath").empty();
|
||||||
|
$.each( selNode.Path, function(){
|
||||||
|
var p = this;
|
||||||
|
$("#dPath").append( $( "<option value='"+ p +"'>" + p + "</option>" ) );
|
||||||
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.on( "deselect", function(e,dt,type,indexes){
|
.on( "deselect", function(e,dt,type,indexes){
|
||||||
|
|
Loading…
Reference in New Issue