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
|
||||
!.screenshot.png
|
||||
minipam
|
||||
MinIPAM
|
||||
*.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
|
||||
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)
|
||||
|
||||
# Compilation
|
||||
|
@ -33,9 +36,13 @@ scan_subnets:
|
|||
- 192.168.145.0/24
|
||||
- 10.250.100.64.0/27
|
||||
delay_between_scans: 15m
|
||||
#Setting this to absolute path seems like a good idea :)
|
||||
persistence_location: "data.json"
|
||||
#Don't scan network and broadcast address, usually you want to leave this set to true
|
||||
exclude_special_addresses: true
|
||||
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_cert_file: "fullchain.pem"
|
||||
```
|
||||
|
|
132
minipam.go
132
minipam.go
|
@ -12,6 +12,7 @@ import (
|
|||
"net/netip"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -120,77 +121,86 @@ func ping(addr string) bool {
|
|||
|
||||
func scanner() {
|
||||
for {
|
||||
var wg sync.WaitGroup
|
||||
var mutex sync.Mutex
|
||||
for _, subnet := range conf.ScanSubnets {
|
||||
|
||||
for _, v := range conf.ScanSubnets {
|
||||
|
||||
persistenceSubnet, ok := p.Subnets[v]
|
||||
if !ok {
|
||||
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
|
||||
go func(v string) {
|
||||
wg.Add(1)
|
||||
defer wg.Done()
|
||||
persistenceSubnet, ok := p.Subnets[v]
|
||||
if !ok {
|
||||
persistenceSubnet = SubnetT{}
|
||||
persistenceSubnet.Hosts = make(map[string]HostT)
|
||||
}
|
||||
//skip broadcast address
|
||||
if conf.ExcludeSpecialAddresses && !prefix.Contains(addr.Next()) {
|
||||
break
|
||||
log.Printf("Scanning subnet %s", v)
|
||||
prefix, err := netip.ParsePrefix(v)
|
||||
if err != nil {
|
||||
log.Printf("Error: %s", err)
|
||||
return
|
||||
}
|
||||
persistenceSubnet.TotalAddresses++
|
||||
//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]
|
||||
}
|
||||
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
|
||||
}
|
||||
if !ok {
|
||||
persistenceSubnet.Hosts[addr.String()] = HostT{
|
||||
FirstSeen: time.Now(),
|
||||
LastSeen: time.Now(),
|
||||
Online: true,
|
||||
RevDNS: rdnsString,
|
||||
//skip broadcast address
|
||||
if conf.ExcludeSpecialAddresses && !prefix.Contains(addr.Next()) {
|
||||
break
|
||||
}
|
||||
persistenceSubnet.TotalAddresses++
|
||||
//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 {
|
||||
host.LastSeen = time.Now()
|
||||
host.Online = true
|
||||
host.RevDNS = rdnsString
|
||||
if !ok {
|
||||
persistenceSubnet.Hosts[addr.String()] = HostT{
|
||||
FirstSeen: time.Now(),
|
||||
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.UsedAddresses++
|
||||
}
|
||||
|
||||
} else if ok {
|
||||
host.Online = false
|
||||
persistenceSubnet.Hosts[addr.String()] = host
|
||||
persistenceSubnet.UsedAddresses++
|
||||
addr = addr.Next()
|
||||
}
|
||||
|
||||
addr = addr.Next()
|
||||
}
|
||||
p.Subnets[v] = persistenceSubnet
|
||||
mutex.Lock()
|
||||
p.Subnets[v] = persistenceSubnet
|
||||
mutex.Unlock()
|
||||
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)
|
||||
if err != nil {
|
||||
log.Printf("Failed to save persistence: %s", err)
|
||||
|
|
Loading…
Reference in a new issue