From e991a74fa8d42bf9a90504a0af5264955b1acb29 Mon Sep 17 00:00:00 2001 From: Harald Wolff Date: Fri, 15 Mar 2019 07:43:12 +0100 Subject: [PATCH] WIP --- SkyScanner.cs | 5 +- crawl/CrawlPool.cs | 67 ++++++ crawl/CrawledHost.cs | 105 ++++++--- crawl/Crawler.cs | 387 +++++++++++++++++++++++++--------- entities/CrawlPool.cs | 47 ----- entities/Subnet.cs | 4 +- http/CrawlerApi.cs | 32 ++- ln.skyscanner.csproj | 5 +- templates/static/crawler.html | 136 ++++++------ templates/static/frame.html | 2 +- templates/static/interface.js | 46 ++-- templates/static/style.css | 37 +++- templates/static/tables.js | 101 +++++++++ 13 files changed, 714 insertions(+), 260 deletions(-) create mode 100644 crawl/CrawlPool.cs delete mode 100644 entities/CrawlPool.cs create mode 100644 templates/static/tables.js diff --git a/SkyScanner.cs b/SkyScanner.cs index 96a72fd..efaee7b 100644 --- a/SkyScanner.cs +++ b/SkyScanner.cs @@ -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(); } diff --git a/crawl/CrawlPool.cs b/crawl/CrawlPool.cs new file mode 100644 index 0000000..7d2e3b7 --- /dev/null +++ b/crawl/CrawlPool.cs @@ -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 hosts = new List(); + public List Subnets = new List(); + + 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; + } + } + + + } +} diff --git a/crawl/CrawledHost.cs b/crawl/CrawledHost.cs index d48717d..17e8f26 100644 --- a/crawl/CrawledHost.cs +++ b/crawl/CrawledHost.cs @@ -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 ipaddresses = new List(); public List IPAddresses => ipaddresses; + public String Name { get; set; } + public CIDR PrimaryIP { get; set; } + Dictionary hints = new Dictionary(); + + 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[] 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(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(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("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("snmp.community"); + return v1; + case 2: + SnmpV2Endpoint v2 = new SnmpV2Endpoint(engine, new IPEndPoint(PrimaryIP, 161)); + v2.CommunityString = GetHint("snmp.community"); + return v2; + case 3: + USMEndpoint endpoint = new USMEndpoint(engine, new IPEndPoint(PrimaryIP, 161)); + endpoint.AuthMethod = SnmpV3AuthMethod.SHA; + endpoint.Username = GetHint("snmp.username"); + endpoint.AuthKeyPhrase = GetHint("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); } } } diff --git a/crawl/Crawler.cs b/crawl/Crawler.cs index 1350a49..2e79869 100644 --- a/crawl/Crawler.cs +++ b/crawl/Crawler.cs @@ -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(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("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 ids = new List(crawledHost.GetHint("snmp.orids", new string[0])); + + if (ids.Contains("1.3.6.1.2.1.31") || crawledHost.GetHint("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 perfFiles = new Dictionary(); + ///** PerfDB **/ - public PerfFile GetPerfFile(string name) - { - if (perfFiles.ContainsKey(name)) - return perfFiles[name]; + //Dictionary perfFiles = new Dictionary(); - 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); +// } + +//} diff --git a/entities/CrawlPool.cs b/entities/CrawlPool.cs deleted file mode 100644 index 249fd87..0000000 --- a/entities/CrawlPool.cs +++ /dev/null @@ -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 Subnets = new Dictionary(); - public Dictionary Nodes = new Dictionary(); - - public Dictionary Checks = new Dictionary(); - - 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; - } - - - } -} diff --git a/entities/Subnet.cs b/entities/Subnet.cs index 2973bbc..cfbb81d 100644 --- a/entities/Subnet.cs +++ b/entities/Subnet.cs @@ -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; } } diff --git a/http/CrawlerApi.cs b/http/CrawlerApi.cs index 50d20de..8f7ad9a 100644 --- a/http/CrawlerApi.cs +++ b/http/CrawlerApi.cs @@ -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)); } diff --git a/ln.skyscanner.csproj b/ln.skyscanner.csproj index a50ab7a..3c927fe 100644 --- a/ln.skyscanner.csproj +++ b/ln.skyscanner.csproj @@ -43,7 +43,6 @@ - @@ -52,6 +51,7 @@ + @@ -76,6 +76,9 @@ PreserveNewest + + PreserveNewest + diff --git a/templates/static/crawler.html b/templates/static/crawler.html index b6d5990..392c7ba 100644 --- a/templates/static/crawler.html +++ b/templates/static/crawler.html @@ -5,76 +5,88 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bezeichnung:
Primäre IP:
Erster Kontakt:
Letzter Kontakt:
Nächster Test:
Letzter Test:
Hints:
+
+ +
+
Nodes
+
+
-
-
Subnets
- -
-
-
Nodes
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDPrimary IPNameFirst SeenLast SeenLast Check
IDPrimary IPNameFirst SeenLast SeenLast Check
IDPrimary IPNameFirst SeenLast SeenLast Check
-
- -
- diff --git a/templates/static/frame.html b/templates/static/frame.html index 1acb77e..78d8a17 100644 --- a/templates/static/frame.html +++ b/templates/static/frame.html @@ -6,7 +6,7 @@ - +
diff --git a/templates/static/interface.js b/templates/static/interface.js index f72d95b..6c17d6d 100644 --- a/templates/static/interface.js +++ b/templates/static/interface.js @@ -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) { diff --git a/templates/static/style.css b/templates/static/style.css index de03822..1be0ec7 100644 --- a/templates/static/style.css +++ b/templates/static/style.css @@ -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; +} diff --git a/templates/static/tables.js b/templates/static/tables.js new file mode 100644 index 0000000..8560bff --- /dev/null +++ b/templates/static/tables.js @@ -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