Scan subnets in parallel, update readme, update gitignore
This commit is contained in:
parent
6642554473
commit
2caf97d535
3 changed files with 80 additions and 62 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -2,5 +2,6 @@
|
||||||
!.gitignore
|
!.gitignore
|
||||||
!.screenshot.png
|
!.screenshot.png
|
||||||
minipam
|
minipam
|
||||||
|
MinIPAM
|
||||||
*.yaml
|
*.yaml
|
||||||
*.json
|
*.json
|
||||||
|
|
|
@ -11,6 +11,9 @@ there is no authorization mechanism built in.
|
||||||
Scanning is kind of slow, but I prefer to keep it that way, since I don't need it to be fast, and I don't want to waste
|
Scanning is kind of slow, but I prefer to keep it that way, since I don't need it to be fast, and I don't want to waste
|
||||||
my compute resources. It doesn't matter for me if my scan completes within 1 minute or within 30 minutes.
|
my compute resources. It doesn't matter for me if my scan completes within 1 minute or within 30 minutes.
|
||||||
|
|
||||||
|
Subnets are scanned in parallel, but addresses in each subnet are still scanned sequentially. So complete scan takes as
|
||||||
|
much time, as scanning of biggest subnet that you have.
|
||||||
|
|
||||||
![Screenshot](.screenshot.png)
|
![Screenshot](.screenshot.png)
|
||||||
|
|
||||||
# Compilation
|
# Compilation
|
||||||
|
@ -33,9 +36,13 @@ scan_subnets:
|
||||||
- 192.168.145.0/24
|
- 192.168.145.0/24
|
||||||
- 10.250.100.64.0/27
|
- 10.250.100.64.0/27
|
||||||
delay_between_scans: 15m
|
delay_between_scans: 15m
|
||||||
|
#Setting this to absolute path seems like a good idea :)
|
||||||
persistence_location: "data.json"
|
persistence_location: "data.json"
|
||||||
|
#Don't scan network and broadcast address, usually you want to leave this set to true
|
||||||
exclude_special_addresses: true
|
exclude_special_addresses: true
|
||||||
use_tls: false
|
use_tls: false
|
||||||
|
#IF use_tls is set to false, following two options are ignored.
|
||||||
|
#key and cert and fullchain can be in one file. In this case, specify the same file in both fields
|
||||||
tls_key_file: "key.pem"
|
tls_key_file: "key.pem"
|
||||||
tls_cert_file: "fullchain.pem"
|
tls_cert_file: "fullchain.pem"
|
||||||
```
|
```
|
||||||
|
|
132
minipam.go
132
minipam.go
|
@ -12,6 +12,7 @@ import (
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -120,77 +121,86 @@ func ping(addr string) bool {
|
||||||
|
|
||||||
func scanner() {
|
func scanner() {
|
||||||
for {
|
for {
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
var mutex sync.Mutex
|
||||||
|
for _, subnet := range conf.ScanSubnets {
|
||||||
|
|
||||||
for _, v := range conf.ScanSubnets {
|
go func(v string) {
|
||||||
|
wg.Add(1)
|
||||||
persistenceSubnet, ok := p.Subnets[v]
|
defer wg.Done()
|
||||||
if !ok {
|
persistenceSubnet, ok := p.Subnets[v]
|
||||||
persistenceSubnet = SubnetT{}
|
if !ok {
|
||||||
persistenceSubnet.Hosts = make(map[string]HostT)
|
persistenceSubnet = SubnetT{}
|
||||||
}
|
persistenceSubnet.Hosts = make(map[string]HostT)
|
||||||
log.Printf("Scanning subnet %s", v)
|
|
||||||
prefix, err := netip.ParsePrefix(v)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Error: %s", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
prefix = prefix.Masked()
|
|
||||||
addr := prefix.Addr()
|
|
||||||
|
|
||||||
if conf.ExcludeSpecialAddresses {
|
|
||||||
addr = addr.Next()
|
|
||||||
}
|
|
||||||
persistenceSubnet.TotalAddresses = 0
|
|
||||||
persistenceSubnet.UsedAddresses = 0
|
|
||||||
persistenceSubnet.HostList = make([]string, 0)
|
|
||||||
for {
|
|
||||||
if !prefix.Contains(addr) {
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
//skip broadcast address
|
log.Printf("Scanning subnet %s", v)
|
||||||
if conf.ExcludeSpecialAddresses && !prefix.Contains(addr.Next()) {
|
prefix, err := netip.ParsePrefix(v)
|
||||||
break
|
if err != nil {
|
||||||
|
log.Printf("Error: %s", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
persistenceSubnet.TotalAddresses++
|
prefix = prefix.Masked()
|
||||||
//fmt.Println(addr.String())
|
addr := prefix.Addr()
|
||||||
persistenceSubnet.HostList = append(persistenceSubnet.HostList, addr.String())
|
|
||||||
pingstate := ping(addr.String())
|
if conf.ExcludeSpecialAddresses {
|
||||||
host, ok := persistenceSubnet.Hosts[addr.String()]
|
addr = addr.Next()
|
||||||
if pingstate {
|
}
|
||||||
persistenceSubnet.UsedAddresses++
|
persistenceSubnet.TotalAddresses = 0
|
||||||
//log.Printf("%s is up", addr.String())
|
persistenceSubnet.UsedAddresses = 0
|
||||||
rdnsString := ""
|
persistenceSubnet.HostList = make([]string, 0)
|
||||||
rdns, err := net.LookupAddr(addr.String())
|
for {
|
||||||
if err == nil {
|
if !prefix.Contains(addr) {
|
||||||
if len(rdns) > 0 {
|
break
|
||||||
rdnsString = rdns[0]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if !ok {
|
//skip broadcast address
|
||||||
persistenceSubnet.Hosts[addr.String()] = HostT{
|
if conf.ExcludeSpecialAddresses && !prefix.Contains(addr.Next()) {
|
||||||
FirstSeen: time.Now(),
|
break
|
||||||
LastSeen: time.Now(),
|
}
|
||||||
Online: true,
|
persistenceSubnet.TotalAddresses++
|
||||||
RevDNS: rdnsString,
|
//fmt.Println(addr.String())
|
||||||
|
persistenceSubnet.HostList = append(persistenceSubnet.HostList, addr.String())
|
||||||
|
pingstate := ping(addr.String())
|
||||||
|
host, ok := persistenceSubnet.Hosts[addr.String()]
|
||||||
|
if pingstate {
|
||||||
|
persistenceSubnet.UsedAddresses++
|
||||||
|
//log.Printf("%s is up", addr.String())
|
||||||
|
rdnsString := ""
|
||||||
|
rdns, err := net.LookupAddr(addr.String())
|
||||||
|
if err == nil {
|
||||||
|
if len(rdns) > 0 {
|
||||||
|
rdnsString = rdns[0]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
if !ok {
|
||||||
host.LastSeen = time.Now()
|
persistenceSubnet.Hosts[addr.String()] = HostT{
|
||||||
host.Online = true
|
FirstSeen: time.Now(),
|
||||||
host.RevDNS = rdnsString
|
LastSeen: time.Now(),
|
||||||
|
Online: true,
|
||||||
|
RevDNS: rdnsString,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
host.LastSeen = time.Now()
|
||||||
|
host.Online = true
|
||||||
|
host.RevDNS = rdnsString
|
||||||
|
persistenceSubnet.Hosts[addr.String()] = host
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if ok {
|
||||||
|
host.Online = false
|
||||||
persistenceSubnet.Hosts[addr.String()] = host
|
persistenceSubnet.Hosts[addr.String()] = host
|
||||||
|
persistenceSubnet.UsedAddresses++
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ok {
|
addr = addr.Next()
|
||||||
host.Online = false
|
|
||||||
persistenceSubnet.Hosts[addr.String()] = host
|
|
||||||
persistenceSubnet.UsedAddresses++
|
|
||||||
}
|
}
|
||||||
|
mutex.Lock()
|
||||||
addr = addr.Next()
|
p.Subnets[v] = persistenceSubnet
|
||||||
}
|
mutex.Unlock()
|
||||||
p.Subnets[v] = persistenceSubnet
|
log.Printf("Scan of %s finished", v)
|
||||||
|
}(subnet)
|
||||||
}
|
}
|
||||||
log.Printf("Scan finished")
|
wg.Wait()
|
||||||
|
log.Printf("All scans finished")
|
||||||
f, err := os.Create(conf.PersistenceLocation)
|
f, err := os.Create(conf.PersistenceLocation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to save persistence: %s", err)
|
log.Printf("Failed to save persistence: %s", err)
|
||||||
|
|
Loading…
Reference in a new issue