broken
Harald Wolff 2019-03-15 07:43:12 +01:00
parent 3d617963e9
commit e991a74fa8
13 changed files with 714 additions and 260 deletions

View File

@ -6,6 +6,7 @@ using ln.skyscanner.http;
using System.IO;
using ln.skyscanner.crawl;
using ln.types.threads;
using System.Threading;
namespace ln.skyscanner
{
public enum ComponentState { STOPPED, INITIALIZED, STARTED, FAILED }
@ -46,8 +47,10 @@ namespace ln.skyscanner
{
Logging.Log(LogLevel.INFO, "SkyScanner: Stop()");
StopCrawler();
StopHttpServer();
new Thread(() => ConveniencePool.NumThreads = 0).Start();
}

67
crawl/CrawlPool.cs 100644
View File

@ -0,0 +1,67 @@
// /**
// * File: CrawlPool.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.Collections.Generic;
using ln.types;
using System.Net;
using System.Linq;
using ln.skyscanner.entities;
namespace ln.skyscanner.crawl
{
public class CrawlPool
{
public List<CrawledHost> hosts = new List<CrawledHost>();
public List<Subnet> Subnets = new List<Subnet>();
public CrawlPool()
{
}
public CrawledHost[] Hosts => hosts.ToArray();
public CrawledHost HostForIP(CIDR ip)
{
lock (this)
{
foreach (CrawledHost host in hosts)
{
if (host.IPAddresses.Contains(ip) || ip.Equals(host.PrimaryIP))
return host;
}
CrawledHost h = new CrawledHost();
h.PrimaryIP = ip;
h.Name = ip.ToString();
hosts.Add(h);
return h;
}
}
public Subnet GetSubnet(CIDR network)
{
lock (this)
{
foreach (Subnet subnet in Subnets)
{
if (subnet.Network.Equals(network))
return subnet;
}
Subnet net = new Subnet(network);
Subnets.Add(net);
return net;
}
}
}
}

View File

@ -16,62 +16,97 @@ using System.Net;
using System.IO;
using System.Net.NetworkInformation;
using ln.logging;
using System.Linq;
using ln.snmp;
using ln.snmp.endpoint;
namespace ln.skyscanner.crawl
{
public class CrawledHost : Syncable
public class CrawledHost
{
[Unsynced]
private Crawler crawler;
public Crawler Crawler { get => crawler; set => crawler = value; }
private Guid id;
public Guid ID { get => id; set => id = value; }
private List<CIDR> ipaddresses = new List<CIDR>();
public List<CIDR> IPAddresses => ipaddresses;
public String Name { get; set; }
public CIDR PrimaryIP { get; set; }
Dictionary<string, object> hints = new Dictionary<string, object>();
public DateTime FirstSeen;
public DateTime LastSeen;
public DateTime LastCheck;
public DateTime NextCheck;
public CrawledHost()
{ }
public CrawledHost(Crawler crawler)
{
Crawler = crawler;
ID = Guid.NewGuid();
FileName = Path.Combine(crawler.BasePath, String.Format("{0}.ch", ID.ToString()));
}
public CrawledHost(Crawler crawler, Guid id)
:this(crawler)
{
ID = id;
FileName = Path.Combine(crawler.BasePath, String.Format("{0}.ch", ID.ToString()));
Load();
}
public CrawledHost(Crawler crawler, string filename)
: base(filename)
{
Name = "noname";
PrimaryIP = IPAddress.Any;
}
public void Crawl()
public KeyValuePair<string, object>[] Hints => hints.ToArray();
public void SetHint(string name,object value)
{
Logging.Log(LogLevel.INFO, "Checking {0}", id);
hints[name] = value;
}
public object GetHint(String name)
{
return hints[name];
}
public T GetHint<T>(string name)
{
return (T)GetHint(name);
}
Ping ping = new Ping();
public object GetHint(string name,object def)
{
if (HasHint(name))
return hints[name];
foreach (CIDR ip in IPAddresses)
return def;
}
public T GetHint<T>(string name,T def)
{
if (HasHint(name))
return (T)hints[name];
return def;
}
public bool HasHint(string name)
{
return hints.ContainsKey(name) && (hints[name] != null);
}
public SnmpEndpoint GetSnmpEndpoint(SNMPEngine engine)
{
int snmpVersion = GetHint<int>("snmp.version", -1);
switch (snmpVersion)
{
PingReply pingReply = ping.Send(ip);
Logging.Log(LogLevel.INFO, "IP {0} Ping: {1}",ip,pingReply.RoundtripTime);
case 1:
SnmpV1Endpoint v1 = new SnmpV1Endpoint(engine, new IPEndPoint(PrimaryIP, 161));
v1.CommunityString = GetHint<string>("snmp.community");
return v1;
case 2:
SnmpV2Endpoint v2 = new SnmpV2Endpoint(engine, new IPEndPoint(PrimaryIP, 161));
v2.CommunityString = GetHint<string>("snmp.community");
return v2;
case 3:
USMEndpoint endpoint = new USMEndpoint(engine, new IPEndPoint(PrimaryIP, 161));
endpoint.AuthMethod = SnmpV3AuthMethod.SHA;
endpoint.Username = GetHint<string>("snmp.username");
endpoint.AuthKeyPhrase = GetHint<string>("snmp.authkey");
return endpoint;
default:
return null;
}
}
public override string ToString()
{
return String.Format("[CrawledHost ID={0} IPAddress=({1})]",ID,String.Join(", ",IPAddresses));
return String.Format("[CrawledHost PrimaryIP={0} IPAddresses=({1}) Name={2}]",PrimaryIP,String.Join(", ",IPAddresses),Name);
}
}
}

View File

@ -25,10 +25,11 @@ using ln.perfdb;
using ln.perfdb.storage;
using ln.skyscanner.check;
using System.Threading;
using ln.snmp.types;
namespace ln.skyscanner.crawl
{
public class Crawler : IPerfFileProvider
public class Crawler
{
public SkyScanner SkyScanner { get; }
@ -47,7 +48,7 @@ namespace ln.skyscanner.crawl
public SNMPEngine SNMPEngine { get; }
Thread threadChecker;
Thread threadScheduler;
public Crawler(SkyScanner skyScanner)
{
@ -62,13 +63,13 @@ namespace ln.skyscanner.crawl
SNMPEngine = new SNMPEngine();
SNMPEngine.Timeout = 1250;
_CrawlPool = new DiskObject<CrawlPool>(String.Format("{0}/pool",BasePath));
crawlThreadPool.NumThreads = 12;
threadChecker = new Thread(Checker);
threadChecker.Start();
threadScheduler = new Thread(scheduler);
threadScheduler.Start();
}
public void Stop()
@ -84,66 +85,242 @@ namespace ln.skyscanner.crawl
crawlThreadPool.Enqueue(job);
}
public void Crawl(IPAddress host)
public void Crawl(CIDR host)
{
crawlThreadPool.Enqueue(() => crawlHost(host));
crawlThreadPool.Enqueue(() => crawlHost(host.Host));
}
private void crawlHost(IPAddress host)
private void crawlHost(CIDR host)
{
Ping ping = new Ping();
PingReply pingReply = ping.Send(host,500);
CrawledHost crawledHost = CrawlPool.HostForIP(host);
crawledHost.LastCheck = DateTime.Now;
crawledHost.NextCheck = DateTime.Now + TimeSpan.FromHours(1);
if (pingReply.Status != IPStatus.Success)
if (crawlPing(crawledHost))
{
Logging.Log(LogLevel.INFO, "Host not reachable: {0} {1}", host, pingReply.Status);
if (crawledHost.FirstSeen.Equals(DateTime.MinValue))
crawledHost.FirstSeen = DateTime.Now;
crawledHost.LastSeen = DateTime.Now;
CrawlSNMP(crawledHost);
}
else
{
//SnmpV1Endpoint v1endpoint = new SnmpV1Endpoint(engine, new IPEndPoint(IPAddress.Parse("10.75.1.10"), 161), "ByFR4oW98hap");
//SnmpV2Endpoint v2endpoint = new SnmpV2Endpoint(engine, new IPEndPoint(IPAddress.Parse("10.113.254.4"), 161), "ghE7wUmFPoPpkRno");
USMEndpoint v3endpoint = new USMEndpoint(SNMPEngine, new IPEndPoint(host, 161));
v3endpoint.AuthMethod = SnmpV3AuthMethod.SHA;
v3endpoint.AuthKeyPhrase = "qVy3hnZJ2fov";
v3endpoint.Username = "skytron";
try
{
RFC1213.Interface[] interfaces = RFC1213.GetInterfaces(v3endpoint);
foreach (RFC1213.Interface netIf in interfaces)
{
Logging.Log(LogLevel.INFO, "Interface: {0}", netIf);
foreach (CIDR ip in netIf.IPAddresses)
{
Subnet subnet = CrawlPool.GetSubnet(ip.Network);
if ((DateTime.Now - subnet.LastScanned).Hours >= 1)
{
Enqueue(() => crawlSubnet(ip.Network));
}
}
}
}
catch (TimeoutException)
{
Logging.Log(LogLevel.INFO, "Host: {0} SNMP communication timed out.", host);
}
}
}
public void crawlSubnet(CIDR subnet)
public bool crawlPing(CrawledHost crawledHost)
{
Ping ping = new Ping();
Subnet sub = CrawlPool.GetSubnet(subnet);
sub.LastScanned = DateTime.Now;
int nSuccess = 0;
long roundTripTime = 0;
for (int n=0;n<10;n++)
{
PingReply pingReply = ping.Send(crawledHost.PrimaryIP, 500);
if (pingReply.Status == IPStatus.Success)
{
nSuccess++;
roundTripTime += pingReply.RoundtripTime;
}
}
if (nSuccess > 0)
{
roundTripTime /= nSuccess;
crawledHost.SetHint("ping.success", true);
crawledHost.SetHint("ping.rta", (int)roundTripTime);
crawledHost.SetHint("ping.out_of_ten", nSuccess);
Logging.Log(LogLevel.INFO, "Host is reachable: {0} RTA={1}ms", crawledHost.PrimaryIP, roundTripTime);
}
else
{
crawledHost.SetHint("ping.success", false);
crawledHost.SetHint("ping.rta", null);
crawledHost.SetHint("ping.out_of_ten", 0);
Logging.Log(LogLevel.INFO, "Host is unreachable: {0}", crawledHost.PrimaryIP);
}
return crawledHost.GetHint<bool>("ping.success");
}
public void CrawlSNMP(CrawledHost crawledHost)
{
string[] communities = new string[] { "VhclfC7lfIojYZ", "Vhclf(C7$lfIojYZ", "ByFR4oW98hap", "qVy3hnZJ2fov" };
bool snmpDetected = false;
using (USMEndpoint v3endpoint = new USMEndpoint(SNMPEngine, new IPEndPoint(crawledHost.PrimaryIP, 161)))
{
try
{
v3endpoint.QueryEngineID();
}
catch (TimeoutException)
{
}
if (v3endpoint.RemoteEngineID != null)
{
crawledHost.SetHint("snmp.version", 3);
Logging.Log(LogLevel.INFO, "{0}: SNMPv3 support detected", crawledHost.PrimaryIP);
bool replied = false;
foreach (string community in communities)
{
v3endpoint.Username = "skytron";
v3endpoint.AuthMethod = SnmpV3AuthMethod.SHA;
v3endpoint.AuthKeyPhrase = community;
try
{
Variable prID = v3endpoint.snmpGet("1.3.6.1.2.1.1.2.0");
crawledHost.SetHint("snmp.username", "skytron");
crawledHost.SetHint("snmp.authkey", community);
crawledHost.SetHint("snmp.sysObjectID", (prID as ObjectIdentifier).AsString);
replied = true;
break;
}
catch (TimeoutException)
{
}
}
if (replied)
{
snmpDetected = true;
}
}
}
if (!snmpDetected)
{
using (SnmpV2Endpoint v2endpoint = new SnmpV2Endpoint(SNMPEngine, new IPEndPoint(crawledHost.PrimaryIP, 161)))
{
foreach (String community in communities)
{
v2endpoint.CommunityString = community;
try
{
Variable prID = v2endpoint.snmpGet("1.3.6.1.2.1.1.2.0");
crawledHost.SetHint("snmp.version", 2);
crawledHost.SetHint("snmp.community", community);
crawledHost.SetHint("snmp.sysObjectID", (prID as ObjectIdentifier).AsString);
snmpDetected = true;
break;
} catch (TimeoutException)
{
}
}
}
}
if (!snmpDetected)
{
using (SnmpV1Endpoint v1endpoint = new SnmpV1Endpoint(SNMPEngine, new IPEndPoint(crawledHost.PrimaryIP, 161)))
{
foreach (String community in communities)
{
v1endpoint.CommunityString = community;
try
{
Variable prID = v1endpoint.snmpGet("1.3.6.1.2.1.1.2.0");
crawledHost.SetHint("snmp.version", 1);
crawledHost.SetHint("snmp.community", community);
crawledHost.SetHint("snmp.sysObjectID", (prID as ObjectIdentifier).AsString);
snmpDetected = true;
break;
}
catch (TimeoutException)
{
}
}
}
}
if (!snmpDetected)
{
crawledHost.SetHint("snmp.version", null);
crawledHost.SetHint("snmp.username", null);
crawledHost.SetHint("snmp.authkey", null);
crawledHost.SetHint("snmp.community", null);
crawledHost.SetHint("snmp.sysObjectID", null);
}
else
{
try
{
using (SnmpEndpoint endpoint = crawledHost.GetSnmpEndpoint(SNMPEngine))
{
try
{
Sequence[] VorIDs = endpoint.snmpWalk("1.3.6.1.2.1.1.9.1.2").ToArray();
string[] orids = new string[VorIDs.Length];
for (int n = 0; n < orids.Length; n++)
{
orids[n] = (VorIDs[n].Items[1] as ObjectIdentifier).AsString;
}
crawledHost.SetHint("snmp.orids", orids);
} catch (TimeoutException)
{ }
List<String> ids = new List<string>(crawledHost.GetHint<String[]>("snmp.orids", new string[0]));
if (ids.Contains("1.3.6.1.2.1.31") || crawledHost.GetHint<string>("snmp.sysObjectID","").Equals("1.3.6.1.4.1.14988.1"))
{
CrawlRFC1213(crawledHost, endpoint);
}
}
} catch (TimeoutException te)
{
Logging.Log(te);
}
}
}
private void CrawlRFC1213(CrawledHost crawledHost, SnmpEndpoint endpoint)
{
RFC1213.Interface[] interfaces = RFC1213.GetInterfaces(endpoint);
foreach (RFC1213.Interface netIf in interfaces)
{
foreach (CIDR ip in netIf.IPAddresses)
{
if (!crawledHost.IPAddresses.Contains(ip))
crawledHost.IPAddresses.Add(ip);
CrawlPool.GetSubnet(ip.Network);
}
}
}
public void CrawlSubnet(CIDR network)
{
Ping ping = new Ping();
Subnet subnet = CrawlPool.GetSubnet(network);
subnet.LastScan = DateTime.Now;
subnet.NextScan = DateTime.Now + TimeSpan.FromHours(6);
Logging.Log(LogLevel.INFO, "Scanning {0}", subnet);
foreach (CIDR ip in subnet)
foreach (CIDR ip in network)
{
long roundTripTime = 0;
int success = 0;
@ -163,75 +340,97 @@ namespace ln.skyscanner.crawl
roundTripTime /= success;
Logging.Log(LogLevel.INFO, "IP {0} reachable ({1}/10) {2}ms", ip, success, roundTripTime);
Node node = CrawlPool.GetNode(ip);
if ((DateTime.Now - node.LastSeen ).Hours > 0)
{
Enqueue(() => crawlHost(ip));
}
string checkID = Hostalive.CalcCheckName(node);
if (!CrawlPool.Checks.ContainsKey(checkID))
{
Hostalive hostalive = new Hostalive(node);
CrawlPool.Checks.Add(hostalive.CheckID, hostalive);
}
}
else
{
Logging.Log(LogLevel.INFO, "IP {0} unreachable", ip);
CrawlPool.HostForIP(ip);
}
}
}
/** Checks **/
private void Checker()
private void scheduler()
{
while (!stopping)
{
DateTime now = DateTime.Now;
Check[] checks = CrawlPool.Checks.Values.ToArray();
if (checks.Length == 0)
Thread.Sleep(1000);
foreach (Check check in checks)
foreach (CrawledHost crawledHost in CrawlPool.Hosts)
{
if (check.NextCheck <= now)
if (crawledHost.NextCheck < DateTime.Now)
{
check.Mark();
Enqueue(() => check.Run(this));
Crawl(crawledHost.PrimaryIP);
}
}
foreach (Subnet subnet in CrawlPool.Subnets.ToArray())
{
if (subnet.NextScan < DateTime.Now)
{
Enqueue(() => CrawlSubnet(subnet.Network));
}
}
Thread.Sleep(15000);
}
}
/** PerfDB **/
Dictionary<string, PerfFile> perfFiles = new Dictionary<string, PerfFile>();
///** PerfDB **/
public PerfFile GetPerfFile(string name)
{
if (perfFiles.ContainsKey(name))
return perfFiles[name];
//Dictionary<string, PerfFile> perfFiles = new Dictionary<string, PerfFile>();
PerfFile perfFile = new PerfFile(Path.Combine(PerfPath, String.Format("{0}.perf", name)));
perfFile.Open();
//public PerfFile GetPerfFile(string name)
//{
// if (perfFiles.ContainsKey(name))
// return perfFiles[name];
perfFiles.Add(name, perfFile);
// PerfFile perfFile = new PerfFile(Path.Combine(PerfPath, String.Format("{0}.perf", name)));
// perfFile.Open();
if (perfFile.FirstSection == null)
{
PerfFile.PerfFileSection section = new PerfFile.PerfFileSection(perfFile, null, 1440, 60, AggregationMethod.AVERAGE);
section = new PerfFile.PerfFileSection(perfFile, section, 1728, 300, AggregationMethod.AVERAGE);
section = new PerfFile.PerfFileSection(perfFile, section, 2016, 900, AggregationMethod.AVERAGE);
section = new PerfFile.PerfFileSection(perfFile, section, 1344, 3600, AggregationMethod.AVERAGE);
section = new PerfFile.PerfFileSection(perfFile, section, 1344, 10800, AggregationMethod.AVERAGE);
}
return perfFile;
}
// perfFiles.Add(name, perfFile);
// if (perfFile.FirstSection == null)
// {
// PerfFile.PerfFileSection section = new PerfFile.PerfFileSection(perfFile, null, 1440, 60, AggregationMethod.AVERAGE);
// section = new PerfFile.PerfFileSection(perfFile, section, 1728, 300, AggregationMethod.AVERAGE);
// section = new PerfFile.PerfFileSection(perfFile, section, 2016, 900, AggregationMethod.AVERAGE);
// section = new PerfFile.PerfFileSection(perfFile, section, 1344, 3600, AggregationMethod.AVERAGE);
// section = new PerfFile.PerfFileSection(perfFile, section, 1344, 10800, AggregationMethod.AVERAGE);
// }
// return perfFile;
//}
}
}
// //SnmpV1Endpoint v1endpoint = new SnmpV1Endpoint(engine, new IPEndPoint(IPAddress.Parse("10.75.1.10"), 161), "ByFR4oW98hap");
// //SnmpV2Endpoint v2endpoint = new SnmpV2Endpoint(engine, new IPEndPoint(IPAddress.Parse("10.113.254.4"), 161), "ghE7wUmFPoPpkRno");
// USMEndpoint v3endpoint = new USMEndpoint(SNMPEngine, new IPEndPoint(host, 161));
// v3endpoint.AuthMethod = SnmpV3AuthMethod.SHA;
// v3endpoint.AuthKeyPhrase = "qVy3hnZJ2fov";
// v3endpoint.Username = "skytron";
// try
// {
// RFC1213.Interface[] interfaces = RFC1213.GetInterfaces(v3endpoint);
// foreach (RFC1213.Interface netIf in interfaces)
// {
// Logging.Log(LogLevel.INFO, "Interface: {0}", netIf);
// foreach (CIDR ip in netIf.IPAddresses)
// {
// Subnet subnet = CrawlPool.GetSubnet(ip.Network);
// if ((DateTime.Now - subnet.LastScanned).Hours >= 1)
// {
// Enqueue(() => crawlSubnet(ip.Network));
// }
// }
// }
// }
// catch (TimeoutException)
// {
// Logging.Log(LogLevel.INFO, "Host: {0} SNMP communication timed out.", host);
// }
//}

