Example #1
0
File: pkg.go Project: yubo/falcon
func pkt(ip [4]byte) []byte {
	h := ipv4.Header{
		Version:  4,
		Len:      20,
		TotalLen: 20 + 10, // 20 bytes for IP, 10 for ICMP
		TTL:      64,
		Protocol: 1, // ICMP
		Dst:      net.IPv4(ip[0], ip[1], ip[2], ip[3]),
		// ID, Src and Checksum will be set for us by the kernel
	}

	icmp := []byte{
		8, // type: echo request
		0, // code: not used by echo request
		0, // checksum (16 bit), we fill in below
		0,
		0, // identifier (16 bit). zero allowed.
		0,
		0, // sequence number (16 bit). zero allowed.
		0,
		0xC0, // Optional data. ping puts time packet sent here
		0xDE,
	}
	cs := csum(icmp)
	icmp[2] = byte(cs)
	icmp[3] = byte(cs >> 8)

	out, err := h.Marshal()
	if err != nil {
		glog.Error(err)
	}
	return append(out, icmp...)
}
Example #2
0
File: ping.go Project: conoro/netx
func (this *Pinger) sendMessage(m *icmp.Message, wh *ipv4.Header) error {
	select {
	case <-this.done:
		return nil

	default:
	}

	var (
		wb        []byte
		tempDelay time.Duration // how long to sleep on accept failure
		ticker    = time.NewTicker(this.Interval)
	)

	for i, dst := range this.IPs() {
		if i != 0 {
			<-ticker.C
		}

		binary.BigEndian.PutUint64(this.payload, uint64(time.Now().UnixNano()))

		wb, err := this.marshalMessage(m, wb)
		if err != nil {
			glog.Errorf("Error creating ICMP payload: %v", err)
			continue
		}

		wh.TotalLen = ipv4.HeaderLen + len(wb)
		wh.Dst = dst

		glog.Debugf("Pinging %s", wh.Dst)
		this.mu.Lock()
		this.results[wh.Dst.String()] = nil
		this.mu.Unlock()

		if err := this.rconn.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
			return err
		}

		if err := this.rconn.WriteTo(wh, wb, nil); err != nil {
			select {
			case <-this.done:
				return nil

			default:
			}

			// Borrowed from go1.3.3/src/pkg/net/http/server.go:1699
			if ne, ok := err.(net.Error); ok && ne.Temporary() {
				if tempDelay == 0 {
					tempDelay = 5 * time.Millisecond
				} else {
					tempDelay *= 2
				}

				if max := 1 * time.Second; tempDelay > max {
					tempDelay = max
				}

				glog.Errorf("write error: %v; retrying in %v", err, tempDelay)
				time.Sleep(tempDelay)
				continue // out of the IP list, wait for next tick
			}

			return err
		}
	}

	if err := this.rconn.SetReadDeadline(time.Now().Add(this.MaxRTT)); err != nil {
		return err
	}

	return nil
}