This commit is contained in:
crusader 2018-09-05 03:58:33 +09:00
parent a1ecf315c6
commit 7535e7ffc1
16 changed files with 158 additions and 159 deletions

View File

@ -142,6 +142,7 @@ LOOP:
} }
req.(*ofDiscoveryRequest).release() req.(*ofDiscoveryRequest).release()
log.Print("Discovery Session complete")
case <-d.stopChan: case <-d.stopChan:
return return
} }

View File

@ -25,15 +25,11 @@ func Scan(discoverySession session.DiscoverySession) error {
zone := discoverySession.Zone() zone := discoverySession.Zone()
ps, err := pcap.RetainScanner(zone) ps := discoverySession.PCapScanner()
if nil != err { if nil == ps {
return fmt.Errorf("Cannot retain pcap instance %v", err) return fmt.Errorf("Cannot retain pcap instance")
} }
defer func() {
pcap.ReleaseScanner(zone)
}()
arpChan := ps.OpenARP() arpChan := ps.OpenARP()
defer func() { defer func() {
ps.CloseARP(arpChan) ps.CloseARP(arpChan)
@ -57,16 +53,13 @@ func Scan(discoverySession session.DiscoverySession) error {
delay.Store(true) delay.Store(true)
if h := handlePacketARP(zone, targetHosts, hosts, packet); nil != h { if h := handlePacketARP(zone, targetHosts, hosts, packet); nil != h {
if h != nil { if h != nil {
// log.Print("Host ", h)
discoverySession.AddHost(h) discoverySession.AddHost(h)
} }
// resultChan <- h
} }
case <-ticker.C: case <-ticker.C:
if false == delay.Load().(bool) { if false == delay.Load().(bool) {
ticker.Stop() ticker.Stop()
timerStopped <- struct{}{} close(timerStopped)
return return
} }
delay.Store(false) delay.Store(false)

View File

@ -4,21 +4,10 @@ import (
"git.loafle.net/overflow_scanner/probe/discovery/protocol/icmp/privileged" "git.loafle.net/overflow_scanner/probe/discovery/protocol/icmp/privileged"
"git.loafle.net/overflow_scanner/probe/discovery/protocol/icmp/unprivileged" "git.loafle.net/overflow_scanner/probe/discovery/protocol/icmp/unprivileged"
"git.loafle.net/overflow_scanner/probe/discovery/session" "git.loafle.net/overflow_scanner/probe/discovery/session"
"git.loafle.net/overflow_scanner/probe/internal/pcap"
) )
func Scan(discoverySession session.DiscoverySession) error { func Scan(discoverySession session.DiscoverySession) error {
zone := discoverySession.Zone() if nil != discoverySession.PCapScanner() {
var _privileged bool
_, err := pcap.RetainScanner(zone)
if nil == err {
pcap.ReleaseScanner(zone)
_privileged = true
}
if _privileged {
return privileged.Scan(discoverySession) return privileged.Scan(discoverySession)
} }

View File

@ -27,15 +27,11 @@ func scanV4(discoverySession session.DiscoverySession) error {
zone := discoverySession.Zone() zone := discoverySession.Zone()
ps, err := pcap.RetainScanner(zone) ps := discoverySession.PCapScanner()
if nil != err { if nil == ps {
return fmt.Errorf("Cannot retain pcap instance %v", err) return fmt.Errorf("Cannot retain pcap instance")
} }
defer func() {
pcap.ReleaseScanner(zone)
}()
icmpChan := ps.OpenICMP4() icmpChan := ps.OpenICMP4()
defer func() { defer func() {
ps.CloseICMP4(icmpChan) ps.CloseICMP4(icmpChan)

View File

@ -27,15 +27,11 @@ func scanV6(discoverySession session.DiscoverySession) error {
zone := discoverySession.Zone() zone := discoverySession.Zone()
ps, err := pcap.RetainScanner(zone) ps := discoverySession.PCapScanner()
if nil != err { if nil == ps {
return fmt.Errorf("Cannot retain pcap instance %v", err) return fmt.Errorf("Cannot retain pcap instance")
} }
defer func() {
pcap.ReleaseScanner(zone)
}()
icmpChan := ps.OpenICMP6() icmpChan := ps.OpenICMP6()
defer func() { defer func() {
ps.CloseICMP6(icmpChan) ps.CloseICMP6(icmpChan)

View File

@ -19,13 +19,10 @@ import (
) )
func scanV4(discoverySession session.DiscoverySession, targetHost *omd.Host) error { func scanV4(discoverySession session.DiscoverySession, targetHost *omd.Host) error {
ps, err := pcap.RetainScanner(targetHost.Zone) ps := discoverySession.PCapScanner()
if nil != err { if nil == ps {
return fmt.Errorf("Discovery: Cannot retain pcap instance %v", err) return fmt.Errorf("Cannot retain pcap instance")
} }
defer func() {
go pcap.ReleaseScanner(targetHost.Zone)
}()
tcpChan := ps.OpenTCP(targetHost.Address) tcpChan := ps.OpenTCP(targetHost.Address)
defer func() { defer func() {
@ -33,6 +30,9 @@ func scanV4(discoverySession session.DiscoverySession, targetHost *omd.Host) err
}() }()
timerStopped := make(chan struct{}) timerStopped := make(chan struct{})
stopChan := make(chan struct{})
defer close(stopChan)
go func() { go func() {
ports := make(map[int]*omd.Port) ports := make(map[int]*omd.Port)
@ -47,9 +47,13 @@ func scanV4(discoverySession session.DiscoverySession, targetHost *omd.Host) err
return return
} }
delay.Store(true) delay.Store(true)
// go func(packet *layers.TCP) {
if p := handlePacketTCP4(discoverySession, targetHost, ports, packet); nil != p { if p := handlePacketTCP4(discoverySession, targetHost, ports, packet); nil != p {
discoverySession.AddPort(p) discoverySession.AddPort(p)
log.Print(p)
} }
// }(packet)
case <-ticker.C: case <-ticker.C:
if false == delay.Load().(bool) { if false == delay.Load().(bool) {
ticker.Stop() ticker.Stop()
@ -61,7 +65,7 @@ func scanV4(discoverySession session.DiscoverySession, targetHost *omd.Host) err
} }
}() }()
if err := sendTCP4(discoverySession, ps, targetHost); nil != err { if err := sendTCP4(discoverySession, ps, targetHost, stopChan); nil != err {
log.Printf("sendTCP %v", err) log.Printf("sendTCP %v", err)
return nil return nil
} }
@ -74,7 +78,7 @@ func scanV4(discoverySession session.DiscoverySession, targetHost *omd.Host) err
} }
} }
func sendTCP4(discoverySession session.DiscoverySession, ps pcap.PCapScanner, host *omd.Host) error { func sendTCP4(discoverySession session.DiscoverySession, ps pcap.PCapScanner, host *omd.Host, stopChan chan struct{}) error {
dp := discoverySession.DiscoverPort() dp := discoverySession.DiscoverPort()
tcpPacket, err := makePacketPortTCP4(host) tcpPacket, err := makePacketPortTCP4(host)
@ -109,6 +113,8 @@ Loop:
select { select {
case <-timer.C: case <-timer.C:
case <-stopChan:
return nil
} }
} }

View File

@ -8,7 +8,6 @@ import (
"git.loafle.net/overflow_scanner/probe/__test" "git.loafle.net/overflow_scanner/probe/__test"
"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/pcap"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
) )
@ -65,27 +64,27 @@ func Test_scanV4(t *testing.T) {
} }
} }
func Test_sendTCP4(t *testing.T) { // func Test_sendTCP4(t *testing.T) {
type args struct { // type args struct {
discoverySession session.DiscoverySession // discoverySession session.DiscoverySession
ps pcap.PCapScanner // ps pcap.PCapScanner
host *omd.Host // host *omd.Host
} // }
tests := []struct { // tests := []struct {
name string // name string
args args // args args
wantErr bool // wantErr bool
}{ // }{
// TODO: Add test cases. // // TODO: Add test cases.
} // }
for _, tt := range tests { // for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { // t.Run(tt.name, func(t *testing.T) {
if err := sendTCP4(tt.args.discoverySession, tt.args.ps, tt.args.host); (err != nil) != tt.wantErr { // if err := sendTCP4(tt.args.discoverySession, tt.args.ps, tt.args.host); (err != nil) != tt.wantErr {
t.Errorf("sendTCP4() error = %v, wantErr %v", err, tt.wantErr) // t.Errorf("sendTCP4() error = %v, wantErr %v", err, tt.wantErr)
} // }
}) // })
} // }
} // }
func Test_handlePacketTCP4(t *testing.T) { func Test_handlePacketTCP4(t *testing.T) {
type args struct { type args struct {

View File

@ -12,6 +12,7 @@ import (
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"
osm "git.loafle.net/overflow/service_matcher-go"
"git.loafle.net/overflow_scanner/probe/discovery/session" "git.loafle.net/overflow_scanner/probe/discovery/session"
"git.loafle.net/overflow_scanner/probe/internal/matcher" "git.loafle.net/overflow_scanner/probe/internal/matcher"
"git.loafle.net/overflow_scanner/probe/internal/pcap" "git.loafle.net/overflow_scanner/probe/internal/pcap"
@ -20,13 +21,10 @@ import (
) )
func scanV4(discoverySession session.DiscoverySession, targetHost *omd.Host) error { func scanV4(discoverySession session.DiscoverySession, targetHost *omd.Host) error {
ps, err := pcap.RetainScanner(targetHost.Zone) ps := discoverySession.PCapScanner()
if nil != err { if nil == ps {
return fmt.Errorf("Discovery: Cannot retain pcap instance %v", err) return fmt.Errorf("Cannot retain pcap instance")
} }
defer func() {
go pcap.ReleaseScanner(targetHost.Zone)
}()
udpChan := ps.OpenUDP(targetHost.Address) udpChan := ps.OpenUDP(targetHost.Address)
defer func() { defer func() {
@ -108,9 +106,11 @@ func sendUDP4(discoverySession session.DiscoverySession, ps pcap.PCapScanner, ho
continue INNER_LOOP continue INNER_LOOP
} }
matchCtx := osm.NewMatchCtx(host.Address, portNumber)
addr := &net.UDPAddr{IP: ip.To4(), Port: portNumber} addr := &net.UDPAddr{IP: ip.To4(), Port: portNumber}
for i := 0; i < _matcher.PacketCount(); i++ { for i := 0; i < _matcher.PacketCount(matchCtx); i++ {
p := _matcher.Packet(i) p := _matcher.Packet(matchCtx, i)
if _, err := conn.WriteToUDP(p.Buffer, addr); err != nil { if _, err := conn.WriteToUDP(p.Buffer, addr); err != nil {
log.Print("UDP write error", err) log.Print("UDP write error", err)
} }

View File

@ -28,8 +28,6 @@ LOOP:
continue LOOP continue LOOP
} }
// log.Print(rd)
discoverySession.AddHost(&omd.Host{ discoverySession.AddHost(&omd.Host{
MetaIPType: discoverySession.Zone().MetaIPType, MetaIPType: discoverySession.Zone().MetaIPType,
Name: rd.FriendlyName, Name: rd.FriendlyName,

View File

@ -10,6 +10,7 @@ import (
omd "git.loafle.net/overflow/model/discovery" omd "git.loafle.net/overflow/model/discovery"
ounc "git.loafle.net/overflow/util-go/net/cidr" 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"
"git.loafle.net/overflow_scanner/probe/internal/pcap"
) )
type DiscoverySession interface { type DiscoverySession interface {
@ -17,6 +18,8 @@ type DiscoverySession interface {
DiscoveryRequest() types.DiscoveryRequest DiscoveryRequest() types.DiscoveryRequest
PCapScanner() pcap.PCapScanner
Zone() *omd.Zone Zone() *omd.Zone
Host() *omd.Host Host() *omd.Host
Port() *omd.Port Port() *omd.Port
@ -47,6 +50,7 @@ type DiscoverySession interface {
type ofDiscoverySession struct { type ofDiscoverySession struct {
discoveryRequest types.DiscoveryRequest discoveryRequest types.DiscoveryRequest
pCapScanner pcap.PCapScanner
zone *omd.Zone zone *omd.Zone
host *omd.Host host *omd.Host
@ -79,6 +83,7 @@ func (ds *ofDiscoverySession) init(request types.DiscoveryRequest) {
ds.discoverHost = nil ds.discoverHost = nil
ds.discoverPort = nil ds.discoverPort = nil
ds.discoverService = nil ds.discoverService = nil
ds.pCapScanner = nil
ds.hosts = make(map[string]*omd.Host) ds.hosts = make(map[string]*omd.Host)
ds.includeMachosts = make(map[string]*omd.Host) ds.includeMachosts = make(map[string]*omd.Host)
@ -168,9 +173,18 @@ func (ds *ofDiscoverySession) InitWithRequest(request types.DiscoveryRequest) er
ds.setDiscoverService(discoverService) ds.setDiscoverService(discoverService)
} }
_pCapScanner := pcap.NewPCapScanner(ds.zone)
if err := _pCapScanner.Start(); nil == err {
ds.pCapScanner = _pCapScanner
}
return nil return nil
} }
func (ds *ofDiscoverySession) PCapScanner() pcap.PCapScanner {
return ds.pCapScanner
}
func (ds *ofDiscoverySession) SetDiscoveryDelegator(discoveryDelegator chan<- interface{}) { func (ds *ofDiscoverySession) SetDiscoveryDelegator(discoveryDelegator chan<- interface{}) {
ds.discoveryDelegator = discoveryDelegator ds.discoveryDelegator = discoveryDelegator
} }
@ -568,20 +582,26 @@ func RetainDiscoverySession() *ofDiscoverySession {
func ReleaseDiscoverySession(ds *ofDiscoverySession) { func ReleaseDiscoverySession(ds *ofDiscoverySession) {
close(ds.stopChan) close(ds.stopChan)
// timer := time.NewTimer(time.Microsecond * 500) if nil != ds.pCapScanner {
ds.pCapScanner.Stop()
// select { }
// case <-timer.C:
// }
ds.pCapScanner = nil
ds.discoveryRequest = nil ds.discoveryRequest = nil
ds.zone = nil ds.zone = nil
ds.host = nil ds.host = nil
ds.port = nil ds.port = nil
ds.discoveryConfig = nil
ds.discoverHost = nil ds.discoverHost = nil
ds.discoverPort = nil ds.discoverPort = nil
ds.discoverService = nil ds.discoverService = nil
ds.targetHosts = nil
ds.discoveryDelegator = nil
ds.includeMachosts = nil ds.includeMachosts = nil
ds.hosts = nil ds.hosts = nil
ds.ports = nil ds.ports = nil

View File

@ -6,7 +6,6 @@ import (
"git.loafle.net/overflow_scanner/probe/discovery/protocol/arp" "git.loafle.net/overflow_scanner/probe/discovery/protocol/arp"
"git.loafle.net/overflow_scanner/probe/discovery/protocol/icmp" "git.loafle.net/overflow_scanner/probe/discovery/protocol/icmp"
"git.loafle.net/overflow_scanner/probe/discovery/session" "git.loafle.net/overflow_scanner/probe/discovery/session"
"git.loafle.net/overflow_scanner/probe/internal/pcap"
) )
func Scan(discoverySession session.DiscoverySession) error { func Scan(discoverySession session.DiscoverySession) error {
@ -15,17 +14,7 @@ func Scan(discoverySession session.DiscoverySession) error {
return nil return nil
} }
zone := discoverySession.Zone() if nil != discoverySession.PCapScanner() {
var privileged bool
_, err := pcap.RetainScanner(zone)
if nil == err {
pcap.ReleaseScanner(zone)
privileged = true
}
if privileged {
return privilegedScan(discoverySession) return privilegedScan(discoverySession)
} }

View File

@ -7,7 +7,6 @@ import (
"git.loafle.net/overflow_scanner/probe/discovery/protocol/tcp/connection" "git.loafle.net/overflow_scanner/probe/discovery/protocol/tcp/connection"
"git.loafle.net/overflow_scanner/probe/discovery/protocol/tcp/syn" "git.loafle.net/overflow_scanner/probe/discovery/protocol/tcp/syn"
"git.loafle.net/overflow_scanner/probe/discovery/session" "git.loafle.net/overflow_scanner/probe/discovery/session"
"git.loafle.net/overflow_scanner/probe/internal/pcap"
) )
func Scan(discoverySession session.DiscoverySession, targetHost *omd.Host) error { func Scan(discoverySession session.DiscoverySession, targetHost *omd.Host) error {
@ -15,17 +14,7 @@ func Scan(discoverySession session.DiscoverySession, targetHost *omd.Host) error
return nil return nil
} }
zone := discoverySession.Zone() if nil != discoverySession.PCapScanner() {
var privileged bool
_, err := pcap.RetainScanner(zone)
if nil == err {
pcap.ReleaseScanner(zone)
privileged = true
}
if privileged {
return privilegedScan(discoverySession, targetHost) return privilegedScan(discoverySession, targetHost)
} }

View File

@ -13,6 +13,10 @@ import (
"git.loafle.net/overflow_scanner/probe/internal/matcher" "git.loafle.net/overflow_scanner/probe/internal/matcher"
) )
const (
deadline = time.Millisecond * 500
)
func scanTCP(discoverySession session.DiscoverySession, targetPort *omd.Port) error { func scanTCP(discoverySession session.DiscoverySession, targetPort *omd.Port) error {
hostAddress := targetPort.Host.Address hostAddress := targetPort.Host.Address
portNumber, err := ouej.NumberToInt(targetPort.PortNumber) portNumber, err := ouej.NumberToInt(targetPort.PortNumber)
@ -38,7 +42,7 @@ LOOP:
continue LOOP continue LOOP
} }
if err := conn.SetReadDeadline(time.Now().Add(1 * time.Second)); nil != err { if err := conn.SetReadDeadline(time.Now().Add(deadline)); nil != err {
continue LOOP continue LOOP
} }
n, err := conn.Read(buf) n, err := conn.Read(buf)
@ -113,7 +117,7 @@ LOOP:
for j := 0; j < packetCount; j++ { for j := 0; j < packetCount; j++ {
_packet := _matcher.Packet(matchCtx, j) _packet := _matcher.Packet(matchCtx, j)
if err := conn.SetWriteDeadline(time.Now().Add(1 * time.Second)); nil != err { if err := conn.SetWriteDeadline(time.Now().Add(deadline)); nil != err {
return nil return nil
} }
_, err := conn.Write(_packet.Buffer) _, err := conn.Write(_packet.Buffer)
@ -121,7 +125,7 @@ LOOP:
return nil return nil
} }
if err := conn.SetReadDeadline(time.Now().Add(1 * time.Second)); nil != err { if err := conn.SetReadDeadline(time.Now().Add(deadline)); nil != err {
return nil return nil
} }
n, err := conn.Read(buf) n, err := conn.Read(buf)
@ -177,7 +181,7 @@ LOOP:
for j := 0; j < packetCount; j++ { for j := 0; j < packetCount; j++ {
_packet := _matcher.Packet(matchCtx, j) _packet := _matcher.Packet(matchCtx, j)
if err := conn.SetWriteDeadline(time.Now().Add(1 * time.Second)); nil != err { if err := conn.SetWriteDeadline(time.Now().Add(deadline)); nil != err {
break INNER_LOOP break INNER_LOOP
} }
_, err := conn.Write(_packet.Buffer) _, err := conn.Write(_packet.Buffer)
@ -185,7 +189,7 @@ LOOP:
break INNER_LOOP break INNER_LOOP
} }
if err := conn.SetReadDeadline(time.Now().Add(1 * time.Second)); nil != err { if err := conn.SetReadDeadline(time.Now().Add(deadline)); nil != err {
break INNER_LOOP break INNER_LOOP
} }
n, err := conn.Read(buf) n, err := conn.Read(buf)

View File

@ -110,20 +110,27 @@ func handlePacketTCP(ps *pCapScan, packet gopacket.Packet) {
} }
ip := ipLayer.(*layers.IPv4).SrcIP.String() ip := ipLayer.(*layers.IPv4).SrcIP.String()
ps.tcpListenerChanMtx.RLock()
defer ps.tcpListenerChanMtx.RUnlock()
chs, ok := ps.tcpListenerChans[ip]
if ok {
layer := packet.Layer(layers.LayerTypeTCP) layer := packet.Layer(layers.LayerTypeTCP)
tcp, _ := layer.(*layers.TCP) tcp, _ := layer.(*layers.TCP)
ps.tcpListenerChanMtx.RLock()
defer func() {
ps.tcpListenerChanMtx.RUnlock()
}()
chs, ok := ps.tcpListenerChans[ip]
if ok {
// for _, ch := range chs {
// ch <- tcp
// }
for _, ch := range chs { for _, ch := range chs {
ch <- tcp select {
case ch <- tcp:
default:
} }
} }
}
} }
func handlePacketUDP(ps *pCapScan, packet gopacket.Packet) { func handlePacketUDP(ps *pCapScan, packet gopacket.Packet) {

View File

@ -1,33 +1,37 @@
package pcap package pcap
import ( import (
"log"
"sync" "sync"
"time" "time"
omd "git.loafle.net/overflow/model/discovery" omd "git.loafle.net/overflow/model/discovery"
) )
var mtx sync.Mutex var instances sync.Map
var instances map[string]PCapScanner
// var instances map[string]PCapScanner
func init() { func init() {
instances = make(map[string]PCapScanner, 0) // instances = make(map[string]PCapScanner, 0)
} }
func RetainScanner(zone *omd.Zone) (PCapScanner, error) { func RetainScanner(zone *omd.Zone) (PCapScanner, error) {
mtx.Lock()
defer mtx.Unlock()
var ps PCapScanner var ps PCapScanner
var ok bool // if ps, ok = instances[zone.Network]; !ok {
if ps, ok = instances[zone.Network]; !ok {
ps = newPCapScanner(zone) _ps, ok := instances.Load(zone.Network)
if err := ps.start(); nil != err { if !ok {
ps = NewPCapScanner(zone)
if err := ps.Start(); nil != err {
return nil, err return nil, err
} }
instances[zone.Network] = ps instances.Store(zone.Network, ps)
} else {
ps = _ps.(PCapScanner)
} }
ps.retain() ps.retain()
log.Print("Pcap retain")
return ps, nil return ps, nil
} }
@ -35,26 +39,28 @@ func RetainScanner(zone *omd.Zone) (PCapScanner, error) {
func ReleaseScanner(zone *omd.Zone) { func ReleaseScanner(zone *omd.Zone) {
go func() { go func() {
time.Sleep(2 * time.Second) time.Sleep(1 * time.Second)
mtx.Lock() if _ps, ok := instances.Load(zone.Network); ok {
defer mtx.Unlock() ps := _ps.(PCapScanner)
log.Print("Pcap release")
if ps, ok := instances[zone.Network]; ok {
if ps.release() { if ps.release() {
ps.stop() ps.Stop()
delete(instances, zone.Network) instances.Delete(zone.Network)
} }
} }
}() }()
} }
func ReleaseScannerAll() { func ReleaseScannerAll() {
mtx.Lock() instances.Range(func(k, v interface{}) bool {
defer mtx.Unlock() ps := v.(PCapScanner)
if ps.release() {
ps.Stop()
instances.Delete(k)
return false
}
for k, ps := range instances { return true
ps.stop() })
delete(instances, k)
}
} }

View File

@ -9,9 +9,10 @@ import (
"github.com/google/gopacket" "github.com/google/gopacket"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap" "github.com/google/gopacket/pcap"
deadlock "github.com/sasha-s/go-deadlock"
) )
func newPCapScanner(zone *omd.Zone) PCapScanner { func NewPCapScanner(zone *omd.Zone) PCapScanner {
ps := &pCapScan{ ps := &pCapScan{
zone: zone, zone: zone,
} }
@ -37,8 +38,8 @@ type PCapScanner interface {
WritePacketData(data []byte) (err error) WritePacketData(data []byte) (err error)
start() error Start() error
stop() Stop()
retain() retain()
release() bool release() bool
@ -48,19 +49,24 @@ type pCapScan struct {
pCapHandle *pcap.Handle pCapHandle *pcap.Handle
zone *omd.Zone zone *omd.Zone
arpListenerChanMtx sync.RWMutex // arpListenerChanMtx sync.RWMutex
arpListenerChanMtx deadlock.RWMutex
arpListenerChans []chan *layers.ARP arpListenerChans []chan *layers.ARP
icmp4ListenerChanMtx sync.RWMutex // icmp4ListenerChanMtx sync.RWMutex
icmp4ListenerChanMtx deadlock.RWMutex
icmp4ListenerChans []chan gopacket.Packet icmp4ListenerChans []chan gopacket.Packet
icmp6ListenerChanMtx sync.RWMutex // icmp6ListenerChanMtx sync.RWMutex
icmp6ListenerChanMtx deadlock.RWMutex
icmp6ListenerChans []chan gopacket.Packet icmp6ListenerChans []chan gopacket.Packet
tcpListenerChanMtx sync.RWMutex // tcpListenerChanMtx sync.RWMutex
tcpListenerChanMtx deadlock.RWMutex
tcpListenerChans map[string][]chan *layers.TCP tcpListenerChans map[string][]chan *layers.TCP
udpListenerChanMtx sync.RWMutex // udpListenerChanMtx sync.RWMutex
udpListenerChanMtx deadlock.RWMutex
udpListenerChans map[string][]chan gopacket.Packet udpListenerChans map[string][]chan gopacket.Packet
refCount int refCount int
@ -68,7 +74,7 @@ type pCapScan struct {
stopWg sync.WaitGroup stopWg sync.WaitGroup
} }
func (ps *pCapScan) start() error { func (ps *pCapScan) Start() error {
if ps.stopChan != nil { if ps.stopChan != nil {
return fmt.Errorf("PCapScanner: already running. Stop it before starting it again") return fmt.Errorf("PCapScanner: already running. Stop it before starting it again")
} }
@ -81,8 +87,8 @@ func (ps *pCapScan) start() error {
} }
// set filter // set filter
// todo add tcp, udp filter // todo add tcp, udp filter
//if err = h.SetBPFFilter("arp and src net " + ps.zone.Network + " or (((tcp[tcpflags] & (tcp-syn|tcp-ack) != 0) or (tcp[tcpflags] & (tcp-rst) != 0)) and port 60000) or udp "); nil != err { if err = h.SetBPFFilter("arp or icmp or icmp6 and src net " + ps.zone.Network + " or (((tcp[tcpflags] & (tcp-syn|tcp-ack) != 0) or (tcp[tcpflags] & (tcp-rst) != 0)) and port 60000) or udp "); nil != err {
if err = h.SetBPFFilter("arp or icmp or icmp6 or tcp or udp"); nil != err { // if err = h.SetBPFFilter("arp or icmp or icmp6 or tcp or udp"); nil != err {
h.Close() h.Close()
return err return err
} }
@ -102,7 +108,7 @@ func (ps *pCapScan) start() error {
return nil return nil
} }
func (ps *pCapScan) stop() { func (ps *pCapScan) Stop() {
if ps.stopChan == nil { if ps.stopChan == nil {
panic("PCapScanner: must be started before stopping it") panic("PCapScanner: must be started before stopping it")
} }
@ -115,7 +121,7 @@ func (ps *pCapScan) OpenARP() chan *layers.ARP {
ps.arpListenerChanMtx.Lock() ps.arpListenerChanMtx.Lock()
defer ps.arpListenerChanMtx.Unlock() defer ps.arpListenerChanMtx.Unlock()
c := make(chan *layers.ARP, 0) c := make(chan *layers.ARP, 128)
ps.arpListenerChans = append(ps.arpListenerChans, c) ps.arpListenerChans = append(ps.arpListenerChans, c)
return c return c
} }
@ -137,7 +143,7 @@ func (ps *pCapScan) OpenICMP4() chan gopacket.Packet {
ps.icmp4ListenerChanMtx.Lock() ps.icmp4ListenerChanMtx.Lock()
defer ps.icmp4ListenerChanMtx.Unlock() defer ps.icmp4ListenerChanMtx.Unlock()
c := make(chan gopacket.Packet, 0) c := make(chan gopacket.Packet, 128)
ps.icmp4ListenerChans = append(ps.icmp4ListenerChans, c) ps.icmp4ListenerChans = append(ps.icmp4ListenerChans, c)
return c return c
} }
@ -159,7 +165,7 @@ func (ps *pCapScan) OpenICMP6() chan gopacket.Packet {
ps.icmp6ListenerChanMtx.Lock() ps.icmp6ListenerChanMtx.Lock()
defer ps.icmp6ListenerChanMtx.Unlock() defer ps.icmp6ListenerChanMtx.Unlock()
c := make(chan gopacket.Packet, 0) c := make(chan gopacket.Packet, 128)
ps.icmp6ListenerChans = append(ps.icmp6ListenerChans, c) ps.icmp6ListenerChans = append(ps.icmp6ListenerChans, c)
return c return c
} }
@ -185,7 +191,7 @@ func (ps *pCapScan) OpenTCP(ip string) chan *layers.TCP {
ps.tcpListenerChans[ip] = make([]chan *layers.TCP, 0) ps.tcpListenerChans[ip] = make([]chan *layers.TCP, 0)
} }
ch := make(chan *layers.TCP, 0) ch := make(chan *layers.TCP, 1024)
ps.tcpListenerChans[ip] = append(ps.tcpListenerChans[ip], ch) ps.tcpListenerChans[ip] = append(ps.tcpListenerChans[ip], ch)
return ch return ch
@ -218,7 +224,7 @@ func (ps *pCapScan) OpenUDP(ip string) chan gopacket.Packet {
ps.udpListenerChans[ip] = make([]chan gopacket.Packet, 0) ps.udpListenerChans[ip] = make([]chan gopacket.Packet, 0)
} }
ch := make(chan gopacket.Packet, 0) ch := make(chan gopacket.Packet, 256)
ps.udpListenerChans[ip] = append(ps.udpListenerChans[ip], ch) ps.udpListenerChans[ip] = append(ps.udpListenerChans[ip], ch)
return ch return ch
@ -313,7 +319,7 @@ func handleReceive(ps *pCapScan) {
for { for {
select { select {
case packet := <-inPacket: case packet := <-inPacket:
handlePacket(ps, packet) go handlePacket(ps, packet)
case <-ps.stopChan: case <-ps.stopChan:
ps.destroy() ps.destroy()
return return