icmp added
This commit is contained in:
parent
f95ca6bdf1
commit
0e953adb3d
19
discovery/protocol/icmp/icmp.go
Normal file
19
discovery/protocol/icmp/icmp.go
Normal file
|
@ -0,0 +1,19 @@
|
|||
package icmp
|
||||
|
||||
import (
|
||||
omm "git.loafle.net/overflow/model/meta"
|
||||
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
||||
)
|
||||
|
||||
func Scan(discoverySession session.DiscoverySession) error {
|
||||
metaIPTypeEnum := omm.ToMetaIPTypeEnum(discoverySession.Zone().MetaIPType)
|
||||
|
||||
switch metaIPTypeEnum {
|
||||
case omm.MetaIPTypeEnumV4:
|
||||
return scanV4(discoverySession)
|
||||
case omm.MetaIPTypeEnumV6:
|
||||
return scanV4(discoverySession)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
175
discovery/protocol/icmp/icmpv4.go
Normal file
175
discovery/protocol/icmp/icmpv4.go
Normal file
|
@ -0,0 +1,175 @@
|
|||
package icmp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"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_scanner/probe/discovery/session"
|
||||
"git.loafle.net/overflow_scanner/probe/internal/pcap"
|
||||
"github.com/google/gopacket"
|
||||
"github.com/google/gopacket/layers"
|
||||
"golang.org/x/net/icmp"
|
||||
"golang.org/x/net/ipv4"
|
||||
)
|
||||
|
||||
func scanV4(discoverySession session.DiscoverySession) error {
|
||||
targetHosts := discoverySession.TargetHosts()
|
||||
if nil == targetHosts || 0 == len(targetHosts) {
|
||||
return nil
|
||||
}
|
||||
|
||||
zone := discoverySession.Zone()
|
||||
|
||||
ps, err := pcap.RetainScanner(zone)
|
||||
if nil != err {
|
||||
return fmt.Errorf("Cannot retain pcap instance %v", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
pcap.ReleaseScanner(zone)
|
||||
}()
|
||||
|
||||
icmpChan := ps.OpenICMP4()
|
||||
defer func() {
|
||||
ps.CloseICMP4(icmpChan)
|
||||
}()
|
||||
|
||||
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 := <-icmpChan:
|
||||
if !ok {
|
||||
// logging.Logger().Debugf("icmp channel is closed")
|
||||
return
|
||||
}
|
||||
delay.Store(true)
|
||||
if h := handlePacketICMP4(zone, targetHosts, 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)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
if err := sendICMP4(ps, zone, targetHosts); nil != err {
|
||||
log.Printf("sendICMP %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
select {
|
||||
case <-timerStopped:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func sendICMP4(ps pcap.PCapScanner, zone *omd.Zone, targetHosts []net.IP) error {
|
||||
conn, err := icmp.ListenPacket("ip4:icmp", "")
|
||||
if nil != err {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
msg, err := makeMessageICMP4()
|
||||
if nil != err {
|
||||
return err
|
||||
}
|
||||
|
||||
var dst net.IPAddr
|
||||
LOOP:
|
||||
for _, targetHost := range targetHosts {
|
||||
dst.IP = targetHost
|
||||
if _, err := conn.WriteTo(msg, &dst); nil != err {
|
||||
continue LOOP
|
||||
}
|
||||
|
||||
timer := time.NewTimer(time.Microsecond * 100)
|
||||
|
||||
select {
|
||||
case <-timer.C:
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func handlePacketICMP4(zone *omd.Zone, targetHosts []net.IP, hosts map[string]*omd.Host, packet gopacket.Packet) *omd.Host {
|
||||
_ethLayer := packet.Layer(layers.LayerTypeEthernet)
|
||||
ethLayer := _ethLayer.(*layers.Ethernet)
|
||||
|
||||
_ip4Layer := packet.Layer(layers.LayerTypeIPv4)
|
||||
ip4Layer := _ip4Layer.(*layers.IPv4)
|
||||
|
||||
_icmp4Layer := packet.Layer(layers.LayerTypeICMPv4)
|
||||
icmp4Layer := _icmp4Layer.(*layers.ICMPv4)
|
||||
|
||||
if icmp4Layer.TypeCode != layers.ICMPv4TypeEchoReply {
|
||||
return nil
|
||||
}
|
||||
|
||||
ip := ip4Layer.SrcIP
|
||||
if _, ok := hosts[ip.String()]; ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
isTarget := false
|
||||
for _, h := range targetHosts {
|
||||
if h.Equal(ip) {
|
||||
isTarget = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isTarget {
|
||||
return nil
|
||||
}
|
||||
|
||||
h := &omd.Host{
|
||||
MetaIPType: omm.ToMetaIPType(omm.MetaIPTypeEnumV4),
|
||||
Address: ip.String(),
|
||||
Mac: net.HardwareAddr(ethLayer.SrcMAC).String(),
|
||||
Zone: zone,
|
||||
DiscoveredDate: omu.NowPtr(),
|
||||
}
|
||||
|
||||
hosts[ip.String()] = h
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
func makeMessageICMP4() ([]byte, error) {
|
||||
id := rand.Intn(0xffff)
|
||||
seq := rand.Intn(0xffff)
|
||||
|
||||
return (&icmp.Message{
|
||||
Type: ipv4.ICMPTypeEcho,
|
||||
Code: 0,
|
||||
Body: &icmp.Echo{
|
||||
ID: id,
|
||||
Seq: seq,
|
||||
Data: []byte("PING by overFlow"),
|
||||
},
|
||||
}).Marshal(nil)
|
||||
}
|
125
discovery/protocol/icmp/icmpv4_test.go
Normal file
125
discovery/protocol/icmp/icmpv4_test.go
Normal file
|
@ -0,0 +1,125 @@
|
|||
package icmp
|
||||
|
||||
import (
|
||||
"net"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
omd "git.loafle.net/overflow/model/discovery"
|
||||
omm "git.loafle.net/overflow/model/meta"
|
||||
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
||||
"git.loafle.net/overflow_scanner/probe/discovery/types"
|
||||
"git.loafle.net/overflow_scanner/probe/internal/pcap"
|
||||
"github.com/google/gopacket"
|
||||
)
|
||||
|
||||
func Test_scanV4(t *testing.T) {
|
||||
s := session.NewMockDiscoverySession(
|
||||
"testRequester",
|
||||
types.DiscoveryRequestTypeHost,
|
||||
&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",
|
||||
DiscoveryConfig: &omd.DiscoveryConfig{},
|
||||
},
|
||||
)
|
||||
|
||||
type args struct {
|
||||
discoverySession session.DiscoverySession
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "1",
|
||||
args: args{
|
||||
discoverySession: s,
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if err := scanV4(tt.args.discoverySession); (err != nil) != tt.wantErr {
|
||||
t.Errorf("scanV4() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_sendICMP4(t *testing.T) {
|
||||
type args struct {
|
||||
ps pcap.PCapScanner
|
||||
zone *omd.Zone
|
||||
targetHosts []net.IP
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantErr bool
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if err := sendICMP4(tt.args.ps, tt.args.zone, tt.args.targetHosts); (err != nil) != tt.wantErr {
|
||||
t.Errorf("sendICMP4() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_handlePacketICMP4(t *testing.T) {
|
||||
type args struct {
|
||||
zone *omd.Zone
|
||||
targetHosts []net.IP
|
||||
hosts map[string]*omd.Host
|
||||
packet gopacket.Packet
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *omd.Host
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := handlePacketICMP4(tt.args.zone, tt.args.targetHosts, tt.args.hosts, tt.args.packet); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("handlePacketICMP4() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_makeMessageICMP4(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
want []byte
|
||||
wantErr bool
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := makeMessageICMP4()
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("makeMessageICMP4() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("makeMessageICMP4() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
175
discovery/protocol/icmp/icmpv6.go
Normal file
175
discovery/protocol/icmp/icmpv6.go
Normal file
|
@ -0,0 +1,175 @@
|
|||
package icmp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"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_scanner/probe/discovery/session"
|
||||
"git.loafle.net/overflow_scanner/probe/internal/pcap"
|
||||
"github.com/google/gopacket"
|
||||
"github.com/google/gopacket/layers"
|
||||
"golang.org/x/net/icmp"
|
||||
"golang.org/x/net/ipv6"
|
||||
)
|
||||
|
||||
func scanV6(discoverySession session.DiscoverySession) error {
|
||||
targetHosts := discoverySession.TargetHosts()
|
||||
if nil == targetHosts || 0 == len(targetHosts) {
|
||||
return nil
|
||||
}
|
||||
|
||||
zone := discoverySession.Zone()
|
||||
|
||||
ps, err := pcap.RetainScanner(zone)
|
||||
if nil != err {
|
||||
return fmt.Errorf("Cannot retain pcap instance %v", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
pcap.ReleaseScanner(zone)
|
||||
}()
|
||||
|
||||
icmpChan := ps.OpenICMP6()
|
||||
defer func() {
|
||||
ps.CloseICMP6(icmpChan)
|
||||
}()
|
||||
|
||||
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 := <-icmpChan:
|
||||
if !ok {
|
||||
// logging.Logger().Debugf("icmp channel is closed")
|
||||
return
|
||||
}
|
||||
delay.Store(true)
|
||||
if h := handlePacketICMP6(zone, targetHosts, 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)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
if err := sendICMP6(ps, zone, targetHosts); nil != err {
|
||||
log.Printf("sendICMP %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
select {
|
||||
case <-timerStopped:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func sendICMP6(ps pcap.PCapScanner, zone *omd.Zone, targetHosts []net.IP) error {
|
||||
conn, err := icmp.ListenPacket("ip6:ipv6-icmp", "")
|
||||
if nil != err {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
msg, err := makeMessageICMP6()
|
||||
if nil != err {
|
||||
return err
|
||||
}
|
||||
|
||||
var dst net.IPAddr
|
||||
LOOP:
|
||||
for _, targetHost := range targetHosts {
|
||||
dst.IP = targetHost
|
||||
if _, err := conn.WriteTo(msg, &dst); nil != err {
|
||||
continue LOOP
|
||||
}
|
||||
|
||||
timer := time.NewTimer(time.Microsecond * 100)
|
||||
|
||||
select {
|
||||
case <-timer.C:
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func handlePacketICMP6(zone *omd.Zone, targetHosts []net.IP, hosts map[string]*omd.Host, packet gopacket.Packet) *omd.Host {
|
||||
_ethLayer := packet.Layer(layers.LayerTypeEthernet)
|
||||
ethLayer := _ethLayer.(*layers.Ethernet)
|
||||
|
||||
_ip6Layer := packet.Layer(layers.LayerTypeIPv6)
|
||||
ip6Layer := _ip6Layer.(*layers.IPv6)
|
||||
|
||||
_icmp6Layer := packet.Layer(layers.LayerTypeICMPv6)
|
||||
icmp6Layer := _icmp6Layer.(*layers.ICMPv6)
|
||||
|
||||
if icmp6Layer.TypeCode != layers.ICMPv6TypeEchoReply {
|
||||
return nil
|
||||
}
|
||||
|
||||
ip := ip6Layer.SrcIP
|
||||
if _, ok := hosts[ip.String()]; ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
isTarget := false
|
||||
for _, h := range targetHosts {
|
||||
if h.Equal(ip) {
|
||||
isTarget = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isTarget {
|
||||
return nil
|
||||
}
|
||||
|
||||
h := &omd.Host{
|
||||
MetaIPType: omm.ToMetaIPType(omm.MetaIPTypeEnumV6),
|
||||
Address: ip.String(),
|
||||
Mac: net.HardwareAddr(ethLayer.SrcMAC).String(),
|
||||
Zone: zone,
|
||||
DiscoveredDate: omu.NowPtr(),
|
||||
}
|
||||
|
||||
hosts[ip.String()] = h
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
func makeMessageICMP6() ([]byte, error) {
|
||||
id := rand.Intn(0xffff)
|
||||
seq := rand.Intn(0xffff)
|
||||
|
||||
return (&icmp.Message{
|
||||
Type: ipv6.ICMPTypeEchoRequest,
|
||||
Code: 0,
|
||||
Body: &icmp.Echo{
|
||||
ID: id,
|
||||
Seq: seq,
|
||||
Data: []byte("PING by overFlow"),
|
||||
},
|
||||
}).Marshal(nil)
|
||||
}
|
|
@ -37,7 +37,7 @@ SERVICE_LOOP:
|
|||
|
||||
ENTRY_LOOP:
|
||||
for _, entry := range entries {
|
||||
// log.Print("serviceEntry ", entry)
|
||||
log.Print("serviceEntry ", entry)
|
||||
|
||||
name := entry.Instance // HP\ LaserJet\ P1505n
|
||||
service := entry.Service // _pdl-datastream._tcp
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
omd "git.loafle.net/overflow/model/discovery"
|
||||
|
@ -26,13 +27,17 @@ type DiscoverySession interface {
|
|||
DiscoverPort() *omd.DiscoverPort
|
||||
DiscoverService() *omd.DiscoverService
|
||||
|
||||
TargetHosts() []net.IP
|
||||
|
||||
SetDiscoveryDelegator(chan<- interface{})
|
||||
|
||||
AddHost(host *omd.Host) *omd.Host
|
||||
AddPort(port *omd.Port) *omd.Port
|
||||
AddService(service *omd.Service) *omd.Service
|
||||
|
||||
TargetHosts() []net.IP
|
||||
|
||||
SetDiscoveryDelegator(chan<- interface{})
|
||||
DiscoveredHost(address string) *omd.Host
|
||||
DiscoveredPort(host *omd.Host, portNumber int) map[string]*omd.Port
|
||||
DiscoveredService(port *omd.Port, name string) map[string]*omd.Service
|
||||
}
|
||||
|
||||
type ofDiscoverySession struct {
|
||||
|
@ -243,6 +248,53 @@ func (ds *ofDiscoverySession) AddService(service *omd.Service) *omd.Service {
|
|||
return s
|
||||
}
|
||||
|
||||
func (ds *ofDiscoverySession) DiscoveredHost(address string) *omd.Host {
|
||||
h, ok := ds.hosts[address]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
func (ds *ofDiscoverySession) DiscoveredPort(host *omd.Host, portNumber int) map[string]*omd.Port {
|
||||
h, _ := ds.findHost(host, false)
|
||||
if nil == h {
|
||||
return nil
|
||||
}
|
||||
|
||||
hostPorts, ok := ds.ports[h]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
ports, ok := hostPorts[json.Number(strconv.Itoa(portNumber))]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return ports
|
||||
}
|
||||
|
||||
func (ds *ofDiscoverySession) DiscoveredService(port *omd.Port, name string) map[string]*omd.Service {
|
||||
p, _ := ds.findPort(port, false)
|
||||
if nil == p {
|
||||
return nil
|
||||
}
|
||||
|
||||
portServices, ok := ds.services[p]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
services, ok := portServices[name]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return services
|
||||
}
|
||||
|
||||
func (ds *ofDiscoverySession) findHost(host *omd.Host, add bool) (h *omd.Host, modified bool) {
|
||||
modified = false
|
||||
var ok bool
|
||||
|
|
|
@ -10,6 +10,8 @@ type PacketType int
|
|||
const (
|
||||
PacketTypeUnknown PacketType = iota
|
||||
PacketTypeARP
|
||||
PacketTypeICMPv4
|
||||
PacketTypeICMPv6
|
||||
PacketTypeTCP
|
||||
PacketTypeUDP
|
||||
)
|
||||
|
@ -23,6 +25,16 @@ func getPacketType(packet gopacket.Packet) PacketType {
|
|||
return PacketTypeARP
|
||||
}
|
||||
|
||||
layer = packet.Layer(layers.LayerTypeICMPv4)
|
||||
if layer != nil {
|
||||
return PacketTypeICMPv4
|
||||
}
|
||||
|
||||
layer = packet.Layer(layers.LayerTypeICMPv6)
|
||||
if layer != nil {
|
||||
return PacketTypeICMPv6
|
||||
}
|
||||
|
||||
layer = packet.Layer(layers.LayerTypeTCP)
|
||||
if layer != nil {
|
||||
if _, ok := layer.(*layers.TCP); ok {
|
||||
|
@ -43,6 +55,10 @@ func handlePacket(ps *pCapScan, packet gopacket.Packet) {
|
|||
switch getPacketType(packet) {
|
||||
case PacketTypeARP:
|
||||
handlePacketARP(ps, packet)
|
||||
case PacketTypeICMPv4:
|
||||
handlePacketICMP4(ps, packet)
|
||||
case PacketTypeICMPv6:
|
||||
handlePacketICMP6(ps, packet)
|
||||
case PacketTypeTCP:
|
||||
handlePacketTCP(ps, packet)
|
||||
case PacketTypeUDP:
|
||||
|
@ -63,6 +79,30 @@ func handlePacketARP(ps *pCapScan, packet gopacket.Packet) {
|
|||
}
|
||||
}
|
||||
|
||||
func handlePacketICMP4(ps *pCapScan, packet gopacket.Packet) {
|
||||
ps.icmp4ListenerChanMtx.RLock()
|
||||
defer ps.icmp4ListenerChanMtx.RUnlock()
|
||||
|
||||
// icmp4Layer := packet.Layer(layers.LayerTypeICMPv4)
|
||||
// icmp4 := icmp4Layer.(*layers.ICMPv4)
|
||||
|
||||
for _, ch := range ps.icmp4ListenerChans {
|
||||
ch <- packet
|
||||
}
|
||||
}
|
||||
|
||||
func handlePacketICMP6(ps *pCapScan, packet gopacket.Packet) {
|
||||
ps.icmp6ListenerChanMtx.RLock()
|
||||
defer ps.icmp6ListenerChanMtx.RUnlock()
|
||||
|
||||
// icmp6Layer := packet.Layer(layers.LayerTypeICMPv6)
|
||||
// icmp6 := icmp6Layer.(*layers.ICMPv6)
|
||||
|
||||
for _, ch := range ps.icmp6ListenerChans {
|
||||
ch <- packet
|
||||
}
|
||||
}
|
||||
|
||||
func handlePacketTCP(ps *pCapScan, packet gopacket.Packet) {
|
||||
ipLayer := packet.Layer(layers.LayerTypeIPv4)
|
||||
if nil == ipLayer {
|
||||
|
|
|
@ -23,6 +23,12 @@ type PCapScanner interface {
|
|||
OpenARP() chan *layers.ARP
|
||||
CloseARP(ch chan *layers.ARP)
|
||||
|
||||
OpenICMP4() chan gopacket.Packet
|
||||
CloseICMP4(ch chan gopacket.Packet)
|
||||
|
||||
OpenICMP6() chan gopacket.Packet
|
||||
CloseICMP6(ch chan gopacket.Packet)
|
||||
|
||||
OpenTCP(ip string) chan *layers.TCP
|
||||
CloseTCP(ip string, ch chan *layers.TCP)
|
||||
|
||||
|
@ -45,6 +51,12 @@ type pCapScan struct {
|
|||
arpListenerChanMtx sync.RWMutex
|
||||
arpListenerChans []chan *layers.ARP
|
||||
|
||||
icmp4ListenerChanMtx sync.RWMutex
|
||||
icmp4ListenerChans []chan gopacket.Packet
|
||||
|
||||
icmp6ListenerChanMtx sync.RWMutex
|
||||
icmp6ListenerChans []chan gopacket.Packet
|
||||
|
||||
tcpListenerChanMtx sync.RWMutex
|
||||
tcpListenerChans map[string][]chan *layers.TCP
|
||||
|
||||
|
@ -70,13 +82,15 @@ func (ps *pCapScan) start() error {
|
|||
// set 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 tcp or udp"); nil != err {
|
||||
if err = h.SetBPFFilter("arp or icmp or icmp6 or tcp or udp"); nil != err {
|
||||
h.Close()
|
||||
return err
|
||||
}
|
||||
ps.pCapHandle = h
|
||||
|
||||
ps.arpListenerChans = make([]chan *layers.ARP, 0)
|
||||
ps.icmp4ListenerChans = make([]chan gopacket.Packet, 0)
|
||||
ps.icmp6ListenerChans = make([]chan gopacket.Packet, 0)
|
||||
ps.tcpListenerChans = make(map[string][]chan *layers.TCP, 0)
|
||||
ps.udpListenerChans = make(map[string][]chan gopacket.Packet, 0)
|
||||
|
||||
|
@ -119,6 +133,50 @@ func (ps *pCapScan) CloseARP(ch chan *layers.ARP) {
|
|||
}
|
||||
}
|
||||
|
||||
func (ps *pCapScan) OpenICMP4() chan gopacket.Packet {
|
||||
ps.icmp4ListenerChanMtx.Lock()
|
||||
defer ps.icmp4ListenerChanMtx.Unlock()
|
||||
|
||||
c := make(chan gopacket.Packet, 0)
|
||||
ps.icmp4ListenerChans = append(ps.icmp4ListenerChans, c)
|
||||
return c
|
||||
}
|
||||
func (ps *pCapScan) CloseICMP4(ch chan gopacket.Packet) {
|
||||
ps.icmp4ListenerChanMtx.Lock()
|
||||
defer ps.icmp4ListenerChanMtx.Unlock()
|
||||
|
||||
i := sort.Search(len(ps.icmp4ListenerChans), func(i int) bool {
|
||||
return ch == ps.icmp4ListenerChans[i]
|
||||
})
|
||||
|
||||
if -1 != i {
|
||||
close(ch)
|
||||
ps.icmp4ListenerChans = append(ps.icmp4ListenerChans[:i], ps.icmp4ListenerChans[i+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
func (ps *pCapScan) OpenICMP6() chan gopacket.Packet {
|
||||
ps.icmp6ListenerChanMtx.Lock()
|
||||
defer ps.icmp6ListenerChanMtx.Unlock()
|
||||
|
||||
c := make(chan gopacket.Packet, 0)
|
||||
ps.icmp6ListenerChans = append(ps.icmp6ListenerChans, c)
|
||||
return c
|
||||
}
|
||||
func (ps *pCapScan) CloseICMP6(ch chan gopacket.Packet) {
|
||||
ps.icmp6ListenerChanMtx.Lock()
|
||||
defer ps.icmp6ListenerChanMtx.Unlock()
|
||||
|
||||
i := sort.Search(len(ps.icmp6ListenerChans), func(i int) bool {
|
||||
return ch == ps.icmp6ListenerChans[i]
|
||||
})
|
||||
|
||||
if -1 != i {
|
||||
close(ch)
|
||||
ps.icmp6ListenerChans = append(ps.icmp6ListenerChans[:i], ps.icmp6ListenerChans[i+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
func (ps *pCapScan) OpenTCP(ip string) chan *layers.TCP {
|
||||
ps.tcpListenerChanMtx.Lock()
|
||||
defer ps.tcpListenerChanMtx.Unlock()
|
||||
|
@ -222,6 +280,20 @@ func (ps *pCapScan) destroy() {
|
|||
}
|
||||
ps.udpListenerChanMtx.Unlock()
|
||||
|
||||
ps.icmp4ListenerChanMtx.Lock()
|
||||
for _, v := range ps.icmp4ListenerChans {
|
||||
close(v)
|
||||
}
|
||||
ps.icmp4ListenerChans = ps.icmp4ListenerChans[:0]
|
||||
ps.icmp4ListenerChanMtx.Unlock()
|
||||
|
||||
ps.icmp6ListenerChanMtx.Lock()
|
||||
for _, v := range ps.icmp6ListenerChans {
|
||||
close(v)
|
||||
}
|
||||
ps.icmp6ListenerChans = ps.icmp6ListenerChans[:0]
|
||||
ps.icmp6ListenerChanMtx.Unlock()
|
||||
|
||||
ps.arpListenerChanMtx.Lock()
|
||||
for _, v := range ps.arpListenerChans {
|
||||
close(v)
|
||||
|
@ -235,7 +307,7 @@ func (ps *pCapScan) destroy() {
|
|||
func handleReceive(ps *pCapScan) {
|
||||
defer ps.stopWg.Done()
|
||||
|
||||
pSrc := gopacket.NewPacketSource(ps.pCapHandle, layers.LayerTypeEthernet)
|
||||
pSrc := gopacket.NewPacketSource(ps.pCapHandle, ps.pCapHandle.LinkType())
|
||||
inPacket := pSrc.Packets()
|
||||
|
||||
for {
|
||||
|
|
Loading…
Reference in New Issue
Block a user