func getRusage(usage usageType) float64 { rusage := &syscall.Rusage{} syscall.Getrusage(0, rusage) var time *syscall.Timeval if usage == USER_TIME { time = &rusage.Utime } else { time = &rusage.Stime } nsec := time.Nano() return float64(nsec) / 1000000000 }
func (p *Pinger) listenIpv4() { if p.conn == nil { panic("conn doesnt exist") } log.Printf("starting rawSocket listener\n") rb := make([]byte, 1500) pkt := EchoResponse{} var readErr error var data []byte ipconn, ok := p.conn.(*net.IPConn) if !ok { panic("connection is not IPConn") } file, err := ipconn.File() if err != nil { panic(err.Error()) } defer file.Close() fd := file.Fd() var pktTime time.Time recvTime := syscall.Timeval{} for { if p.conn == nil { break } n, peer, err := p.conn.ReadFrom(rb) if err != nil { readErr = err break } _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.SIOCGSTAMP), uintptr(unsafe.Pointer(&recvTime))) err = nil if errno != 0 { err = errno } if err == nil { pktTime = time.Unix(0, recvTime.Nano()) } else { pktTime = time.Now() } rm, err := icmp.ParseMessage(ProtocolICMP, rb[:n]) if err != nil { fmt.Println(err.Error()) continue } if rm.Type == ipv4.ICMPTypeEchoReply { data = rm.Body.(*icmp.Echo).Data if len(data) < 9 { log.Printf("go-pinger: invalid data payload from %s. Expected at least 9bytes got %d", peer.String(), len(data)) continue } pkt = EchoResponse{ Peer: peer.String(), Seq: rm.Body.(*icmp.Echo).Seq, Id: rm.Body.(*icmp.Echo).ID, Received: pktTime, } if p.Debug { log.Printf("go-pinger: recieved pkt. %s\n", pkt.String()) } select { case p.packetChan <- pkt: default: log.Printf("go-pinger: droped echo response due to blocked packetChan. %s\n", pkt.String()) } } } if p.Debug { log.Printf("listen loop ended.") } p.m.Lock() if p.running { log.Println(readErr.Error()) p.Stop() p.start() } p.m.Unlock() }
func timevalToDuration(tv syscall.Timeval) time.Duration { return time.Duration(tv.Nano()) * time.Nanosecond }