ing
This commit is contained in:
parent
6161d7fade
commit
4728182733
|
@ -15,8 +15,16 @@ import (
|
|||
"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"
|
||||
)
|
||||
|
||||
const (
|
||||
// IP flag
|
||||
DF = 0x02
|
||||
// // IP header len
|
||||
// IPHLEN = 40
|
||||
//
|
||||
// SIOCGIFMTU = 0x8921
|
||||
UINT16 = 65535
|
||||
)
|
||||
|
||||
func scanV4(discoverySession session.DiscoverySession) error {
|
||||
|
@ -38,12 +46,15 @@ func scanV4(discoverySession session.DiscoverySession) error {
|
|||
}()
|
||||
|
||||
timerStopped := make(chan struct{})
|
||||
stopChan := make(chan struct{})
|
||||
defer close(stopChan)
|
||||
|
||||
go func() {
|
||||
hosts := make(map[string]*omd.Host)
|
||||
|
||||
var delay atomic.Value
|
||||
delay.Store(false)
|
||||
ticker := time.NewTicker(time.Millisecond * 500)
|
||||
ticker := time.NewTicker(time.Millisecond * 1000)
|
||||
|
||||
for {
|
||||
select {
|
||||
|
@ -67,7 +78,7 @@ func scanV4(discoverySession session.DiscoverySession) error {
|
|||
}
|
||||
}()
|
||||
|
||||
if err := sendICMP4(ps, zone, targetHosts); nil != err {
|
||||
if err := sendICMP4(ps, discoverySession, stopChan); nil != err {
|
||||
log.Printf("sendICMP %v", err)
|
||||
return nil
|
||||
}
|
||||
|
@ -80,31 +91,53 @@ func scanV4(discoverySession session.DiscoverySession) error {
|
|||
}
|
||||
}
|
||||
|
||||
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()
|
||||
func sendICMP4(ps pcap.PCapScanner, discoverySession session.DiscoverySession, stopChan chan struct{}) error {
|
||||
targetHosts := discoverySession.TargetHosts()
|
||||
|
||||
msg, err := makeMessageICMP4()
|
||||
icmp4Packet, err := makePacketICMPv4(discoverySession.Zone())
|
||||
if nil != err {
|
||||
return err
|
||||
}
|
||||
|
||||
var dst net.IPAddr
|
||||
buf := gopacket.NewSerializeBuffer()
|
||||
|
||||
LOOP:
|
||||
for _, targetHost := range targetHosts {
|
||||
dst.IP = targetHost
|
||||
if _, err := conn.WriteTo(msg, &dst); nil != err {
|
||||
h := discoverySession.DiscoveredHost(targetHost.String())
|
||||
if nil != h && "" != h.Mac {
|
||||
mac, err := net.ParseMAC(h.Mac)
|
||||
if nil != err {
|
||||
icmp4Packet.Eth.DstMAC = nil
|
||||
} else {
|
||||
icmp4Packet.Eth.DstMAC = mac
|
||||
}
|
||||
}
|
||||
if nil == icmp4Packet.Eth.DstMAC {
|
||||
icmp4Packet.Eth.DstMAC = net.HardwareAddr{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
|
||||
}
|
||||
|
||||
icmp4Packet.IP.DstIP = targetHost
|
||||
icmp4Packet.IP.Id = uint16(rand.Intn(UINT16))
|
||||
|
||||
icmp4Packet.ICMPv4.Id = uint16(rand.Intn(0xffff))
|
||||
icmp4Packet.ICMPv4.Seq = uint16(rand.Intn(0xffff))
|
||||
|
||||
if err := gopacket.SerializeLayers(buf, icmp4Packet.Opts, icmp4Packet.Eth, icmp4Packet.IP, icmp4Packet.ICMPv4); err != nil {
|
||||
log.Print(err)
|
||||
continue LOOP
|
||||
}
|
||||
if err := ps.WritePacketData(buf.Bytes()); err != nil {
|
||||
log.Print(err)
|
||||
continue LOOP
|
||||
}
|
||||
|
||||
select {
|
||||
case <-time.After(time.Microsecond * 100):
|
||||
case <-stopChan:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -152,17 +185,47 @@ func handlePacketICMP4(zone *omd.Zone, targetHosts []net.IP, hosts map[string]*o
|
|||
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)
|
||||
type PacketICMPv4 struct {
|
||||
Eth *layers.Ethernet
|
||||
IP *layers.IPv4
|
||||
ICMPv4 *layers.ICMPv4
|
||||
Opts gopacket.SerializeOptions
|
||||
}
|
||||
|
||||
func makePacketICMPv4(zone *omd.Zone) (*PacketICMPv4, error) {
|
||||
packetICMPv4 := &PacketICMPv4{}
|
||||
|
||||
srcIP := net.ParseIP(zone.Address)
|
||||
if nil == srcIP {
|
||||
return nil, fmt.Errorf("IP(%s) of zone is not valid", zone.Address)
|
||||
}
|
||||
|
||||
srcMac, err := net.ParseMAC(zone.Mac)
|
||||
if nil != err {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
packetICMPv4.Eth = &layers.Ethernet{
|
||||
SrcMAC: srcMac,
|
||||
EthernetType: layers.EthernetTypeIPv4,
|
||||
}
|
||||
|
||||
packetICMPv4.IP = &layers.IPv4{
|
||||
SrcIP: srcIP,
|
||||
Flags: DF,
|
||||
Version: 4,
|
||||
TTL: 64,
|
||||
Protocol: layers.IPProtocolICMPv4,
|
||||
}
|
||||
|
||||
packetICMPv4.ICMPv4 = &layers.ICMPv4{
|
||||
TypeCode: layers.CreateICMPv4TypeCode(layers.ICMPv4TypeEchoRequest, 0),
|
||||
}
|
||||
|
||||
packetICMPv4.Opts = gopacket.SerializeOptions{
|
||||
ComputeChecksums: true,
|
||||
FixLengths: true,
|
||||
}
|
||||
|
||||
return packetICMPv4, nil
|
||||
}
|
||||
|
|
|
@ -18,7 +18,12 @@ func Test_scanV4(t *testing.T) {
|
|||
"testRequester",
|
||||
types.DiscoveryRequestTypeHost,
|
||||
__test.Zone(),
|
||||
__test.DiscoverHost(__test.DiscoveryConfig(), 1, 254, nil),
|
||||
__test.DiscoverHost(
|
||||
__test.DiscoveryConfig(),
|
||||
1,
|
||||
254,
|
||||
nil,
|
||||
),
|
||||
)
|
||||
|
||||
type args struct {
|
||||
|
@ -49,8 +54,8 @@ func Test_scanV4(t *testing.T) {
|
|||
func Test_sendICMP4(t *testing.T) {
|
||||
type args struct {
|
||||
ps pcap.PCapScanner
|
||||
zone *omd.Zone
|
||||
targetHosts []net.IP
|
||||
discoverySession session.DiscoverySession
|
||||
stopChan chan struct{}
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@ -61,7 +66,7 @@ func Test_sendICMP4(t *testing.T) {
|
|||
}
|
||||
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 {
|
||||
if err := sendICMP4(tt.args.ps, tt.args.discoverySession, tt.args.stopChan); (err != nil) != tt.wantErr {
|
||||
t.Errorf("sendICMP4() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
|
@ -91,23 +96,27 @@ func Test_handlePacketICMP4(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_makeMessageICMP4(t *testing.T) {
|
||||
func Test_makePacketICMPv4(t *testing.T) {
|
||||
type args struct {
|
||||
zone *omd.Zone
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
want []byte
|
||||
args args
|
||||
want *PacketICMPv4
|
||||
wantErr bool
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := makeMessageICMP4()
|
||||
got, err := makePacketICMPv4(tt.args.zone)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("makeMessageICMP4() error = %v, wantErr %v", err, tt.wantErr)
|
||||
t.Errorf("makePacketICMPv4() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("makeMessageICMP4() = %v, want %v", got, tt.want)
|
||||
t.Errorf("makePacketICMPv4() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user