ing
This commit is contained in:
parent
c28149db4b
commit
558e13da2e
|
@ -6,10 +6,11 @@ import (
|
||||||
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
omd "git.loafle.net/overflow/model/discovery"
|
||||||
omu "git.loafle.net/overflow/model/util"
|
omu "git.loafle.net/overflow/model/util"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/protocol/mdns"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/protocol/snmp"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/protocol/upnp"
|
||||||
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
||||||
"git.loafle.net/overflow_scanner/probe/discovery/types"
|
"git.loafle.net/overflow_scanner/probe/discovery/types"
|
||||||
"git.loafle.net/overflow_scanner/probe/internal/protocol/mdns"
|
|
||||||
"git.loafle.net/overflow_scanner/probe/internal/protocol/upnp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Discoverer interface {
|
type Discoverer interface {
|
||||||
|
@ -47,21 +48,25 @@ type ofDiscoverer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ofDiscoverer) DiscoverHost(requesterID string, zone *omd.Zone, dh *omd.DiscoverHost) {
|
func (d *ofDiscoverer) DiscoverHost(requesterID string, zone *omd.Zone, dh *omd.DiscoverHost) {
|
||||||
d.enqueue(retainDiscoveryRequest(d.messageChan, requesterID, types.DiscoveryRequestTypeHost, zone, dh))
|
d.enqueue(retainDiscoveryRequest(requesterID, types.DiscoveryRequestTypeHost, zone, dh))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ofDiscoverer) DiscoverPort(requesterID string, host *omd.Host, dp *omd.DiscoverPort) {
|
func (d *ofDiscoverer) DiscoverPort(requesterID string, host *omd.Host, dp *omd.DiscoverPort) {
|
||||||
d.enqueue(retainDiscoveryRequest(d.messageChan, requesterID, types.DiscoveryRequestTypePort, host, dp))
|
d.enqueue(retainDiscoveryRequest(requesterID, types.DiscoveryRequestTypePort, host, dp))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ofDiscoverer) DiscoverService(requesterID string, port *omd.Port, ds *omd.DiscoverService) {
|
func (d *ofDiscoverer) DiscoverService(requesterID string, port *omd.Port, ds *omd.DiscoverService) {
|
||||||
d.enqueue(retainDiscoveryRequest(d.messageChan, requesterID, types.DiscoveryRequestTypeService, port, ds))
|
d.enqueue(retainDiscoveryRequest(requesterID, types.DiscoveryRequestTypeService, port, ds))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ofDiscoverer) Message() <-chan types.DiscoveryMessage {
|
func (d *ofDiscoverer) Message() <-chan types.DiscoveryMessage {
|
||||||
return d.messageChan
|
return d.messageChan
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *ofDiscoverer) SendMessage(discoveryRequest types.DiscoveryRequest, messageType types.DiscoveryMessageType, data interface{}, err error) {
|
||||||
|
d.messageChan <- retainDiscoveryMessage(discoveryRequest, messageType, data, err)
|
||||||
|
}
|
||||||
|
|
||||||
func (d *ofDiscoverer) Shutdown() {
|
func (d *ofDiscoverer) Shutdown() {
|
||||||
if d.stopChan == nil {
|
if d.stopChan == nil {
|
||||||
return
|
return
|
||||||
|
@ -89,18 +94,18 @@ func (d *ofDiscoverer) start() {
|
||||||
func (d *ofDiscoverer) enqueue(req *ofDiscoveryRequest) {
|
func (d *ofDiscoverer) enqueue(req *ofDiscoveryRequest) {
|
||||||
select {
|
select {
|
||||||
case d.requestQueue <- req:
|
case d.requestQueue <- req:
|
||||||
req.SendMessage(types.DiscoveryMessageTypeQueueing, omu.Now(), nil)
|
d.SendMessage(req, types.DiscoveryMessageTypeQueueing, omu.Now(), nil)
|
||||||
go func() {
|
go func() {
|
||||||
select {
|
select {
|
||||||
case <-req.dequeue:
|
case <-req.dequeue:
|
||||||
case <-time.After(10 * time.Second):
|
case <-time.After(10 * time.Second):
|
||||||
req.timeout = true
|
req.timeout = true
|
||||||
req.SendMessage(types.DiscoveryMessageTypeTimeout, omu.Now(), nil)
|
d.SendMessage(req, types.DiscoveryMessageTypeTimeout, omu.Now(), nil)
|
||||||
req.release()
|
req.release()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
default:
|
default:
|
||||||
req.SendMessage(types.DiscoveryMessageTypeFailedQueueing, omu.Now(), nil)
|
d.SendMessage(req, types.DiscoveryMessageTypeFailedQueueing, omu.Now(), nil)
|
||||||
req.release()
|
req.release()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,9 +127,9 @@ LOOP:
|
||||||
}
|
}
|
||||||
req.(*ofDiscoveryRequest).dequeue <- true
|
req.(*ofDiscoveryRequest).dequeue <- true
|
||||||
|
|
||||||
req.SendMessage(types.DiscoveryMessageTypeStart, omu.Now(), nil)
|
d.SendMessage(req, types.DiscoveryMessageTypeStart, omu.Now(), nil)
|
||||||
d.discover(req)
|
d.discover(req)
|
||||||
req.SendMessage(types.DiscoveryMessageTypeStop, omu.Now(), nil)
|
d.SendMessage(req, types.DiscoveryMessageTypeStop, omu.Now(), nil)
|
||||||
|
|
||||||
req.(*ofDiscoveryRequest).release()
|
req.(*ofDiscoveryRequest).release()
|
||||||
case <-d.stopChan:
|
case <-d.stopChan:
|
||||||
|
@ -144,17 +149,43 @@ func (d *ofDiscoverer) discover(req types.DiscoveryRequest) {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err := s.InitWithRequest(req); nil != err {
|
if err := s.InitWithRequest(req); nil != err {
|
||||||
req.SendMessage(types.DiscoveryMessageTypeError, nil, err)
|
d.SendMessage(req, types.DiscoveryMessageTypeError, nil, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
d.preDiscovery(s)
|
d.complexDiscover(s)
|
||||||
d.layerDiscovery(s)
|
d.hierarchyDiscover(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ofDiscoverer) preDiscovery(s session.DiscoverySession) {
|
func (d *ofDiscoverer) complexDiscover(s session.DiscoverySession) {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
discoveredChan := make(chan interface{})
|
||||||
|
s.SetDiscoveryDelegator(discoveredChan)
|
||||||
|
defer func() {
|
||||||
|
s.SetDiscoveryDelegator(nil)
|
||||||
|
close(discoveredChan)
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case target, ok := <-discoveredChan:
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch target.(type) {
|
||||||
|
case *omd.Host:
|
||||||
|
d.SendMessage(s.DiscoveryRequest(), types.DiscoveryMessageTypeHost, target, nil)
|
||||||
|
case *omd.Port:
|
||||||
|
d.SendMessage(s.DiscoveryRequest(), types.DiscoveryMessageTypePort, target, nil)
|
||||||
|
case *omd.Service:
|
||||||
|
d.SendMessage(s.DiscoveryRequest(), types.DiscoveryMessageTypeService, target, nil)
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
@ -167,11 +198,15 @@ func (d *ofDiscoverer) preDiscovery(s session.DiscoverySession) {
|
||||||
mdns.Scan(s)
|
mdns.Scan(s)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
snmp.Scan(s)
|
||||||
|
}()
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ofDiscoverer) layerDiscovery(s session.DiscoverySession) {
|
func (d *ofDiscoverer) hierarchyDiscover(s session.DiscoverySession) {
|
||||||
// SNMP
|
|
||||||
// mDNS
|
|
||||||
// UPnP
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,8 @@ type ofDiscoveryRequest struct {
|
||||||
requestType types.DiscoveryRequestType
|
requestType types.DiscoveryRequestType
|
||||||
params []interface{}
|
params []interface{}
|
||||||
|
|
||||||
messageChan chan<- types.DiscoveryMessage
|
dequeue chan bool
|
||||||
dequeue chan bool
|
timeout bool
|
||||||
timeout bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dr *ofDiscoveryRequest) RequesterID() string {
|
func (dr *ofDiscoveryRequest) RequesterID() string {
|
||||||
|
@ -28,17 +27,13 @@ func (dr *ofDiscoveryRequest) Params() []interface{} {
|
||||||
return dr.params
|
return dr.params
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dr *ofDiscoveryRequest) SendMessage(messageType types.DiscoveryMessageType, data interface{}, err error) {
|
|
||||||
dr.messageChan <- retainDiscoveryMessage(dr, messageType, data, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dr *ofDiscoveryRequest) release() {
|
func (dr *ofDiscoveryRequest) release() {
|
||||||
releaseDiscoveryRequest(dr)
|
releaseDiscoveryRequest(dr)
|
||||||
}
|
}
|
||||||
|
|
||||||
var discoveryRequestPool sync.Pool
|
var discoveryRequestPool sync.Pool
|
||||||
|
|
||||||
func retainDiscoveryRequest(messageChan chan<- types.DiscoveryMessage, requesterID string, requestType types.DiscoveryRequestType, params ...interface{}) *ofDiscoveryRequest {
|
func retainDiscoveryRequest(requesterID string, requestType types.DiscoveryRequestType, params ...interface{}) *ofDiscoveryRequest {
|
||||||
v := discoveryRequestPool.Get()
|
v := discoveryRequestPool.Get()
|
||||||
var dr *ofDiscoveryRequest
|
var dr *ofDiscoveryRequest
|
||||||
if v == nil {
|
if v == nil {
|
||||||
|
@ -50,7 +45,6 @@ func retainDiscoveryRequest(messageChan chan<- types.DiscoveryMessage, requester
|
||||||
dr.requesterID = requesterID
|
dr.requesterID = requesterID
|
||||||
dr.requestType = requestType
|
dr.requestType = requestType
|
||||||
dr.params = params
|
dr.params = params
|
||||||
dr.messageChan = messageChan
|
|
||||||
dr.dequeue = make(chan bool, 1)
|
dr.dequeue = make(chan bool, 1)
|
||||||
dr.timeout = false
|
dr.timeout = false
|
||||||
|
|
||||||
|
@ -61,7 +55,6 @@ func releaseDiscoveryRequest(dr *ofDiscoveryRequest) {
|
||||||
dr.requesterID = ""
|
dr.requesterID = ""
|
||||||
dr.requestType = types.DiscoveryRequestTypeNone
|
dr.requestType = types.DiscoveryRequestTypeNone
|
||||||
dr.params = nil
|
dr.params = nil
|
||||||
dr.messageChan = nil
|
|
||||||
close(dr.dequeue)
|
close(dr.dequeue)
|
||||||
dr.dequeue = nil
|
dr.dequeue = nil
|
||||||
dr.timeout = false
|
dr.timeout = false
|
||||||
|
|
|
@ -1,69 +1,141 @@
|
||||||
package snmp
|
package snmp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
omcc "git.loafle.net/overflow/model/config/credential"
|
||||||
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"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
||||||
"github.com/k-sone/snmpgo"
|
"github.com/k-sone/snmpgo"
|
||||||
)
|
)
|
||||||
|
|
||||||
var defaultPort = 161
|
const (
|
||||||
var defaultOIDs = []string{
|
defaultPort = 161
|
||||||
"1.3.6.1.2.1.1.5.0", //sysName
|
defaultTimeout = 3
|
||||||
|
defaultCommunity = "public"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
defaultOIDs = []string{
|
||||||
|
"1.3.6.1.2.1.1.5.0", //sysName
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultCredentials = []*omcc.SNMPCredential{
|
||||||
|
&omcc.SNMPCredential{
|
||||||
|
Version: "2c",
|
||||||
|
Community: "public",
|
||||||
|
Port: json.Number(strconv.Itoa(defaultPort)),
|
||||||
|
Timeout: json.Number(strconv.Itoa(defaultTimeout)),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func Scan(discoverySession session.DiscoverySession) {
|
||||||
|
if nil == discoverySession.TargetHosts() || 0 == len(discoverySession.TargetHosts()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var cs []*omcc.SNMPCredential
|
||||||
|
|
||||||
|
if _csMap := discoverySession.DiscoveryConfig().Credentials; nil != _csMap {
|
||||||
|
_cs, ok := _csMap["SNMP"]
|
||||||
|
if ok {
|
||||||
|
cs = _cs.([]*omcc.SNMPCredential)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if nil == cs {
|
||||||
|
cs = defaultCredentials
|
||||||
|
}
|
||||||
|
|
||||||
|
credentials := make(map[string][]*omcc.SNMPCredential)
|
||||||
|
for _, _c := range cs {
|
||||||
|
credentials[_c.Version] = append(credentials[_c.Version], _c)
|
||||||
|
}
|
||||||
|
|
||||||
|
_2cCS, ok := credentials["2c"]
|
||||||
|
if ok {
|
||||||
|
go func() {
|
||||||
|
LOOP:
|
||||||
|
for _, target := range discoverySession.TargetHosts() {
|
||||||
|
for _, c := range _2cCS {
|
||||||
|
if scanV2(target, discoverySession, c) {
|
||||||
|
continue LOOP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type SNMPResponse struct {
|
func scanV2(target net.IP, discoverySession session.DiscoverySession, credential *omcc.SNMPCredential) bool {
|
||||||
Host *omd.Host
|
|
||||||
Value map[string]string
|
|
||||||
Error error
|
|
||||||
}
|
|
||||||
|
|
||||||
func ScanSNMP(host *omd.Host, community string, ch chan *SNMPResponse) {
|
address := fmt.Sprintf("%s:%d", target.String(), credential.Port)
|
||||||
go func() {
|
|
||||||
getV2(host, defaultPort, community, defaultOIDs, ch)
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
func getV2(host *omd.Host, port int, community string, _oids []string, ch chan *SNMPResponse) {
|
|
||||||
address := fmt.Sprintf("%s:%d", host.Address, port)
|
|
||||||
snmp, err := snmpgo.NewSNMP(snmpgo.SNMPArguments{
|
snmp, err := snmpgo.NewSNMP(snmpgo.SNMPArguments{
|
||||||
Version: snmpgo.V2c,
|
Version: snmpgo.V2c,
|
||||||
Address: address,
|
Address: address,
|
||||||
Retries: 1,
|
Retries: 1,
|
||||||
Community: community,
|
Community: credential.Community,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ch <- &SNMPResponse{host, nil, err}
|
// ch <- &SNMPResponse{host, nil, err}
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
defer snmp.Close()
|
defer snmp.Close()
|
||||||
|
|
||||||
oids, err := snmpgo.NewOids(_oids)
|
oids, err := snmpgo.NewOids(defaultOIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ch <- &SNMPResponse{host, nil, err}
|
// ch <- &SNMPResponse{host, nil, err}
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
pdu, err := snmp.GetRequest(oids)
|
pdu, err := snmp.GetRequest(oids)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ch <- &SNMPResponse{host, nil, err}
|
// ch <- &SNMPResponse{host, nil, err}
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if pdu.ErrorStatus() != snmpgo.NoError {
|
if pdu.ErrorStatus() != snmpgo.NoError {
|
||||||
ch <- &SNMPResponse{host, nil, fmt.Errorf("%s", pdu.ErrorStatus().String())}
|
// ch <- &SNMPResponse{host, nil, fmt.Errorf("%s", pdu.ErrorStatus().String())}
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if pdu == nil {
|
if pdu == nil {
|
||||||
ch <- &SNMPResponse{host, nil, fmt.Errorf("%s", "Empty PDU")}
|
// ch <- &SNMPResponse{host, nil, fmt.Errorf("%s", "Empty PDU")}
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
resMap := make(map[string]string)
|
meta := make(map[string]string)
|
||||||
for _, val := range pdu.VarBinds() {
|
for _, val := range pdu.VarBinds() {
|
||||||
resMap[val.Oid.String()] = val.Variable.String()
|
meta[val.Oid.String()] = val.Variable.String()
|
||||||
}
|
}
|
||||||
ch <- &SNMPResponse{host, resMap, nil}
|
|
||||||
return
|
h := discoverySession.AddHost(&omd.Host{
|
||||||
|
MetaIPType: discoverySession.Zone().MetaIPType,
|
||||||
|
Name: "",
|
||||||
|
Address: target.String(),
|
||||||
|
Meta: meta,
|
||||||
|
Zone: discoverySession.Zone(),
|
||||||
|
DiscoveredDate: omu.NowPtr(),
|
||||||
|
})
|
||||||
|
|
||||||
|
p := discoverySession.AddPort(&omd.Port{
|
||||||
|
MetaPortType: omm.ToMetaPortType(omm.MetaPortTypeEnumUDP),
|
||||||
|
PortNumber: credential.Port,
|
||||||
|
Meta: meta,
|
||||||
|
Host: h,
|
||||||
|
})
|
||||||
|
|
||||||
|
discoverySession.AddService(&omd.Service{
|
||||||
|
MetaCryptoType: omm.ToMetaCryptoType(omm.MetaCryptoTypeEnumNONE),
|
||||||
|
Key: "SNMP",
|
||||||
|
Name: "SNMP V2c",
|
||||||
|
Port: p,
|
||||||
|
})
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,21 +3,36 @@ package snmp
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
"git.loafle.net/overflow_scanner/probe/discovery"
|
||||||
omm "git.loafle.net/overflow/model/meta"
|
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
||||||
|
"git.loafle.net/overflow_scanner/probe/discovery/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSNMPScan(t *testing.T) {
|
func TestSNMPScan(t *testing.T) {
|
||||||
host := &omd.Host{
|
s := session.MockDiscoverySession()
|
||||||
MetaIPType: omm.ToMetaIPType(omm.MetaIPTypeEnumV4),
|
s.InitWithRequest(
|
||||||
Address: "192.168.1.229",
|
discovery.MockDiscoveryRequest(
|
||||||
}
|
"testRequester",
|
||||||
|
types.DiscoveryRequestTypeHost,
|
||||||
|
[]interface{}{
|
||||||
|
&omd.Zone{
|
||||||
|
Network: "192.168.1.0/24",
|
||||||
|
Iface: "enp3s0",
|
||||||
|
MetaIPType: omm.ToMetaIPType(omm.MetaIPTypeEnumV4),
|
||||||
|
Address: "192.168.1.101",
|
||||||
|
Mac: "44:8a:5b:f1:f1:f3",
|
||||||
|
},
|
||||||
|
&omd.DiscoverHost{
|
||||||
|
MetaIPType: omm.ToMetaIPType(omm.MetaIPTypeEnumV4),
|
||||||
|
FirstScanRange: "192.168.1.1",
|
||||||
|
LastScanRange: "192.168.1.254",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
ch := make(chan *SNMPResponse)
|
Scan(s)
|
||||||
defer close(ch)
|
|
||||||
ScanSNMP(host, "test1252serc", ch)
|
|
||||||
|
|
||||||
msg := <-ch
|
|
||||||
t.Log(msg)
|
t.Log(msg)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,26 +3,36 @@ package session
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
omd "git.loafle.net/overflow/model/discovery"
|
omd "git.loafle.net/overflow/model/discovery"
|
||||||
|
ounc "git.loafle.net/overflow/util-go/net/cidr"
|
||||||
"git.loafle.net/overflow_scanner/probe/discovery/types"
|
"git.loafle.net/overflow_scanner/probe/discovery/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DiscoverySession interface {
|
type DiscoverySession interface {
|
||||||
|
InitWithRequest(request types.DiscoveryRequest) error
|
||||||
|
|
||||||
|
DiscoveryRequest() types.DiscoveryRequest
|
||||||
|
|
||||||
Zone() *omd.Zone
|
Zone() *omd.Zone
|
||||||
Host() *omd.Host
|
Host() *omd.Host
|
||||||
Port() *omd.Port
|
Port() *omd.Port
|
||||||
|
|
||||||
|
DiscoveryConfig() *omd.DiscoveryConfig
|
||||||
|
|
||||||
DiscoverHost() *omd.DiscoverHost
|
DiscoverHost() *omd.DiscoverHost
|
||||||
DiscoverPort() *omd.DiscoverPort
|
DiscoverPort() *omd.DiscoverPort
|
||||||
DiscoverService() *omd.DiscoverService
|
DiscoverService() *omd.DiscoverService
|
||||||
|
|
||||||
InitWithRequest(request types.DiscoveryRequest) error
|
|
||||||
|
|
||||||
AddHost(host *omd.Host) *omd.Host
|
AddHost(host *omd.Host) *omd.Host
|
||||||
AddPort(port *omd.Port) *omd.Port
|
AddPort(port *omd.Port) *omd.Port
|
||||||
AddService(service *omd.Service) *omd.Service
|
AddService(service *omd.Service) *omd.Service
|
||||||
|
|
||||||
|
TargetHosts() []net.IP
|
||||||
|
|
||||||
|
SetDiscoveryDelegator(chan<- interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
type ofDiscoverySession struct {
|
type ofDiscoverySession struct {
|
||||||
|
@ -32,10 +42,16 @@ type ofDiscoverySession struct {
|
||||||
host *omd.Host
|
host *omd.Host
|
||||||
port *omd.Port
|
port *omd.Port
|
||||||
|
|
||||||
|
discoveryConfig *omd.DiscoveryConfig
|
||||||
|
|
||||||
discoverHost *omd.DiscoverHost
|
discoverHost *omd.DiscoverHost
|
||||||
discoverPort *omd.DiscoverPort
|
discoverPort *omd.DiscoverPort
|
||||||
discoverService *omd.DiscoverService
|
discoverService *omd.DiscoverService
|
||||||
|
|
||||||
|
targetHosts []net.IP
|
||||||
|
|
||||||
|
discoveryDelegator chan<- interface{}
|
||||||
|
|
||||||
hosts map[string]*omd.Host
|
hosts map[string]*omd.Host
|
||||||
ports map[*omd.Host]map[json.Number]map[string]*omd.Port
|
ports map[*omd.Host]map[json.Number]map[string]*omd.Port
|
||||||
services map[*omd.Port]map[string]map[string]*omd.Service
|
services map[*omd.Port]map[string]map[string]*omd.Service
|
||||||
|
@ -76,6 +92,17 @@ func (ds *ofDiscoverySession) InitWithRequest(request types.DiscoveryRequest) er
|
||||||
return fmt.Errorf("DiscoverHost of parameter is not valid")
|
return fmt.Errorf("DiscoverHost of parameter is not valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if nil == discoverHost.DiscoveryConfig {
|
||||||
|
return fmt.Errorf("DiscoveryConfig of parameter is not valid")
|
||||||
|
}
|
||||||
|
|
||||||
|
if ts, err := ds.getTargetHosts(zone, discoverHost); nil != err {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
ds.targetHosts = ts
|
||||||
|
}
|
||||||
|
|
||||||
|
ds.discoveryConfig = discoverHost.DiscoveryConfig
|
||||||
ds.setZone(zone)
|
ds.setZone(zone)
|
||||||
ds.setDiscoverHost(discoverHost)
|
ds.setDiscoverHost(discoverHost)
|
||||||
case types.DiscoveryRequestTypePort:
|
case types.DiscoveryRequestTypePort:
|
||||||
|
@ -93,6 +120,11 @@ func (ds *ofDiscoverySession) InitWithRequest(request types.DiscoveryRequest) er
|
||||||
return fmt.Errorf("DiscoverPort of parameter is not valid")
|
return fmt.Errorf("DiscoverPort of parameter is not valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if nil == discoverPort.DiscoveryConfig {
|
||||||
|
return fmt.Errorf("DiscoveryConfig of parameter is not valid")
|
||||||
|
}
|
||||||
|
|
||||||
|
ds.discoveryConfig = discoverPort.DiscoveryConfig
|
||||||
ds.setHost(host)
|
ds.setHost(host)
|
||||||
ds.setDiscoverPort(discoverPort)
|
ds.setDiscoverPort(discoverPort)
|
||||||
case types.DiscoveryRequestTypeService:
|
case types.DiscoveryRequestTypeService:
|
||||||
|
@ -110,6 +142,11 @@ func (ds *ofDiscoverySession) InitWithRequest(request types.DiscoveryRequest) er
|
||||||
return fmt.Errorf("DiscoverService of parameter is not valid")
|
return fmt.Errorf("DiscoverService of parameter is not valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if nil == discoverService.DiscoveryConfig {
|
||||||
|
return fmt.Errorf("DiscoveryConfig of parameter is not valid")
|
||||||
|
}
|
||||||
|
|
||||||
|
ds.discoveryConfig = discoverService.DiscoveryConfig
|
||||||
ds.setPort(port)
|
ds.setPort(port)
|
||||||
ds.setDiscoverService(discoverService)
|
ds.setDiscoverService(discoverService)
|
||||||
}
|
}
|
||||||
|
@ -117,6 +154,14 @@ func (ds *ofDiscoverySession) InitWithRequest(request types.DiscoveryRequest) er
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ds *ofDiscoverySession) SetDiscoveryDelegator(discoveryDelegator chan<- interface{}) {
|
||||||
|
ds.discoveryDelegator = discoveryDelegator
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *ofDiscoverySession) DiscoveryRequest() types.DiscoveryRequest {
|
||||||
|
return ds.discoveryRequest
|
||||||
|
}
|
||||||
|
|
||||||
func (ds *ofDiscoverySession) Zone() *omd.Zone {
|
func (ds *ofDiscoverySession) Zone() *omd.Zone {
|
||||||
return ds.zone
|
return ds.zone
|
||||||
}
|
}
|
||||||
|
@ -127,6 +172,10 @@ func (ds *ofDiscoverySession) Port() *omd.Port {
|
||||||
return ds.port
|
return ds.port
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ds *ofDiscoverySession) DiscoveryConfig() *omd.DiscoveryConfig {
|
||||||
|
return ds.discoveryConfig
|
||||||
|
}
|
||||||
|
|
||||||
func (ds *ofDiscoverySession) DiscoverHost() *omd.DiscoverHost {
|
func (ds *ofDiscoverySession) DiscoverHost() *omd.DiscoverHost {
|
||||||
return ds.discoverHost
|
return ds.discoverHost
|
||||||
}
|
}
|
||||||
|
@ -137,59 +186,93 @@ func (ds *ofDiscoverySession) DiscoverService() *omd.DiscoverService {
|
||||||
return ds.discoverService
|
return ds.discoverService
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ds *ofDiscoverySession) TargetHosts() []net.IP {
|
||||||
|
return ds.targetHosts
|
||||||
|
}
|
||||||
|
|
||||||
func (ds *ofDiscoverySession) AddHost(host *omd.Host) *omd.Host {
|
func (ds *ofDiscoverySession) AddHost(host *omd.Host) *omd.Host {
|
||||||
h := ds.findHost(host, true)
|
h, modified := ds.findHost(host, true)
|
||||||
|
|
||||||
if "" == h.Mac && "" != host.Mac {
|
if "" == h.Mac && "" != host.Mac {
|
||||||
h.Mac = host.Mac
|
h.Mac = host.Mac
|
||||||
|
modified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
h.Meta = ds.appendMeta(h.Meta, host.Meta)
|
meta, metaModified := ds.appendMeta(h.Meta, host.Meta)
|
||||||
|
if metaModified {
|
||||||
|
h.Meta = meta
|
||||||
|
modified = metaModified
|
||||||
|
}
|
||||||
|
|
||||||
ds.discoveryRequest.SendMessage(types.DiscoveryMessageTypeHost, h, nil)
|
if modified && nil != ds.discoveryDelegator {
|
||||||
|
ds.discoveryDelegator <- h
|
||||||
|
}
|
||||||
|
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *ofDiscoverySession) AddPort(port *omd.Port) *omd.Port {
|
func (ds *ofDiscoverySession) AddPort(port *omd.Port) *omd.Port {
|
||||||
p := ds.findPort(port, true)
|
p, modified := ds.findPort(port, true)
|
||||||
|
|
||||||
p.Meta = ds.appendMeta(p.Meta, port.Meta)
|
meta, metaModified := ds.appendMeta(p.Meta, port.Meta)
|
||||||
|
if metaModified {
|
||||||
|
p.Meta = meta
|
||||||
|
modified = metaModified
|
||||||
|
}
|
||||||
|
|
||||||
|
if modified && nil != ds.discoveryDelegator {
|
||||||
|
ds.discoveryDelegator <- p
|
||||||
|
}
|
||||||
|
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *ofDiscoverySession) AddService(service *omd.Service) *omd.Service {
|
func (ds *ofDiscoverySession) AddService(service *omd.Service) *omd.Service {
|
||||||
s := ds.findService(service, true)
|
s, modified := ds.findService(service, true)
|
||||||
|
|
||||||
s.Meta = ds.appendMeta(s.Meta, service.Meta)
|
meta, metaModified := ds.appendMeta(s.Meta, service.Meta)
|
||||||
|
if metaModified {
|
||||||
|
s.Meta = meta
|
||||||
|
modified = metaModified
|
||||||
|
}
|
||||||
|
|
||||||
|
if modified && nil != ds.discoveryDelegator {
|
||||||
|
ds.discoveryDelegator <- s
|
||||||
|
}
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *ofDiscoverySession) findHost(host *omd.Host, add bool) *omd.Host {
|
func (ds *ofDiscoverySession) findHost(host *omd.Host, add bool) (h *omd.Host, modified bool) {
|
||||||
h, ok := ds.hosts[host.Address]
|
modified = false
|
||||||
|
var ok bool
|
||||||
|
|
||||||
|
h, ok = ds.hosts[host.Address]
|
||||||
if !ok {
|
if !ok {
|
||||||
if !add {
|
if !add {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
ds.hosts[host.Address] = host
|
ds.hosts[host.Address] = host
|
||||||
h = host
|
h = host
|
||||||
|
modified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return h
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *ofDiscoverySession) findPort(port *omd.Port, add bool) *omd.Port {
|
func (ds *ofDiscoverySession) findPort(port *omd.Port, add bool) (p *omd.Port, modified bool) {
|
||||||
h := ds.findHost(port.Host, false)
|
modified = false
|
||||||
|
var ok bool
|
||||||
|
|
||||||
|
h, _ := ds.findHost(port.Host, false)
|
||||||
if nil == h {
|
if nil == h {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
hostPorts, ok := ds.ports[h]
|
hostPorts, ok := ds.ports[h]
|
||||||
if !ok {
|
if !ok {
|
||||||
if !add {
|
if !add {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ds.ports[h] = make(map[json.Number]map[string]*omd.Port)
|
ds.ports[h] = make(map[json.Number]map[string]*omd.Port)
|
||||||
|
@ -199,36 +282,40 @@ func (ds *ofDiscoverySession) findPort(port *omd.Port, add bool) *omd.Port {
|
||||||
ports, ok := hostPorts[port.PortNumber]
|
ports, ok := hostPorts[port.PortNumber]
|
||||||
if !ok {
|
if !ok {
|
||||||
if !add {
|
if !add {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
hostPorts[port.PortNumber] = make(map[string]*omd.Port)
|
hostPorts[port.PortNumber] = make(map[string]*omd.Port)
|
||||||
ports = hostPorts[port.PortNumber]
|
ports = hostPorts[port.PortNumber]
|
||||||
}
|
}
|
||||||
|
|
||||||
p, ok := ports[port.MetaPortType.Key]
|
p, ok = ports[port.MetaPortType.Key]
|
||||||
if !ok {
|
if !ok {
|
||||||
if !add {
|
if !add {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ports[port.MetaPortType.Key] = port
|
ports[port.MetaPortType.Key] = port
|
||||||
p = ports[port.MetaPortType.Key]
|
p = ports[port.MetaPortType.Key]
|
||||||
|
modified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return p
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *ofDiscoverySession) findService(service *omd.Service, add bool) *omd.Service {
|
func (ds *ofDiscoverySession) findService(service *omd.Service, add bool) (s *omd.Service, modified bool) {
|
||||||
p := ds.findPort(service.Port, false)
|
modified = false
|
||||||
|
var ok bool
|
||||||
|
|
||||||
|
p, _ := ds.findPort(service.Port, false)
|
||||||
if nil == p {
|
if nil == p {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
portServices, ok := ds.services[p]
|
portServices, ok := ds.services[p]
|
||||||
if !ok {
|
if !ok {
|
||||||
if !add {
|
if !add {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ds.services[p] = make(map[string]map[string]*omd.Service)
|
ds.services[p] = make(map[string]map[string]*omd.Service)
|
||||||
|
@ -238,48 +325,57 @@ func (ds *ofDiscoverySession) findService(service *omd.Service, add bool) *omd.S
|
||||||
services, ok := portServices[service.Key]
|
services, ok := portServices[service.Key]
|
||||||
if !ok {
|
if !ok {
|
||||||
if !add {
|
if !add {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
portServices[service.Key] = make(map[string]*omd.Service)
|
portServices[service.Key] = make(map[string]*omd.Service)
|
||||||
services = portServices[service.Key]
|
services = portServices[service.Key]
|
||||||
}
|
}
|
||||||
|
|
||||||
s, ok := services[service.MetaCryptoType.Key]
|
s, ok = services[service.MetaCryptoType.Key]
|
||||||
if !ok {
|
if !ok {
|
||||||
if !add {
|
if !add {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
services[service.MetaCryptoType.Key] = service
|
services[service.MetaCryptoType.Key] = service
|
||||||
s = services[service.MetaCryptoType.Key]
|
s = services[service.MetaCryptoType.Key]
|
||||||
|
modified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return s
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *ofDiscoverySession) appendMeta(oriMeta map[string]string, newMeta map[string]string) map[string]string {
|
func (ds *ofDiscoverySession) appendMeta(oriMeta map[string]string, newMeta map[string]string) (resultMap map[string]string, modified bool) {
|
||||||
|
modified = false
|
||||||
if nil == newMeta {
|
if nil == newMeta {
|
||||||
return oriMeta
|
resultMap = oriMeta
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if nil == oriMeta {
|
if nil == oriMeta {
|
||||||
return newMeta
|
resultMap = newMeta
|
||||||
|
modified = true
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
LOOP:
|
LOOP:
|
||||||
for k, v := range oriMeta {
|
for k, v := range newMeta {
|
||||||
_v, _ok := oriMeta[k]
|
_v, _ok := oriMeta[k]
|
||||||
if !_ok {
|
if !_ok {
|
||||||
oriMeta[k] = v
|
oriMeta[k] = v
|
||||||
|
modified = true
|
||||||
continue LOOP
|
continue LOOP
|
||||||
}
|
}
|
||||||
if v == _v {
|
if v == _v {
|
||||||
continue LOOP
|
continue LOOP
|
||||||
}
|
}
|
||||||
oriMeta[k] = fmt.Sprintf("%s|||%s", _v, v)
|
oriMeta[k] = fmt.Sprintf("%s|||%s", _v, v)
|
||||||
|
modified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return oriMeta
|
resultMap = oriMeta
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *ofDiscoverySession) setZone(zone *omd.Zone) {
|
func (ds *ofDiscoverySession) setZone(zone *omd.Zone) {
|
||||||
|
@ -331,6 +427,53 @@ func (ds *ofDiscoverySession) setDiscoverService(discoverService *omd.DiscoverSe
|
||||||
ds.discoverService = discoverService
|
ds.discoverService = discoverService
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ds *ofDiscoverySession) getTargetHosts(zone *omd.Zone, discoverHost *omd.DiscoverHost) ([]net.IP, error) {
|
||||||
|
cr, err := ounc.NewCIDRRanger(zone.Network)
|
||||||
|
if nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var firstIP net.IP
|
||||||
|
if "" != discoverHost.FirstScanRange {
|
||||||
|
firstIP = net.ParseIP(discoverHost.FirstScanRange)
|
||||||
|
if nil == firstIP {
|
||||||
|
return nil, fmt.Errorf("IP(%v) of FirstScanRange host is not valid", firstIP)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var lastIP net.IP
|
||||||
|
if "" != discoverHost.LastScanRange {
|
||||||
|
lastIP = net.ParseIP(discoverHost.LastScanRange)
|
||||||
|
if nil == lastIP {
|
||||||
|
return nil, fmt.Errorf("IP(%v) of LastScanRange host is not valid", lastIP)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
includeIPs := make([]net.IP, 0)
|
||||||
|
for _, iHost := range discoverHost.IncludeHosts {
|
||||||
|
iIP := net.ParseIP(iHost)
|
||||||
|
if nil == iIP {
|
||||||
|
return nil, fmt.Errorf("IP(%v) of include host is not valid", iHost)
|
||||||
|
}
|
||||||
|
includeIPs = append(includeIPs, iIP)
|
||||||
|
}
|
||||||
|
|
||||||
|
excludeIPs := make([]net.IP, 0)
|
||||||
|
for _, eHost := range discoverHost.ExcludeHosts {
|
||||||
|
eIP := net.ParseIP(eHost)
|
||||||
|
if nil == eIP {
|
||||||
|
return nil, fmt.Errorf("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
|
||||||
|
}
|
||||||
|
|
||||||
var discoverySessionPool sync.Pool
|
var discoverySessionPool sync.Pool
|
||||||
|
|
||||||
func RetainDiscoverySession() *ofDiscoverySession {
|
func RetainDiscoverySession() *ofDiscoverySession {
|
||||||
|
|
|
@ -36,6 +36,4 @@ type DiscoveryRequest interface {
|
||||||
RequesterID() string
|
RequesterID() string
|
||||||
RequestType() DiscoveryRequestType
|
RequestType() DiscoveryRequestType
|
||||||
Params() []interface{}
|
Params() []interface{}
|
||||||
|
|
||||||
SendMessage(messageType DiscoveryMessageType, data interface{}, err error)
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user