View File

@ -1,47 +0,0 @@
// /**
// * File: CrawlPool.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.Collections.Generic;
using ln.types;
namespace ln.skyscanner.entities
{
public class CrawlPool
{
public Dictionary<CIDR, Subnet> Subnets = new Dictionary<CIDR, Subnet>();
public Dictionary<CIDR, Node> Nodes = new Dictionary<CIDR, Node>();
public Dictionary<string, Check> Checks = new Dictionary<String, Check>();
public CrawlPool()
{
}
public Subnet GetSubnet(CIDR network)
{
if (Subnets.ContainsKey(network))
return Subnets[network];
Subnet subnet = new Subnet(network);
Subnets.Add(network,subnet);
return subnet;
}
public Node GetNode(CIDR ip)
{
if (Nodes.ContainsKey(ip))
return Nodes[ip];
Node node = new Node(ip);
Nodes[ip] = node;
return node;
}
}
}

View File

@ -17,7 +17,8 @@ namespace ln.skyscanner.entities
public String Name;
public DateTime FirstSeen;
public DateTime LastScanned;
public DateTime LastScan;
public DateTime NextScan;
public Subnet()
{
@ -27,6 +28,7 @@ namespace ln.skyscanner.entities
public Subnet(CIDR cidr)
{
Network = cidr;
Name = Network.ToString();
FirstSeen = DateTime.Now;
}
}

