ing
This commit is contained in:
parent
de287a64a4
commit
f8a302e632
|
@ -1,293 +0,0 @@
|
||||||
package discoverer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
|
||||||
"git.loafle.net/overflow/model/util"
|
|
||||||
"git.loafle.net/overflow/util-go/net/cidr"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DiscoveryDataType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
DiscoveryDataTypeNone DiscoveryDataType = iota
|
|
||||||
DiscoveryDataTypeStart
|
|
||||||
DiscoveryDataTypeStop
|
|
||||||
DiscoveryDataTypeError
|
|
||||||
DiscoveryDataTypeZone
|
|
||||||
DiscoveryDataTypeHost
|
|
||||||
DiscoveryDataTypePort
|
|
||||||
DiscoveryDataTypeService
|
|
||||||
)
|
|
||||||
|
|
||||||
type DiscoveryData struct {
|
|
||||||
Type DiscoveryDataType
|
|
||||||
Result interface{}
|
|
||||||
Error error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dd *DiscoveryData) Release() {
|
|
||||||
releaseDiscoveryData(dd)
|
|
||||||
}
|
|
||||||
|
|
||||||
var _discoverer Discoverer
|
|
||||||
|
|
||||||
func GetDiscoverer() Discoverer {
|
|
||||||
if nil == _discoverer {
|
|
||||||
_discoverer = &defaultDiscoverer{}
|
|
||||||
}
|
|
||||||
return _discoverer
|
|
||||||
}
|
|
||||||
|
|
||||||
type Discoverer interface {
|
|
||||||
Retain() chan *DiscoveryData
|
|
||||||
Release(dataChan chan *DiscoveryData)
|
|
||||||
Stop()
|
|
||||||
DiscoverZone(dataChan chan *DiscoveryData, dz *omd.DiscoverZone)
|
|
||||||
DiscoverHost(dataChan chan *DiscoveryData, zone *omd.Zone, dh *omd.DiscoverHost)
|
|
||||||
DiscoverPort(dataChan chan *DiscoveryData, host *omd.Host, dp *omd.DiscoverPort)
|
|
||||||
DiscoverSerice(dataChan chan *DiscoveryData, port *omd.Port, ds *omd.DiscoverService)
|
|
||||||
}
|
|
||||||
|
|
||||||
type defaultDiscoverer struct {
|
|
||||||
dataChanPool chan chan *DiscoveryData
|
|
||||||
|
|
||||||
stopChan chan struct{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *defaultDiscoverer) Retain() chan *DiscoveryData {
|
|
||||||
if nil == d.dataChanPool {
|
|
||||||
d.dataChanPool = make(chan chan *DiscoveryData, 1)
|
|
||||||
d.dataChanPool <- make(chan *DiscoveryData, 256)
|
|
||||||
}
|
|
||||||
return <-d.dataChanPool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *defaultDiscoverer) Release(dataChan chan *DiscoveryData) {
|
|
||||||
d.dataChanPool <- dataChan
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *defaultDiscoverer) Stop() {
|
|
||||||
if nil != d.stopChan {
|
|
||||||
close(d.stopChan)
|
|
||||||
d.stopChan = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *defaultDiscoverer) DiscoverZone(dataChan chan *DiscoveryData, dz *omd.DiscoverZone) {
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
d.stopChan = make(chan struct{})
|
|
||||||
|
|
||||||
dataChan <- retainDiscoveryData(DiscoveryDataTypeStart, util.Now(), nil, nil)
|
|
||||||
wg.Add(1)
|
|
||||||
go d.innerDiscoverZone(&wg, dataChan, dz)
|
|
||||||
wg.Wait()
|
|
||||||
if nil != d.stopChan {
|
|
||||||
close(d.stopChan)
|
|
||||||
d.stopChan = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
dataChan <- retainDiscoveryData(DiscoveryDataTypeStop, util.Now(), nil, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *defaultDiscoverer) DiscoverHost(dataChan chan *DiscoveryData, zone *omd.Zone, dh *omd.DiscoverHost) {
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
d.stopChan = make(chan struct{})
|
|
||||||
|
|
||||||
dataChan <- retainDiscoveryData(DiscoveryDataTypeStart, util.Now(), nil, nil)
|
|
||||||
wg.Add(1)
|
|
||||||
go d.innerDiscoverHost(&wg, dataChan, zone, dh)
|
|
||||||
wg.Wait()
|
|
||||||
if nil != d.stopChan {
|
|
||||||
close(d.stopChan)
|
|
||||||
d.stopChan = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
dataChan <- retainDiscoveryData(DiscoveryDataTypeStop, util.Now(), nil, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *defaultDiscoverer) DiscoverPort(dataChan chan *DiscoveryData, host *omd.Host, dp *omd.DiscoverPort) {
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
d.stopChan = make(chan struct{})
|
|
||||||
|
|
||||||
dataChan <- retainDiscoveryData(DiscoveryDataTypeStart, util.Now(), nil, nil)
|
|
||||||
wg.Add(1)
|
|
||||||
go d.innerDiscoverPort(&wg, dataChan, host, dp)
|
|
||||||
wg.Wait()
|
|
||||||
if nil != d.stopChan {
|
|
||||||
close(d.stopChan)
|
|
||||||
d.stopChan = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
dataChan <- retainDiscoveryData(DiscoveryDataTypeStop, util.Now(), nil, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *defaultDiscoverer) DiscoverSerice(dataChan chan *DiscoveryData, port *omd.Port, ds *omd.DiscoverService) {
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
d.stopChan = make(chan struct{})
|
|
||||||
|
|
||||||
dataChan <- retainDiscoveryData(DiscoveryDataTypeStart, util.Now(), nil, nil)
|
|
||||||
wg.Add(1)
|
|
||||||
go d.innerDiscoverSerice(&wg, dataChan, port, ds)
|
|
||||||
wg.Wait()
|
|
||||||
if nil != d.stopChan {
|
|
||||||
close(d.stopChan)
|
|
||||||
d.stopChan = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
dataChan <- retainDiscoveryData(DiscoveryDataTypeStop, util.Now(), nil, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *defaultDiscoverer) innerDiscoverZone(wg *sync.WaitGroup, dataChan chan *DiscoveryData, dz *omd.DiscoverZone) {
|
|
||||||
defer func() {
|
|
||||||
wg.Done()
|
|
||||||
}()
|
|
||||||
|
|
||||||
taskScan(d,
|
|
||||||
func(resultChan chan interface{}, errChan chan error, doneChan chan struct{}, stopChan chan struct{}) {
|
|
||||||
scanZone(dz, resultChan, errChan, doneChan, stopChan)
|
|
||||||
},
|
|
||||||
func(result interface{}) {
|
|
||||||
z := result.(*omd.Zone)
|
|
||||||
dataChan <- retainDiscoveryData(DiscoveryDataTypeZone, util.Now(), z, nil)
|
|
||||||
if nil != dz.DiscoverHost {
|
|
||||||
cr, _ := cidr.NewCIDRRanger(z.Network)
|
|
||||||
dh := &omd.DiscoverHost{
|
|
||||||
MetaIPType: z.MetaIPType,
|
|
||||||
FirstScanRange: cr.First().String(),
|
|
||||||
LastScanRange: cr.Last().String(),
|
|
||||||
DiscoverPort: dz.DiscoverHost.DiscoverPort,
|
|
||||||
}
|
|
||||||
|
|
||||||
wg.Add(1)
|
|
||||||
go d.innerDiscoverHost(wg, dataChan, z, dh)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
func(err error) {
|
|
||||||
dataChan <- retainDiscoveryData(DiscoveryDataTypeError, util.Now(), nil, err)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *defaultDiscoverer) innerDiscoverHost(wg *sync.WaitGroup, dataChan chan *DiscoveryData, zone *omd.Zone, dh *omd.DiscoverHost) {
|
|
||||||
defer func() {
|
|
||||||
wg.Done()
|
|
||||||
}()
|
|
||||||
|
|
||||||
taskScan(d,
|
|
||||||
func(resultChan chan interface{}, errChan chan error, doneChan chan struct{}, stopChan chan struct{}) {
|
|
||||||
scanHost(zone, dh, resultChan, errChan, doneChan, stopChan)
|
|
||||||
},
|
|
||||||
func(result interface{}) {
|
|
||||||
h := result.(*omd.Host)
|
|
||||||
dataChan <- retainDiscoveryData(DiscoveryDataTypeHost, util.Now(), h, nil)
|
|
||||||
if nil != dh.DiscoverPort {
|
|
||||||
wg.Add(1)
|
|
||||||
go d.innerDiscoverPort(wg, dataChan, h, dh.DiscoverPort)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
func(err error) {
|
|
||||||
dataChan <- retainDiscoveryData(DiscoveryDataTypeError, util.Now(), nil, err)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *defaultDiscoverer) innerDiscoverPort(wg *sync.WaitGroup, dataChan chan *DiscoveryData, host *omd.Host, dp *omd.DiscoverPort) {
|
|
||||||
defer func() {
|
|
||||||
wg.Done()
|
|
||||||
}()
|
|
||||||
|
|
||||||
taskScan(d,
|
|
||||||
func(resultChan chan interface{}, errChan chan error, doneChan chan struct{}, stopChan chan struct{}) {
|
|
||||||
scanPort(host, dp, resultChan, errChan, doneChan, stopChan)
|
|
||||||
},
|
|
||||||
func(result interface{}) {
|
|
||||||
p := result.(*omd.Port)
|
|
||||||
dataChan <- retainDiscoveryData(DiscoveryDataTypePort, util.Now(), p, nil)
|
|
||||||
if nil != dp.DiscoverService {
|
|
||||||
wg.Add(1)
|
|
||||||
go d.innerDiscoverSerice(wg, dataChan, p, dp.DiscoverService)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
func(err error) {
|
|
||||||
dataChan <- retainDiscoveryData(DiscoveryDataTypeError, util.Now(), nil, err)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *defaultDiscoverer) innerDiscoverSerice(wg *sync.WaitGroup, dataChan chan *DiscoveryData, port *omd.Port, ds *omd.DiscoverService) {
|
|
||||||
defer func() {
|
|
||||||
wg.Done()
|
|
||||||
}()
|
|
||||||
|
|
||||||
taskScan(d,
|
|
||||||
func(resultChan chan interface{}, errChan chan error, doneChan chan struct{}, stopChan chan struct{}) {
|
|
||||||
scanService(port, ds, resultChan, errChan, doneChan, stopChan)
|
|
||||||
},
|
|
||||||
func(result interface{}) {
|
|
||||||
s := result.(*omd.Service)
|
|
||||||
dataChan <- retainDiscoveryData(DiscoveryDataTypeService, util.Now(), s, nil)
|
|
||||||
},
|
|
||||||
func(err error) {
|
|
||||||
dataChan <- retainDiscoveryData(DiscoveryDataTypeError, util.Now(), nil, err)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func taskScan(d *defaultDiscoverer,
|
|
||||||
taskFunc func(resultChan chan interface{}, errChan chan error, doneChan chan struct{}, stopChan chan struct{}),
|
|
||||||
reesultFunc func(result interface{}),
|
|
||||||
errorFunc func(err error)) {
|
|
||||||
|
|
||||||
resultChan := make(chan interface{})
|
|
||||||
errChan := make(chan error)
|
|
||||||
stopChan := make(chan struct{})
|
|
||||||
doneChan := make(chan struct{})
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
}()
|
|
||||||
|
|
||||||
go taskFunc(resultChan, errChan, doneChan, stopChan)
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case r := <-resultChan:
|
|
||||||
reesultFunc(r)
|
|
||||||
case err := <-errChan:
|
|
||||||
errorFunc(err)
|
|
||||||
case <-doneChan:
|
|
||||||
return
|
|
||||||
case <-d.stopChan:
|
|
||||||
close(stopChan)
|
|
||||||
<-doneChan
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var discoveryDataPool sync.Pool
|
|
||||||
|
|
||||||
func retainDiscoveryData(discoveryDataType DiscoveryDataType, t util.Timestamp, result interface{}, err error) *DiscoveryData {
|
|
||||||
v := discoveryDataPool.Get()
|
|
||||||
var discoveryData *DiscoveryData
|
|
||||||
if v == nil {
|
|
||||||
discoveryData = &DiscoveryData{}
|
|
||||||
} else {
|
|
||||||
discoveryData = v.(*DiscoveryData)
|
|
||||||
}
|
|
||||||
|
|
||||||
discoveryData.Type = discoveryDataType
|
|
||||||
discoveryData.Result = result
|
|
||||||
discoveryData.Error = err
|
|
||||||
|
|
||||||
return discoveryData
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseDiscoveryData(discoveryData *DiscoveryData) {
|
|
||||||
discoveryData.Type = DiscoveryDataTypeNone
|
|
||||||
discoveryData.Result = nil
|
|
||||||
discoveryData.Error = nil
|
|
||||||
|
|
||||||
discoveryDataPool.Put(discoveryData)
|
|
||||||
}
|
|
|
@ -1,168 +0,0 @@
|
||||||
package discoverer_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"log"
|
|
||||||
"strconv"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
olog "git.loafle.net/overflow/log-go"
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
|
||||||
omm "git.loafle.net/overflow/model/meta"
|
|
||||||
omu "git.loafle.net/overflow/model/util"
|
|
||||||
"git.loafle.net/overflow_scanner/probe/discoverer"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
dz = &omd.DiscoverZone{
|
|
||||||
ExcludePatterns: []string{},
|
|
||||||
}
|
|
||||||
z = &omd.Zone{
|
|
||||||
Network: "192.168.35.0/24",
|
|
||||||
MetaIPType: omm.ToMetaIPType(omm.MetaIPTypeEnumV4),
|
|
||||||
// Address: "192.168.1.201",
|
|
||||||
// Iface: "\\Device\\NPF_{1924FA2B-6927-4BA5-AF43-876C3F8853CE}",
|
|
||||||
// Mac: "30:9C:23:15:A3:09",
|
|
||||||
// Address: "192.168.1.101",
|
|
||||||
// Iface: "enp3s0",
|
|
||||||
// Mac: "44:8a:5b:f1:f1:f3",
|
|
||||||
Address: "192.168.35.234",
|
|
||||||
Iface: "wlp5s0",
|
|
||||||
Mac: "d0:7e:35:da:26:68",
|
|
||||||
}
|
|
||||||
dh = &omd.DiscoverHost{
|
|
||||||
MetaIPType: omm.ToMetaIPType(omm.MetaIPTypeEnumV4),
|
|
||||||
FirstScanRange: "192.168.35.1",
|
|
||||||
LastScanRange: "192.168.35.254",
|
|
||||||
}
|
|
||||||
h = &omd.Host{
|
|
||||||
Zone: z,
|
|
||||||
MetaIPType: omm.ToMetaIPType(omm.MetaIPTypeEnumV4),
|
|
||||||
Address: "192.168.35.80",
|
|
||||||
Mac: "6c:ad:f8:d3:f8:c6",
|
|
||||||
}
|
|
||||||
dp = &omd.DiscoverPort{
|
|
||||||
FirstScanRange: 1,
|
|
||||||
LastScanRange: 65535,
|
|
||||||
ExcludePorts: []int{
|
|
||||||
631,
|
|
||||||
},
|
|
||||||
IncludeTCP: true,
|
|
||||||
IncludeUDP: true,
|
|
||||||
}
|
|
||||||
p = &omd.Port{
|
|
||||||
Host: h,
|
|
||||||
MetaPortType: omm.ToMetaPortType(omm.MetaPortTypeEnumTCP),
|
|
||||||
PortNumber: json.Number(strconv.Itoa(21)),
|
|
||||||
DiscoveredDate: omu.NowPtr(),
|
|
||||||
}
|
|
||||||
|
|
||||||
dha = &omd.DiscoverHost{
|
|
||||||
MetaIPType: omm.ToMetaIPType(omm.MetaIPTypeEnumV4),
|
|
||||||
FirstScanRange: "192.168.1.0",
|
|
||||||
LastScanRange: "192.168.1.255",
|
|
||||||
DiscoverPort: &omd.DiscoverPort{
|
|
||||||
FirstScanRange: 1,
|
|
||||||
LastScanRange: 20000,
|
|
||||||
ExcludePorts: []int{
|
|
||||||
631,
|
|
||||||
},
|
|
||||||
IncludeTCP: true,
|
|
||||||
IncludeUDP: false,
|
|
||||||
DiscoverService: nil,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// runtime.LockOSThread()
|
|
||||||
olog.InitializeLogger("")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDiscoverZone(t *testing.T) {
|
|
||||||
_discoverer := discoverer.GetDiscoverer()
|
|
||||||
|
|
||||||
handleDiscovery(_discoverer, func(dataChan chan *discoverer.DiscoveryData) {
|
|
||||||
_discoverer.DiscoverZone(dataChan, dz)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDiscoverHost(t *testing.T) {
|
|
||||||
_discoverer := discoverer.GetDiscoverer()
|
|
||||||
|
|
||||||
handleDiscovery(_discoverer, func(dataChan chan *discoverer.DiscoveryData) {
|
|
||||||
_discoverer.DiscoverHost(dataChan, z, dh)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDiscoverPort(t *testing.T) {
|
|
||||||
_discoverer := discoverer.GetDiscoverer()
|
|
||||||
|
|
||||||
handleDiscovery(_discoverer, func(dataChan chan *discoverer.DiscoveryData) {
|
|
||||||
_discoverer.DiscoverPort(dataChan, h, dp)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDiscoverService(t *testing.T) {
|
|
||||||
_discoverer := discoverer.GetDiscoverer()
|
|
||||||
|
|
||||||
handleDiscovery(_discoverer, func(dataChan chan *discoverer.DiscoveryData) {
|
|
||||||
_discoverer.DiscoverSerice(dataChan, p, nil)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDiscoverHostAll(t *testing.T) {
|
|
||||||
_discoverer := discoverer.GetDiscoverer()
|
|
||||||
|
|
||||||
handleDiscovery(_discoverer, func(dataChan chan *discoverer.DiscoveryData) {
|
|
||||||
_discoverer.DiscoverHost(dataChan, z, dha)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleDiscovery(_discoverer discoverer.Discoverer, discoveryFunc func(dataChan chan *discoverer.DiscoveryData)) error {
|
|
||||||
var dataChan chan *discoverer.DiscoveryData
|
|
||||||
retainChan := make(chan struct{})
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
dataChan = _discoverer.Retain()
|
|
||||||
close(retainChan)
|
|
||||||
}()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-retainChan:
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
_discoverer.Release(dataChan)
|
|
||||||
}()
|
|
||||||
|
|
||||||
go discoveryFunc(dataChan)
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case data, ok := <-dataChan:
|
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
switch data.Type {
|
|
||||||
case discoverer.DiscoveryDataTypeStart:
|
|
||||||
log.Printf("DiscoveryService.DiscoveryStart")
|
|
||||||
case discoverer.DiscoveryDataTypeStop:
|
|
||||||
log.Printf("DiscoveryService.DiscoveryStop")
|
|
||||||
data.Release()
|
|
||||||
return nil
|
|
||||||
case discoverer.DiscoveryDataTypeError:
|
|
||||||
log.Printf("DiscoveryService.DiscoveryDataTypeError %v", data.Error)
|
|
||||||
case discoverer.DiscoveryDataTypeZone:
|
|
||||||
log.Printf("DiscoveryService.DiscoveryDataTypeZone %v", data.Result)
|
|
||||||
case discoverer.DiscoveryDataTypeHost:
|
|
||||||
log.Printf("DiscoveryService.DiscoveryDataTypeHost %v", data.Result)
|
|
||||||
case discoverer.DiscoveryDataTypePort:
|
|
||||||
log.Printf("DiscoveryService.DiscoveryDataTypePort %v", data.Result)
|
|
||||||
case discoverer.DiscoveryDataTypeService:
|
|
||||||
// log.Printf("DiscoveryService.DiscoveryDataTypeService %v", data.Result)
|
|
||||||
log.Println(data.Result)
|
|
||||||
}
|
|
||||||
data.Release()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package discoverer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
|
||||||
omm "git.loafle.net/overflow/model/meta"
|
|
||||||
"git.loafle.net/overflow_scanner/probe/discoverer/ipv4"
|
|
||||||
"git.loafle.net/overflow_scanner/probe/discoverer/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
func scanHost(zone *omd.Zone, dh *omd.DiscoverHost, resultChan chan interface{}, errChan chan error, doneChan chan<- struct{}, stopChan chan struct{}) {
|
|
||||||
defer func() {
|
|
||||||
doneChan <- struct{}{}
|
|
||||||
}()
|
|
||||||
|
|
||||||
switch omm.ToMetaIPTypeEnum(dh.MetaIPType) {
|
|
||||||
case omm.MetaIPTypeEnumV4:
|
|
||||||
ipv4.ScanHost(zone, dh, resultChan, errChan, stopChan)
|
|
||||||
case omm.MetaIPTypeEnumV6:
|
|
||||||
ipv6.ScanHost(zone, dh, resultChan, errChan, stopChan)
|
|
||||||
default:
|
|
||||||
errChan <- fmt.Errorf("Discovery: Not supported MetaIPType")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,226 +0,0 @@
|
||||||
package ipv4
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net"
|
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
|
||||||
omm "git.loafle.net/overflow/model/meta"
|
|
||||||
omu "git.loafle.net/overflow/model/util"
|
|
||||||
"git.loafle.net/overflow/util-go/net/cidr"
|
|
||||||
"git.loafle.net/overflow_scanner/probe/pcap"
|
|
||||||
"github.com/google/gopacket"
|
|
||||||
"github.com/google/gopacket/layers"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ScanHost(zone *omd.Zone, dh *omd.DiscoverHost, resultChan chan interface{}, errChan chan error, stopChan chan struct{}) {
|
|
||||||
ps, err := pcap.RetainScanner(zone)
|
|
||||||
if nil != err {
|
|
||||||
errChan <- fmt.Errorf("Discovery: Cannot retain pcap instance %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
pcap.ReleaseScanner(zone)
|
|
||||||
}()
|
|
||||||
|
|
||||||
cr, err := cidr.NewCIDRRanger(zone.Network)
|
|
||||||
if nil != err {
|
|
||||||
errChan <- err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
hostRanges, err := GetTargetHostRange(dh, cr)
|
|
||||||
if nil != err {
|
|
||||||
errChan <- err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
arpChan := ps.OpenARP()
|
|
||||||
defer func() {
|
|
||||||
ps.CloseARP(arpChan)
|
|
||||||
}()
|
|
||||||
|
|
||||||
timerStopped := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
hosts := make(map[string]*omd.Host)
|
|
||||||
|
|
||||||
var delay atomic.Value
|
|
||||||
delay.Store(false)
|
|
||||||
ticker := time.NewTicker(time.Millisecond * 500)
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case packet, ok := <-arpChan:
|
|
||||||
if !ok {
|
|
||||||
// logging.Logger().Debugf("arp channel is closed")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
delay.Store(true)
|
|
||||||
if h := handlePacketARP(zone, hostRanges, hosts, packet); nil != h {
|
|
||||||
if h != nil {
|
|
||||||
log.Println(h)
|
|
||||||
}
|
|
||||||
|
|
||||||
// resultChan <- h
|
|
||||||
}
|
|
||||||
case <-ticker.C:
|
|
||||||
if false == delay.Load().(bool) {
|
|
||||||
ticker.Stop()
|
|
||||||
timerStopped <- struct{}{}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
delay.Store(false)
|
|
||||||
case <-stopChan:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
if err := sendARP(ps, zone, hostRanges, stopChan); nil != err {
|
|
||||||
errChan <- err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-stopChan:
|
|
||||||
return
|
|
||||||
case <-timerStopped:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func sendARP(ps pcap.PCapScanner, zone *omd.Zone, hostRanges []net.IP, stopChan chan struct{}) error {
|
|
||||||
hwAddr, err := net.ParseMAC(zone.Mac)
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ip := net.ParseIP(zone.Address)
|
|
||||||
if nil == ip {
|
|
||||||
return fmt.Errorf("Discovery: IP(%s) of zone is not valid", zone.Address)
|
|
||||||
}
|
|
||||||
|
|
||||||
ethPacket := makePacketEthernet(hwAddr)
|
|
||||||
arpPacket := makePacketARP(hwAddr, ip.To4())
|
|
||||||
opts := gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true}
|
|
||||||
buf := gopacket.NewSerializeBuffer()
|
|
||||||
|
|
||||||
for _, targetHost := range hostRanges {
|
|
||||||
arpPacket.DstProtAddress = []byte(targetHost)
|
|
||||||
// log.Printf("ARP:%v", arpPacket)
|
|
||||||
gopacket.SerializeLayers(buf, opts, ðPacket, &arpPacket)
|
|
||||||
if err := ps.WritePacketData(buf.Bytes()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
timer := time.NewTimer(time.Microsecond * 100)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-stopChan:
|
|
||||||
return nil
|
|
||||||
case <-timer.C:
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func handlePacketARP(zone *omd.Zone, hostRanges []net.IP, hosts map[string]*omd.Host, packet *layers.ARP) *omd.Host {
|
|
||||||
if packet.Operation != layers.ARPReply {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
ip := net.IP(packet.SourceProtAddress)
|
|
||||||
if _, ok := hosts[ip.String()]; ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
inRange := false
|
|
||||||
for _, h := range hostRanges {
|
|
||||||
if h.Equal(ip) {
|
|
||||||
inRange = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !inRange {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
h := &omd.Host{
|
|
||||||
MetaIPType: omm.ToMetaIPType(omm.MetaIPTypeEnumV4),
|
|
||||||
Address: ip.String(),
|
|
||||||
Mac: net.HardwareAddr(packet.SourceHwAddress).String(),
|
|
||||||
Zone: zone,
|
|
||||||
DiscoveredDate: omu.NowPtr(),
|
|
||||||
}
|
|
||||||
|
|
||||||
hosts[ip.String()] = h
|
|
||||||
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetTargetHostRange(dh *omd.DiscoverHost, cr cidr.CIDRRanger) ([]net.IP, error) {
|
|
||||||
var firstIP net.IP
|
|
||||||
if "" != dh.FirstScanRange {
|
|
||||||
firstIP = net.ParseIP(dh.FirstScanRange)
|
|
||||||
if nil == firstIP {
|
|
||||||
return nil, fmt.Errorf("Discovery: IP(%v) of FirstScanRange host is not valid", firstIP)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var lastIP net.IP
|
|
||||||
if "" != dh.LastScanRange {
|
|
||||||
lastIP = net.ParseIP(dh.LastScanRange)
|
|
||||||
if nil == lastIP {
|
|
||||||
return nil, fmt.Errorf("Discovery: IP(%v) of LastScanRange host is not valid", lastIP)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
includeIPs := make([]net.IP, 0)
|
|
||||||
for _, iHost := range dh.IncludeHosts {
|
|
||||||
iIP := net.ParseIP(iHost)
|
|
||||||
if nil == iIP {
|
|
||||||
return nil, fmt.Errorf("Discovery: IP(%v) of include host is not valid", iHost)
|
|
||||||
}
|
|
||||||
includeIPs = append(includeIPs, iIP)
|
|
||||||
}
|
|
||||||
|
|
||||||
excludeIPs := make([]net.IP, 0)
|
|
||||||
for _, eHost := range dh.ExcludeHosts {
|
|
||||||
eIP := net.ParseIP(eHost)
|
|
||||||
if nil == eIP {
|
|
||||||
return nil, fmt.Errorf("Discovery: IP(%v) of exclude host is not valid", eHost)
|
|
||||||
}
|
|
||||||
excludeIPs = append(excludeIPs, eIP)
|
|
||||||
}
|
|
||||||
|
|
||||||
ranges, err := cr.Ranges(firstIP, lastIP, includeIPs, excludeIPs)
|
|
||||||
if nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return ranges, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func makePacketEthernet(hw net.HardwareAddr) layers.Ethernet {
|
|
||||||
return layers.Ethernet{
|
|
||||||
SrcMAC: hw,
|
|
||||||
DstMAC: net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
|
||||||
EthernetType: layers.EthernetTypeARP,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func makePacketARP(hw net.HardwareAddr, ip net.IP) layers.ARP {
|
|
||||||
return layers.ARP{
|
|
||||||
AddrType: layers.LinkTypeEthernet,
|
|
||||||
Protocol: layers.EthernetTypeIPv4,
|
|
||||||
HwAddressSize: 6,
|
|
||||||
ProtAddressSize: 4,
|
|
||||||
Operation: layers.ARPRequest,
|
|
||||||
SourceHwAddress: []byte(hw),
|
|
||||||
SourceProtAddress: []byte(ip),
|
|
||||||
DstHwAddress: []byte{0, 0, 0, 0, 0, 0},
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package ipv4
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ScanPort(host *omd.Host, dp *omd.DiscoverPort, resultChan chan interface{}, errChan chan error, stopChan chan struct{}) {
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
|
|
||||||
if dp.IncludeTCP {
|
|
||||||
wg.Add(1)
|
|
||||||
go scanPortTCP(host, dp, resultChan, errChan, stopChan, &wg)
|
|
||||||
}
|
|
||||||
|
|
||||||
if dp.IncludeUDP {
|
|
||||||
wg.Add(1)
|
|
||||||
go scanPortUDP(host, dp, resultChan, errChan, stopChan, &wg)
|
|
||||||
}
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
}
|
|
|
@ -1,211 +0,0 @@
|
||||||
package ipv4
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"strconv"
|
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"go.uber.org/zap"
|
|
||||||
|
|
||||||
olog "git.loafle.net/overflow/log-go"
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
|
||||||
omm "git.loafle.net/overflow/model/meta"
|
|
||||||
omu "git.loafle.net/overflow/model/util"
|
|
||||||
"git.loafle.net/overflow_scanner/probe/pcap"
|
|
||||||
"github.com/google/gopacket"
|
|
||||||
"github.com/google/gopacket/layers"
|
|
||||||
)
|
|
||||||
|
|
||||||
func scanPortTCP(host *omd.Host, dp *omd.DiscoverPort, resultChan chan interface{}, errChan chan error, stopChan chan struct{}, wg *sync.WaitGroup) {
|
|
||||||
defer func() {
|
|
||||||
wg.Done()
|
|
||||||
}()
|
|
||||||
|
|
||||||
ps, err := pcap.RetainScanner(host.Zone)
|
|
||||||
if nil != err {
|
|
||||||
errChan <- fmt.Errorf("Discovery: Cannot retain pcap instance %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
go pcap.ReleaseScanner(host.Zone)
|
|
||||||
}()
|
|
||||||
|
|
||||||
tcpChan := ps.OpenTCP(host.Address)
|
|
||||||
defer func() {
|
|
||||||
go ps.CloseTCP(host.Address, tcpChan)
|
|
||||||
}()
|
|
||||||
|
|
||||||
timerStopped := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
ports := make(map[int]*omd.Port)
|
|
||||||
|
|
||||||
var delay atomic.Value
|
|
||||||
delay.Store(false)
|
|
||||||
ticker := time.NewTicker(time.Millisecond * 500)
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case packet, ok := <-tcpChan:
|
|
||||||
if !ok {
|
|
||||||
olog.Logger().Debug("Discovery: tcp channel is closed")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
delay.Store(true)
|
|
||||||
if p := handlePacketTCP(host, dp, ports, packet); nil != p {
|
|
||||||
resultChan <- p
|
|
||||||
}
|
|
||||||
case <-ticker.C:
|
|
||||||
if false == delay.Load().(bool) {
|
|
||||||
ticker.Stop()
|
|
||||||
timerStopped <- struct{}{}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
delay.Store(false)
|
|
||||||
case <-stopChan:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
if err := sendTCP(ps, host, dp, stopChan); nil != err {
|
|
||||||
errChan <- err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-stopChan:
|
|
||||||
return
|
|
||||||
case <-timerStopped:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func sendTCP(ps pcap.PCapScanner, host *omd.Host, dp *omd.DiscoverPort, stopChan chan struct{}) error {
|
|
||||||
tcpPacket, err := makePacketPortTCP(host)
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
buf := gopacket.NewSerializeBuffer()
|
|
||||||
|
|
||||||
Loop:
|
|
||||||
for portNumber := dp.FirstScanRange; portNumber < dp.LastScanRange; portNumber++ {
|
|
||||||
if nil != dp.ExcludePorts {
|
|
||||||
for _, exPortNumber := range dp.ExcludePorts {
|
|
||||||
if portNumber == exPortNumber {
|
|
||||||
continue Loop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tcpPacket.TCP.DstPort = layers.TCPPort(portNumber)
|
|
||||||
if err := tcpPacket.TCP.SetNetworkLayerForChecksum(tcpPacket.IP); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := gopacket.SerializeLayers(buf, tcpPacket.Opts, tcpPacket.Eth, tcpPacket.IP, tcpPacket.TCP); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := ps.WritePacketData(buf.Bytes()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
timer := time.NewTimer(time.Microsecond * 100)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-stopChan:
|
|
||||||
return nil
|
|
||||||
case <-timer.C:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func handlePacketTCP(host *omd.Host, dp *omd.DiscoverPort, ports map[int]*omd.Port, packet *layers.TCP) *omd.Port {
|
|
||||||
if nil == packet || packet.DstPort != 60000 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if packet.SYN && packet.ACK {
|
|
||||||
port := int(packet.SrcPort)
|
|
||||||
|
|
||||||
if _, ok := ports[port]; ok || !dp.Contains(port) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
olog.Logger().Debug("Discovery", zap.String("ip", host.Address), zap.Int("port", port))
|
|
||||||
|
|
||||||
p := &omd.Port{
|
|
||||||
MetaPortType: omm.ToMetaPortType(omm.MetaPortTypeEnumTCP),
|
|
||||||
PortNumber: json.Number(strconv.Itoa(port)),
|
|
||||||
DiscoveredDate: omu.NowPtr(),
|
|
||||||
}
|
|
||||||
p.Host = host
|
|
||||||
|
|
||||||
ports[port] = p
|
|
||||||
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
type PortPacketTCP struct {
|
|
||||||
Eth *layers.Ethernet
|
|
||||||
IP *layers.IPv4
|
|
||||||
TCP *layers.TCP
|
|
||||||
Opts gopacket.SerializeOptions
|
|
||||||
//PacketConn net.PacketConn
|
|
||||||
}
|
|
||||||
|
|
||||||
func makePacketPortTCP(host *omd.Host) (*PortPacketTCP, error) {
|
|
||||||
packetTCP := &PortPacketTCP{}
|
|
||||||
|
|
||||||
srcIP := net.ParseIP(host.Zone.Address)
|
|
||||||
if nil == srcIP {
|
|
||||||
return nil, fmt.Errorf("Discovery: IP(%s) of zone is not valid", host.Zone.Address)
|
|
||||||
}
|
|
||||||
dstIP := net.ParseIP(host.Address)
|
|
||||||
if nil == dstIP {
|
|
||||||
return nil, fmt.Errorf("Discovery: IP(%s) of host is not valid", host.Address)
|
|
||||||
}
|
|
||||||
|
|
||||||
srcMac, err := net.ParseMAC("30:9C:23:15:A3:09")
|
|
||||||
if nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
dstMac, err := net.ParseMAC("50:E5:49:46:93:28")
|
|
||||||
if nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
packetTCP.Eth = &layers.Ethernet{
|
|
||||||
SrcMAC: srcMac,
|
|
||||||
DstMAC: dstMac,
|
|
||||||
EthernetType: layers.EthernetTypeIPv4,
|
|
||||||
}
|
|
||||||
|
|
||||||
packetTCP.IP = &layers.IPv4{
|
|
||||||
SrcIP: srcIP,
|
|
||||||
DstIP: dstIP,
|
|
||||||
Version: 4,
|
|
||||||
TTL: 64,
|
|
||||||
Protocol: layers.IPProtocolTCP,
|
|
||||||
}
|
|
||||||
packetTCP.TCP = &layers.TCP{
|
|
||||||
SrcPort: 60000,
|
|
||||||
DstPort: 0, // will be incremented during the scan
|
|
||||||
SYN: true,
|
|
||||||
Seq: 0,
|
|
||||||
}
|
|
||||||
packetTCP.Opts = gopacket.SerializeOptions{
|
|
||||||
ComputeChecksums: true,
|
|
||||||
FixLengths: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
return packetTCP, nil
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
package ipv4
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
|
||||||
omm "git.loafle.net/overflow/model/meta"
|
|
||||||
omu "git.loafle.net/overflow/model/util"
|
|
||||||
ouej "git.loafle.net/overflow/util-go/encoding/json"
|
|
||||||
"github.com/google/gopacket/layers"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ScanService(port *omd.Port, ds *omd.DiscoverService, resultChan chan interface{}, errChan chan error, stopChan chan struct{}) {
|
|
||||||
portNumber, err := ouej.NumberToInt(port.PortNumber)
|
|
||||||
if err != nil {
|
|
||||||
errChan <- fmt.Errorf("Discovery: Service scan port[%s] error %v ", port.PortNumber, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch omm.ToMetaPortTypeEnum(port.MetaPortType) {
|
|
||||||
case omm.MetaPortTypeEnumTCP:
|
|
||||||
if !scanServiceTCP(port, ds, resultChan, errChan, stopChan) {
|
|
||||||
if dName, ok := layers.TCPPortNames[layers.TCPPort(portNumber)]; ok {
|
|
||||||
description := fmt.Sprintf("Not Supported Service. Perhaps %s[%d]", dName, portNumber)
|
|
||||||
s := &omd.Service{
|
|
||||||
Key: omm.MetaTargetServiceTypeEnumUNKNOWN.String(),
|
|
||||||
Description: description,
|
|
||||||
DiscoveredDate: omu.NowPtr(),
|
|
||||||
Port: port,
|
|
||||||
MetaCryptoType: omm.ToMetaCryptoType(omm.MetaCryptoTypeEnumUNKNOWN),
|
|
||||||
Metadata: nil,
|
|
||||||
}
|
|
||||||
resultChan <- s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case omm.MetaPortTypeEnumUDP:
|
|
||||||
if !scanServiceUDP(port, ds, resultChan, errChan, stopChan) {
|
|
||||||
if dName, ok := layers.UDPPortNames[layers.UDPPort(portNumber)]; ok {
|
|
||||||
description := fmt.Sprintf("Not Supported Service. Perhaps %s[%d]", dName, portNumber)
|
|
||||||
s := &omd.Service{
|
|
||||||
Key: omm.MetaTargetServiceTypeEnumUNKNOWN.String(),
|
|
||||||
Description: description,
|
|
||||||
DiscoveredDate: omu.NowPtr(),
|
|
||||||
Port: port,
|
|
||||||
MetaCryptoType: omm.ToMetaCryptoType(omm.MetaCryptoTypeEnumUNKNOWN),
|
|
||||||
Metadata: nil,
|
|
||||||
}
|
|
||||||
resultChan <- s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
package ipv4
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/tls"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
omm "git.loafle.net/overflow/model/meta"
|
|
||||||
)
|
|
||||||
|
|
||||||
type serviceConnector interface {
|
|
||||||
MetaCryptoType() *omm.MetaCryptoType
|
|
||||||
Dial(ip string, port int) (net.Conn, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type normalServiceConn struct {
|
|
||||||
metaCryptoType *omm.MetaCryptoType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (nsc *normalServiceConn) MetaCryptoType() *omm.MetaCryptoType {
|
|
||||||
return nsc.metaCryptoType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (nsc *normalServiceConn) Dial(ip string, port int) (net.Conn, error) {
|
|
||||||
addr := fmt.Sprintf("%s:%d", ip, port)
|
|
||||||
conn, err := net.DialTimeout("tcp", addr, time.Duration(3)*time.Second)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return conn, err
|
|
||||||
}
|
|
||||||
|
|
||||||
type tlsServiceConn struct {
|
|
||||||
metaCryptoType *omm.MetaCryptoType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tsc *tlsServiceConn) MetaCryptoType() *omm.MetaCryptoType {
|
|
||||||
return tsc.metaCryptoType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tsc *tlsServiceConn) Dial(ip string, port int) (net.Conn, error) {
|
|
||||||
addr := fmt.Sprintf("%s:%d", ip, port)
|
|
||||||
dialer := &net.Dialer{
|
|
||||||
Timeout: 3 * time.Second,
|
|
||||||
}
|
|
||||||
conn, err := tls.DialWithDialer(
|
|
||||||
dialer,
|
|
||||||
"tcp",
|
|
||||||
addr,
|
|
||||||
&tls.Config{
|
|
||||||
InsecureSkipVerify: true,
|
|
||||||
ServerName: ip,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return conn, err
|
|
||||||
}
|
|
|
@ -1,257 +0,0 @@
|
||||||
package ipv4
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
|
||||||
omm "git.loafle.net/overflow/model/meta"
|
|
||||||
omu "git.loafle.net/overflow/model/util"
|
|
||||||
osm "git.loafle.net/overflow/service_matcher-go"
|
|
||||||
cuej "git.loafle.net/overflow/util-go/encoding/json"
|
|
||||||
"git.loafle.net/overflow_scanner/probe/matcher"
|
|
||||||
)
|
|
||||||
|
|
||||||
func scanServiceTCP(port *omd.Port, ds *omd.DiscoverService, resultChan chan interface{}, errChan chan error, stopChan chan struct{}) bool {
|
|
||||||
hostIP := port.Host.Address
|
|
||||||
portNumber, err := cuej.NumberToInt(port.PortNumber)
|
|
||||||
if err != nil {
|
|
||||||
errChan <- fmt.Errorf("Discovery: Service scan on %s:%s error has occurred %v ", hostIP, port.PortNumber, err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
info := osm.NewMatchInfo(hostIP, portNumber)
|
|
||||||
var s *omd.Service
|
|
||||||
|
|
||||||
scs := []serviceConnector{
|
|
||||||
&normalServiceConn{
|
|
||||||
metaCryptoType: omm.ToMetaCryptoType(omm.MetaCryptoTypeEnumNONE),
|
|
||||||
},
|
|
||||||
&tlsServiceConn{
|
|
||||||
metaCryptoType: omm.ToMetaCryptoType(omm.MetaCryptoTypeEnumTLS),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
LOOP:
|
|
||||||
for i := 0; i < len(scs); i++ {
|
|
||||||
sc := scs[i]
|
|
||||||
|
|
||||||
conn, err := sc.Dial(hostIP, portNumber)
|
|
||||||
if err != nil {
|
|
||||||
errChan <- fmt.Errorf("Discovery: Service scan[%s] on %s:%d error has occurred %v ", sc.MetaCryptoType().Key, hostIP, portNumber, err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// olog.Logger().Debug("Discovery: Service scan connected", zap.String("hostIP", hostIP), zap.Int("portNumber", portNumber), zap.String("MetaCryptoType", sc.MetaCryptoType().Key))
|
|
||||||
|
|
||||||
buf := make([]byte, 1024)
|
|
||||||
|
|
||||||
if err := conn.SetReadDeadline(time.Now().Add(1 * time.Second)); nil != err {
|
|
||||||
// olog.Logger().Debug("Discovery: cannot set readdeadline connected", zap.String("hostIP", hostIP), zap.Int("portNumber", portNumber), zap.String("MetaCryptoType", sc.MetaCryptoType().Key))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
rn, err := conn.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
rn = 0
|
|
||||||
}
|
|
||||||
if rn != 0 {
|
|
||||||
s = hadlePrePacket(info, sc, conn, osm.NewPacket(buf, rn))
|
|
||||||
} else {
|
|
||||||
conn.Close()
|
|
||||||
s = hadlePostPacket(info, sc, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
if nil != s {
|
|
||||||
if s.Key == "HTTP" {
|
|
||||||
hsm := matcher.GetHTTPSubMatchers()
|
|
||||||
if ss := hadlePostPacket(info, sc, hsm); ss != nil {
|
|
||||||
s = ss
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break LOOP
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-stopChan:
|
|
||||||
return false
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if nil != s {
|
|
||||||
s.Port = port
|
|
||||||
resultChan <- s
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func hadlePrePacket(info osm.MatchInfo, sc serviceConnector, conn net.Conn, packet *osm.Packet) *omd.Service {
|
|
||||||
defer func() {
|
|
||||||
conn.Close()
|
|
||||||
}()
|
|
||||||
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan pre packet length[%d], buf[%v]", packet.Len, packet.Buffer)
|
|
||||||
// olog.Logger().Debug("Discovery: Service scan[%s] on %s:%d pre packet length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), packet.Len)
|
|
||||||
|
|
||||||
ms := matcher.GetTCPMatchers(true)
|
|
||||||
buf := make([]byte, 1024)
|
|
||||||
var s *omd.Service
|
|
||||||
|
|
||||||
LOOP:
|
|
||||||
for i := 0; i < len(ms); i++ {
|
|
||||||
m := ms[i]
|
|
||||||
|
|
||||||
if err := m.Match(info, 0, packet); err == nil {
|
|
||||||
packetCount := m.PacketCount()
|
|
||||||
|
|
||||||
if 0 == packetCount {
|
|
||||||
s = discoveredService(m, sc)
|
|
||||||
break LOOP
|
|
||||||
}
|
|
||||||
|
|
||||||
found := false
|
|
||||||
|
|
||||||
for j := 0; j < packetCount; j++ {
|
|
||||||
tPacket := m.Packet(j)
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan send packet length[%d], buf[%v]", tPacket.Len, tPacket.Buffer)
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d send packet length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), tPacket.Len)
|
|
||||||
|
|
||||||
if err := conn.SetWriteDeadline(time.Now().Add(1 * time.Second)); nil != err {
|
|
||||||
// olog.Logger().Debugf("Discovery: cannot set writeDeadLine Service scan[%s] on %s:%d send packet length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), tPacket.Len)
|
|
||||||
break LOOP
|
|
||||||
}
|
|
||||||
wn, err := conn.Write(tPacket.Buffer)
|
|
||||||
if nil != err {
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d send packet error %v", sc.MetaCryptoType().Key, info.IP(), info.Port(), err)
|
|
||||||
continue LOOP
|
|
||||||
}
|
|
||||||
if wn != tPacket.Len {
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d send packet length[%d] not same with %d", sc.MetaCryptoType().Key, info.IP(), info.Port(), wn, tPacket.Len)
|
|
||||||
continue LOOP
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := conn.SetReadDeadline(time.Now().Add(1 * time.Second)); nil != err {
|
|
||||||
// olog.Logger().Debugf("Discovery: cannot set readDeadLine Service scan[%s] on %s:%d send packet length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), tPacket.Len)
|
|
||||||
break LOOP
|
|
||||||
}
|
|
||||||
rn, err := conn.Read(buf)
|
|
||||||
if nil != err {
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d receive packet error %v", sc.MetaCryptoType().Key, info.IP(), info.Port(), err)
|
|
||||||
break LOOP
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := m.Match(info, j+1, osm.NewPacket(buf, rn)); err == nil {
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan receive match length[%d], buf[%v]", rn, buf)
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d receive match length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), rn)
|
|
||||||
found = true
|
|
||||||
} else {
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan receive not match length[%d], buf[%v]", rn, buf)
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d receive not match length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), rn)
|
|
||||||
found = false
|
|
||||||
continue LOOP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if found {
|
|
||||||
s = discoveredService(m, sc)
|
|
||||||
break LOOP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func hadlePostPacket(info osm.MatchInfo, sc serviceConnector, limitedMatchers []osm.Matcher) *omd.Service {
|
|
||||||
defer func() {
|
|
||||||
}()
|
|
||||||
|
|
||||||
ms := matcher.GetTCPMatchers(false)
|
|
||||||
if limitedMatchers != nil {
|
|
||||||
ms = limitedMatchers
|
|
||||||
}
|
|
||||||
|
|
||||||
buf := make([]byte, 1024)
|
|
||||||
var s *omd.Service
|
|
||||||
|
|
||||||
LOOP:
|
|
||||||
for i := 0; i < len(ms); i++ {
|
|
||||||
m := ms[i]
|
|
||||||
|
|
||||||
conn, err := sc.Dial(info.IP(), info.Port())
|
|
||||||
if err != nil {
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d socket dial error %v", sc.MetaCryptoType().Key, info.IP(), info.Port(), err)
|
|
||||||
break LOOP
|
|
||||||
}
|
|
||||||
|
|
||||||
packetCount := m.PacketCount()
|
|
||||||
for j := 0; j < packetCount; j++ {
|
|
||||||
tPacket := m.Packet(j)
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan send packet length[%d], buf[%v]", tPacket.Len, tPacket.Buffer)
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d send packet length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), tPacket.Len)
|
|
||||||
|
|
||||||
if err := conn.SetWriteDeadline(time.Now().Add(1 * time.Second)); nil != err {
|
|
||||||
// olog.Logger().Debugf("Discovery: cannot set writeDeadLine Service scan[%s] on %s:%d send packet length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), tPacket.Len)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
wn, err := conn.Write(tPacket.Buffer)
|
|
||||||
if nil != err {
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d send packet error %v", sc.MetaCryptoType().Key, info.IP(), info.Port(), err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if wn != tPacket.Len {
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d send packet length[%d] not same with %d", sc.MetaCryptoType().Key, info.IP(), info.Port(), wn, tPacket.Len)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := conn.SetReadDeadline(time.Now().Add(1 * time.Second)); nil != err {
|
|
||||||
// olog.Logger().Debugf("Discovery: cannot set readDeadLine Service scan[%s] on %s:%d send packet length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), tPacket.Len)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
rn, err := conn.Read(buf)
|
|
||||||
if nil != err {
|
|
||||||
if !m.HasResponse(j) {
|
|
||||||
s = discoveredService(m, sc)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d receive packet error %v", sc.MetaCryptoType().Key, info.IP(), info.Port(), err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := m.Match(info, j, osm.NewPacket(buf, rn)); err == nil {
|
|
||||||
if packetCount-1 == j {
|
|
||||||
s = discoveredService(m, sc)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan receive match length[%d], buf[%v]", rn, buf)
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d receive match length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), rn)
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan receive not match length[%d], buf[%v]", rn, buf)
|
|
||||||
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d receive not match length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), rn)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
conn.Close()
|
|
||||||
|
|
||||||
if nil != s {
|
|
||||||
break LOOP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func discoveredService(m osm.Matcher, sc serviceConnector) *omd.Service {
|
|
||||||
return &omd.Service{
|
|
||||||
Key: m.Key(),
|
|
||||||
MetaCryptoType: sc.MetaCryptoType(),
|
|
||||||
DiscoveredDate: omu.NowPtr(),
|
|
||||||
Metadata: m.Meta(),
|
|
||||||
Name: m.Name(),
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package ipv4
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
|
||||||
omm "git.loafle.net/overflow/model/meta"
|
|
||||||
omu "git.loafle.net/overflow/model/util"
|
|
||||||
osm "git.loafle.net/overflow/service_matcher-go"
|
|
||||||
ouej "git.loafle.net/overflow/util-go/encoding/json"
|
|
||||||
"git.loafle.net/overflow_scanner/probe/matcher"
|
|
||||||
)
|
|
||||||
|
|
||||||
func scanServiceUDP(port *omd.Port, ds *omd.DiscoverService, resultChan chan interface{}, errChan chan error, stopChan chan struct{}) bool {
|
|
||||||
portNumber, err := ouej.NumberToInt(port.PortNumber)
|
|
||||||
if err != nil {
|
|
||||||
errChan <- fmt.Errorf("Discovery: Service scan port[%s] error %v ", port.PortNumber, err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
ms := matcher.GetUDPMatchers()
|
|
||||||
mi := osm.NewMatchInfo(port.Host.Address, portNumber)
|
|
||||||
|
|
||||||
for i := 0; i < len(ms); i++ {
|
|
||||||
m := ms[i]
|
|
||||||
p := osm.NewPacket(port.UDPLayer.LayerPayload(), len(port.UDPLayer.LayerPayload()))
|
|
||||||
|
|
||||||
if err := m.Match(mi, 0, p); err == nil {
|
|
||||||
s := &omd.Service{
|
|
||||||
Key: m.Key(),
|
|
||||||
Port: port,
|
|
||||||
MetaCryptoType: omm.ToMetaCryptoType(omm.MetaCryptoTypeEnumNONE),
|
|
||||||
DiscoveredDate: omu.NowPtr(),
|
|
||||||
Metadata: m.Meta(),
|
|
||||||
Name: m.Name(),
|
|
||||||
}
|
|
||||||
|
|
||||||
resultChan <- s
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ScanHost(zone *omd.Zone, omd *omd.DiscoverHost, resultChan chan interface{}, errChan chan error, stopChan chan struct{}) {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ScanPort(host *omd.Host, dp *omd.DiscoverPort, resultChan chan interface{}, errChan chan error, stopChan chan struct{}) {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ScanService(port *omd.Port, ds *omd.DiscoverService, resultChan chan interface{}, errChan chan error, stopChan chan struct{}) {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package discoverer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
|
||||||
omm "git.loafle.net/overflow/model/meta"
|
|
||||||
"git.loafle.net/overflow_scanner/probe/discoverer/ipv4"
|
|
||||||
"git.loafle.net/overflow_scanner/probe/discoverer/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
func scanPort(host *omd.Host, dp *omd.DiscoverPort, resultChan chan interface{}, errChan chan error, doneChan chan<- struct{}, stopChan chan struct{}) {
|
|
||||||
defer func() {
|
|
||||||
doneChan <- struct{}{}
|
|
||||||
}()
|
|
||||||
|
|
||||||
switch omm.ToMetaIPTypeEnum(host.MetaIPType) {
|
|
||||||
case omm.MetaIPTypeEnumV4:
|
|
||||||
ipv4.ScanPort(host, dp, resultChan, errChan, stopChan)
|
|
||||||
case omm.MetaIPTypeEnumV6:
|
|
||||||
ipv6.ScanPort(host, dp, resultChan, errChan, stopChan)
|
|
||||||
default:
|
|
||||||
errChan <- fmt.Errorf("Discovery: Not supported MetaIPType")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package discoverer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
|
||||||
omm "git.loafle.net/overflow/model/meta"
|
|
||||||
"git.loafle.net/overflow_scanner/probe/discoverer/ipv4"
|
|
||||||
"git.loafle.net/overflow_scanner/probe/discoverer/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
func scanService(port *omd.Port, ds *omd.DiscoverService, resultChan chan interface{}, errChan chan error, doneChan chan<- struct{}, stopChan chan struct{}) {
|
|
||||||
defer func() {
|
|
||||||
doneChan <- struct{}{}
|
|
||||||
}()
|
|
||||||
|
|
||||||
switch omm.ToMetaIPTypeEnum(port.Host.MetaIPType) {
|
|
||||||
case omm.MetaIPTypeEnumV4:
|
|
||||||
ipv4.ScanService(port, ds, resultChan, errChan, stopChan)
|
|
||||||
case omm.MetaIPTypeEnumV6:
|
|
||||||
ipv6.ScanService(port, ds, resultChan, errChan, stopChan)
|
|
||||||
default:
|
|
||||||
errChan <- fmt.Errorf("Discovery: Not supported MetaIPType")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,98 +0,0 @@
|
||||||
package discoverer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"regexp"
|
|
||||||
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
|
||||||
omm "git.loafle.net/overflow/model/meta"
|
|
||||||
omu "git.loafle.net/overflow/model/util"
|
|
||||||
oun "git.loafle.net/overflow/util-go/net"
|
|
||||||
)
|
|
||||||
|
|
||||||
func scanZone(dz *omd.DiscoverZone, resultChan chan interface{}, errChan chan error, doneChan chan<- struct{}, stopChan chan struct{}) {
|
|
||||||
defer func() {
|
|
||||||
doneChan <- struct{}{}
|
|
||||||
}()
|
|
||||||
|
|
||||||
var err error
|
|
||||||
var ifaces []net.Interface
|
|
||||||
var addrs []net.Addr
|
|
||||||
var ipnet *oun.IPNet
|
|
||||||
var zones []*oun.IPNet
|
|
||||||
// var gwIP net.IP
|
|
||||||
// var gwIFace string
|
|
||||||
|
|
||||||
// if gwIP, gwIFace, err = gateway.DiscoverGateway(); nil != err {
|
|
||||||
// logChan <- err
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
if ifaces, err = net.Interfaces(); nil != err {
|
|
||||||
errChan <- err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
zones = make([]*oun.IPNet, 0)
|
|
||||||
|
|
||||||
for _, i := range ifaces {
|
|
||||||
|
|
||||||
if addrs, err = i.Addrs(); nil != err {
|
|
||||||
errChan <- err
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, addr := range addrs {
|
|
||||||
|
|
||||||
if _, ipnet, err = oun.ParseCIDR(addr.String()); nil != err {
|
|
||||||
errChan <- err
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if ipnet.IP.IsLoopback() || checkSameZone(zones, ipnet) || checkExclude(dz.ExcludePatterns, i.Name) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
zones = append(zones, ipnet)
|
|
||||||
|
|
||||||
z := &omd.Zone{
|
|
||||||
Network: ipnet.String(),
|
|
||||||
Iface: i.Name,
|
|
||||||
Mac: i.HardwareAddr.String(),
|
|
||||||
Address: addr.String(),
|
|
||||||
DiscoveredDate: omu.NowPtr(),
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ipnet.Version() {
|
|
||||||
case 6:
|
|
||||||
z.MetaIPType = omm.ToMetaIPType(omm.MetaIPTypeEnumV6)
|
|
||||||
default:
|
|
||||||
z.MetaIPType = omm.ToMetaIPType(omm.MetaIPTypeEnumV4)
|
|
||||||
}
|
|
||||||
|
|
||||||
resultChan <- z
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkExclude(ep []string, iface string) bool {
|
|
||||||
var r *regexp.Regexp
|
|
||||||
var err error
|
|
||||||
for _, p := range ep {
|
|
||||||
if r, err = regexp.Compile(p); nil != err {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if r.MatchString(iface) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkSameZone(zones []*oun.IPNet, ipnet *oun.IPNet) bool {
|
|
||||||
for _, i := range zones {
|
|
||||||
if i.Contains(ipnet.IP) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
|
@ -17,7 +17,7 @@ func Scan(discoverySession session.DiscoverySession, targetHost *omd.Host) error
|
||||||
case omm.MetaIPTypeEnumV4:
|
case omm.MetaIPTypeEnumV4:
|
||||||
return scanV4(discoverySession, targetHost)
|
return scanV4(discoverySession, targetHost)
|
||||||
case omm.MetaIPTypeEnumV6:
|
case omm.MetaIPTypeEnumV6:
|
||||||
return scanV4(discoverySession, targetHost)
|
return scanV6(discoverySession, targetHost)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
10
discovery/protocol/tcp/syn/synv6.go
Normal file
10
discovery/protocol/tcp/syn/synv6.go
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package syn
|
||||||
|
|
||||||
|
import (
|
||||||
|
omd "git.loafle.net/overflow/model/discovery"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
||||||
|
)
|
||||||
|
|
||||||
|
func scanV6(discoverySession session.DiscoverySession, targetHost *omd.Host) error {
|
||||||
|
return nil
|
||||||
|
}
|
115
discovery/protocol/udp/connection/connection.go
Normal file
115
discovery/protocol/udp/connection/connection.go
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
package connection
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net"
|
||||||
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
omd "git.loafle.net/overflow/model/discovery"
|
||||||
|
omm "git.loafle.net/overflow/model/meta"
|
||||||
|
omu "git.loafle.net/overflow/model/util"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
||||||
|
"golang.org/x/sync/semaphore"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultUlimit = 1024
|
||||||
|
)
|
||||||
|
|
||||||
|
func Scan(discoverySession session.DiscoverySession, targetHost *omd.Host) error {
|
||||||
|
if nil == targetHost || nil == discoverySession.DiscoverPort() || !discoverySession.DiscoverPort().IncludeTCP {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
dp := discoverySession.DiscoverPort()
|
||||||
|
|
||||||
|
lock := semaphore.NewWeighted(Ulimit())
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
timeout := 500 * time.Millisecond
|
||||||
|
ports := make(map[int]*omd.Port)
|
||||||
|
|
||||||
|
Loop:
|
||||||
|
for portNumber := dp.FirstScanRange; portNumber < dp.LastScanRange; portNumber++ {
|
||||||
|
if nil != dp.ExcludePorts {
|
||||||
|
for _, exPortNumber := range dp.ExcludePorts {
|
||||||
|
if portNumber == exPortNumber {
|
||||||
|
continue Loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.Acquire(context.TODO(), 1)
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
go func(port int) {
|
||||||
|
defer func() {
|
||||||
|
lock.Release(1)
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
|
tryConnect(discoverySession, ports, targetHost, port, timeout)
|
||||||
|
}(portNumber)
|
||||||
|
|
||||||
|
timer := time.NewTimer(time.Microsecond * 100)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-timer.C:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func tryConnect(discoverySession session.DiscoverySession, ports map[int]*omd.Port, targetHost *omd.Host, port int, timeout time.Duration) {
|
||||||
|
addr := net.JoinHostPort(targetHost.Address, strconv.Itoa(port))
|
||||||
|
conn, err := net.DialTimeout("tcp", addr, timeout)
|
||||||
|
dp := discoverySession.DiscoverPort()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "too many open files") {
|
||||||
|
time.Sleep(timeout)
|
||||||
|
tryConnect(discoverySession, ports, targetHost, port, timeout)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.Close()
|
||||||
|
|
||||||
|
if _, ok := ports[port]; ok || !dp.Contains(port) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p := &omd.Port{
|
||||||
|
MetaPortType: omm.ToMetaPortType(omm.MetaPortTypeEnumTCP),
|
||||||
|
PortNumber: json.Number(strconv.Itoa(port)),
|
||||||
|
DiscoveredDate: omu.NowPtr(),
|
||||||
|
}
|
||||||
|
p.Host = targetHost
|
||||||
|
|
||||||
|
ports[port] = p
|
||||||
|
|
||||||
|
discoverySession.AddPort(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Ulimit() int64 {
|
||||||
|
out, err := exec.Command("ulimit", "-n").Output()
|
||||||
|
if nil != err {
|
||||||
|
return defaultUlimit
|
||||||
|
}
|
||||||
|
|
||||||
|
s := strings.TrimSpace(string(out))
|
||||||
|
|
||||||
|
i, err := strconv.ParseInt(s, 10, 64)
|
||||||
|
if nil != err {
|
||||||
|
return defaultUlimit
|
||||||
|
}
|
||||||
|
|
||||||
|
return i
|
||||||
|
}
|
101
discovery/protocol/udp/connection/connection_test.go
Normal file
101
discovery/protocol/udp/connection/connection_test.go
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
package connection
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
omd "git.loafle.net/overflow/model/discovery"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/__test"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestScan(t *testing.T) {
|
||||||
|
s := session.NewMockDiscoverySession(
|
||||||
|
"testRequester",
|
||||||
|
types.DiscoveryRequestTypeHost,
|
||||||
|
__test.Zone(),
|
||||||
|
__test.DiscoverHost(
|
||||||
|
__test.DiscoveryConfig(),
|
||||||
|
1,
|
||||||
|
254,
|
||||||
|
__test.DiscoverPort(
|
||||||
|
nil,
|
||||||
|
1,
|
||||||
|
65535,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
nil,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
targetHost := __test.Host(
|
||||||
|
"atGame",
|
||||||
|
"1",
|
||||||
|
"00:11:32:7f:20:61",
|
||||||
|
)
|
||||||
|
|
||||||
|
type args struct {
|
||||||
|
discoverySession session.DiscoverySession
|
||||||
|
targetHost *omd.Host
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "1",
|
||||||
|
args: args{
|
||||||
|
discoverySession: s,
|
||||||
|
targetHost: targetHost,
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if err := Scan(tt.args.discoverySession, tt.args.targetHost); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("Scan() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_scanPort(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
discoverySession session.DiscoverySession
|
||||||
|
ports map[int]*omd.Port
|
||||||
|
targetHost *omd.Host
|
||||||
|
port int
|
||||||
|
timeout time.Duration
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
tryConnect(tt.args.discoverySession, tt.args.ports, tt.args.targetHost, tt.args.port, tt.args.timeout)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUlimit(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
want int64
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := Ulimit(); got != tt.want {
|
||||||
|
t.Errorf("Ulimit() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
24
discovery/protocol/udp/matcher/matcher.go
Normal file
24
discovery/protocol/udp/matcher/matcher.go
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
package matcher
|
||||||
|
|
||||||
|
import (
|
||||||
|
omd "git.loafle.net/overflow/model/discovery"
|
||||||
|
omm "git.loafle.net/overflow/model/meta"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Scan(discoverySession session.DiscoverySession, targetHost *omd.Host) error {
|
||||||
|
if nil == targetHost || nil == discoverySession.DiscoverPort() || !discoverySession.DiscoverPort().IncludeTCP {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
metaIPTypeEnum := omm.ToMetaIPTypeEnum(discoverySession.Zone().MetaIPType)
|
||||||
|
|
||||||
|
switch metaIPTypeEnum {
|
||||||
|
case omm.MetaIPTypeEnumV4:
|
||||||
|
return scanV4(discoverySession, targetHost)
|
||||||
|
case omm.MetaIPTypeEnumV6:
|
||||||
|
return scanV6(discoverySession, targetHost)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,43 +1,36 @@
|
||||||
package ipv4
|
package matcher
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go.uber.org/zap"
|
|
||||||
|
|
||||||
olog "git.loafle.net/overflow/log-go"
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
omd "git.loafle.net/overflow/model/discovery"
|
||||||
omm "git.loafle.net/overflow/model/meta"
|
omm "git.loafle.net/overflow/model/meta"
|
||||||
omu "git.loafle.net/overflow/model/util"
|
omu "git.loafle.net/overflow/model/util"
|
||||||
"git.loafle.net/overflow_scanner/probe/matcher"
|
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
||||||
"git.loafle.net/overflow_scanner/probe/pcap"
|
"git.loafle.net/overflow_scanner/probe/internal/matcher"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/internal/pcap"
|
||||||
"github.com/google/gopacket"
|
"github.com/google/gopacket"
|
||||||
"github.com/google/gopacket/layers"
|
"github.com/google/gopacket/layers"
|
||||||
)
|
)
|
||||||
|
|
||||||
func scanPortUDP(host *omd.Host, dp *omd.DiscoverPort, resultChan chan interface{}, errChan chan error, stopChan chan struct{}, wg *sync.WaitGroup) {
|
func scanV4(discoverySession session.DiscoverySession, targetHost *omd.Host) error {
|
||||||
defer func() {
|
ps, err := pcap.RetainScanner(targetHost.Zone)
|
||||||
wg.Done()
|
|
||||||
}()
|
|
||||||
|
|
||||||
ps, err := pcap.RetainScanner(host.Zone)
|
|
||||||
if nil != err {
|
if nil != err {
|
||||||
errChan <- fmt.Errorf("Discovery: Cannot retain pcap instance %v", err)
|
return fmt.Errorf("Discovery: Cannot retain pcap instance %v", err)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
pcap.ReleaseScanner(host.Zone)
|
go pcap.ReleaseScanner(targetHost.Zone)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
udpChan := ps.OpenUDP(host.Address)
|
udpChan := ps.OpenUDP(targetHost.Address)
|
||||||
defer func() {
|
defer func() {
|
||||||
ps.CloseUDP(host.Address, udpChan)
|
go ps.CloseUDP(targetHost.Address, udpChan)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
timerStopped := make(chan struct{})
|
timerStopped := make(chan struct{})
|
||||||
|
@ -46,18 +39,17 @@ func scanPortUDP(host *omd.Host, dp *omd.DiscoverPort, resultChan chan interface
|
||||||
|
|
||||||
var delay atomic.Value
|
var delay atomic.Value
|
||||||
delay.Store(false)
|
delay.Store(false)
|
||||||
ticker := time.NewTicker(time.Second * 3)
|
ticker := time.NewTicker(time.Millisecond * 500)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case packet, ok := <-udpChan:
|
case packet, ok := <-udpChan:
|
||||||
if !ok {
|
if !ok {
|
||||||
olog.Logger().Debug("Discovery: udp channel is closed")
|
// olog.Logger().Debug("Discovery: udp channel is closed")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
delay.Store(true)
|
delay.Store(true)
|
||||||
if p := handlePacketUDP(host, dp, ports, packet); nil != p {
|
if p := handlePacketUDP4(discoverySession, targetHost, ports, packet); nil != p {
|
||||||
resultChan <- p
|
discoverySession.AddPort(p)
|
||||||
}
|
}
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
if false == delay.Load().(bool) {
|
if false == delay.Load().(bool) {
|
||||||
|
@ -66,32 +58,30 @@ func scanPortUDP(host *omd.Host, dp *omd.DiscoverPort, resultChan chan interface
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
delay.Store(false)
|
delay.Store(false)
|
||||||
case <-stopChan:
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err := sendUDP(host, dp, stopChan); nil != err {
|
if err := sendUDP4(discoverySession, ps, targetHost); nil != err {
|
||||||
errChan <- err
|
log.Printf("sendUDP4 %v", err)
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-stopChan:
|
|
||||||
return
|
|
||||||
case <-timerStopped:
|
case <-timerStopped:
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendUDP(host *omd.Host, dp *omd.DiscoverPort, stopChan chan struct{}) error {
|
func sendUDP4(discoverySession session.DiscoverySession, ps pcap.PCapScanner, host *omd.Host) error {
|
||||||
|
dp := discoverySession.DiscoverPort()
|
||||||
|
|
||||||
ip := net.ParseIP(host.Address)
|
ip := net.ParseIP(host.Address)
|
||||||
if nil == ip {
|
if nil == ip {
|
||||||
return fmt.Errorf("Discovery: IP(%s) of host is not valid", host.Address)
|
return fmt.Errorf("IP(%s) of host is not valid", host.Address)
|
||||||
}
|
}
|
||||||
|
|
||||||
ms := matcher.GetUDPMatchers()
|
matchers := matcher.GetUDPMatchers()
|
||||||
|
|
||||||
conn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: 0})
|
conn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: 0})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -101,36 +91,32 @@ func sendUDP(host *omd.Host, dp *omd.DiscoverPort, stopChan chan struct{}) error
|
||||||
conn.Close()
|
conn.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
for indexI := 0; indexI < len(ms); indexI++ {
|
for _, _matcher := range matchers {
|
||||||
m := ms[indexI]
|
INNER_LOOP:
|
||||||
|
|
||||||
Loop:
|
|
||||||
for portNumber := dp.FirstScanRange; portNumber < dp.LastScanRange; portNumber++ {
|
for portNumber := dp.FirstScanRange; portNumber < dp.LastScanRange; portNumber++ {
|
||||||
if nil != dp.ExcludePorts {
|
if nil != dp.ExcludePorts {
|
||||||
for _, exPortNumber := range dp.ExcludePorts {
|
for _, exPortNumber := range dp.ExcludePorts {
|
||||||
if portNumber == exPortNumber {
|
if portNumber == exPortNumber {
|
||||||
continue Loop
|
continue INNER_LOOP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !m.IsSend(portNumber) {
|
if !_matcher.IsSend(portNumber) {
|
||||||
continue
|
continue INNER_LOOP
|
||||||
}
|
}
|
||||||
|
|
||||||
addr := &net.UDPAddr{IP: ip.To4(), Port: portNumber}
|
addr := &net.UDPAddr{IP: ip.To4(), Port: portNumber}
|
||||||
for i := 0; i < m.PacketCount(); i++ {
|
for i := 0; i < _matcher.PacketCount(); i++ {
|
||||||
p := m.Packet(i)
|
p := _matcher.Packet(i)
|
||||||
if _, err := conn.WriteToUDP(p.Buffer, addr); err != nil {
|
if _, err := conn.WriteToUDP(p.Buffer, addr); err != nil {
|
||||||
olog.Logger().Error("Discovery: UDP write error", zap.Error(err))
|
log.Print("UDP write error", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timer := time.NewTimer(time.Microsecond * 200)
|
timer := time.NewTimer(time.Microsecond * 100)
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-stopChan:
|
|
||||||
return nil
|
|
||||||
case <-timer.C:
|
case <-timer.C:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,20 +125,22 @@ func sendUDP(host *omd.Host, dp *omd.DiscoverPort, stopChan chan struct{}) error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handlePacketUDP(host *omd.Host, dp *omd.DiscoverPort, ports map[int]*omd.Port, packet gopacket.Packet) *omd.Port {
|
func handlePacketUDP4(discoverySession session.DiscoverySession, host *omd.Host, ports map[int]*omd.Port, packet gopacket.Packet) *omd.Port {
|
||||||
ipLayer := packet.Layer(layers.LayerTypeIPv4)
|
ipLayer := packet.Layer(layers.LayerTypeIPv4)
|
||||||
|
|
||||||
if ipLayer.(*layers.IPv4).SrcIP.String() == host.Zone.Address {
|
if ipLayer.(*layers.IPv4).SrcIP.String() == host.Zone.Address {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dp := discoverySession.DiscoverPort()
|
||||||
|
|
||||||
if net := packet.NetworkLayer(); net == nil {
|
if net := packet.NetworkLayer(); net == nil {
|
||||||
} else if udpLayer := packet.Layer(layers.LayerTypeUDP); udpLayer == nil {
|
} else if udpLayer := packet.Layer(layers.LayerTypeUDP); udpLayer == nil {
|
||||||
} else if udp, ok := udpLayer.(*layers.UDP); ok {
|
} else if udp, ok := udpLayer.(*layers.UDP); ok {
|
||||||
|
|
||||||
srcIP := ipLayer.(*layers.IPv4).SrcIP
|
// srcIP := ipLayer.(*layers.IPv4).SrcIP
|
||||||
port := int(udp.SrcPort)
|
port := int(udp.SrcPort)
|
||||||
olog.Logger().Debug("Discovery", zap.String("ip", srcIP.String()), zap.Int("port", port))
|
|
||||||
if _, ok := ports[port]; ok || !dp.Contains(port) {
|
if _, ok := ports[port]; ok || !dp.Contains(port) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
10
discovery/protocol/udp/matcher/matcher6.go
Normal file
10
discovery/protocol/udp/matcher/matcher6.go
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package matcher
|
||||||
|
|
||||||
|
import (
|
||||||
|
omd "git.loafle.net/overflow/model/discovery"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
||||||
|
)
|
||||||
|
|
||||||
|
func scanV6(discoverySession session.DiscoverySession, targetHost *omd.Host) error {
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,11 +1,45 @@
|
||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
omd "git.loafle.net/overflow/model/discovery"
|
||||||
|
omm "git.loafle.net/overflow/model/meta"
|
||||||
|
omu "git.loafle.net/overflow/model/util"
|
||||||
|
osm "git.loafle.net/overflow/service_matcher-go"
|
||||||
|
ouej "git.loafle.net/overflow/util-go/encoding/json"
|
||||||
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/internal/matcher"
|
||||||
)
|
)
|
||||||
|
|
||||||
func scanUDP(discoverySession session.DiscoverySession, targetPort *omd.Port) error {
|
func scanUDP(discoverySession session.DiscoverySession, targetPort *omd.Port) error {
|
||||||
|
portNumber, err := ouej.NumberToInt(targetPort.PortNumber)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Service scan port[%s] error %v ", targetPort.PortNumber, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ms := matcher.GetUDPMatchers()
|
||||||
|
mi := osm.NewMatchInfo(targetPort.Host.Address, portNumber)
|
||||||
|
|
||||||
|
for i := 0; i < len(ms); i++ {
|
||||||
|
m := ms[i]
|
||||||
|
p := osm.NewPacket(targetPort.UDPLayer.LayerPayload(), len(targetPort.UDPLayer.LayerPayload()))
|
||||||
|
|
||||||
|
if err := m.Match(mi, 0, p); err == nil {
|
||||||
|
s := &omd.Service{
|
||||||
|
Key: m.Key(),
|
||||||
|
Port: targetPort,
|
||||||
|
MetaCryptoType: omm.ToMetaCryptoType(omm.MetaCryptoTypeEnumNONE),
|
||||||
|
DiscoveredDate: omu.NowPtr(),
|
||||||
|
Metadata: m.Meta(),
|
||||||
|
Name: m.Name(),
|
||||||
|
}
|
||||||
|
|
||||||
|
discoverySession.AddService(s)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user