discovery/discovery/host.go
2017-06-26 19:10:52 +09:00

96 lines
2.6 KiB
Go

package discovery
import (
"errors"
"github.com/cihub/seelog"
"github.com/google/gopacket/layers"
//"git.loafle.net/overflow/central/client/events"
//"git.loafle.net/overflow/discovery/communicate"
"git.loafle.net/overflow/discovery/core/scan/host"
"git.loafle.net/overflow/discovery/core/scan/service/matcher/dhcp"
"git.loafle.net/overflow/discovery/discovery/types"
"git.loafle.net/overflow/discovery/discovery/types/timestamp"
"git.loafle.net/overflow/discovery/util/converter"
"net"
"strconv"
)
func discoveryHost(zone *types.DiscoveryZone, callback discoverHostCallback) {
_, err := getHostRangeCount(zone)
if err != nil {
return
}
//communicate.Send(events.NewEvent(events.CENTRAL_EVENT, events.NewHostStartEvent(rangeCount, zone.CidrInt64())))
arpCallback := func(packet *layers.ARP) {
keyIp := net.IP(packet.SourceProtAddress).String()
if _, ok := zone.GetHost(keyIp); ok == true {
return
}
h := types.NewHost(packet.SourceProtAddress, packet.SourceHwAddress)
h.FirstScanRange = 1
h.LastScanRange = 10000
h.Zone = zone
zone.SetHost(keyIp, h)
updateHostHistoryProperty(h, packet, h)
//e := events.NewEvent(events.CENTRAL_EVENT, events.NewHostFoundEvent(zone.CidrInt64(), h.Ip))
//communicate.Send(e)
callback(h)
}
// arp send history callback // todo 히스토리 콜백이 필요???
historyCallback := func(targetHost net.IP) {
hh := types.NewHostHistory(targetHost, types.TIMEOUT, "")
zone.AddHistory(hh)
}
host.Scan(zone, arpCallback, historyCallback)
//mdns
//nbns
dhcp.DiscoverDHCP(zone)
//communicate.Send(events.NewEvent(events.CENTRAL_EVENT, events.NewHostEndEvent(zone.CidrInt64(), zone.Histories)))
}
func getHostRangeCount(zone *types.DiscoveryZone) (int, error) {
minIp := converter.IntToIP4(zone.FirstScanRange).To4()
maxIp := converter.IntToIP4(zone.LastScanRange).To4()
if maxIp[3] == 0 || minIp[0] == 0 {
err := errors.New("target host range error")
seelog.Critical(err)
return -1, err
}
return int(maxIp[3]) - (int(minIp[3]) - 1), nil
}
func updateHostHistoryProperty(host *types.DiscoveryHost, arp *layers.ARP, h *types.DiscoveryHost) {
idx := findHistoriyByIP(len(host.Zone.Histories), func(i int) bool {
if host.Zone.Histories[i].Ip == h.Ip {
return true
}
return false
})
if idx >= 0 {
hh := host.Zone.Histories[idx]
hh.ResultType = types.SUCCESS
hh.ResultDate = timestamp.Now()
hh.Description = strconv.FormatInt(converter.MacToInt(arp.SourceHwAddress), 10)
}
}
func findHistoriyByIP(limit int, predicate func(i int) bool) int {
for i := 0; i < limit; i++ {
if predicate(i) {
return i
}
}
return -1
}