View File

@ -2,6 +2,9 @@
using ln.http.resources;
using ln.skyscanner.entities;
using System.Linq;
using ln.skyscanner.crawl;
using ln.types;
using System.Net;
namespace ln.skyscanner.http
{
@ -18,7 +21,34 @@ namespace ln.skyscanner.http
[Callable]
public Subnet[] GetSubnets()
{
return SkyScanner.Crawler.CrawlPool.Subnets.Values.ToArray();
return new Subnet[0];
}
[Callable]
public CrawledHost[] GetHosts()
{
return SkyScanner.Crawler?.CrawlPool?.Hosts;
}
[Callable]
public CrawledHost GetHostByIP(string _ip)
{
return SkyScanner.Crawler.CrawlPool.HostForIP(CIDR.Parse(_ip));
}
[Callable]
public CrawledHost AddHost(string _ip, string name)
{
CIDR ip = CIDR.Parse(_ip);
CrawledHost host = SkyScanner.Crawler.CrawlPool.HostForIP(ip);
host.Name = name;
return host;
}
[Callable]
public void Crawl(string _ip)
{
SkyScanner.Crawler.Crawl(CIDR.Parse(_ip));
}

View File

@ -43,7 +43,6 @@
<Compile Include="crawl\Crawler.cs" />
<Compile Include="crawl\CrawledHost.cs" />
<Compile Include="entities\Subnet.cs" />
<Compile Include="entities\CrawlPool.cs" />
<Compile Include="entities\Router.cs" />
<Compile Include="Check.cs" />
<Compile Include="check\Hostalive.cs" />
@ -52,6 +51,7 @@
<Compile Include="http\SkyScannerHttpApi.cs" />
<Compile Include="http\SkyScannerHttpManagement.cs" />
<Compile Include="http\CrawlerApi.cs" />
<Compile Include="crawl\CrawlPool.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
@ -76,6 +76,9 @@
<None Include="templates\static\crawler.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\tables.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="identify\" />

View File

@ -5,76 +5,88 @@
<button onclick="api.call('api/management','StartCrawler')">Start</button>
<button onclick="api.call('api/management','StopCrawler')">Stop</button>
</div>
<div>
<div class="group right">
<table>
<tr>
<td>Bezeichnung:</td>
<td id="chName"></td>
<td><button onclick="api.call('api/crawler','Crawl', [$('chIP').innerText]);">CRAWL</button></td>
</tr>
<tr>
<td>Prim&auml;re IP:</td>
<td id="chIP"></td>
</tr>
<tr>
<td>Erster Kontakt:</td>
<td id="chFirstSeen"></td>
</tr>
<tr>
<td>Letzter Kontakt:</td>
<td id="chLastSeen"></td>
</tr>
<tr>
<td>N&auml;chster Test:</td>
<td id="chNextCheck"></td>
</tr>
<tr>
<td>Letzter Test:</td>
<td id="chLastCheck"></td>
</tr>
<tr>
<td>Hints:</td>
<td id="chHints"></td>
</tr>
</table>
</div>
<div class="group" style="bottom: 24px;">
<div>Nodes</div>
<table onload="NodeTable(this);"></table>
</div>
<div class="group">
<div>Subnets</div>
<input type="text" id="tfSubnet"/><button onclick="addSubnet();">Hinzufügen</button>
<select id="selSubnets">
</select>
</div>
<div class="group">
<div>Nodes</div>
<table id="nodeTable">
<thead>
<tr>
<td>ID</td>
<td>Primary IP</td>
<td>Name</td>
<td>First Seen</td>
<td>Last Seen</td>
<td>Last Check</td>
<td></td>
</tr>
<tr>
<td></td>
<td><input type="text" name="PrimaryIP"/></td>
<td><input type="text" name="Name"/></td>
<td></td>
<td></td>
<td></td>
<td><button>+</button></td>
</tr>
</thead>
<tbody>
<tr>
<td>ID</td>
<td>Primary IP</td>
<td>Name</td>
<td>First Seen</td>
<td>Last Seen</td>
<td>Last Check</td>
</tr>
<tr>
<td>ID</td>
<td>Primary IP</td>
<td>Name</td>
<td>First Seen</td>
<td>Last Seen</td>
<td>Last Check</td>
</tr>
</tbody>
</table>
</div>
</div>
<script onload="fillSubnets();">
<script>
function addSubnet()
function showHostDetails(ip)
{
var network = $("tfSubnet").value;
alert(network);
var crawledHost = api.call('api/crawler','GetHostByIP', [ip]);
$("chName").innerText = crawledHost.Name;
$("chIP").innerText = crawledHost.PrimaryIP;
$("chFirstSeen").innerText = crawledHost.FirstSeen;
$("chLastSeen").innerText = crawledHost.LastSeen;
$("chLastCheck").innerText = crawledHost.LastCheck;
$("chNextCheck").innerText = crawledHost.NextCheck;
$("chHints").innerText = JSON.stringify( crawledHost.Hints );
}
function fillSubnets()
function NodeTable(t)
{
var subnets = api.call("api/crawler","GetSubnets");
for (var n=0;n<subnets.length;n++)
{
var columns = [
{ "Label": 'Primäre IP', "Field": "PrimaryIP", "ToAdd": true },
{ "Label": 'Name', "Field": "Name", "ToAdd": true },
{ "Label": 'First Seen', "Field": "FirstSeen" },
{ "Label": 'Last Seen', "Field": "LastSeen" },
{ "Label": 'Last Check', "Field": "LastCheck" },
{ "Label": 'Next Check', "Field": "NextCheck" }
];
var loader = function(){ return api.call('api/crawler','GetHosts'); };
var adder = function(p){
return api.call('api/crawler','AddHost', p);
};
DynamicTable(t,columns,loader, adder);
t.selectedRowChanged = function(row){
showHostDetails(row.PrimaryIP);
}
}
</script>

View File

@ -6,7 +6,7 @@
<link href="/static/style.css" rel="stylesheet" />
<script type="text/javascript" src="/static/interface.js"></script>
<script type="text/javascript" src="/static/workspace.js"></script>
<script type="text/javascript" src="/static/tables.js"></script>
</head>
<body onload="initApi('<%=request.self()%>');">
<div id="body">

View File

@ -1,4 +1,23 @@

function $(id)
{
return document.getElementById(id);
}
function CE(eName, parent = null)
{
var e = document.createElement(eName);
if (parent){
parent.appendChild( e );
}
return e;
}
function CLEAN(e){
while (e.firstChild) {
e.removeChild( e.firstChild );
}
}
function API(baseurl){
@ -90,24 +109,13 @@ function API(baseurl){
}
function $(id)
{
return document.getElementById(id);
}
function CE(eName)
{
return document.createElement(eName);
}
var api = null;
function loadStatistics()
{
function showStatistics(stats)
{
try
{
var stats = api.call("api/management","GetStatistics");
$("ServerTime").innerText = "ServerTime: " + stats.ServerTime;
$("indHttpServer").attributes["state"].value = stats.States.HttpServer;
@ -128,6 +136,18 @@ function loadStatistics()
}
}
function loadStatistics()
{
try
{
var stats = api.call("api/management","GetStatistics");
showStatistics(stats);
} catch (e)
{
showStatistics(false);
}
}
function initApi(baseurl)
{

View File

@ -23,6 +23,11 @@ a {
color: inherit;
}
.right {
float: right;
right: 0px;
}
#header {
border-bottom: 1px solid black;
padding: 6px;
@ -127,11 +132,13 @@ a {
position: absolute;
top: 80px;
bottom: 32px;
bottom: 40px;
left: 0px;
right: 0px;
padding: 12px;
overflow: auto;
}
#workspace {
@ -166,7 +173,13 @@ a {
table {
border-collapse: collapse;
border-collapse: collapse;
overflow: auto;
height: 600px;
width: 75%;
display: inline-block;
}
table > thead > tr {
@ -177,13 +190,20 @@ table > thead > tr > td
border-bottom: 1px solid black;
padding-left: 2px;
padding-right: 16px;
font-style: italic;
}
table > tbody {
}
table > tbody > tr {
}
table > tbody > tr > td {
padding-top: 4px;
padding-bottom: 4px;
padding-left: 2px;
padding-right: 16px;
}
table > tbody > tr:hover > td {
@ -196,6 +216,15 @@ table input {
}
.group {
min-width: 240px;
}
.group.right {
width: 24%;
border-left: 1px solid black;
padding-left: 8px;
top: 0px;
bottom: 0px;
}

View File

@ -0,0 +1,101 @@

function DynamicTable(table, columns, loader, adder = null, deleter = null)
{
if (!table.dtable)
{
table.dtable = {};
table.dtable.loader = loader;
table.dtable.columns = columns;
table.dtable.adder = adder;
table.dtable.deleter = deleter;
table.dtable.lAdd = []
table.addRow = function(){
var ap = [];
for (var n=0;n<this.dtable.lAdd.length;n++)
{
ap.push(this.dtable.lAdd[n].value);
}
return this.dtable.adder(ap);
}
table.create = function(){
CLEAN(this);
var thead = CE("thead", this);
this.trhead = CE("tr", thead);
this.trfilter = CE("tr", thead);
this.tradd = CE("tr", thead);
for (var n=0;n<this.dtable.columns.length;n++)
{
var col = CE("td", this.trhead);
col.innerText = this.dtable.columns[n].Label;
var fcol = CE("td", this.trfilter);
if (this.dtable.columns[n].ToFilter)
{
var ia = CE("input", fcol);
}
if (this.dtable.adder)
{
var acol = CE("td", this.tradd);
if (this.dtable.columns[n].ToAdd)
{
var ia = CE("input", acol);
ia.id = this.dtable.columns[n].Field;
this.dtable.lAdd.push(ia);
}
}
}
CE("td",this.trhead);
if (this.dtable.adder)
{
var ab = CE("button", CE("td",this.tradd));
ab.onclick = function(){ table.addRow(); };
ab.innerText = "+";
}
var tbody = CE("tbody", this);
this.tbody = tbody;
}
table.load = function(){
CLEAN(this.tbody);
var dtable = this;
var rows = this.dtable.loader();
for (var n=0;n<rows.length;n++)
{
var tr = CE("tr",this.tbody);
tr.dtRow = rows[n]
tr.onclick = function(){ dtable.selectedRow = this.dtRow; dtable.selectedRowChanged(dtable.selectedRow); };
for (var c=0;c<this.dtable.columns.length;c++)
{
var td = CE("td",tr);
td.innerText = rows[n][this.dtable.columns[c].Field];
tr.onclick = function(){ dtable.selectedRow = this.dtRow; dtable.selectedRowChanged(dtable.selectedRow); };
}
}
}
table.selectedRowChanged = function(selectedRow){}
}
table.create();
table.load();
return table;
}