ing
This commit is contained in:
		
							parent
							
								
									4728182733
								
							
						
					
					
						commit
						9a8684e25a
					
				@ -3,7 +3,6 @@ package privileged
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
	"math/rand"
 | 
			
		||||
	"net"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
	"time"
 | 
			
		||||
@ -15,8 +14,6 @@ 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/ipv6"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func scanV6(discoverySession session.DiscoverySession) error {
 | 
			
		||||
@ -38,17 +35,21 @@ func scanV6(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 {
 | 
			
		||||
			case packet, ok := <-icmpChan:
 | 
			
		||||
				if !ok {
 | 
			
		||||
					// logging.Logger().Debugf("icmp channel is closed")
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				delay.Store(true)
 | 
			
		||||
@ -66,7 +67,7 @@ func scanV6(discoverySession session.DiscoverySession) error {
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	if err := sendICMP6(ps, zone, targetHosts); nil != err {
 | 
			
		||||
	if err := sendICMP6(ps, discoverySession, stopChan); nil != err {
 | 
			
		||||
		log.Printf("sendICMP %v", err)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
@ -79,31 +80,49 @@ func scanV6(discoverySession session.DiscoverySession) error {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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()
 | 
			
		||||
func sendICMP6(ps pcap.PCapScanner, discoverySession session.DiscoverySession, stopChan chan struct{}) error {
 | 
			
		||||
	targetHosts := discoverySession.TargetHosts()
 | 
			
		||||
 | 
			
		||||
	msg, err := makeMessageICMP6()
 | 
			
		||||
	icmp6Packet, err := makePacketICMPv6(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 {
 | 
			
		||||
				icmp6Packet.Eth.DstMAC = nil
 | 
			
		||||
			} else {
 | 
			
		||||
				icmp6Packet.Eth.DstMAC = mac
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if nil == icmp6Packet.Eth.DstMAC {
 | 
			
		||||
			icmp6Packet.Eth.DstMAC = net.HardwareAddr{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		icmp6Packet.IP.DstIP = targetHost
 | 
			
		||||
 | 
			
		||||
		if err := gopacket.SerializeLayers(buf, icmp6Packet.Opts, icmp6Packet.Eth, icmp6Packet.IP, icmp6Packet.ICMPv6); 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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -151,17 +170,49 @@ func handlePacketICMP6(zone *omd.Zone, targetHosts []net.IP, hosts map[string]*o
 | 
			
		||||
	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)
 | 
			
		||||
type PacketICMPv6 struct {
 | 
			
		||||
	Eth    *layers.Ethernet
 | 
			
		||||
	IP     *layers.IPv6
 | 
			
		||||
	ICMPv6 *layers.ICMPv6
 | 
			
		||||
	Opts   gopacket.SerializeOptions
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func makePacketICMPv6(zone *omd.Zone) (*PacketICMPv6, error) {
 | 
			
		||||
	packetICMPv6 := &PacketICMPv6{}
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	packetICMPv6.Eth = &layers.Ethernet{
 | 
			
		||||
		SrcMAC:       srcMac,
 | 
			
		||||
		EthernetType: layers.EthernetTypeIPv6,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	packetICMPv6.IP = &layers.IPv6{
 | 
			
		||||
		Version:      6,
 | 
			
		||||
		TrafficClass: 0,
 | 
			
		||||
		FlowLabel:    0,
 | 
			
		||||
		Length:       24,
 | 
			
		||||
		NextHeader:   layers.IPProtocolICMPv6,
 | 
			
		||||
		HopLimit:     255,
 | 
			
		||||
		SrcIP:        srcIP,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	packetICMPv6.ICMPv6 = &layers.ICMPv6{
 | 
			
		||||
		TypeCode: layers.CreateICMPv6TypeCode(layers.ICMPv6TypeEchoRequest, 0),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	packetICMPv6.Opts = gopacket.SerializeOptions{
 | 
			
		||||
		ComputeChecksums: true,
 | 
			
		||||
		FixLengths:       true,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return packetICMPv6, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user