Пример #1
0
func ping(ip string) error {
	c, err := net.Dial("ip4:icmp", ip)
	if err != nil {
		panic(err)
	}
	glog.V(4).Infof("icmp to %s\n", ip)
	c.SetDeadline(time.Now().Add(time.Second))
	defer c.Close()
	typ := icmpv4EchoRequest
	xid := os.Getpid() & 0xffff
	xseq := 1
	wb, err := (&icmpMessage{Type: typ, Code: 0, Body: &icmpEcho{ID: xid, Seq: xseq, Data: bytes.Repeat([]byte("Go ping"), 10)}}).Marshal()
	if err != nil {
		return err
	}
	if _, err := c.Write(wb); err != nil {
		return err
	}
	rb := make([]byte, 20+len(wb))
	var m *icmpMessage
	for {
		if _, err := c.Read(rb); err != nil {
			if strings.HasSuffix(err.Error(), "i/o timeout") {
				return fmt.Errorf("timeout: %v", err)
			} else {
				return (err)
			}
		}
		rb = ipv4Payload(rb)
		if m, err = parseICMPMessage(rb); err != nil {
			return (err)
		}
		switch m.Type {
		case icmpv4EchoRequest:
			continue
		}
		break
	}
	switch p := m.Body.(type) {
	case *icmpEcho:
		if p.ID != xid || p.Seq != xseq {
			fmt.Printf("bad xid %d != %d seq %d != %d\n", p.ID, xid, p.Seq, xseq)
			return fmt.Errorf("bad xid")
		}
	default:
		return fmt.Errorf("bad type")
	}
	glog.V(2).Infof("got %v", m)
	return nil
}
Пример #2
0
func main() {
	var CIDR, dev, OUIFile string
	var timeout int64
	JSON := false
	flag.BoolVar(&JSON, "json", false, "output JSON")
	flag.StringVar(&CIDR, "cidr", "", "CIDR to scan")
	flag.StringVar(&OUIFile, "ouifile", "ieee-oui.txt", "IEEE OUI database text file")
	flag.StringVar(&dev, "dev", "", "net device to use")
	flag.Int64Var(&timeout, "timeout", 5, "seconds to timeout")
	flag.Parse()
	if dev == "" || CIDR == "" {
		flag.Usage()
		os.Exit(1)
	}
	ch := make(chan *pingcap.PingScanResult, 1)
	startTime := time.Now().Unix()
	go func() {
		for {
			time.Sleep(time.Second)
			if (time.Now().Unix() - startTime) > timeout {
				glog.V(2).Infof("stopping after %d seconds.", timeout)
				os.Exit(1)
			}
		}
	}()
	go func() {
		for {
			res := <-ch
			if res.Type == "scan" {
				if JSON {
					jstr, err := json.Marshal(res.Scan)
					if err != nil {
						glog.Errorf("marshalling error: %v", err)
						continue
					}
					fmt.Println(string(jstr))
				} else {
					fmt.Println(res.Scan)
				}
			}
		}
	}()
	err := pingcap.PingScan(CIDR, OUIFile, dev, ch)
	if err != nil {
		panic(err)
	}
}
Пример #3
0
func pingAll(CIDR string, ch chan *PingScanResult) {
	ip, ipnet, err := net.ParseCIDR(CIDR)
	if err != nil {
		glog.Fatal(err)
	}
	targets := make([]string, 0)
	for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) {
		glog.V(4).Infof("adding %v", ip)
		targets = append(targets, ip.String())
	}
	var wg sync.WaitGroup
	for _, ip := range targets {
		wg.Add(1)
		go func(ipa string) {
			ping(ipa)
			psRes := PingScanResult{}
			psRes.Type = "ping"
			ch <- &psRes
			wg.Done()
		}(ip)
	}
	wg.Wait()
}
Пример #4
0
func PingScan(CIDR, OUIFile, dev string, ch chan *PingScanResult) error {
	h, err := pcap.OpenLive(dev, 256, true, 500)
	if err != nil {
		return err
	}
	defer h.Close()
	err = h.SetFilter("icmp")
	if err != nil {
		return err
	}
	go func() {
		pingAll(CIDR, ch)
	}()
	ouiDB := make(map[string]string)
	ouiFileExists := true
	f, err := os.OpenFile(OUIFile, os.O_RDONLY, 0666)
	if err != nil {
		ouiFileExists = false
	}
	defer f.Close()
	if ouiFileExists {
		fc, err := ioutil.ReadFile(OUIFile)
		if err == nil {
			lines := strings.Split(string(fc), "\n")
			for _, line := range lines {
				if line == "" || strings.HasPrefix(line, "#") {
					continue
				}
				fields := strings.Fields(line)
				ouiDB[fields[0]] = strings.Join(fields[1:], " ")
			}
		}
	}
	sres := []ScanResult{}
	// REDFLAG: cannot put this loop in goroutine because of
	// runtime.sigpanic from pkg/runtime/os_linux.c:222
	for pkt, r := h.NextEx(); r >= 0; pkt, r = h.NextEx() {
		if r == 0 {
			continue
		}
		pkt.Decode()
		srcVend := "?"
		destVend := "?"
		if len(ouiDB) > 0 {
			srcVend = fmt.Sprintf("%02X%02X%02X",
				pkt.SrcMac&0xff0000000000>>40,
				pkt.SrcMac&0xff00000000>>32,
				pkt.SrcMac&0xff000000>>24)
			srcVend = ouiDB[srcVend]
			destVend = fmt.Sprintf("%02X%02X%02X",
				pkt.DestMac&0xff0000000000>>40,
				pkt.DestMac&0xff00000000>>32,
				pkt.DestMac&0xff000000>>24)
			destVend = ouiDB[destVend]
		}
		glog.V(2).Infof("pkt: ether[%02X:%012X(%s):%012X(%s)] %v",
			pkt.Type, pkt.DestMac, destVend, pkt.SrcMac, srcVend, pkt)
		sr := ScanResult{}
		sr.SrcMACAddr = fmt.Sprintf("%012X", pkt.SrcMac)
		sr.SrcVendor = srcVend
		sr.SrcIPAddr = ""
		var ip *pcap.Iphdr
		for _, h := range pkt.Headers {
			glog.Infof("%v", reflect.TypeOf(h))
			if reflect.TypeOf(h) == reflect.TypeOf(ip) {
				ip = h.(*pcap.Iphdr)
				sr.SrcIPAddr = ip.SrcAddr()
			}
		}
		sres = append(sres, sr)
		psRes := PingScanResult{}
		psRes.Type = "scan"
		psRes.Scan = sr
		ch <- &psRes
	}
	//not reached
	glog.V(2).Infof("exiting pcap capture. %v", h.Geterror())
	return nil
}